Issue in display of barchart with latest ioscharts - swift

I updated ios-charts to the latest code after 2 months. I see lot of difference when I run the code.
This is before updating the library:
After updating:
Here's the code that generates the chart:
chart.infoTextColor = UIColor.blackColor()
chart.backgroundColor = UIColor.whiteColor()
chart.descriptionText = ""
chart.noDataText = "Loading..."
chart.rightAxis.enabled = false
chart.xAxis.wordWrapEnabled = true
chart.legend.position = .BelowChartCenter;
chart.legend.form = .Circle;
chart.legend.formSize = 10.0;
chart.legend.formToTextSpace = 10.0;
chart.legend.xEntrySpace = 4.0;
chart.legend.yEntrySpace = 2.0
chart.legend.stackSpace = 5.0
chart.legend.textColor = UIColor.blueColor()
chart.xAxis.gridColor = UIColor.blueColor()
// chart.xAxis.axisLineColor = UIColor.blueColor()
chart.gridBackgroundColor = UIColor.whiteColor()
chart.borderColor = UIColor.redColor()
// chart.xAxis.labelHeight = 18
// chart.xAxis.labelWidth = 18
chart.xAxis.labelPosition = .Bottom;
chart.xAxis.drawGridLinesEnabled = false;
chart.rightAxis.drawGridLinesEnabled = false;
//zooming..
chart.pinchZoomEnabled = false
chart.doubleTapToZoomEnabled = false
chart.scaleXEnabled = false
chart.scaleYEnabled = false
//new..
chart.leftAxis.labelPosition = .InsideChart
chartDataSet.barSpace = 0.38

Latest release has deprecated startAtZeroEnabled, which seems is your case.
Please try set customAxisMin to get the expcted range. e.g. customAxisMin = 0
remember to set it before calling chartView.data = yourData, or you need to specificly call chartView.notifyDataSetChanged()

Related

Why moveViewToX() won't move my display to the last value in my bar chart? - Swift

I'm new to Swift and I'm trying to create bar chart. I manage to create a chart but for some reason moveViewToX() does not work as expected - it does not scroll to the last x values. Here is my relevant function to create a chart:
func createBarView() {
// Set basic parameters
barChartView.xAxis.labelTextColor = .black
barChartView.leftAxis.labelTextColor = .black
barChartView.leftAxis.axisMinimum = 0
barChartView.xAxis.labelPosition = XAxis.LabelPosition.bottom
barChartView.xAxis.labelRotationAngle = 0
barChartView.xAxis.granularity = 1
barChartView.xAxis.labelFont = UIFont.systemFont(ofSize: 20.0, weight: .regular)
barChartView.xAxis.drawGridLinesEnabled = false
barChartView.rightAxis.drawGridLinesEnabled = false
barChartView.leftAxis.drawGridLinesEnabled = false
barChartView.rightAxis.enabled = false
barChartView.leftAxis.enabled = false
barChartView.xAxis.labelPosition = .bottom
barChartView.clipsToBounds = true
barChartView.layer.cornerRadius = 10
barChartView.legend.enabled = false
barChartView.animate(yAxisDuration: 1.3, easingOption: .easeInOutQuart)
barChartView.scaleYEnabled = false
barChartView.scaleXEnabled = false
barChartView.pinchZoomEnabled = false
barChartView.doubleTapToZoomEnabled = false
//Get X (days) and Y data (calories)
let count = realm.objects(WorkoutData.self).count
for i in 0 ..< count {
let graphDates = realm.objects(WorkoutData.self)[i].date
allDates.append(graphDates)
let calendarDate = Calendar.current.dateComponents([.day, .year, .month], from: graphDates)
graphDays.append(String(calendarDate.day!)) // Get days array for xAxis
let graphCalories = realm.objects(WorkoutData.self)[i].calories
visosKalorijos.append(graphCalories) // Get calories array for yAxis
}
//Supply data for BarChartDataEntry
var entries = [BarChartDataEntry]()
for i in 0 ..< count { // dataPoints
let dataEntry = BarChartDataEntry(x: Double(i), y: Double(visosKalorijos[i]))
entries.append(dataEntry) //// Get x:y data
}
//Set labels of xAxis (to show days of the month)
barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: graphDays)
// Create dataset
let set = BarChartDataSet(entries: entries, label: "-")
set.colors = ChartColorTemplates.solid()
set.valueFont = UIFont.systemFont(ofSize: 16)
let data = BarChartData(dataSet: set)
data.barWidth = Double(0.4)
barChartView.data = data
// Set visibility
barChartView.setVisibleXRangeMaximum(7)
barChartView.moveViewToX(Double(count))
}
When function is executed I can see only up to 17th day, but there are more days on the xAxis if I scroll.
After view is loaded I need to scroll to the end.
The last part - // Set visibility is where the problem is - it does not scroll automatically to the last x value. What Am I doing wrong? Thanks for your help.
After some time I figured this out. Last step //Set visibility needs delay of 0.1s:
barChartView.setVisibleXRangeMaximum(7)
let when = DispatchTime.now() + 0.1
DispatchQueue.main.asyncAfter(deadline: when) {
self.barChartView.moveViewToX(Double(self.count))
}
Hopefully this will help someone in the future :)

