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!
Related
I am using charts framework for drawing charts. I need to add some strings in left of every bars. In my code always there are two bars, one for Income and one for Expense. I want to show these string aside of every bar.
Below you can see my codes:
let ys1 = [model.totalIncome, abs(model.totalExpense)]
var yse1 = ys1.enumerated().map { x, y -> BarChartDataEntry in
return BarChartDataEntry(x: Double(x), y: y)
}
let count = 2
let data = BarChartData()
let ds1 = BarChartDataSet(values: yse1, label: "")
ds1.colors = [UIColor.red, UIColor.blue]
// Number formatting of Values
ds1.valueFormatter = YAxisValueFormatter()
ds1.valueFont = UIFont(fontType: .H6)!
ds1.valueTextColor = UIColor.dark_text
// Data set
data.addDataSet(ds1)
horizontalBarChartView.data = data
// General setting
horizontalBarChartView.xAxis.drawLabelsEnabled = false
horizontalBarChartView.setScaleEnabled(false)
// Grid
horizontalBarChartView.xAxis.drawGridLinesEnabled = false
horizontalBarChartView.leftAxis.gridLineDashLengths = [15.0, 15.0]
horizontalBarChartView.leftAxis.gridColor = UIColor.palette_28
horizontalBarChartView.rightAxis.drawGridLinesEnabled = false
// Disable number formatting of leftAxis and rightAxis
horizontalBarChartView.leftAxis.enabled = false
horizontalBarChartView.rightAxis.enabled = false
horizontalBarChartView.xAxis.valueFormatter =
IndexAxisValueFormatter(values: ["Income","Expense"])
horizontalBarChartView.xAxis.granularityEnabled = true
horizontalBarChartView.xAxis.granularity = 1
// setViewPortOffsets
let digitCount = Int(data.yMax).digitCount
let leftOffcet: CGFloat = digitCount > 2 ? CGFloat((digitCount - 1) * 10) : 10.0
horizontalBarChartView.setViewPortOffsets(left: leftOffcet, top: 0, right: 0, bottom: 50)
horizontalBarChartView.leftAxis.axisMinimum = 0
And my view:
lazy var horizontalBarChartView: HorizontalBarChartView = {
let chartView = HorizontalBarChartView()
chartView.contentMode = .scaleAspectFit
chartView.drawBordersEnabled = false
chartView.drawGridBackgroundEnabled = false
chartView.gridBackgroundColor = UIColor.clear
chartView.legend.enabled = false
chartView.chartDescription = nil
chartView.highlighter = nil
chartView.clipsToBounds = true
chartView.translatesAutoresizingMaskIntoConstraints = false
return chartView
}()
I guess below code should add these labels, however, it is not working
horizontalBarChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: ["Income","Expense"])
horizontalBarChartView.xAxis.granularityEnabled = true
horizontalBarChartView.xAxis.granularity = 1
Update
See orange rectangle. I need these labels.
I am using an extension for this
extension BarChartView {
private class BarChartFormatter: NSObject, IAxisValueFormatter {
var labels: [String] = []
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return labels[Int(value)]
}
init(labels: [String]) {
super.init()
self.labels = labels
}
}
func setBarChartData(xValues: [String], yValues: [Double], label: String) {
var dataEntries: [BarChartDataEntry] = []
for i in 0..<yValues.count {
let dataEntry = BarChartDataEntry(x: Double(i), y: yValues[i])
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: label)
let chartData = BarChartData(dataSet: chartDataSet)
let chartFormatter = BarChartFormatter(labels: xValues)
let xAxis = XAxis()
xAxis.valueFormatter = chartFormatter
self.xAxis.valueFormatter = xAxis.valueFormatter
self.data = chartData
}
}
you can use this in code like this
chartView.setBarChartData(xValues: xEntries, yValues: yEntries, label: "Income")
where,
//You need to add values dynamically
var yEntries: [Double] = [1000, 200, 500]
var xEntries: [String] = ["Income1", "Income2", "Income3"]
Hope this works.
Charts framework is a great tool for drawing charts. You should study it perfectly. I used an old code in our project (copy/paste), so it caused some problems for drawing xAxis labels in my chart.
Just comment below line:
horizontalBarChartView.xAxis.drawLabelsEnabled = false
When you create your BarChartDataSet you can pass the label.
let data = BarChartData()
let ds1 = BarChartDataSet(values: yse1, label: "Income")
ds1.colors = [UIColor.red, UIColor.blue]
Hope this helps.
self.ChartObj.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in
print(index)
return YourArray.object(at: Int(index)) as! String
})
self.ChartObj.xAxis.setLabelCount(YourArray.count, force: true)
Try this code
I have a bar chart which currently looks like this:
I would like to put the value of each bar at the end of the bar in white.
This is my current code:
viewDidLoad{
self.results = ["Lost", "Drawn", "Won"]
let games = [total_Losses, total_Draws, total_Wins]
self.setChart(dataPoints: self.results, values: games)
}
func setChart(dataPoints: [String], values: [Double]){
let formato:BarChartFormatter = BarChartFormatter()
let xaxis:XAxis = XAxis()
let xAxis : XAxis = self.barChartView.xAxis;
barChartView.noDataText = "you need to provide some data for the chart."
var dataEntries: [BarChartDataEntry] = Array()
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(x: Double(i), y: values[i])
dataEntries.append(dataEntry)
formato.stringForValue (Double(i), axis: xaxis)
}
xaxis.valueFormatter = formato
barChartView.xAxis.valueFormatter = xaxis.valueFormatter
xAxis.labelFont = UIFont(name: "Avenir", size: 14.0)!
xAxis.labelTextColor = UIColor.white
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Games Played")
let chartData = BarChartData(dataSets: [chartDataSet])
chartDataSet.colors = ChartColorTemplates.material()
barChartView.leftAxis.enabled = true
barChartView.legend.enabled = false
barChartView.chartDescription?.text = ""
chartData.addDataSet(chartDataSet)
barChartView.data = chartData
barChartView.leftAxis.forceLabelsEnabled = true
barChartView.rightAxis.forceLabelsEnabled = true
barChartView.xAxis.granularityEnabled = true
barChartView.xAxis.granularity = 1.0
barChartView.leftAxis.drawGridLinesEnabled = false
barChartView.rightAxis.drawGridLinesEnabled = false
barChartView.xAxis.drawGridLinesEnabled = false
barChartView.rightAxis.enabled = false
barChartView.drawGridBackgroundEnabled = false
self.barChartView.xAxis.labelPosition = XAxis.LabelPosition.bottom
}
How do I add values to the bars in this chart, in white and pixel size 14?
The answers so far have failed to work - I think the problem may lie within:
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(x: Double(i), y: values[i])
dataEntries.append(dataEntry)
formato.stringForValue (Double(i), axis: xaxis) // This line has a warning: "Result of call to 'stringForValue(_:axis:)' is unused
}
This above snippet of code calls this class below:
public class BarChartFormatter: NSObject, IAxisValueFormatter
{
var matches: [String]! = ["Lost", "Drawn", "Won"]
public func stringForValue(_ value: Double, axis: AxisBase?) -> String
{
return matches[Int(value)]
}
}
You can set the color and fonts using the BarChartData class object. For your case, it is chartData
Follow below code in order to set the required fonts and color of labels.
chartData.setValueFont(UIFont.systemFont(ofSize: 14.0))
chartData.setValueTextColor(UIColor.white)
In case you want to show the label within the bar then set your BarChartView object property drawValueAboveBarEnabled to false. It will render your labels within the bars.
barChartView.drawValueAboveBarEnabled = false
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'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 :)