I am trying to create a line chart in which I will continuously plot data so the graph can be observed in real time updating, will be plotting around 5 points or so a second. The kind of graph I am looking for will look something like the graph shown here
https://www.vanmil.org/live-heart-rate-with-ios-and-meteor/
or
http://www.highcharts.com/demo/dynamic-update
I have been playing about with several different charting frameworks such as iOS charts, but I can't seem to get the exact graph I am looking for where live updates can be charted with an evolving X-Axis.
Using iOS charts, I managed to create a sort of evolving graph, example code below.
@IBOutlet weak var chartView: LineChartView!
var xAxisArray : [String]?
var yAxisArray : [Double]?
var date : NSDate?
var dateFormatter : NSDateFormatter?
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Live Graph"
let stringArray = NSMutableArray()
let numberArray = NSMutableArray()
dateFormatter = NSDateFormatter()
dateFormatter!.dateFormat = "HH:mm:ss"
date = NSDate()
//Insert random values into chart
for(var i = 0; i < 40; i++)
{
date = date!.dateByAddingTimeInterval(0.3)
let stringDate = dateFormatter?.stringFromDate(date!)
stringArray.addObject(stringDate!)
let randomNum = self.randomBetweenNumbers(0.0005, secondNum: 0.0015)
numberArray.addObject(randomNum)
}
xAxisArray = stringArray as NSArray as? [String]
yAxisArray = numberArray as NSArray as? [Double]
configureChart()
setData()
NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector: "updateChart", userInfo: nil, repeats: true)
}
func configureChart()
{
//Chart config
chartView.descriptionText = ""
chartView.noDataTextDescription = "Add Data"
chartView.drawGridBackgroundEnabled = false
chartView.dragEnabled = true
chartView.rightAxis.enabled = false
chartView.doubleTapToZoomEnabled = false
chartView.legend.enabled = false
//Configure xAxis
let chartXAxis = chartView.xAxis as ChartXAxis
chartXAxis.labelPosition = .Bottom
chartXAxis.setLabelsToSkip(5)
//configure yAxis
chartView.zoom(1.0, scaleY: 1.0, x: 0.0, y: 0.0)
}
func randomBetweenNumbers(firstNum: CGFloat, secondNum: CGFloat) -> CGFloat{
return CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(firstNum - secondNum) + min(firstNum, secondNum)
}
func updateChart()
{
let mutableArray = NSMutableArray()
for(var i = 1; i < xAxisArray?.count; i++)
{
mutableArray.addObject(xAxisArray![i])
}
date = date!.dateByAddingTimeInterval(1.0)
let str = dateFormatter!.stringFromDate(date!)
mutableArray.addObject(str)
xAxisArray = mutableArray as NSArray as? [String]
//Numbers
let numberArray = NSMutableArray()
for(var i = 1; i < yAxisArray?.count; i++)
{
numberArray.addObject(yAxisArray![i])
}
let randomNum = self.randomBetweenNumbers(0.0005, secondNum: 0.0015)
let convertToDouble = Double(randomNum)
numberArray.addObject(convertToDouble)
yAxisArray = numberArray as NSArray as? [Double]
setData()
}
func setData()
{
// 1 - creating an array of data entries
var yVals1 : [ChartDataEntry] = [ChartDataEntry]()
for var i = 0; i < xAxisArray!.count; i++ {
yVals1.append(ChartDataEntry(value: yAxisArray![i], xIndex: i))
}
// 2 - create a data set with our array
let set1: LineChartDataSet = LineChartDataSet(yVals: yVals1, label: "")
set1.axisDependency = .Left // Line will correlate with left axis values
set1.setColor(UIColor.blueColor().colorWithAlphaComponent(0.5)) // our line's opacity is 50%
set1.setCircleColor(UIColor.blueColor()) // our circle will be dark red
set1.lineWidth = 2.0
set1.circleRadius = 6.0 // the radius of the node circle
set1.fillAlpha = 65 / 255.0
set1.fillColor = UIColor.blueColor()
set1.highlightColor = UIColor.whiteColor()
set1.drawCircleHoleEnabled = true
set1.drawFilledEnabled = true
//3 - create an array to store our LineChartDataSets
var dataSets : [LineChartDataSet] = [LineChartDataSet]()
dataSets.append(set1)
//4 - pass our months in for our x-axis label value along with our dataSets
let data: LineChartData = LineChartData(xVals: xAxisArray, dataSets: dataSets)
//5 - finally set our data
self.chartView.data = data
//Clear text color
chartView.data?.setValueTextColor(UIColor.clearColor())
}
But if you try it out, you can see it is fairly jerky, plus every x axis label updates, I was hoping to have the X axis continue to evolve and just have it animate off the screen as the plotting continues like the one shown in the example.
Does anyone know any charting software that would allow me to replicate this type of graph, or if this effect can be achieved using iOS charts?
Edit:
I am trying to achieve this type of plotting example
http://www.code4app.net/ios/Dynamic-plot-curve-line-like-stock-chart/52d68b75cb7e84802f8b5340
Just hopefully a lot smoother,
Now this can be done using iOS charts:
override func viewDidLoad() {
super.viewDidLoad()
//charts
self.lineChartView.delegate = self
let set_a: LineChartDataSet = LineChartDataSet(yVals: [ChartDataEntry](), label: "a")
set_a.drawCirclesEnabled = false
set_a.setColor(UIColor.blueColor())
let set_b: LineChartDataSet = LineChartDataSet(yVals: [ChartDataEntry](), label: "b")
set_b.drawCirclesEnabled = false
set_b.setColor(UIColor.greenColor())
self.lineChartView.data = LineChartData(xVals: [String](), dataSets: [set_a, set_b])
timer = NSTimer.scheduledTimerWithTimeInterval(0.010, target:self, selector: #selector(ViewController.updateCounter), userInfo: nil, repeats: true)
}
// add point
var i = 0
func updateCounter() {
self.lineChartView.data?.addEntry(ChartDataEntry(value: reading_a[i], xIndex: i), dataSetIndex: 0)
self.lineChartView.data?.addEntry(ChartDataEntry(value: reading_b[i], xIndex: i), dataSetIndex: 1)
self.lineChartView.data?.addXValue(String(i))
self.lineChartView.setVisibleXRange(minXRange: CGFloat(1), maxXRange: CGFloat(50))
self.lineChartView.notifyDataSetChanged()
self.lineChartView.moveViewToX(CGFloat(i))
i = i + 1
}