Styling of NSTextField

How to make border and style of NStextField like that (except icon on the right)? Is it custom or built-in?
Set new CALayer and play with isBezeled and isBordered properties before setting colors.
let field = NSTextField()
field.layer = CALayer()
field.wantsLayer = true
field.isBezeled = false
field.isEditable = true
field.isBordered = true
field.backgroundColor = NSColor.white
field.layer?.borderColor = NSColor.gray.cgColor
field.layer?.backgroundColor = NSColor.white.cgColor
field.layer?.borderWidth = 1
field.layer?.cornerRadius = 5

Line chart lines with same value are overlapping

I am using danielgindi
/
Charts for creating line chart. When Line chart data has same values, only the last drawn line showing. Other lines are hidden behind the last drawn line. Is there any way to show all lines.
image: 'fff' and 'User B' is hidden behind 'User C', they all have number of activities equal to zero
Line chart initialisation
func commonInit() {
guard let view = loadViewFromNib() else { return }
view.frame = self.bounds
self.addSubview(view)
lblXAxis.text = "Days"
lblYAxis.text = "Number of Activities"
lblYAxis.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
self.roundAllCorners(radius: 6)
let valFormatter = NumberFormatter()
valFormatter.numberStyle = .none
valFormatter.maximumFractionDigits = 0
viewProgressLineChart.leftAxis.valueFormatter = DefaultAxisValueFormatter(formatter: valFormatter)
viewProgressLineChart.leftAxis.granularity = 1
viewProgressLineChart.xAxis.granularity = 1
viewProgressLineChart.xAxis.labelCount = 11
viewProgressLineChart.xAxis.avoidFirstLastClippingEnabled = false
viewProgressLineChart.xAxis.labelPosition = .bottom
viewProgressLineChart.chartDescription?.text = ""
viewProgressLineChart.xAxis.labelTextColor = UIColor.onPrimary
viewProgressLineChart.leftAxis.labelTextColor = UIColor.onPrimary
viewProgressLineChart.rightAxis.labelTextColor = UIColor.onPrimary
viewProgressLineChart.clipValuesToContentEnabled = true
viewProgressLineChart.legend.enabled = false
viewProgressLineChart.rightAxis.enabled = false
viewProgressLineChart.animate(xAxisDuration: 0.8)
}
This is how data is given to line chart,
func updateGraph(users: [User]){
let data = LineChartData()
for (index,user) in users.enumerated(){
let userColor = UIColor.selectedColors[index]
userAndStatusColorArray.append(UserAndStatusColor(name: user.name ?? "user", color: userColor))
var lineChartEntry = [ChartDataEntry]()
if user.progress != nil{
for progress in user.progress!{
let chartData = ChartDataEntry(x: Double(progress.day), y: Double(progress.activitiesCompleted!))
lineChartEntry.append(chartData)
}
let chartDataSet = LineChartDataSet(entries: lineChartEntry)
chartDataSet.colors = [userColor]
chartDataSet.circleColors = [userColor]
chartDataSet.circleRadius = 3
chartDataSet.drawValuesEnabled = false
data.addDataSet(chartDataSet)
}
}
viewPODProgressLineChart.viewProgressLineChart.data = data
}

How to align both right and left axis in the same line using ios-charts?

I have the following line chart with 2 datasets.
One data set is dependent on the left yAxis the other one on the right yAxis.
Now i want them both to have the zero value in the same line.
The other values are ok to not be aligned.
How can i do that?
Code:
let speedLine = LineChartDataSet(values: speedEntries, label: "Speed")
speedLine.colors = [UIColor.white]
speedLine.drawCirclesEnabled = false
speedLine.axisDependency = .left
let powerLine = LineChartDataSet(values: powerEntries, label: "Power")
powerLine.colors = [UIColor.green]
powerLine.drawCirclesEnabled = false
powerLine.axisDependency = .right
let data = LineChartData()
data.addDataSet(speedLine)
data.addDataSet(powerLine)
chartView.data = data
chartView.xAxis.labelTextColor = UIColor.white
chartView.xAxis.labelCount = 20
chartView.leftAxis.labelTextColor = UIColor.white
chartView.rightAxis.labelTextColor = UIColor.green
chartView.legend.textColor = UIColor.white
chartView.rightAxis.axisMinimum = -80.0
chartView.chartDescription?.text = ""
Since you have:
chartView.rightAxis.axisMinimum = -80.0
You might need to do this as well:
chartView.leftAxis.axisMinimum = -80.0
I think there is still no resolution for this problem but we can still hide yAxis right side.
let yAxisLeft = chartView.leftAxis
yAxisLeft.drawGridLinesEnabled = true
yAxisLeft.gridColor = UIColor(hex: "DCE5EE")
yAxisLeft.labelFont = Theme.Font.main(ofSize: 9, weight: .regular)
yAxisLeft.labelXOffset = 2
yAxisLeft.labelTextColor = Theme.Color.white
yAxisLeft.axisLineColor = UIColor(hex: "DCE5EE")
yAxisLeft.drawAxisLineEnabled = false
yAxisLeft.labelCount = 4
yAxisLeft.axisMinLabels = 1
yAxisLeft.enabled = true
yAxisLeft.axisMinimum = 0
let yAxisRight = chartView.rightAxis
yAxisRight.drawGridLinesEnabled = false
yAxisRight.labelFont = Theme.Font.main(ofSize: 9, weight: .regular)
yAxisRight.labelXOffset = -2
yAxisRight.labelTextColor = Theme.Color.white
yAxisRight.drawAxisLineEnabled = false
yAxisRight.labelCount = 4
yAxisRight.axisMinLabels = 1
yAxisRight.enabled = true
yAxisRight.axisMinimum = 0
This is the final result:

