You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I have an issue in iOS, with a custom IValueFormatter. I can't get the values on two cubic line charts to show up or the func func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) to be called. Until the chart is barely zoomed. The zoom gesture seems to make the IValueFormatter to run and the values appear. In this app I only need the first and last values to show up. But the thing is, the IValueFormatter isn't being called at all until I zoom.
Thanks for the support. I'll Add the code:
import Foundation
import Charts
extension KeyStatDetailVC: ChartViewDelegate {
func setupDoubleChart(unitString: String,
chartValues1: [Date : Double],
chartValues2: [Date : Double]) {
if chartValues1.count == 0 || chartValues1.count == 0 {
return
}
let sortedValues1 = chartValues1.sorted( by: { $1.key > $0.key } )
let values1 = sortedValues1.map({ ChartDataEntry(x: $0.key.timeIntervalSince1970, y: $0.value) })
let sortedValues2 = chartValues2.sorted( by: { $1.key > $0.key } )
let values2 = sortedValues2.map({ ChartDataEntry(x: $0.key.timeIntervalSince1970, y: $0.value) })
chartConfig()
let set1 = LineChartDataSet(values: values1, label: "left set")
let set2 = LineChartDataSet(values: values2, label: "right set")
dataSetConfig(set: set1, isDoubleChart: true)
dataSetConfig(set: set2, isDoubleChart: true)
set1.setColor( .chartLineColor )
set2.setColor( .chartLineColor )
set1.drawFilledEnabled = false
set2.drawFilledEnabled = false
set1.valueFormatter = MeasuresValueFormatter(valuesRange: values1,
unitString: unitString,
left: true)
set2.valueFormatter = MeasuresValueFormatter(valuesRange: values2,
unitString: unitString,
left: false)
let sets = [set1, set2]
let data = LineChartData(dataSets: sets)
measuresAxisValuesConfig(set1: set1, set2: set2)
formattingConfig(anySet: set1)
chartView.data = data
}
// MARK: - Delegate methods
func chartValueNothingSelected(_ chartView: ChartViewBase) {
chartHighlightedValueLabel.text = ""
}
func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
let myText = String(format: "%.2f", entry.y) + " " + unitString
chartHighlightedValueLabel.text = myText
}
// MARK: - Dataset base config
func dataSetConfig(set: LineChartDataSet, isDoubleChart: Bool) {
set.mode = .horizontalBezier
set.lineWidth = 1
//highlight
set.highlightEnabled = true
set.highlightColor = .black
set.highlightLineDashPhase = CGFloat(2.0)
set.highlightLineDashLengths = [CGFloat(2.0)]
set.drawHorizontalHighlightIndicatorEnabled = false
set.valueFont = isDoubleChart ? .maisonNeueBook(size: 15) : .maisonNeueBook(size: 15)
set.drawValuesEnabled = true
set.drawCirclesEnabled = false
set.axisDependency = .left
}
// MARK: - Chart config
func chartConfig() {
chartView.delegate = self
chartView.dragEnabled = true
chartView.setScaleEnabled(true)
chartView.pinchZoomEnabled = true
chartView.setViewPortOffsets(left: 8, top: 0, right: 8, bottom: 0)
chartView.highlightPerTapEnabled = true
chartView.legend.enabled = false
chartView.animate(xAxisDuration: 0.8)
chartView.backgroundColor = .clear
// X Axis
let xAxis = chartView.xAxis
xAxis.labelTextColor = .clear
xAxis.axisLineColor = .clear
xAxis.labelPosition = .bottom
xAxis.drawAxisLineEnabled = false
xAxis.drawGridLinesEnabled = false
// Y Axis (Left & Right)
let leftAxis = chartView.leftAxis
leftAxis.labelTextColor = .clear
leftAxis.axisLineColor = .clear
leftAxis.labelPosition = .outsideChart
leftAxis.drawGridLinesEnabled = false
// Deactivate axes if necessary
chartView.rightAxis.enabled = false
chartView.chartDescription?.text = ""
}
// MARK: - Stats Axis Min and Max Settings
func statsAxisValuesConfig(set: LineChartDataSet) {
let leftAxis = chartView.leftAxis
// Y scale goes from -%3 of the min value to +%3 of the max value
let yValueToAdd = set.yMax * KeyStatDetailVC.chartXAxisRangeToAdd
leftAxis.axisMinimum = set.yMin - yValueToAdd
leftAxis.axisMaximum = set.yMax + yValueToAdd
setXAxis(set: set)
}
// MARK: - Measures Axis Min and Max Settings
func measuresAxisValuesConfig(set1: LineChartDataSet, set2: LineChartDataSet) {
let leftAxis = chartView.leftAxis
let minYValue = set1.yMin < set2.yMin ? set1.yMin : set2.yMin
let maxYValue = set1.yMax > set2.yMax ? set1.yMax : set2.yMax
// Y scale goes from -%3 of the min value to +%3 of the max value
let yValueToAdd = maxYValue * KeyStatDetailVC.chartXAxisRangeToAdd
leftAxis.axisMinimum = minYValue - yValueToAdd
leftAxis.axisMaximum = maxYValue + yValueToAdd
setXAxis(set: set1)
}
func setXAxis(set: LineChartDataSet) {
let xAxis = chartView.xAxis
let valueToAdd = (set.xMax - set.xMin) * 0.14
xAxis.axisMinimum = set.xMin - valueToAdd
xAxis.axisMaximum = set.xMax + valueToAdd
}
// MARK: - Date Formatting
func formattingConfig(anySet: LineChartDataSet) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM dd"
var date = dateFormatter.string(from: Date(timeIntervalSince1970: anySet.xMax))
maxValueLabel.textAlignment = .right
maxValueLabel.text = date.uppercased()
date = dateFormatter.string(from: Date(timeIntervalSince1970: anySet.xMin))
minValueLabel.textAlignment = .right
minValueLabel.text = date.uppercased()
}
}
// The goal of implementing this IValueFormatter subclass is to show only the first and last values of the line
public class MeasuresValueFormatter: NSObject, IValueFormatter {
var valuesRange: [ChartDataEntry]?
var unitString = ""
var left = true
convenience init(valuesRange: [ChartDataEntry], unitString: String, left: Bool) {
self.init()
self.valuesRange = valuesRange
self.unitString = unitString
self.left = left
}
public func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
guard let myValues = valuesRange else { return "" }
let bodySideString = left ? "(L)" : "(R)"
let myText = String(format: "%.2f", entry.y) + " " + unitString + " " + bodySideString
if entry.x == myValues.first?.x {
return myText
}
else if entry.x == myValues.last?.x {
return myText
}
return ""
}
}
public class DateValueFormatter: NSObject, IAxisValueFormatter {
private let dateFormatter = DateFormatter()
override init() {
super.init()
dateFormatter.dateFormat = "MMM dd"
}
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
let date = dateFormatter.string(from: Date(timeIntervalSince1970: value))
return date.uppercased()
}
}
The text was updated successfully, but these errors were encountered:
please refer ChartsDemo, to see what's going on with your value formatter. It usually means your axis labels are not generated because of not enough space or something else.
We are now encouraging people to ask questions on Stack overflow with tag iOS-charts, as we are overwhelmed to read and answer questions and not able to get the real problem solved.
Hi, I have an issue in iOS, with a custom IValueFormatter. I can't get the values on two cubic line charts to show up or the func func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) to be called. Until the chart is barely zoomed. The zoom gesture seems to make the IValueFormatter to run and the values appear. In this app I only need the first and last values to show up. But the thing is, the IValueFormatter isn't being called at all until I zoom.
Thanks for the support. I'll Add the code:
The text was updated successfully, but these errors were encountered: