Barchart with grouped values: center-align x-axis labels - ios

I'm using the Charts library to generate a bar chart. This is the design I've been given, which I am trying to recreate:
This is what I've managed to build:
It's getting close, but I'm having serious issues showing the bars. For example, the x-axis labels need to be shown in the center of the group, not directly under the vertical line. And the last gray bar is not shown at all for some reason.
Code:
import Charts
import UIKit
class DayAxisValueFormatter: NSObject, IAxisValueFormatter {
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
let day = Int(value)
return ["Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu"][day]
}
}
class ReportBarChart: UITableViewCell {
#IBOutlet private var chartView: BarChartView!
let groupSpace = 0.06
let barSpace = 0.02
let barWidth = 0.45
override func awakeFromNib() {
super.awakeFromNib()
chartView.backgroundColor = .reportCard
chartView.drawBarShadowEnabled = false
chartView.drawValueAboveBarEnabled = false
chartView.dragEnabled = false
chartView.setScaleEnabled(false)
chartView.pinchZoomEnabled = false
let xAxis = chartView.xAxis
xAxis.labelPosition = .bottom
xAxis.labelFont = .systemFont(ofSize: 11, weight: .semibold)
xAxis.labelTextColor = .reportGrayText
xAxis.granularity = 1
xAxis.labelCount = 7
xAxis.valueFormatter = DayAxisValueFormatter()
let leftAxis = chartView.leftAxis
leftAxis.enabled = false
let rightAxis = chartView.rightAxis
rightAxis.enabled = true
rightAxis.labelFont = .systemFont(ofSize: 11, weight: .semibold)
rightAxis.labelTextColor = .reportGrayText
rightAxis.axisMinimum = 0
rightAxis.labelCount = 3
let legend = chartView.legend
legend.font = .systemFont(ofSize: 11, weight: .semibold)
legend.textColor = .white
legend.form = .circle
legend.xEntrySpace = 16
}
func configure() {
let currentValues = [
BarChartDataEntry(x: 0, y: 1),
BarChartDataEntry(x: 1, y: 2),
BarChartDataEntry(x: 2, y: 3),
BarChartDataEntry(x: 3, y: 4),
BarChartDataEntry(x: 4, y: 4),
BarChartDataEntry(x: 5, y: 1),
BarChartDataEntry(x: 6, y: 6),
]
let currentValuesSet = BarChartDataSet(entries: currentValues, label: "This week")
currentValuesSet.setColor(UIColor.reportOrange)
currentValuesSet.drawValuesEnabled = false
let previousValues = [
BarChartDataEntry(x: 0, y: 4),
BarChartDataEntry(x: 1, y: 3),
BarChartDataEntry(x: 2, y: 2),
BarChartDataEntry(x: 3, y: 1),
BarChartDataEntry(x: 4, y: 3),
BarChartDataEntry(x: 5, y: 2),
BarChartDataEntry(x: 6, y: 5),
]
let previousValuesSet = BarChartDataSet(entries: previousValues, label: "Last week")
previousValuesSet.setColor(UIColor.reportGrayChart)
previousValuesSet.drawValuesEnabled = false
let data = BarChartData(dataSets: [currentValuesSet, previousValuesSet])
data.highlightEnabled = false
data.barWidth = barWidth
data.groupBars(fromX: 0, groupSpace: groupSpace, barSpace: barSpace)
chartView.data = data
}
}

Okay, found the answer 😅
xAxis.axisMinimum = 0
xAxis.axisMaximum = 7
xAxis.centerAxisLabelsEnabled = true

Related

How to get full length background colors to the grouped bars in barchart in swift

I am using Charts Framework to achieve my task of bar charts, here is the look of the barchart i have created and the one which i want to achieve.
Also please suggest how to correct xAxis values.
*Achieved chart: https://i.stack.imgur.com/YFTcI.png
I have achieved the corner Radiues to the bars by modifying the BarChartRenderer.swift class in Charts FrammeWork.
Requirement : https://i.stack.imgur.com/Ptc9c.png*
Modification in BarChartRenderer.swift class
craeted a varible
#objc open var barCornerRadius = CGFloat(3.0)
i simply replace the line
context.fill(barRect)
with the code code here
let bezierPath = UIBezierPath(roundedRect: barRect, cornerRadius: barCornerRadius)
context.addPath(bezierPath.cgPath)
context.drawPath(using: .fill)
Here is the code
import Foundation
import Charts
class BarChartView: UIView, NibLoadable {
// MARK: Variables/Properties
private var viewModel: BarChartVM!
// MARK: IBOutlets
#IBOutlet weak var barChartView: BarChartView!
// MARK: View Life Cycle
override init(frame: CGRect){
super.init(frame: frame)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.commonInit()
}
// MARK: Functions
private func commonInit() {
setUpLoadableView()
self.setupViews()
}
// MARK: Setup View Model
func setupVM(vm: BarChartVM, color: UIColor = AppColors.appGreen) {
self.viewModel = vm
self.setupBarChartData()
}
}
extension BarChartView {
private func setupViews() {
self.barChartView.chartDescription?.enabled = false
self.barChartView.chartDescription?.enabled = false
self.barChartView.highlightFullBarEnabled = true
self.barChartView.setScaleEnabled(false)
self.barChartView.legend.enabled = false
self.barChartView.minOffset = 0
self.barChartView.leftAxis.enabled = false
self.barChartView.leftAxis.axisMaximum = 24
self.barChartView.leftAxis.axisMinimum = 0
self.barChartView.xAxis.enabled = true
self.barChartView.xAxis.gridColor = .clear
self.barChartView.xAxis.axisLineWidth = 1
self.barChartView.xAxis.axisLineColor = .clear
self.barChartView.xAxis.spaceMax = 0
self.barChartView.xAxis.labelPosition = .bottom
self.barChartView.xAxis.labelFont = AppFonts.Soleto_Medium.withSize(11.0)
self.barChartView.xAxis.labelTextColor =
AppColors.subtitleColor.withAlphaComponent(0.5)
self.barChartView.xAxis.drawAxisLineEnabled = false
self.barChartView.xAxis.granularity = 1.1
self.barChartView.xAxis.granularityEnabled = true
self.barChartView.xAxis.yOffset = 0
self.barChartView.xAxis.valueFormatter = self
self.barChartView.xAxis.centerAxisLabelsEnabled = false
self.barChartView.rightAxis.enabled = false
}
private func setupBarChartData() {
self.barChartView.isUserInteractionEnabled = false
self.barChartView.data = self.generateBarData(barData: self.viewModel.getBarPointSet())
}
private func generateBarData(barData: [[BarChartVM.ChartPoint]]) -> BarChartData {
var entries1 = [BarChartDataEntry]()
for (index, data) in barData[0].enumerated() {
entries1.append(BarChartDataEntry(x: Double(index), y: data.y))
}
var entries2 = [BarChartDataEntry]()
for (index, data) in barData[1].enumerated() {
entries2.append(BarChartDataEntry(x: Double(index), y: data.y))
}
let set1 = BarChartDataSet(entries: entries1)
set1.valueTextColor = AppColors.titleColor
set1.colors = [AppColors.blueLinkColor]
set1.valueFont = AppFonts.Soleto_Medium.withSize(11.0)
set1.axisDependency = .left
let set2 = BarChartDataSet(entries: entries2)
set2.valueTextColor = AppColors.titleColor
set2.colors = [AppColors.appGreen]
set2.valueFont = AppFonts.Soleto_Medium.withSize(11.0)
set2.axisDependency = .left
let groupSpace = 0.7
let barSpace = 0.38
let barWidth = 0.25
let data: BarChartData = BarChartData(dataSets: [set1, set2])
data.barWidth = barWidth
// make this BarData object grouped
data.groupBars(fromX: -0.8, groupSpace: groupSpace, barSpace: barSpace)
let formatter = NumberFormatter()
formatter.numberStyle = .none
formatter.maximumFractionDigits = 0
formatter.multiplier = 1.0
data.setValueFormatter(DefaultValueFormatter(formatter: formatter))
return data
}
}
//MARK: - Axis Value Formatter
extension BarChartView: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
let dates = self.viewModel.getDateStrings()
return dates[Int(value) % dates.count]
}
}
Here is the ViewModel Class
class BarChartVM {
struct ChartPoint {
var x: Double
var y: Double
init(x: Double, y: Double) {
self.x = x
self.y = y
}
}
private var barPointSet1: [ChartPoint]!
private var barPointSet2: [ChartPoint]!
private var dateStrings: [String]!
init(barPoints: [[ChartPoint]], dates: [String]) {
self.barPointSet1 = barPoints[0]
self.barPointSet2 = barPoints[1]
self.dateStrings = dates
}
func getBarPointSet() -> [[ChartPoint]] { [self.barPointSet1, self.barPointSet2] }
func getDateStrings() -> [String] { self.dateStrings }
}
The data which i am getting in ViewModel
BAR DATA SET 1:
[
BarChartVM.ChartPoint(x: 0.0, y: 16.0),
BarChartVM.ChartPoint(x: 1.0, y: 5.0),
BarChartVM.ChartPoint(x: 2.0, y: 9.0),
BarChartVM.ChartPoint(x: 3.0, y: 19.0),
BarChartVM.ChartPoint(x: 4.0, y: 13.0),
BarChartVM.ChartPoint(x: 5.0, y: 6.0),
BarChartVM.ChartPoint(x: 6.0, y: 1.0),
BarChartVM.ChartPoint(x: 7.0, y: 6.0),
BarChartVM.ChartPoint(x: 8.0, y: 1.0),
BarChartVM.ChartPoint(x: 9.0, y: 17.0),
BarChartVM.ChartPoint(x: 10.0, y: 0.0),
BarChartVM.ChartPoint(x: 11.0, y: 22.0)
]
BAR DATA SET 2:
[
BarChartVM.ChartPoint(x: 0.0, y: 12.0),
BarChartVM.ChartPoint(x: 1.0, y: 15.0),
BarChartVM.ChartPoint(x: 2.0, y: 10.0),
BarChartVM.ChartPoint(x: 3.0, y: 12.0),
BarChartVM.ChartPoint(x: 4.0, y: 7.0),
BarChartVM.ChartPoint(x: 5.0, y: 7.0),
BarChartVM.ChartPoint(x: 6.0, y: 5.0),
BarChartVM.ChartPoint(x: 7.0, y: 2.0),
BarChartVM.ChartPoint(x: 8.0, y: 23.0),
BarChartVM.ChartPoint(x: 9.0, y: 22.0),
BarChartVM.ChartPoint(x: 10.0, y: 8.0),
BarChartVM.ChartPoint(x: 11.0, y: 8.0)
]