Change yValue label vertical spacing in combined chart (ios-charts)

I have a combined chart that uses a line and bar chart to show yValues.
In some instances the line and bar chart values will overlap, is there a way to set the vertical spacing of the labels for the yValues so that they're not on top of each other (like Jan to Oct in the image)?
Combined Chart Image
I'm using the Charts framework (formerly ios-charts), here is the code to setup the CombineChartView:
let xValues = getXAxisLabelsForYear(year)
let runningTotalsByMonth = getRunningTotalByMonthForYear(year)!
var yValsBar = [BarChartDataEntry]()
var yValsLine = [ChartDataEntry]()
for i in 0 ..< xValues.count {
let yBarDataEntry = BarChartDataEntry(value: monthlyWinnings[i], xIndex: i)
yValsBar.append(yBarDataEntry)
let yLineDataEntry = ChartDataEntry(value: runningTotalsByMonth[i], xIndex: i)
yValsLine.append(yLineDataEntry)
}
let barChartDataSet = BarChartDataSet(yVals: yValsBar, label: "Monthly Winnings")
//setup bar chart
var barChartColors = [UIColor]()
for i in monthlyWinnings {
if i >= 0.0 {
barChartColors.append(myGreen)
} else {
barChartColors.append(UIColor.redColor())
}
}
barChartDataSet.colors = barChartColors
barChartDataSet.barShadowColor = UIColor.clearColor()
barChartDataSet.valueFont = UIFont.systemFontOfSize(10.0)
//setup line chart
let lineChartDataSet = LineChartDataSet(yVals: yValsLine, label: "Cumulative Winnings")
var lineChartColors = [UIColor]()
for i in runningTotalsByMonth {
if i >= 0.0 {
lineChartColors.append(myGreen)
} else {
lineChartColors.append(UIColor.redColor())
}
}
lineChartDataSet.colors = lineChartColors
lineChartDataSet.circleColors = [UIColor.blueColor()]
lineChartDataSet.drawCircleHoleEnabled = false
lineChartDataSet.circleRadius = 5
lineChartDataSet.lineWidth = 2
lineChartDataSet.valueFont = UIFont.systemFontOfSize(10.0)
//combine data
let data = CombinedChartData(xVals: xValues)
data.barData = BarChartData(xVals: xValues, dataSet: barChartDataSet)
data.lineData = LineChartData(xVals: xValues, dataSet: lineChartDataSet)
combinedChartView.data = data
//format the chart
combinedChartView.xAxis.setLabelsToSkip(0)
combinedChartView.xAxis.labelPosition = .Bottom
combinedChartView.descriptionText = ""
combinedChartView.rightAxis.drawLabelsEnabled = false
combinedChartView.rightAxis.drawGridLinesEnabled = false
combinedChartView.drawGridBackgroundEnabled = false
combinedChartView.leftAxis.drawZeroLineEnabled = true
combinedChartView.xAxis.drawGridLinesEnabled = false
combinedChartView.xAxis.wordWrapEnabled = true
You can draw bar chart values below the top of the bar using
chartView.drawValueAboveBarEnabled = false
and setting some color
barChartDataSet.valueTextColor = UIColor.someColor()
Will look like this:
See my comment above, but something like this may work if you're not using auto layout:
let labelA = UILabel()
let labelB = UILabel()
let padding: CGFloat = 5.0 // or whatever
if CGRectIntersectsRect(labelA.frame, labelB.frame) {
// If the minY of labelA is <= labelB's that means labelA is ABOVE labelB
if labelA.frame.minY <= labelB.frame.minY {
// Set it above, with some (optional) padding
labelA.frame.origin.y = labelB.frame.origin.y - padding - labelA.frame.height
} else {
labelB.frame.origin.y = labelA.frame.origin.y - padding - labelB.frame.height
}
}
Of course you'll need additional code for checking if it's too high and other edge cases.