I'm populating a Combined Chart having a Line Chart and a Grouped Bar Chart BUT
the bars are not coming up as expected. They're not in sync with xAxis indexes. Any help will be appreciated.
Combined Chart Image: Line + Grouped Bar
For the image I've attached, bars should be in sync with each month but they are not.
Here's the code:
private func setLineChartWith(data: [Double]) {
var lineChartEntries: [ChartDataEntry] = []
for i in 0..<data.count {
let lineChartEntry = ChartDataEntry(value: data[i], xIndex: i)
lineChartEntries.append(lineChartEntry)
}
let lineDataSet = LineChartDataSet(yVals: lineChartEntries, label: "Line")
lineDataSet.lineWidth = 3
lineDataSet.circleRadius = 4
lineDataSet.mode = .CubicBezier
lineDataSet.highlightEnabled = true
let lineChartData = LineChartData(xVals: datesData, dataSets: [lineDataSet])
chartData.lineData = lineChartData
}
// MARK: Bar Chart Code
func setBarChartWith(data: [Double], secondaryData: [Double]?) {
var barChartEntries1: [BarChartDataEntry] = []
var barChartEntries2: [BarChartDataEntry] = []
for i in 0..<data.count {
barChartEntries1.append(BarChartDataEntry(value: data[i], xIndex: i))
barChartEntries2.append(BarChartDataEntry(value: data[i], xIndex: i))
}
let barDataSet = BarChartDataSet(yVals: barChartEntries1, label: "Bar1")
barDataSet.barSpace = 0.5
barDataSet.highlightEnabled = true
barDataSet.barShadowColor = UIColor.clearColor()
let barDataSet2 = BarChartDataSet(yVals: barChartEntries1, label: "Bar2")
barDataSet2.barSpace = 0.5
barDataSet2.highlightEnabled = true
barDataSet2.barShadowColor = UIColor.clearColor()
var dataSets : [BarChartDataSet] = [BarChartDataSet]()
dataSets.append(barDataSet)
dataSets.append(barDataSet2)
let barChartData = BarChartData(xVals: datesData, dataSets: dataSets)
chartData.barData = barChartData
}
Probably you are using a library to create your graphic. This bibliotca have this problem, the items are limited in the x-axis. The graph divides them so that the User can understand even without some data. You will realize that it always starts on the first index and ends on the last index of the array so it takes some data from the middle of the x-axis. Thus the User can understand the graph and the graph is not overloaded. There is no right solution in the library for this but you can try to zoom the graph or the labels on the x axis. Increasing the width of the graph should also help.
set those in class level
var barCartDataSet : [IChartDataSet] = []
var colNamesArray : [String]!
//call this function as many time as you needed means how much bars you need in one group
setChartData("Test Lable", values: [2.0,3.0] , color: UIColor.darkGrayColor())
//After that at last call this
setChartDataSet(colNamesArray, chartDataSet: barCartDataSet)
//Functios
func setChartData(lableName: String, values: [Double] , color : UIColor) {
var dataEntries: [BarChartDataEntry] = []
for i in 0..<values.count {
let dataEntry = BarChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(yVals: dataEntries, label: lableName)
barCartDataSet.append(chartDataSet)
//changing color
chartDataSet.colors = [color]
}
func setChartDataSet(dataPoints: [String], chartDataSet : [IChartDataSet]) {
BarChartDrawingView.noDataText = "You need to provide data for the chart."
let chartData = BarChartData(xVals: dataPoints, dataSets: chartDataSet)
chartData.groupSpace = 0.8
BarChartDrawingView.data = chartData
BarChartDrawingView.xAxis.labelPosition = .Bottom
//Description Text
BarChartDrawingView.descriptionText = " "
}
sorry for bad English. Hope it helps :)
Related
I have the following code to display lines on my chart using ChartsRealm. How can I show/hide individual lines on the chart?
let line1 = LineChartDataSet(values: lineChartEntry1, label: "CH4")
let line2 = LineChartDataSet(values: lineChartEntry2, label: "O2")
let line3 = LineChartDataSet(values: lineChartEntry3, label: "H2S")
line1.colors = [NSUIColor.blue]
line2.colors = [NSUIColor.green]
line3.colors = [NSUIColor.red]
let data = LineChartData()
data.addDataSet(line1)
data.addDataSet(line2)
data.addDataSet(line3)
chtChart.data = (data)
As such there is no methods to hide/show data set in Chart library.
But we can do it logically without refreshing page.
Please check below code for the same:
Create LineChartView Extension:
extension LineChartView {
func setLineChartData(xValues: [String], labels: [String],dataSets:[Array<Double>],colors:[UIColor]) {
var dataSetsArray: [LineChartDataSet] = []
let dataSetCount = self.lineData?.dataSets.count
if dataSetCount != nil && dataSetCount! > 0 {
self.data = nil
}
for i in 0..<dataSets.count {
let yVals = dataSets[i]
var dataEntries: [ChartDataEntry] = []
for i in 0..<yVals.count {
let dataEntry = ChartDataEntry(x: Double(i), y: yVals[i])
dataEntries.append(dataEntry)
}
let chartDataSet = LineChartDataSet(values: dataEntries, label: labels[i])
chartDataSet.highlightEnabled = true
chartDataSet.drawHorizontalHighlightIndicatorEnabled = false
chartDataSet.highlightColor = .blue
chartDataSet.highlightLineWidth = 1
chartDataSet.lineWidth = 2.0
chartDataSet.mode = .horizontalBezier
chartDataSet.drawCircleHoleEnabled = true
chartDataSet.drawValuesEnabled = true
chartDataSet.axisDependency = .left
chartDataSet.circleHoleColor = colors[i]
chartDataSet.highlightColor = colors[i]
chartDataSet.colors = [colors[i]]
//Add Data Set Into Sets array
dataSetsArray.append(chartDataSet)
}
let chartData = LineChartData(dataSets: dataSetsArray)
self.data = chartData
self.animate(xAxisDuration: 1.0,easingOption: .easeInExpo)
}
func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
}
}
By adding one method into LineChartView extension and call it as per your requirements or user actins.
I called it from my segment change method like below :
#IBAction func segmentValueChanged(_ sender: Any) {
switch self.lineSegment.selectedSegmentIndex {
case 0:
let colors = [UIColor.red,UIColor.green,UIColor.blue]
lineChartView.setLineChartData(xValues: months,
labels: ["Monthly Sales","Quarterly Sales","Yearly Sales"],
dataSets: [unitsSold,unitsSold1,unitsSold2],
colors: colors)
break
case 1:
lineChartView.setLineChartData(xValues: months,
labels: ["Monthly Sales"],
dataSets: [unitsSold],
colors: [UIColor.red])
break
case 2:
lineChartView.setLineChartData(xValues: months,
labels: ["Quarterly Sales"],
dataSets: [unitsSold1],
colors: [UIColor.green])
break
case 3:
lineChartView.setLineChartData(xValues: months,
labels: ["Yearly Sales"],
dataSets: [unitsSold2],
colors: [UIColor.blue])
break
default:
break
}
}
you can pass different data what you want in your dataset.
Check below screens for output reference:
My Segments are All | Monthly | Quarterly | Yearly
Hope this will helps you to achieve your requirements!
I would like to draw radar charts with iOS Charts library by danielgindi, but I cannot figure out how to use options, especially the options regarding the axis.
It does work usually, but when I set the list of variables (array) as [100.0, 100.0, 100.0, 100.0, 100.0], it shows too zoomed a chart like this:
Instead, when I set array as [90.0, 80.0, 90.0, 70.0, 20.0], the interval of the grid lines is not 20 in spite of my code:
Judging from these outputs, the cause of the problem seems to be the options for the axis. However, I could not to solve this problem myself.
How do you fix the size of the chart and the range of the axis, and draw grid lines just as you like?
I use Xcode 8.1 / swift 2.3 / Charts 2.3.1.
import UIKit
import Charts
class ViewController: UIViewController {
#IBOutlet weak var radarChartView: RadarChartView!
//Label
let subjects = ["English", "Math", "Physics", "Chemistry", "Biology"]
//Points
let array = [100.0, 100.0, 100.0, 100.0, 100.0]
override func viewDidLoad() {
super.viewDidLoad()
setChart(subjects, values: array)
print("array:")
print(array)
}
func setChart(dataPoints: [String], values: [Double]) {
radarChartView.noDataText = "You need to provide data for the chart."
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
let chartDataSet = RadarChartDataSet(yVals: dataEntries, label: "Units Sold")
let chartData = RadarChartData(xVals: subjects, dataSet: chartDataSet)
radarChartView.data = chartData
//Options of radarChart
radarChartView.sizeToFit()
radarChartView.descriptionText = ""
//Options for the axis from here. The range is 0-100, the interval is 20
radarChartView.yAxis.labelCount = 6
radarChartView.yAxis.axisMinValue = 0.0
radarChartView.yAxis.axisMaxValue = 100.0
radarChartView.rotationEnabled = false
chartDataSet.drawFilledEnabled = true
//Present the number as integer
let numberFormatter = NSNumberFormatter()
numberFormatter.generatesDecimalNumbers = false
chartDataSet.valueFormatter = numberFormatter
radarChartView.yAxis.valueFormatter = numberFormatter
//Other options
radarChartView.legend.enabled = false
radarChartView.yAxis.gridAntialiasEnabled = true
radarChartView.animate(yAxisDuration: 2.0)
}
I just had to set data AFTER options.
picture
func setChart(dataPoints: [String], values: [Double]) {
radarChartView.noDataText = "You need to provide data for the chart."
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
let chartDataSet = RadarChartDataSet(yVals: dataEntries, label: "Units Sold")
//Set options...
//Then set data
let chartData = RadarChartData(xVals: subjects, dataSet: chartDataSet)
}
I added a bar chart to the storyboard, but I cannot properly set labels for my data entries.
here is my code:
var names = ["aaa", "bbb", "ccc", "ddd"]
var values = [230.0, 280.0, 450.0, 340.0]
setChart(dataPoints: names, values: values)
setChart function:
func setChart(dataPoints: [String], values: [Double])
{
let formatter = BarChartFormatter()
formatter.setValues(values: dataPoints)
let xaxis:XAxis = XAxis()
barChartView.noDataText = "You need to provide data for the chart."
var dataEntries: [BarChartDataEntry] = []
for i in 0..<dataPoints.count
{
let dataEntry = BarChartDataEntry(x: Double(i), y: values[i])
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: "موجودی")
let chartData = BarChartData(dataSet: chartDataSet)
xaxis.valueFormatter = formatter
barChartView.xAxis.labelPosition = .bottom
barChartView.xAxis.drawGridLinesEnabled = false
barChartView.xAxis.valueFormatter = xaxis.valueFormatter
barChartView.chartDescription?.enabled = false
barChartView.legend.enabled = true
barChartView.rightAxis.enabled = false
barChartView.data = chartData
}
and finally the formatter:
#objc(BarChartFormatter)
public class BarChartFormatter: NSObject, IAxisValueFormatter
{
var names = [String]()
public func stringForValue(_ value: Double, axis: AxisBase?) -> String
{
return names[Int(value)]
}
public func setValues(values: [String])
{
self.names = values
}
}
but it didn't work well as shown below:
as shown here, it add 6 labels instead 4 labels, and it also has duplicates.
I already read this solution, however, as you can see, it has some issues yet.
How can I solve this problem?
I think you can try to set the following properties:
barChartView.xAxis.granularityEnabled = true
barChartView.xAxis.granularity = 1.0 //default granularity is 1.0, but it is better to be explicit
barChartView.xAxis.decimals = 0
The source code tells you a lot about the properties above. https://github.com/danielgindi/Charts/blob/master/Source/Charts/Components/AxisBase.swift
I am developing one activity tracker iOS application in which I need to show a history of steps and calories in a bar chart. I used iOS Charts
for this. I am able to get the grouped charts by using this but i am not able to show two seperate axis bars for steps and calories. Below is my requirment. Please suggest me how can i achive this using iOS-Charts or suggest me any other charts written in Swift.
Grouped Bar Chart
I wrote the code using iOS Charts library as below,
func setUpDataForCharts()
{
var weekDays = [String]()
for i in 1 ... 7
{
let value = String(i)
weekDays.append(value)
}
let steps = [2000, 4000, 3500, 1300, 5000, 4800, 2400]
let calories = [20.5, 40.3, 34.0, 13.3, 50.0, 80.2, 20.0]
setChartBarGroupDataSet(weekDays, values: steps, values2: calories)
//setChart(weekDays, values: steps)
barChartView.xAxis.labelPosition = ChartXAxis.LabelPosition.Bottom
barChartView.xAxis.drawGridLinesEnabled = false
}
func setChartBarGroupDataSet(dataPoints: [String], values: [Double], values2: [Double]) {
var dataEntries: [BarChartDataEntry] = []
var dataEntries2: [BarChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(value: values2[i], xIndex: i)
dataEntries2.append(dataEntry)
}
let chartDataSet = BarChartDataSet(yVals: dataEntries, label: "Steps")
let chartDataSet2 = BarChartDataSet(yVals: dataEntries2, label: "Calories")
chartDataSet2.colors = [UIColor(hex: "3F7FD0")]
chartDataSet.colors = [UIColor(hex: "F53609")]
let dataSets: [BarChartDataSet] = [chartDataSet,chartDataSet2]
let data = BarChartData(xVals: dataPoints, dataSets: dataSets)
barChartView.data = data
barChartView.descriptionText = ""
barChartView.rightAxis.axisMaxValue = chartDataSet2.yMax + 1.0
barChartView.rightAxis.labelCount = chartDataSet2.valueCount
barChartView.rightAxis.drawGridLinesEnabled = true
barChartView.rightAxis.drawAxisLineEnabled = false
barChartView.rightAxis.drawLabelsEnabled = true
barChartView.animate(xAxisDuration: 2.0, yAxisDuration: 2.0, easingOption: .Linear)
}
Out put with the above code is,
Output
Thanks in advance!
I am using CHARTS library in swift.
https://github.com/danielgindi/Charts
I got suceess in creating Pie chart and bar chart.
Now I want to create bar chart with one "x" value and 2 "y" values.
I created the bar chart with two different values.
But I am not able to set the colours for them
I passed the colour array to delegate method setColors but it takes the last colour from the array.
Can any one please guide me for having different colours on bar chart.
Here is my code to call BarChart library
months = ["HR","Operations","iOS","Android","PHP","Support","Testing","Designer"]
let unitsSold = [10.0,20.0,30.0,20.0,20.0,10.0,15.0,20.0]
let unitsSold1 = [20.0,30.0,50.0,40.0,30.0,20.0,45.0,50.0]
let barChartClass = self.storyboard!.instantiateViewControllerWithIdentifier("BarChartViewControllerID") as! BarChartViewController
self.addChildViewController(barChartClass)
barChartClass.view.frame = CGRectMake(20, 20, 740, 900)
barChartClass.barChartView.doubleTapToZoomEnabled = false
barChartClass.barChartView.setScaleEnabled(false)
self.view.addSubview(barChartClass.view)
barChartClass.barChartView.legend.enabled = false
barChartClass.setChartBarGroupDataSet(months, values: unitsSold, values2: unitsSold1, sortIndex: 0)
And this is the method call for setChartBarGroupDataSet
func setChartBarGroupDataSet(dataPoints: [String], values: [Double], values2: [Double],sortIndex:Int)
{
var dataEntries: [BarChartDataEntry] = []
for i in 0..<dataPoints.count
{
let dataEntry = BarChartDataEntry(value: values[i], xIndex: i)
let dataEntry1 = BarChartDataEntry(value: values2[i], xIndex: i)
dataEntries.append(dataEntry)
dataEntries.append(dataEntry1)
}
let chartDataSet = BarChartDataSet(yVals: dataEntries, label: " ")
let COLOR_SET : [UIColor]!
COLOR_SET = [UIColor.redColor(),UIColor.greenColor()]
chartDataSet.setColors(COLOR_SET, alpha: 1.0)
let dataSets: [BarChartDataSet] = [chartDataSet]
let data = BarChartData(xVals: dataPoints, dataSets: dataSets)
barChartView.data = data
barChartView.descriptionText = ""
barChartView.rightAxis.drawGridLinesEnabled = false
barChartView.rightAxis.drawAxisLineEnabled = false
barChartView.rightAxis.drawLabelsEnabled = false
barChartView.animate(xAxisDuration: 2.0, yAxisDuration: 2.0, easingOption: .EaseInBounce)
}
What I want is something like this
Thanks in advance.
This is a stacked bar chart. In Charts' demos, you can see a stacked bar chart.
Basically, each BarChartDataEntry received either one value, or an array of values. Pass in an array of values - and you are good to go!
let entry = BarChartDataEntry(values: [4.6, 3.8], xIndex: 0)
dataset.colors = [UIColor.cyanColor(), UIColor.greenColor()]
dataset.stackLabels = ["Inactive inventory", "Active inventory"]
Answered in the duplicate issue too: https://github.com/danielgindi/Charts/issues/1324