SwiftUI Chart: how can I overlay multiple graph datas?

here are two charts.
and I would like to show the data of object and object2 together in one chart.
Would it be possible?
Chart(db.objects, id: \.self) { object in
LineMark(
x: .value("name", object.name),
y: .value("value", Int(object.value) ?? 0)
)
}
Chart(db.objects2, id: \.self) { object2 in
LineMark(
x: .value("name", object2.name),
y: .value("value", Int(object2.value) ?? 0)
)
}
I just found the way from apple developer website
https://developer.apple.com/documentation/charts/chart/
struct ProfitOverTime {
var date: Date
var profit: Double
}
let departmentAProfit: [ProfitOverTime] = [] // ...
let departmentBProfit: [ProfitOverTime] = [] // ...
var body: some View {
Chart {
ForEach(departmentAProfit) {
LineMark(
x: .value("Date", $0.date),
y: .value("Profit A", $0.profit)
)
.foregroundStyle(.blue)
}
ForEach(departmentBProfit) {
LineMark(
x: .value("Date", $0.date),
y: .value("Profit B", $0.profit)
)
.foregroundStyle(.green)
}
RuleMark(
y: .value("Threshold", 500.0)
)
.foregroundStyle(.red)
}
}
This is an alternative solution. Since the data structure is the same, the data could be one source and displayed using one LineMark.
As an example, dept was added to the model to identify each group of data that represents a single line in the chart:
struct ProfitOverTime {
var dept: String
var date: Date
var profit: Double
}
The data combined into one array:
let data: [ProfitOverTime] = [] // ...
The foreground style is based on the department, that is, each line in the chart.
struct DepartmentChart: View {
var body: some View {
Chart(data) {
LineMark(
x: .value("Date", $0.date),
y: .value("Profit", $0.profit)
series: .value("Department", $0.dept)
)
.foregroundStyle(by: .value("Department", $0.dept))
RuleMark(
y: .value("Threshold", 500.0)
)
.foregroundStyle(.red)
}
.chartForegroundStyleScale(["Profit A": .green, "Profit B": .blue])
}
}
Series was added to identify each line by its color:
The chartForegroundStyleScale is optional since each line will automatically be colored differently. But chartForegroundStyleScale can be used to customize the line colors.
Here I am showing the data for a week. So if you want to show more than data then you can increase the number of entries. So that’s it from my side hope you understand.
Now use MultiLineChartView like this.
Complete Code:
import SwiftUI
import Charts
struct ContentView: View {
let days = ["S", "M", "T", "W", "T", "F", "S"]
let entries1 = [
ChartDataEntry(x: 1, y: 1),
ChartDataEntry(x: 2, y: 2),
ChartDataEntry(x: 3, y: 0),
ChartDataEntry(x: 4, y: 0),
ChartDataEntry(x: 5, y: 0),
ChartDataEntry(x: 6, y: 0),
ChartDataEntry(x: 7, y: 1),
]
let entries2 = [
ChartDataEntry(x: 1, y: 2),
ChartDataEntry(x: 2, y: 3),
ChartDataEntry(x: 3, y: 0),
ChartDataEntry(x: 4, y: 0),
ChartDataEntry(x: 5, y: 0),
ChartDataEntry(x: 6, y: 0),
ChartDataEntry(x: 7, y: 2)
]
var body: some View {
VStack{
Spacer()
MultiLineChartView(entries1: entries1, entries2: entries2, days: days)
.frame(height: 220)
Spacer()
}
}
}
struct MultiLineChartView : UIViewRepresentable {
var entries1 : [ChartDataEntry]
var entries2 : [ChartDataEntry]
var days: [String]
func makeUIView(context: Context) -> LineChartView {
let chart = LineChartView()
return createChart(chart: chart)
}
func updateUIView(_ uiView: LineChartView, context: Context) {
uiView.data = addData()
}
func createChart(chart: LineChartView) -> LineChartView{
chart.chartDescription?.enabled = false
chart.xAxis.drawGridLinesEnabled = false
chart.xAxis.drawLabelsEnabled = true
chart.xAxis.drawAxisLineEnabled = false
chart.xAxis.labelPosition = .bottom
chart.rightAxis.enabled = false
chart.leftAxis.enabled = false
chart.drawBordersEnabled = false
chart.legend.form = .none
chart.xAxis.labelCount = 7
chart.xAxis.forceLabelsEnabled = true
chart.xAxis.granularityEnabled = true
chart.xAxis.granularity = 1
chart.xAxis.valueFormatter = CustomChartFormatter(days: days)
chart.data = addData()
return chart
}
func addData() -> LineChartData{
let data = LineChartData(dataSets: [
//Schedule Trips Line
generateLineChartDataSet(dataSetEntries: entries1, color: UIColor(Color(#colorLiteral(red: 0.6235294118, green: 0.7333333333, blue: 0.3568627451, alpha: 1))), fillColor: UIColor(Color(#colorLiteral(red: 0, green: 0.8134518862, blue: 0.9959517121, alpha: 1)))),
//Unloadings Line
generateLineChartDataSet(dataSetEntries: entries2, color: UIColor(Color(#colorLiteral(red: 0.003921568627, green: 0.231372549, blue: 0.431372549, alpha: 1))), fillColor: UIColor(Color(#colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1))))
])
return data
}
func generateLineChartDataSet(dataSetEntries: [ChartDataEntry], color: UIColor, fillColor: UIColor) -> LineChartDataSet{
let dataSet = LineChartDataSet(entries: dataSetEntries, label: "")
dataSet.colors = [color]
dataSet.mode = .cubicBezier
dataSet.circleRadius = 5
dataSet.circleHoleColor = UIColor(Color(#colorLiteral(red: 0.003921568627, green: 0.231372549, blue: 0.431372549, alpha: 1)))
dataSet.fill = Fill.fillWithColor(fillColor)
dataSet.drawFilledEnabled = true
dataSet.setCircleColor(UIColor.clear)
dataSet.lineWidth = 2
dataSet.valueTextColor = color
dataSet.valueFont = UIFont(name: "Avenir", size: 12)!
return dataSet
}
}
class CustomChartFormatter: NSObject, IAxisValueFormatter {
var days: [String]
init(days: [String]) {
self.days = days
}
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return days[Int(value-1)]
}
}

The piechart data set is merging or not picking up the Data assigned

I'm trying to produce a pie chart in iOS and there seems some issue regarding the datasets and visuals which I am not able to figure out.
This my code below:
let months = ["Jan" , "Feb", "Mar" , "April"]
let unitsSold = [1000.0 , 200.0, 200.0 , 200.0]
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(x: values[i], y: Double(i))
dataEntries.append(dataEntry)
}
print(dataEntries)
let pieChartDataSet = PieChartDataSet(values: dataEntries, label: "Loans")
let pieChartData = PieChartData(dataSet: pieChartDataSet)
pieChart.data = pieChartData
pieChart.holeRadiusPercent = 0.0
pieChart.transparentCircleRadiusPercent = 0.0
pieChart.holeColor = UIColor.clear
var colors: [UIColor] = []
for j in 0..<dataPoints.count {
let red = Double(arc4random_uniform(256))
let green = Double(arc4random_uniform(256))
let blue = Double(arc4random_uniform(256))
let color = UIColor(red: CGFloat(red/255), green: CGFloat(green/255), blue: CGFloat(blue/255), alpha: 1)
colors.append(color)
}
pieChartDataSet.selectionShift = 0.0
pieChartDataSet.drawValuesEnabled = false
pieChartDataSet.sliceSpace = 8.0
pieChartDataSet.colors = colors
pieChart.legend.enabled = false
}
This is the output of the code, I don't understand what's happening. Either it's merging datasets or skipping something.
You have a little mistake in your code.
To fix it you need change string
let dataEntry = ChartDataEntry(x: values[i], y: Double(i))
to
let dataEntry = ChartDataEntry(x: Double(i), y: values[i])
In y parameter you set the actual value of the entry (sold units in your case).

Values are not showing on chart graph swift

I am using chart library to plot graph in swift. I want to show below values on LineChartView.
My values are as follows.
1) x: 0.0 y: 0.62020133693747
2) x: 0.0 y: 0.62020133693747
3) x: 0.0 y: 0.62020133693747
4) x: 8500.0 y: 0.62020133693747
5) x: 8500.0 y: 0.925703706122449
6) x: 9000.0 y: 0.925703706122449
7) x: 9000.0 y: 1.43307403327373
8) x: 9500.0 y: 1.43307403327373
9) x: 9500.0 y: 0.37799568
10) x: 9500.0 y: 0.37799568
11) x: 9500.0 y: 0.37799568
12) x: 9000.0 y: 0.37799568
13) x: 9000.0 y: 0.269996914285714
14) x: 8500.0 y: 0.269996914285714
15) x: 8500.0 y: 0.239997257142857
16) x: 6000.0 y: 0.239997257142857
17) x: 6000.0 y: 0.219552079597251
18) x: 0.0 y: 0.219552079597251
19) x: 0.0 y: 0.453594816
20) x: 0.0 y: 0.453594816
From these values the expected graph is:
But when I am using chart library I am getting the following graph:
It seems that the library is not able to plot the last values.
I have tried various setting but it didn't solve my issue.
My Code:
`func updateChartValues(arrLineCDE: Array<ChartDataEntry>) -> (LineChartDataSet) {
let Xvalues: [Double] = [/*All My X values are here*/]
let Yvalues: [Double] = [/*All My Y values are here*/]
var entries: [ChartDataEntry] = Array()
for (i, x) in Xvalues.enumerated() {
entries.append(ChartDataEntry(x: Xvalues[i], y: Yvalues[i], data: UIImage(named: "icon", in: Bundle(for: self.classForCoder), compatibleWith: nil)))
}
self.dataSet = LineChartDataSet(values: entries, label: "Depth vs. FV")
self.dataSet.mode = LineChartDataSet.Mode.cubicBezier
return dataSet
}`
Line Chart Sttings
`func setLineChartProperty(lineChartView lcv: LineChartView) {
//Line Chart Setting:
// lcv.delegate = self
lcv.setViewPortOffsets(left: 44.0, top: 30.0, right: 44.0, bottom: 44.0)
lcv.backgroundColor = darkBlueColor
lcv.chartDescription?.enabled = false
lcv.dragEnabled = false
lcv.setScaleEnabled(false)
lcv.pinchZoomEnabled = false
lcv.drawGridBackgroundEnabled = false
lcv.xAxis.labelFont = UIFont(name: "HelveticaNeue-Light", size: CGFloat(12.0))!
lcv.xAxis.setLabelCount(6, force: false)
lcv.xAxis.labelTextColor = UIColor.white
lcv.xAxis.labelPosition = .bottom
lcv.xAxis.axisLineColor = UIColor.white
lcv.xAxis.gridColor = UIColor.white
lcv.xAxis.drawGridLinesEnabled = true
lcv.xAxis.axisMaximum = 10000
lcv.xAxis.axisMinimum = 0
lcv.leftAxis.labelFont = UIFont(name: "HelveticaNeue-Light", size: CGFloat(12.0))!
lcv.leftAxis.setLabelCount(6, force: false)
lcv.leftAxis.labelTextColor = UIColor.white
lcv.leftAxis.labelPosition = .outsideChart
lcv.leftAxis.axisLineColor = UIColor.white
lcv.leftAxis.gridColor = UIColor.white
lcv.leftAxis.drawGridLinesEnabled = true
lcv.legend.horizontalAlignment = .right
lcv.legend.verticalAlignment = .bottom
lcv.legend.orientation = .horizontal
lcv.legend.drawInside = true
lcv.legend.form = .square
lcv.legend.formSize = 8.0
lcv.legend.formToTextSpace = 4.0
lcv.legend.xEntrySpace = 6.0
lcv.xAxis.enabled = true
lcv.rightAxis.enabled = false
lcv.leftAxis.enabled = true
lcv.legend.enabled = true
lcv.legend.textColor = UIColor.white
lcv.animate(xAxisDuration: 1.0, yAxisDuration: 1.0)
}`

