How to make a grouped BarChart with ios-charts? - ios

I am using ios-charts library.
I would like to group my inverter values so that each year is one group. Unfortunately, the number of monthly values per year may vary.
My data json looks like this:
{"monthlyData":[{"ERTRAG":"30.2989999055862","MONAT":"2","JAHR":"2016"},{"ERTRAG":"154.897000223398","MONAT":"1","JAHR":"2016"},{"ERTRAG":"141.996000155807","MONAT":"12","JAHR":"2015"},{"ERTRAG":"135.449000149965","MONAT":"11","JAHR":"2015"},{"ERTRAG":"319.437000751495","MONAT":"10","JAHR":"2015"},{"ERTRAG":"483.369997739792","MONAT":"9","JAHR":"2015"},{"ERTRAG":"698.112997770309","MONAT":"8","JAHR":"2015"},{"ERTRAG":"771.764000892639","MONAT":"7","JAHR":"2015"},{"ERTRAG":"736.611003398895","MONAT":"6","JAHR":"2015"},{"ERTRAG":"737.237999916077","MONAT":"5","JAHR":"2015"},{"ERTRAG":"720.181995391846","MONAT":"4","JAHR":"2015"},{"ERTRAG":"484.979001283646","MONAT":"3","JAHR":"2015"},{"ERTRAG":"249.974001646042","MONAT":"2","JAHR":"2015"},{"ERTRAG":"92.8830004036427","MONAT":"1","JAHR":"2015"},{"ERTRAG":"52.7970000207424","MONAT":"12","JAHR":"2014"},{"ERTRAG":"181.025999426842","MONAT":"11","JAHR":"2014"},{"ERTRAG":"332.789002537727","MONAT":"10","JAHR":"2014"},{"ERTRAG":"482.244999885559","MONAT":"9","JAHR":"2014"},{"ERTRAG":"602.811999320984","MONAT":"8","JAHR":"2014"},{"ERTRAG":"699.872003316879","MONAT":"7","JAHR":"2014"},{"ERTRAG":"828.212007522583","MONAT":"6","JAHR":"2014"},{"ERTRAG":"679.010004997253","MONAT":"5","JAHR":"2014"},{"ERTRAG":"635.115998744965","MONAT":"4","JAHR":"2014"},{"ERTRAG":"559.617002010345","MONAT":"3","JAHR":"2014"},{"ERTRAG":"265.135001063347","MONAT":"2","JAHR":"2014"},{"ERTRAG":"165.272998273373","MONAT":"1","JAHR":"2014"},{"ERTRAG":"134.578999936581","MONAT":"12","JAHR":"2013"},{"ERTRAG":"153.774000287056","MONAT":"11","JAHR":"2013"},{"ERTRAG":"321.733997344971","MONAT":"10","JAHR":"2013"},{"ERTRAG":"482.768000483513","MONAT":"9","JAHR":"2013"},{"ERTRAG":"692.864000797272","MONAT":"8","JAHR":"2013"},{"ERTRAG":"846.429007053375","MONAT":"7","JAHR":"2013"},{"ERTRAG":"709.758005619049","MONAT":"6","JAHR":"2013"},{"ERTRAG":"532.493996858597","MONAT":"5","JAHR":"2013"},{"ERTRAG":"462.539998054504","MONAT":"4","JAHR":"2013"},{"ERTRAG":"419.105004012585","MONAT":"3","JAHR":"2013"},{"ERTRAG":"143.189998820424","MONAT":"2","JAHR":"2013"},{"ERTRAG":"78.720000628382","MONAT":"1","JAHR":"2013"},{"ERTRAG":"90.1430006623268","MONAT":"12","JAHR":"2012"},{"ERTRAG":"155.483000457287","MONAT":"11","JAHR":"2012"},{"ERTRAG":"348.231998205185","MONAT":"10","JAHR":"2012"},{"ERTRAG":"598.037001848221","MONAT":"9","JAHR":"2012"},{"ERTRAG":"729.740003108978","MONAT":"8","JAHR":"2012"},{"ERTRAG":"676.923998832703","MONAT":"7","JAHR":"2012"},{"ERTRAG":"694.879002094269","MONAT":"6","JAHR":"2012"},{"ERTRAG":"811.281997680664","MONAT":"5","JAHR":"2012"},{"ERTRAG":"489.765002369881","MONAT":"4","JAHR":"2012"},{"ERTRAG":"538.866001605988","MONAT":"3","JAHR":"2012"},{"ERTRAG":"277.856996208429","MONAT":"2","JAHR":"2012"},{"ERTRAG":"155.854999214411","MONAT":"1","JAHR":"2012"},{"ERTRAG":"148.157999750227","MONAT":"12","JAHR":"2011"},{"ERTRAG":"230.409998774529","MONAT":"11","JAHR":"2011"}]}
I tried the following:
var months = Array<String>()
var years = Array<String>()
var dataEntries: [BarChartDataEntry] = []
var dataSets: [BarChartDataSet] = []
var overallSum = 0.0
var year = 2010 //monthlyValues[0].year
var count = 0
var chartDataSet: BarChartDataSet?
for i in 0..<monthlyValues.count {
// if year is different, create new barchartdataset
if monthlyValues[i].year != year {
years.append("\(monthlyValues[i].year)")
chartDataSet = BarChartDataSet(yVals: dataEntries, label: "\(year)")
chartDataSet!.colors = [UIColor.whiteColor()]
dataSets.append(chartDataSet!)
year = monthlyValues[i].year
dataEntries = []
//months = []
count = 0
}
months.append("\(monthlyValues[i].month)")
overallSum += monthlyValues[i].amount
let dataEntry = BarChartDataEntry(value: monthlyValues[i].amount, xIndex: count)
count++
dataEntries.append(dataEntry)
}
let chartData = BarChartData(xVals: months, dataSets: dataSets)
self.barChartView.data = chartData
This results in five series with the right year labels in the legend but there is no group separator in the chart and also the number of bars per year is either 4 or 5 (expected = 12).
Thanks for any hint on this!

