How to Replace the Values of Labels in iOS-Charts

how to replace the values of labels in iOS-charts?

You can't change the value the chart is using to draw; however, you could provide your own NSNumberFormatter implementation to get the formatted value you want. yAxis has valueFormatter, so does dataSet

Another way is, you subclass dataSet to pass your value text array, and override renderAxisLabels or drawValues to draw the text you want.

I would prefer the first one since it does not touch the library code

Changing point labels to specific string values using iOS charts?

As per my experience, you can achieve this with the help of ChartFormatter in Charts library.

Use below code to show string values on your Charts.

Set Value Formatter:

let chartFormatter = BarChartFormatter(labels: xValues)
let xAxis = XAxis()
xAxis.valueFormatter = chartFormatter
self.xAxis.valueFormatter = xAxis.valueFormatter

Implement Valuformatter methods:

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
}
}

By adding above code for your respective charts you can set string values on your XAxis.

Note: Replace BarChartFormatter with your Chart type.

Hope this will helps!

iOS Charts, data label customization

Create a custom renderer by inheriting from LineChartRenderer. In this renderer, you need to overwrite one function - drawValues(context: CGContext). In fact, you can copy-paste most of the source code for this function from the base class, you only need to change ChartUtils.drawText function on a variant with a text rotation parameter. Fortunately, ChartUtils class has such kind of function. Also, add new initializer and redefine shouldDrawValues function because of it inaccessible through internal access level in the base class.

import Foundation
import Charts

open class LineChartRendererWithVerticalValues: LineChartRenderer
{

var _xBounds = XBounds() // Reusable XBounds object

init(view: LineChartView) {
super.init(dataProvider: view, animator: view.chartAnimator, viewPortHandler: view.viewPortHandler)
}

// Redefine `shouldDrawValues` function because of `internal` access level in the base class
func shouldDrawValues(forDataSet set: IChartDataSet) -> Bool
{
return set.isVisible && (set.isDrawValuesEnabled || set.isDrawIconsEnabled)
}

// Keep all source code from the base class, except using another version of `ChartUtils.drawText` function
open override func drawValues(context: CGContext)
{
guard
let dataProvider = dataProvider,
let lineData = dataProvider.lineData
else { return }

if isDrawingValuesAllowed(dataProvider: dataProvider)
{
var dataSets = lineData.dataSets

let phaseY = animator.phaseY

var pt = CGPoint()

for i in 0 ..< dataSets.count
{
guard let dataSet = dataSets[i] as? ILineChartDataSet else { continue }

if !shouldDrawValues(forDataSet: dataSet)
{
continue
}

let valueFont = dataSet.valueFont

guard let formatter = dataSet.valueFormatter else { continue }

let trans = dataProvider.getTransformer(forAxis: dataSet.axisDependency)
let valueToPixelMatrix = trans.valueToPixelMatrix

let iconsOffset = dataSet.iconsOffset

var valOffset = Int(dataSet.circleRadius * 1.75)

if !dataSet.isDrawCirclesEnabled
{
valOffset = valOffset / 2
}

_xBounds.set(chart: dataProvider, dataSet: dataSet, animator: animator)

for j in stride(from: _xBounds.min, through: min(_xBounds.min + _xBounds.range, _xBounds.max), by: 1)
{
guard let e = dataSet.entryForIndex(j) else { break }

pt.x = CGFloat(e.x)
pt.y = CGFloat(e.y * phaseY)
pt = pt.applying(valueToPixelMatrix)

if (!viewPortHandler.isInBoundsRight(pt.x))
{
break
}

if (!viewPortHandler.isInBoundsLeft(pt.x) || !viewPortHandler.isInBoundsY(pt.y))
{
continue
}

if dataSet.isDrawValuesEnabled {

// Changes are here!
// Draw text with rotation
ChartUtils.drawText(
context: context,
text: formatter.stringForValue(
e.y,
entry: e,
dataSetIndex: i,
viewPortHandler: viewPortHandler),
point: CGPoint(
x: pt.x,
y: pt.y - CGFloat(valOffset) - valueFont.lineHeight),
attributes: [NSAttributedStringKey.font: valueFont, NSAttributedStringKey.foregroundColor: dataSet.valueTextColorAt(j)],
anchor: CGPoint(x: 0.5, y: 0.5),
angleRadians:CGFloat.pi*3.0/2.0)
}

if let icon = e.icon, dataSet.isDrawIconsEnabled
{
ChartUtils.drawImage(context: context,
image: icon,
x: pt.x + iconsOffset.x,
y: pt.y + iconsOffset.y,
size: icon.size)
}
}
}
}
}
}

Use custom renderer for your LineChartView and add the extra offset if vertical values don't fit on the view.

myLineChartView.renderer = LineChartRendererWithVerticalValues(view: lineChartView)
myLineChartView.extraTopOffset = 20

LineChartView with vertical data labels

Remove Value Labels from iOS Charts Pie Chart

If you need to disable drawing values of Data Set Entries use this

pieChartDataSet.drawValuesEnabled = false

If you need to disable drawing values on some Axis use this:

chartIMG.rightAxis.drawLabelsEnabled = false
chartIMG.leftAxis.drawLabelsEnabled = false
chartIMG.xAxis.drawLabelsEnabled = false
chartIMG.rightAxis.drawLabelsEnabled = false

Change label size in iOS-Charts library

I solved my problem by updating the Charts library to version 3.0.2 and then adding the following code:

 let legend = mChart.legend
legend.font = UIFont(name: "Verdana", size: 16.0)!

this legend option is something that was not available in the previous version of Charts I was using.

How to customize datapoint labels in iOS Charts?

You have to append IValueFormatter protocol to your ViewController and implement stringForValue(_:entry:dataSetIndex:viewPortHandler:) method (1).

Then set ViewController as valueFormatter delegate for charts data set (2).

import UIKit
import Charts

class ViewController: UIViewController, IValueFormatter {

@IBOutlet weak var lineChartView: LineChartView!

// Some data
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
let unitsSold = [20.0, 4.0, 3.0, 6.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]

// (1) Implementation the delegate method for changing data point labels.
func stringForValue(_ value: Double,
entry: ChartDataEntry,
dataSetIndex: Int,
implement delegate methodviewPortHandler: ViewPortHandler?) -> String{

return "My cool label " + String(value)
}

func setChart(dataPoints: [String], values: [Double]){
var dataEntries: [ChartDataEntry] = []

// Prepare data for chart
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(x: Double(i), y: values[i])
dataEntries.append(dataEntry)
}

let lineChartDataSet = LineChartDataSet(values: dataEntries, label: "Units Sold")
let lineChartData = LineChartData(dataSets: [lineChartDataSet])

// (2) Set delegate for formatting datapoint labels
lineChartData.dataSets[0].valueFormatter = self

lineChartView.data = lineChartData
}

override func viewDidLoad() {
super.viewDidLoad()

setChart(dataPoints: months, values: unitsSold)
}
}

iOS Charts remove values on the bar of the bar chart

Add following line of code where you setup sets of chart to fix your issue:

var set = BarChartDataSet(values: yVals, label: "Data Set")        
set.drawValuesEnabled = false // Set this property to false to hide all values

let data = BarChartData(dataSet: set)
yourChartView.data = data

This code will hide all values above bar chart. I hope this will help you.



Related Topics



Leave a reply



Submit