Bar Chart jumps up when there's more than 2 columns

I am working on a chart with data set change when the button is pressed. But it looks like when I have more than 2 bars, the chart origin point shifts.
Two columns is fine:
Creating data set:
private func buildMoodDummyBarData(period: Period) -> [BarChartDataEntry] {
if period == .week {
let entry1 = BarChartDataEntry(x: 0, y: 720)
let entry2 = BarChartDataEntry(x: 1, y: 440)
let entry3 = BarChartDataEntry(x: 2, y: 0)
let entry4 = BarChartDataEntry(x: 3, y: 30)
let entry5 = BarChartDataEntry(x: 4, y: 30)
return [entry1, entry2, entry3, entry4, entry5]
} else if period == .month {
let entry1 = BarChartDataEntry(x: 0, y: 100)
let entry2 = BarChartDataEntry(x: 1, y: 300)
let entry3 = BarChartDataEntry(x: 2, y: 50)
let entry4 = BarChartDataEntry(x: 3, y: 30)
let entry5 = BarChartDataEntry(x: 4, y: 30)
return [entry1, entry2, entry3, entry4, entry5]
} else {
return []
}
}
Finishing building data set and changing bar colors:
func buildMoodBarData(period: Period) -> BarChartData? {
let entries = buildMoodDummyBarData(period: period)
let set = BarChartDataSet(values: entries, label: nil)
set.highlightEnabled = false
let tempData = BarChartData(dataSet: set) // Just to find max
let max = tempData.yMax
let onePercent = max / 100
var colors = [UIColor]()
for item in entries {
let percentValue = item.y / onePercent
colors.append(setColor(value: percentValue))
}
set.colors = colors
let data = BarChartData(dataSet: set)
data.setDrawValues(true)
data.barWidth = 0.72
return data
}
// barChartView is storyboard outlet
private func makeMoodBarChart() {
barChartView.backgroundColor = UIColor.red
barChartView.chartDescription = nil
barChartView.leftAxis.enabled = false
barChartView.rightAxis.enabled = false
barChartView.legend.enabled = false
barChartView.xAxis.enabled = false
}
private func updateMoodBarChart(with data: BarChartData) {
barChartView.data = data
barChartView.fitBars = false
barChartView.fitScreen()
}
The problem is related to data set. When I replaced it to following data, problem disappeared. I think issue occurs because Y scale values was changing too much.
private func buildMoodDummyBarData(period: Period) -> [BarChartDataEntry] {
if period == .week {
let entry1 = BarChartDataEntry(x: 0, y: 10)
let entry2 = BarChartDataEntry(x: 1, y: 50)
let entry3 = BarChartDataEntry(x: 2, y: 100)
let entry4 = BarChartDataEntry(x: 3, y: 20)
let entry5 = BarChartDataEntry(x: 4, y: 30)
return [entry1, entry2, entry3, entry4, entry5]
} else if period == .month {
let entry1 = BarChartDataEntry(x: 0, y: 100)
let entry2 = BarChartDataEntry(x: 1, y: 30)
let entry3 = BarChartDataEntry(x: 2, y: 30)
let entry4 = BarChartDataEntry(x: 3, y: 20)
let entry5 = BarChartDataEntry(x: 4, y: 30)
return [entry1, entry2, entry3, entry4, entry5]
} else {
return []
}
}
This doesn't mean min and max value has to be exactly the same in both data sets (20 to 100), however if difference is too big (30 to 320 in first data set and 30 to 720 in second), chart baseline changes.
This is not ideal solution.
While updating Barchart with new dataset make chartdata as nil
if let bardata = buildMoodBarData(period: state) {
barChatView.data = nil
updateMoodBarChart(with: bardata)
}

Resources