let months = ["Jan", "Feb", "Mar", "Apr", "May"]
let unitsSold = [20.0, 4.0, 6.0, 3.0, 12.0]
let unitsBought = [10.0, 14.0, 60.0, 13.0, 2.0]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
barChartView.delegate = self
barChartView.noDataText = "You need to provide data for the chart."
barChartView.chartDescription?.text = "sales vs bought "
//legend
let legend = barChartView.legend
legend.enabled = true
legend.horizontalAlignment = .right
legend.verticalAlignment = .top
legend.orientation = .vertical
legend.drawInside = true
legend.yOffset = 10.0;
legend.xOffset = 10.0;
legend.yEntrySpace = 0.0;
let xaxis = barChartView.xAxis
xaxis.valueFormatter = axisFormatDelegate
xaxis.drawGridLinesEnabled = true
xaxis.labelPosition = .bottom
xaxis.centerAxisLabelsEnabled = true
xaxis.valueFormatter = IndexAxisValueFormatter(values:self.months)
xaxis.granularity = 1
let leftAxisFormatter = NumberFormatter()
leftAxisFormatter.maximumFractionDigits = 1
let yaxis = barChartView.leftAxis
yaxis.spaceTop = 0.35
yaxis.axisMinimum = 0
yaxis.drawGridLinesEnabled = false
barChartView.rightAxis.enabled = false
//axisFormatDelegate = self
setChart()
}
func setChart() {
barChartView.noDataText = "You need to provide data for the chart."
var dataEntries: [BarChartDataEntry] = []
var dataEntries1: [BarChartDataEntry] = []
for i in 0..<self.months.count {
let dataEntry = BarChartDataEntry(x: Double(i) , y: self.unitsSold[i])
dataEntries.append(dataEntry)
let dataEntry1 = BarChartDataEntry(x: Double(i) , y: self.self.unitsBought[i])
dataEntries1.append(dataEntry1)
//stack barchart
//let dataEntry = BarChartDataEntry(x: Double(i), yValues: [self.unitsSold[i],self.unitsBought[i]], label: "groupChart")
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Unit sold")
let chartDataSet1 = BarChartDataSet(values: dataEntries1, label: "Unit Bought")
let dataSets: [BarChartDataSet] = [chartDataSet,chartDataSet1]
chartDataSet.colors = [UIColor(red: 230/255, green: 126/255, blue: 34/255, alpha: 1)]
//chartDataSet.colors = ChartColorTemplates.colorful()
//let chartData = BarChartData(dataSet: chartDataSet)
let chartData = BarChartData(dataSets: dataSets)
let groupSpace = 0.3
let barSpace = 0.05
let barWidth = 0.3
// (0.3 + 0.05) * 2 + 0.3 = 1.00 -> interval per "group"
let groupCount = self.months.count
let startYear = 0
chartData.barWidth = barWidth;
barChartView.xAxis.axisMinimum = Double(startYear)
let gg = chartData.groupWidth(groupSpace: groupSpace, barSpace: barSpace)
print("Groupspace: \(gg)")
barChartView.xAxis.axisMaximum = Double(startYear) + gg * Double(groupCount)
chartData.groupBars(fromX: Double(startYear), groupSpace: groupSpace, barSpace: barSpace)
//chartData.groupWidth(groupSpace: groupSpace, barSpace: barSpace)
barChartView.notifyDataSetChanged()
barChartView.data = chartData
//background color
barChartView.backgroundColor = UIColor(red: 189/255, green: 195/255, blue: 199/255, alpha: 1)
//chart animation
barChartView.animate(xAxisDuration: 1.5, yAxisDuration: 1.5, easingOption: .linear)
}

You got something wrong here. Right now you are creating a new DataSet for every year.
What you need to do is create as many DataSets as you want bars per group where one DataSet represents one bar in each group. (e.g. DataSet 1 represents every first bar of a group, DataSet 2 every second bar of a group, ...)
As an example, imagine a chart like this with 4 groups of 3 bars per group. Each group represents one year.
||| ||| ||| |||
The setup shown above requires 3 DataSets (one for each group)
Entries in the same group have the same x-index (e.g. in the first group all have x-index 0)
It consists of a total of 12 entries
Each DataSet contains 4 entries with Entry x-indices ranging from 0 to 3
Here you can find an example of the scenario described above and check out the documentation.

if you have noticed in above code in function chart. There is let
groupSpace = 0.3
let barSpace = 0.05
let barWidth = 0.3
// (0.3 + 0.05) * 2 + 0.3 = 1.00 -> interval per "group"
which will make equation
(groupSpace * barSpace) * n + groupSpace = 1
you need to play around this equation for n number of bars

I've tried Rajan Twanabashu solution, but it was almost the good one. Maybe it has changed since, I don't know.
Here's what I've done, after I found the groupWidth function in the BarDataChart file from Charts.
groupWidth function declaration
let groupSpace = 1 - n * (barWidth + barSpace)
Hope it could help

After diving in this equation "(0.3 + 0.05) * 2 + 0.3 = 1.00" to work on variant amount of grouping I got:
let n = Double(data.dataSets.count)
let groupSpace = 0.0031 * n
let barSpace = 0.002 * n
let barWidth = (1 - (n * barSpace) - groupSpace) / n
What is varying is barWidth.

Related

Not to start xAxis at zero in LineChart iOS Swift

I have created lineChartView. Below xAxis values are displayed hours with 1 hour time interval. My graph starts at 0 and I am not able to show proper xAxis label value.
I want to put extra space in xAxis starting so that the xAxis label can proper visible.
Here is my code:
func setChart(yValues: [Double], xValues: [String]) {
chartView.noDataText = "You need to provide data for the chart."
var dataEntries: [ChartDataEntry] = []
for i in 0..<yValues.count {
let dataEntry = ChartDataEntry(x: Double(i), y: yValues[i])
dataEntries.append(dataEntry)
}
let chartDataSet = LineChartDataSet(entries: dataEntries, label: "")
chartDataSet.colors = [.black]
chartDataSet.drawFilledEnabled = true
let chartData = LineChartData(dataSet: chartDataSet)
let chartFormatter = LineChartFormatter(labels: xValues)
chartView.xAxis.valueFormatter = chartFormatter
chartView.xAxis.labelCount = dataEntries.count
chartView.data = chartData
chartView.xAxis.granularity = 1.0
chartView.xAxis.granularityEnabled = true
chartView.xAxis.centerAxisLabelsEnabled = false
chartView.xAxis.axisMinimum = 0
chartView.xAxis.axisMaximum = Double(dataEntries.count)
chartView.setVisibleXRange(minXRange: 1.0, maxXRange: 3.0)
}

How to create a grouped bar chart in Swift?

I am using Charts library to display charts in my app. I have a bar chart in my app that used to work fine in Swift 2.3 and Charts version 2.2.5. However, I recently updated my app to Swift 4.1 and Charts 3.1.0, but breaking changes in Charts library break the functionality in my app.
How do I properly migrate this block of code to work in new versions?
This is the example chart that I am using:
And this is the JSON data that creates this chart:
[{"Items":[{"X":"01.03.2018","Value":10000},{"X":"02.03.2018","Value":2500}],"Name":"Group 1"},{"Items":[{"X":"01.03.2018","Value":5000}],"Name":"Group 2"}]
This is the code that I used in Swift 2.3 that worked fine:
var xVals = [String]()
var datasets = [BarChartDataSet]()
for i in 0..<json.count{
var entries = [BarChartDataEntry]()
for j in 0..<json[i]["Items"].count{
if i == 0{
xVals.append(json[i]["Items"][j]["X"].stringValue)
}
if json[i]["Items"][j]["Value"].doubleValue != 0.0{
let entry = BarChartDataEntry(value: json[i]["Items"][j]["Value"].doubleValue, xIndex: j)
entries.append(entry)
}
}
let dataset = BarChartDataSet(yVals: entries, label: json[i]["Name"].stringValue)
datasets.append(dataset)
}
let data = BarChartData(xVals: xVals, dataSets: datasets)
barChart.data = data
This is how it looks after migration:
There are 2 problems with this:
Bars are stacked instead of grouped.
xAxis does show indexes instead of dates.
This is the new Swift 4.1 code:
var xVals = [String]()
var datasets = [BarChartDataSet]()
for i in 0..<json.count{
var entries = [BarChartDataEntry]()
for j in 0..<json[i]["Items"].count{
if i == 0{
xVals.append(json[i]["Items"][j]["X"].stringValue)
}
if json[i]["Items"][j]["Value"].doubleValue != 0.0{
let entry = BarChartDataEntry(x: Double(j), y: json[i]["Items"][j]["Value"].doubleValue)
entries.append(entry)
}
}
let dataset = BarChartDataSet(values: entries, label: json[i]["Name"].stringValue)
datasets.append(dataset)
}
let data = BarChartData(dataSets: datasets)
barChart.data = data
So how do I solve those 2 problems?
[Swift 4]You need to use groupBars and valueFormatter form BarChart API.
This is just an example of code, you need to fine tuning as per your requirement.
[Edit 1]
Formula: (0.2 + 0.03) * countGourp + 0.08 = 1.00 -> interval per "group"
let data = BarChartData(dataSets: datasets)
// (0.2 + 0.03) * 2 + 0.54 = 1.00
let groupSpace = 0.54
let barSpace = 0.03
let barWidth = 0.2
data.barWidth = barWidth
barView.xAxis.axisMinimum = Double(0)
barView.xAxis.axisMaximum = Double(0) + data.groupWidth(groupSpace: groupSpace, barSpace: barSpace) * Double(2) // group count : 2
data.groupBars(fromX: Double(0), groupSpace: groupSpace, barSpace: barSpace)
barView.data = data
let x_Axis = barView.xAxis
x_Axis.valueFormatter = IndexAxisValueFormatter(values:xVals)
x_Axis.centerAxisLabelsEnabled = true
x_Axis.granularity = 1
barView.xAxis.labelPosition = .top

iOS-Charts grouped bar chart with size to fit

I recently added "barChartData.groupBars(fromX: 0, groupSpace: 0.5, barSpace: 0.03)" to my Bar Chart so that I don't have overlapping bars and I can't figure it out how to set the width to fit (no horizontal overflow)
func setupGroupedBarChartData(values1: [String], values2: [String], barLabel1: String, barLabel2: String, barColor1: UIColor, barColor2: UIColor) -> BarChartData {
let dataValues1 = values1.flatMap{ Double($0) }
let dataValues2 = values2.flatMap{ Double($0) }
var dataEntries1: [BarChartDataEntry] = []
var dataEntries2: [BarChartDataEntry] = []
for i in 0..<dataValues1.count {
let dataEntry1 = BarChartDataEntry(x: Double(i), y: dataValues1[i])
dataEntries1.append(dataEntry1)
let dataEntry2 = BarChartDataEntry(x: Double(i), y: dataValues2[i])
dataEntries2.append(dataEntry2)
}
let chartDataSet1 = BarChartDataSet(values: dataEntries1, label: barLabel1)
chartDataSet1.colors = [barColor1]
chartDataSet1.valueTextColor = AppColors.lightText
let chartDataSet2 = BarChartDataSet(values: dataEntries2, label: barLabel2)
chartDataSet2.colors = [barColor2]
chartDataSet2.valueTextColor = AppColors.lightText
var groupedDataSet : [BarChartDataSet] = [BarChartDataSet]()
groupedDataSet.append(chartDataSet1)
groupedDataSet.append(chartDataSet2)
let barChartData = BarChartData(dataSets: groupedDataSet)
barChartData.groupBars(fromX: 0, groupSpace: 0.5, barSpace: 0.03)
//display data as integer
let format = NumberFormatter()
format.generatesDecimalNumbers = false
let formatter = DefaultValueFormatter(formatter: format)
barChartData.setValueFormatter(formatter)
return barChartData
}
You can use like this :
You calculation will be like below :
// (barWidth + barSpace) * (no.of.bars) + groupSpace = 1.00 -> interval per "group"
In your code :
barChartData.groupBars(fromX: 0, groupSpace: 0.14, barSpace: 0.03)
barChartData.barWidth = 0.4
barChartView.xAxis.axisMinimum = 0
barChartView.xAxis.axisMaximum = 23

ios charts not displaying line/bar in charts

I am working on ios-charts by Daniel Gindi on swift 3.0. I have written following code for bar charts
var dataEntries: [BarChartDataEntry] = []
for i in 0..<dateTime.count {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy hh:mm:ss aa"
let dateObj = dateFormatter.date(from: dateTime[i])
let timeIntervalForDate = dateObj!.timeIntervalSince1970
let dataEntry = BarChartDataEntry(x: Double(timeIntervalForDate), y: Double(readings[i]))
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Units")
let chartData = BarChartData(dataSet: chartDataSet)
self.ChartsView.data = chartData
i get following result in emulator:
you can see no red line reflecing my values. I even zoomed to charts but nothing was shown.
I also tried line chart with sample values. Here is the code:
let dollars1 = [20.0, 4.0, 6.0, 3.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
var yValues : [ChartDataEntry] = [ChartDataEntry]()
for i in 0 ..< months.count {
yValues.append(ChartDataEntry(x: Double(i + 1), y: dollars1[i]))
}
let LineData = LineChartData()
let ds = LineChartDataSet(values: yValues, label: "Months")
LineData.addDataSet(ds)
self.ChartsView.data = LineData
Its result is even more weird. No grid lines are shown either in this chart. Here is the image.
I am not sure what is wrong with these graphs. Am I missing something. So far i am unable to look any furthur as most solutions are using old version of charts(or may be it is something else i am not aware). Please guide me to proper direction. Thanks
I am struggling with Version 3.0 and Swift 3 and the lack of documentation... May I point you to the best text on the subject which can be found here
Xvals as Parameters are gone, instead you use two-dimensional data on axis
Regarding your problem with timevalues.. you could use the "timeIntervalSince1970" of the date-object and format things with an extension
return dateFormatter.string(from: Date(timeIntervalSince1970: value))
all of which is to be found at the link mentioned above
There is a bug in ios-charts try to use index of timestamp rather than using timestamp or date to show on the x-axis.
// i is the index of that timestamp in data.
let dataEntry = BarChartDataEntry(x: i, y: Double(readings[i]))
hey nothing is disabled in iOS charts everything is working fine..Here is the code that I have used in my app to display horizontal chart as well as vertical chart hope it helps to anyone who is stucked on IOS chart...stay tune with StackOverflow... enjoy coding :)
import UIKit
import Charts
class DashboardViewController: UIViewController, ChartViewDelegate
{
#IBOutlet weak var barview: BarChartView!
#IBOutlet weak var horizontalview: HorizontalBarChartView!
var attendencelabels = [String]()
let Present = [60.0, 60.0]
let Absent = [20.0,40.0]
var subjects : [String]!
var maxUnits : Double!
override func viewDidLoad() {
super.viewDidLoad()
barview.delegate = self
barview.noDataText = "You need to provide data for the chart."
barview.chartDescription?.text = ""
attendencelabels.append("March")
attendencelabels.append("April")
subjects = ["Physics","Chemistry","Biology","English","Maths"]
horizontalview.delegate = self
var marks = [60.0,70.0,60.0,80.0,90.0]
maxUnits = marks.max()
setHorizontalChart(dataPoints: subjects, values: marks)
//legend
let legend = barview.legend
legend.enabled = true
legend.horizontalAlignment = .center
legend.verticalAlignment = .bottom
legend.orientation = .horizontal
legend.drawInside = false
legend.yOffset = 10.0;
legend.xOffset = 10.0;
legend.yEntrySpace = 0.0;
let xaxis = barview.xAxis
xaxis.valueFormatter = DefaultAxisValueFormatter.self as! IAxisValueFormatter
xaxis.drawGridLinesEnabled = true
xaxis.labelPosition = .top
xaxis.centerAxisLabelsEnabled = true
xaxis.valueFormatter = IndexAxisValueFormatter(values:self.attendencelabels)
xaxis.granularity = 1
let leftAxisFormatter = NumberFormatter()
leftAxisFormatter.maximumFractionDigits = 1
let yaxis = barview.leftAxis
yaxis.spaceTop = 0.35
yaxis.axisMinimum = 0
yaxis.drawGridLinesEnabled = false
barview.rightAxis.enabled = false
setChart()
}
func setChart() {
barview.noDataText = "You need to provide data for the chart."
var dataEntries: [BarChartDataEntry] = []
var dataEntries1: [BarChartDataEntry] = []
for i in 0..<self.attendencelabels.count
{
let dataEntry = BarChartDataEntry(x: Double(i) , y: self.Present[i])
dataEntries.append(dataEntry)
let dataEntry1 = BarChartDataEntry(x: Double(i) , y: self.self.Absent[i])
dataEntries1.append(dataEntry1)
//stack barchart
//let dataEntry = BarChartDataEntry(x: Double(i), yValues: [self.unitsSold[i],self.unitsBought[i]], label: "groupChart")
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Working Days")
let chartDataSet1 = BarChartDataSet(values: dataEntries1, label: "Present Days")
let dataSets: [BarChartDataSet] = [chartDataSet,chartDataSet1]
chartDataSet.colors = [UIColor(red: 0/255, green: 255/255, blue: 25/255, alpha: 1)]
chartDataSet1.colors = [UIColor(red: 255/255, green: 0/255, blue: 61/255, alpha: 1)]
//chartDataSet.colors = ChartColorTemplates.colorful()
//let chartData = BarChartData(dataSet: chartDataSet)
let chartData = BarChartData(dataSets: dataSets)
let groupSpace = 0.3
let barSpace = 0.05
let barWidth = 0.3
// (0.3 + 0.05) * 2 + 0.3 = 1.00 -> interval per "group"
let groupCount = self.attendencelabels.count
let startYear = 0
chartData.barWidth = barWidth;
barview.xAxis.axisMinimum = Double(startYear)
let gg = chartData.groupWidth(groupSpace: groupSpace, barSpace: barSpace)
print("Groupspace: \(gg)")
barview.xAxis.axisMaximum = Double(startYear) + gg * Double(groupCount)
chartData.groupBars(fromX: Double(startYear), groupSpace: groupSpace, barSpace: barSpace)
//chartData.groupWidth(groupSpace: groupSpace, barSpace: barSpace)
barview.notifyDataSetChanged()
barview.data = chartData
//background color
barview.backgroundColor = UIColor.white
//chart animation
barview.animate(xAxisDuration: 1.5, yAxisDuration: 1.5, easingOption: .linear)
}
func setHorizontalChart(dataPoints: [String], values: [Double]) {
horizontalview.noDataText = "You need to provide data for the chart."
let formato: horizontalbarformatter = horizontalbarformatter()
let xaxiss: XAxis = XAxis()
var dataEntriesss: [BarChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntryy = BarChartDataEntry(x: Double(Int(i)), y: values[i])
dataEntriesss.append(dataEntryy)
formato.stringForValue(Double(i), axis: xaxiss)
}
xaxiss.valueFormatter = formato
let chartHorizontalDataSet = BarChartDataSet(values: dataEntriesss, label: "Marks")
let horizontalchartData = BarChartData(dataSet: chartHorizontalDataSet)
chartHorizontalDataSet.colors = ChartColorTemplates.colorful()
horizontalview.xAxis.valueFormatter = xaxiss.valueFormatter
horizontalview.data = horizontalchartData
horizontalview.backgroundColor = UIColor.white
horizontalview.descriptionText = ""
horizontalview.xAxis.labelPosition = .bottom
horizontalview.leftAxis.axisMinimum = 0
horizontalview.leftAxis.axisMaximum = maxUnits + 1
//barChartView.animate(xAxisDuration: 2.0, yAxisDuration: 2.0)
horizontalview.animate(xAxisDuration: 2.0, yAxisDuration: 2.0, easingOption: .easeInBounce)
let ll = ChartLimitLine(limit: 10.0, label: "Target")
horizontalview.rightAxis.addLimitLine(ll)
}
func chartValueSelected(chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
print("\(entry.y) in \(attendencelabels[Int(entry.x)])")
}
}

How to update data in iOS-Charts?

I have tried to update the data in my barChart, when i passed another dataSet which contains more data points everything goes well, but when i passed another dataSet with a lower data points, the app crashes.
I have also tried putting the barchartView.notifyDataSetChanged() after the line chart.DataSet.color but still crashes, maybe is the wrong place, but i have tried putting the notifyDataSetChanged in many places.
I let you my code, what i do when change the dataSet values is just calling the setChart method and pass the new values array as parameter.
func setChart(values: [Double]) {
let formato:BarChartFormatter = BarChartFormatter()
formato.setArray(self.listadoLabels)
let xaxis:XAxis = XAxis()
barChartView.noDataText = "You need to provide data for the chart."
max = values.maxElement()
var dataEntries: [BarChartDataEntry] = []
for i in 0..<values.count {
let dataEntry = BarChartDataEntry(x: Double(i), y:values[i])
dataEntries.append(dataEntry)
formato.stringForValue(Double(i), axis: xaxis)
}
xaxis.valueFormatter = formato
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Units")
chartDataSet.colors = ChartColorTemplates.joyful()
barChartView.notifyDataSetChanged()
barChartView.fitBars = true
barChartView.xAxis.valueFormatter = xaxis.valueFormatter
barChartView.xAxis.labelPosition = .Bottom
if(values.count > 5){barChartView.zoom(scaleX: 17.0, scaleY: 1.0, x: 0, y: 0)}
barChartView.xAxis.granularityEnabled = true
barChartView.xAxis.granularity = 1.0
barChartView.leftAxis.axisMinimum = 0
barChartView.leftAxis.axisMaximum = max != nil ? max + (2 * max/10) : 5
barChartView.rightAxis.enabled = false
barChartView.drawValueAboveBarEnabled = true
barChartView.descriptionText = ""
barChartView.xAxis.drawGridLinesEnabled = false
barChartView.animate(xAxisDuration: 1.0, yAxisDuration: 1.0)
let chartData = BarChartData()
chartData.addDataSet(chartDataSet)
barChartView.data?.notifyDataChanged()
barChartView.data = chartData
}
The console shows "fatal error: index out of range".
Hope someone can help, thanks.

Resources