How can I show first value and last value in line Chart - ios

I'm using charts library and i'm trying to add first value and last value on line chart graph.Please let me know how can I achieve it. I have tried customising drawValue method in linechartrenderer but didn't worked.
Here is my code
var months = ["Dec 15", "Jun 16", "Dec 16", "Jun 17", "Dec 17", "Jun 18"]
var unitsSold = [50.0, 25.0, 50.0, 75.0, 100.0, 75.0]
Viewdidload:
setChart(dataPoints: months, values: unitsSold)
Method:
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [ChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = ChartDataEntry(x: Double(i), y: values[i], data: dataPoints[i] as AnyObject)
dataEntries.append(dataEntry)
}
let chartDataSet = LineChartDataSet(values: dataEntries, label: nil)
chartDataSet.setColor(UIColor(red: 53/255, green: 85/255, blue: 123/255, alpha: 1))
chartDataSet.circleRadius = 5
chartDataSet.circleHoleRadius = 2
chartDataSet.drawValuesEnabled = false
chartDataSet.drawCirclesEnabled = false
let chartData = LineChartData(dataSets: [chartDataSet])
defaultChartView.data = chartData
defaultChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: months)
defaultChartView.xAxis.labelPosition = .bottom
defaultChartView.xAxis.drawGridLinesEnabled = false
//lineChartView.xAxis.avoidFirstLastClippingEnabled = true
defaultChartView.xAxis.axisMinimum = 0
defaultChartView.xAxis.granularity = 1
defaultChartView.rightAxis.drawAxisLineEnabled = false
defaultChartView.rightAxis.drawLabelsEnabled = false
defaultChartView.rightAxis.enabled = false
defaultChartView.leftAxis.drawAxisLineEnabled = false
defaultChartView.leftAxis.axisMinimum = 0.0
defaultChartView.leftAxis.drawLabelsEnabled = false
//lineChartView.leftAxis.drawGridLinesEnabled = false
//lineChartView.leftAxis.granularityEnabled = false
defaultChartView.pinchZoomEnabled = true
defaultChartView.doubleTapToZoomEnabled = true
defaultChartView.legend.enabled = false
defaultChartView.chartDescription?.text = " "
}

viewDidLoad:
guard let firstMonth = months.first, let lastMonth = months.last else {
return
}
let myMonths = [firstMonth, lastMonth]
guard let firstValue = unitsSold.first, let lastValue = unitsSold.last else {
return
}
let myValues = [firstValue, lastValue]
setChart(dataPoints: myMonths, values: myValues)

Solution is go to linechartrenderer file and replace drawValues method
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
// make sure the values do not interfear with the circles
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 }
if(j == 0 || j == dataSet.entryCount - 1)
{
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 {
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),
align: .center,
attributes: [NSAttributedStringKey.font: valueFont, NSAttributedStringKey.foregroundColor: dataSet.valueTextColorAt(j)])
}
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)
}
}
else{
}
}
}
}
}

Set below property of X axis
barChartView.xAxis.setLabelCount(2, force: true)

Related

iOS Charts not showing all xAxis Value

I am writing an iOS App in Swift 4.2
I am using Charts library to display Horizontal Bar Chart. I need to set its xAxis Values. Only last value is being displayed.
Issue Screenshot:
Code Snippet:
#IBOutlet var chartView: HorizontalBarChartView!
override func viewDidLoad() {
super.viewDidLoad()
let xAxis = chartView.xAxis
xAxis.labelPosition = .bottom
xAxis.labelFont = .systemFont(ofSize: 10)
xAxis.drawAxisLineEnabled = false
xAxis.drawGridLinesEnabled = false
xAxis.granularity = 1
xAxis.enabled=true
xAxis.setLabelCount(3, force: false) //Not working as per expectations
xAxis.valueFormatter=IndexAxisValueFormatter(values: ["A","B","C"]) //Not working as per expectations
self.setDataCount(3,values:[142000,122400,100110])
chartView.animate(yAxisDuration: 2.5)
}
func setDataCount(_ count: Int, values:[Double]) {
let barWidth = 2.0
let spaceForBar = 4.0
var n=0
let yVals = (0..<count).map { (i) -> BarChartDataEntry in
let val = values[n]
n+=1
return BarChartDataEntry(x: Double(i)*spaceForBar, y: val)
}
let set1 = BarChartDataSet(entries: yVals, label: "DataSet")
set1.drawIconsEnabled = false
let data = BarChartData(dataSet: set1)
data.setValueFont(UIFont(name:"HelveticaNeue-Light", size:10)!)
data.barWidth = barWidth
chartView.data = data
//let xAxis = chartView.xAxis
//xAxis.setLabelCount(3, force: false)
//xAxis.valueFormatter=IndexAxisValueFormatter(values: ["A","B","C"])
}
I tried to find solutions:
xAxis.valueFormatter=IndexAxisValueFormatter(values: ["A","B","C"])
but these are not working.
This is happening because the default functionality of IndexAxisValueFormatter
You have to code your own custom IAxisValueFormatter like this
final class CustomFormatter: IAxisValueFormatter {
var labels: [String] = []
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
let count = self.labels.count
guard let axis = axis, count > 0 else {
return ""
}
let factor = axis.axisMaximum / Double(count)
let index = Int((value / factor).rounded())
if index >= 0 && index < count {
return self.labels[index]
}
return ""
}
}
Then use it like
let customFormater = CustomFormater()
customFormater.labels = ["A","B","C"]
chartView.xAxis.valueFormatter = customFormater
Make sure the size/count of the data and labels is the same or it wont give you the desired results.
I updated your given code please check changes.
I hope its work for you.
class ViewController: UIViewController {
#IBOutlet var chartView: HorizontalBarChartView!
override func viewDidLoad() {
super.viewDidLoad()
let xAxis = chartView.xAxis
xAxis.labelPosition = .bottom
xAxis.labelFont = .systemFont(ofSize: 10)
xAxis.drawAxisLineEnabled = false
xAxis.drawGridLinesEnabled = false
xAxis.granularity = 1
xAxis.enabled=true
xAxis.setLabelCount(3, force: false) //Not working as per expectations
xAxis.valueFormatter = IndexAxisValueFormatter(values: ["A","B","C"])//AxisValueFormatter(values: ["A","B","C"]) //Not working as per expectations
self.setDataCount(3,values:[142000,122400,100110])
chartView.animate(yAxisDuration: 2.5)
}
func setDataCount(_ count: Int, values:[Double]) {
let yVals = (0..<count).map { (i) -> BarChartDataEntry in
let val = values[i]
return BarChartDataEntry(x: Double(i), y: val)
}
let set1 = BarChartDataSet(values: yVals, label: "DataSet")
set1.drawIconsEnabled = false
let data = BarChartData(dataSet: set1)
data.setValueFont(UIFont(name:"HelveticaNeue-Light", size:10)!)
//data.barWidth = barWidth
chartView.data = data
//let xAxis = chartView.xAxis
//xAxis.setLabelCount(3, force: false)
//xAxis.valueFormatter=IndexAxisValueFormatter(values: ["A","B","C"])
}
}

iOS Charts - How to set the y values under the x axis

I'm using the danielgindi/Charts library and I'm trying to put the Y Value under the X axis.
At the moment I have this:
And I need this:
My code:
private func setupBarChart(){
var barChart = BarChartView(frame: frame)
barChartContainer.addSubview(barChart)
let labels = ["Ericsson", "Siemens", "Huawei", "Ericsson", "Siemens"]
barChartContainer.addConstraintsWithFormat("H:|[v0]|", views: barChart)
barChartContainer.addConstraintsWithFormat("V:|[v0]|", views: barChart)
let entry1 = BarChartDataEntry(x: 0, y: 3670)
let set1 = BarChartDataSet(values: [entry1], label: labels[0])
set1.setColor(UIColor.cnBlue)
let entry2 = BarChartDataEntry(x: 1, y: 2292)
let set2 = BarChartDataSet(values: [entry2], label: labels[1])
set2.setColor(UIColor.cnBlue)
let entry3 = BarChartDataEntry(x: 2, y: 3670)
let set3 = BarChartDataSet(values: [entry3], label: labels[2])
set3.setColor(UIColor.cnBlue)
let entry4 = BarChartDataEntry(x: 3, y: 2292)
let set4 = BarChartDataSet(values: [entry4], label: labels[3])
set4.setColor(UIColor.cnBlue)
let entry5 = BarChartDataEntry(x: 4, y: 675)
let set5 = BarChartDataSet(values: [entry5], label: labels[4])
set5.setColor(UIColor.cnBlue)
let data = BarChartData(dataSets: [set1, set2, set3, set4, set5])
barChart.data = data
barChart.drawGridBackgroundEnabled = false
barChart.drawValueAboveBarEnabled = false
barChart.drawBordersEnabled = false
barChart.legend.enabled = false
barChart.chartDescription?.text = "Sites per technology"
barChart.chartDescription?.textAlign = .center
barChart.chartDescription?.position = CGPoint(x: barChartContainer.bounds.width/2, y: 0)
barChart.xAxis.labelPosition = .bottom
barChart.xAxis.drawGridLinesEnabled = false
barChart.xAxis.wordWrapEnabled = true
barChart.xAxis.labelFont = .cnFont(ofSize: 14, weight: .semibold)
barChart.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in
return labels[Int(index)]
})
barChart.leftAxis.enabled = false
barChart.rightAxis.enabled = false
barChart.drawValueAboveBarEnabled = false
barChart.doubleTapToZoomEnabled = false
barChart.pinchZoomEnabled = false
barChart.scaleXEnabled = false
barChart.scaleYEnabled = false
barChart.setExtraOffsets(left: 10, top: 10, right: 10, bottom: 10)
barChart.fitBars = true
barChart.animate(xAxisDuration: 1, yAxisDuration: 1, easingOption: .easeInOutCirc)
}
Do I have to make a custom AxisRenderer and if so can you give me some leads on this? I have been searching for examples but I still haven't been able to understand how to get what I need with the renderer.
Thank you in advance!
You can implement IAxisValueFormatter protocol this way
struct Label {
var text: String
var value: Double
}
public class DayAxisValueFormatter: NSObject, IAxisValueFormatter {
var xToY = [Double: Label]()
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return "\(xToY[value]!.text ),\n\(xToY[value]!.value)"
}
}
Then assign this formatter to x axis
let f = DayAxisValueFormatter(chart: chartView)
f.xToY = [
0: Label(text: "Biemens", value: 6354),
1: Label(text: "Siemens", value: 2344),
2: Label(text: "Ericsson", value: 2345),
3: Label(text: "Huawei", value: 5241),
4: Label(text: "Shmericsson", value: 3525)
]
barChart.xAxis.valueFormatter = f

iOS-Charts grouped bar chart with size to fit

I recently added "barChartData.groupBars(fromX: 0, groupSpace: 0.5, barSpace: 0.03)" to my Bar Chart so that I don't have overlapping bars and I can't figure it out how to set the width to fit (no horizontal overflow)
func setupGroupedBarChartData(values1: [String], values2: [String], barLabel1: String, barLabel2: String, barColor1: UIColor, barColor2: UIColor) -> BarChartData {
let dataValues1 = values1.flatMap{ Double($0) }
let dataValues2 = values2.flatMap{ Double($0) }
var dataEntries1: [BarChartDataEntry] = []
var dataEntries2: [BarChartDataEntry] = []
for i in 0..<dataValues1.count {
let dataEntry1 = BarChartDataEntry(x: Double(i), y: dataValues1[i])
dataEntries1.append(dataEntry1)
let dataEntry2 = BarChartDataEntry(x: Double(i), y: dataValues2[i])
dataEntries2.append(dataEntry2)
}
let chartDataSet1 = BarChartDataSet(values: dataEntries1, label: barLabel1)
chartDataSet1.colors = [barColor1]
chartDataSet1.valueTextColor = AppColors.lightText
let chartDataSet2 = BarChartDataSet(values: dataEntries2, label: barLabel2)
chartDataSet2.colors = [barColor2]
chartDataSet2.valueTextColor = AppColors.lightText
var groupedDataSet : [BarChartDataSet] = [BarChartDataSet]()
groupedDataSet.append(chartDataSet1)
groupedDataSet.append(chartDataSet2)
let barChartData = BarChartData(dataSets: groupedDataSet)
barChartData.groupBars(fromX: 0, groupSpace: 0.5, barSpace: 0.03)
//display data as integer
let format = NumberFormatter()
format.generatesDecimalNumbers = false
let formatter = DefaultValueFormatter(formatter: format)
barChartData.setValueFormatter(formatter)
return barChartData
}
You can use like this :
You calculation will be like below :
// (barWidth + barSpace) * (no.of.bars) + groupSpace = 1.00 -> interval per "group"
In your code :
barChartData.groupBars(fromX: 0, groupSpace: 0.14, barSpace: 0.03)
barChartData.barWidth = 0.4
barChartView.xAxis.axisMinimum = 0
barChartView.xAxis.axisMaximum = 23

iOS Charts, line chart doesn't refresh datas

I have this problem:
everytime I switch between the segments of the segmented control the datas are messed up, but only if I switch in runtime and only in the 0 segment, the 1 segment works flawlessly no matter how many time I switch. Here's a gif that explains what I mean:
How to deal with this problem? Here's some code
the ibaction func of the segmented control
#IBAction func timeSelectionSegControl(_ sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case 0:
last7Filler()
case 1:
todayFiller()
case 2:
last30Filler()
default:
break
} }
todayFiller() (the one which works well):
func todayFiller() {
emptyArrays()
low = CoreDataController.shared.loadCigFromSeverityNumber(severity: "Bassa intensità")
mid = CoreDataController.shared.loadCigFromSeverityNumber(severity: "Media intensità")
high = CoreDataController.shared.loadCigFromSeverityNumber(severity: "Alta intensità")
for i in low {
if i.date == currentDate() { //put in arrays xxxA the elements which have the property .date equals to today
lowA.append(i)
}
}
for i in mid {
if i.date == currentDate() {
midA.append(i)
}
}
for i in high {
if i.date == currentDate() {
highA.append(i)
}
}
//low severity fill funcs FOR TIME
if !lowA.isEmpty || !midA.isEmpty || !highA.isEmpty {
fillBarChart()
var lowSeverityDataEntry = [ChartDataEntry]()
let crossReferenceLow = lowA.reduce(into: [String: [Cig]]()) {
$0[$1.time!.returnFirstNcharacters(n: 3), default: []].append($1)}
let sortedKeysLow = Array(crossReferenceLow.keys).sorted(by: <)
for key in sortedKeysLow {
let matchingTerms = values.filter({
$0.range(of: key, options: .caseInsensitive) != nil
})
if matchingTerms.isEmpty {
print("no elements found in \(key)")
} else {
let index = values.index(of: matchingTerms[0])
let indexString = matchingTerms[0]
let first3 = indexString.returnFirstNcharacters(n: 3)
let value = ChartDataEntry(x: Double(index!), y: Double((crossReferenceLow[first3]?.count)!))
lowSeverityDataEntry.append(value)
doubleArray.append(Double(index!))
doubleArrayMax.append(Double((crossReferenceLow[first3]?.count)!))
}
}
let lowSeverityLine = LineChartDataSet(values: lowSeverityDataEntry, label: "Bassa")
lowSeverityLine.colors = [NSUIColor.green]
lowSeverityLine.mode = .cubicBezier
lowSeverityLine.lineCapType = self.lineCap
lowSeverityLine.lineWidth = self.lineWidth
lowSeverityLine.circleRadius = self.circleRadius
lowSeverityLine.circleColors = [NSUIColor.green]
lowSeverityLine.circleHoleColor = NSUIColor.white
lowSeverityLine.circleHoleRadius = self.circleHoleRadius
lowSeverityLine.drawValuesEnabled = false
//mid severity fill funcs FOR TIME
var midSeverityDataEntry = [ChartDataEntry]()
let crossReferenceMid = midA.reduce(into: [String: [Cig]]()) {
$0[$1.time!.returnFirstNcharacters(n: 3), default: []].append($1)}
let sortedKeysMid = Array(crossReferenceMid.keys).sorted(by: <)
for key in sortedKeysMid {
let matchingTerms = values.filter({
$0.range(of: key, options: .caseInsensitive) != nil
})
if matchingTerms.isEmpty {
print("no elements found in \(key)")
} else {
let index = values.index(of: matchingTerms[0])
let indexString = matchingTerms[0]
let first3 = indexString.returnFirstNcharacters(n: 3)
let value = ChartDataEntry(x: Double(index!), y: Double((crossReferenceMid[first3]?.count)!))
midSeverityDataEntry.append(value)
doubleArray.append(Double(index!))
doubleArrayMax.append(Double((crossReferenceMid[first3]?.count)!))
}
}
let midSeverityLine = LineChartDataSet(values: midSeverityDataEntry, label: "Media")
midSeverityLine.colors = [NSUIColor.yellow]
midSeverityLine.mode = .cubicBezier
midSeverityLine.lineCapType = self.lineCap
midSeverityLine.lineWidth = self.lineWidth
midSeverityLine.circleRadius = self.circleRadius
midSeverityLine.circleColors = [NSUIColor.yellow]
midSeverityLine.circleHoleColor = NSUIColor.white
midSeverityLine.circleHoleRadius = self.circleHoleRadius
midSeverityLine.drawValuesEnabled = false
//high severity fill funcs FOR TIME
var highSeverityDataEntry = [ChartDataEntry]()
let crossReferenceHigh = highA.reduce(into: [String: [Cig]]()) {
$0[$1.time!.returnFirstNcharacters(n: 3), default: []].append($1)}
let sortedKeysHigh = Array(crossReferenceHigh.keys).sorted(by: <)
for key in sortedKeysHigh {
let matchingTerms = values.filter({
$0.range(of: key, options: .caseInsensitive) != nil
})
if matchingTerms.isEmpty {
print("no elements found in \(key)")
} else {
let index = values.index(of: matchingTerms[0])
let indexString = matchingTerms[0]
let first3 = indexString.returnFirstNcharacters(n: 3)
let value = ChartDataEntry(x: Double(index!), y: Double((crossReferenceHigh[first3]?.count)!))
highSeverityDataEntry.append(value)
doubleArray.append(Double(index!))
doubleArrayMax.append(Double((crossReferenceHigh[first3]?.count)!))
}
}
let highSeverityLine = LineChartDataSet(values: highSeverityDataEntry, label: "Alta")
highSeverityLine.colors = [NSUIColor.red]
highSeverityLine.mode = .cubicBezier
highSeverityLine.lineCapType = self.lineCap
highSeverityLine.lineWidth = self.lineWidth
highSeverityLine.circleRadius = self.circleRadius
highSeverityLine.circleColors = [NSUIColor.red]
highSeverityLine.circleHoleColor = NSUIColor.white
highSeverityLine.circleHoleRadius = self.circleHoleRadius
highSeverityLine.drawValuesEnabled = false
let data = LineChartData()
data.addDataSet(lowSeverityLine)
data.addDataSet(midSeverityLine)
data.addDataSet(highSeverityLine)
lineChartView.data = data
guard let min = doubleArray.min() else {return}
guard let max = doubleArrayMax.max() else {return}
lineChartView.xAxis.axisMinimum = min
lineChartView.leftAxis.axisMaximum = max
let myXaxis = lineChartView.xAxis
myXaxis.granularity = 1.0
myXaxis.axisMaximum = Double(values.count)
myXaxis.labelPosition = .bottom
myXaxis.gridLineWidth = 0.2
myXaxis.axisLineWidth = 1.0
myXaxis.axisLineColor = UIColor.black
myXaxis.valueFormatter = IndexAxisValueFormatter(values: values)
let yLeftAxis = lineChartView.leftAxis
yLeftAxis.granularity = 1.0
yLeftAxis.axisMinimum = 0.0
yLeftAxis.gridLineWidth = 0.2
yLeftAxis.axisLineWidth = 1.0
yLeftAxis.axisLineColor = UIColor.black
lineChartView.rightAxis.enabled = false
lineChartView.chartDescription?.text = ""
lineChartView.animate(xAxisDuration: 1.0, easingOption: .linear)
} else {
lineChartView.noDataText = "Nessuna sigaretta fumata oggi"
barChartView.noDataText = "Nessuna sigaretta fumata oggi"
} }
last7Filler() func (the one which give me problems):
func last7Filler() {
emptyArrays()
low = CoreDataController.shared.loadCigFromSeverityNumber(severity: "Bassa intensità")
mid = CoreDataController.shared.loadCigFromSeverityNumber(severity: "Media intensità")
high = CoreDataController.shared.loadCigFromSeverityNumber(severity: "Alta intensità")
for i in low {
let first3Date = i.date!.returnFirstNcharacters(n: 3)
for a in past7Days() {
let first3Day = "\(a)-"
if first3Date == first3Day {
lowA.append(i)
}
}
}
for i in mid {
let first3Date = i.date!.returnFirstNcharacters(n: 3)
for a in past7Days() {
let first3Day = "\(a)-"
if first3Date == first3Day {
midA.append(i)
}
}
}
for i in high {
let first3Date = i.date!.returnFirstNcharacters(n: 3)
for a in past7Days() {
let first3Day = "\(a)-"
if first3Date == first3Day {
highA.append(i)
}
}
}
if !lowA.isEmpty || !midA.isEmpty || !highA.isEmpty {
fillBarChart()
var lowSeverityDataEntry = [ChartDataEntry]()
let crossReferenceLow = lowA.reduce(into: [String:[Cig]]() ) {
$0[$1.date!.returnFirstNcharacters(n: 5), default: []].append($1)}
let sortedKeysLow = Array(crossReferenceLow.keys).sorted(by: <)
for key in sortedKeysLow {
let matchingTerms = values.filter({
$0.range(of: key, options: .caseInsensitive) != nil
})
if matchingTerms.isEmpty {
print("no elements found in \(key)")
} else {
let index = values.index(of: matchingTerms[0])
let value = ChartDataEntry(x: Double(index!), y: Double((crossReferenceLow[key]?.count)!))
lowSeverityDataEntry.append(value)
}
}
let lowSeverityLine = LineChartDataSet(values: lowSeverityDataEntry, label: "Bassa")
lowSeverityLine.colors = [NSUIColor.green]
lowSeverityLine.mode = .cubicBezier
lowSeverityLine.lineCapType = self.lineCap
lowSeverityLine.lineWidth = self.lineWidth
lowSeverityLine.circleRadius = self.circleRadius
lowSeverityLine.circleColors = [NSUIColor.green]
lowSeverityLine.circleHoleColor = NSUIColor.white
lowSeverityLine.circleHoleRadius = self.circleHoleRadius
lowSeverityLine.drawValuesEnabled = false
var midSeverityDataEntry = [ChartDataEntry]()
let crossReferenceMid = midA.reduce(into: [String: [Cig]]() ) {
$0[$1.date!.returnFirstNcharacters(n: 5), default: []].append($1)}
let sortedKeysMid = Array(crossReferenceMid.keys).sorted(by: <)
for key in sortedKeysMid {
let matchingTerms = values.filter({
$0.range(of: key, options: .caseInsensitive) != nil
})
if matchingTerms.isEmpty {
print("no elements found in \(key)")
} else {
let index = values.index(of: matchingTerms[0])
let value = ChartDataEntry(x: Double(index!), y: Double((crossReferenceMid[key]?.count)!))
midSeverityDataEntry.append(value)
}
}
let midSeverityLine = LineChartDataSet(values: midSeverityDataEntry, label: "Media")
midSeverityLine.colors = [NSUIColor.yellow]
midSeverityLine.mode = .cubicBezier
midSeverityLine.lineCapType = self.lineCap
midSeverityLine.lineWidth = self.lineWidth
midSeverityLine.circleRadius = self.circleRadius
midSeverityLine.circleColors = [NSUIColor.yellow]
midSeverityLine.circleHoleColor = NSUIColor.white
midSeverityLine.circleHoleRadius = self.circleHoleRadius
midSeverityLine.drawValuesEnabled = false
var highSeverityDataEntry = [ChartDataEntry]()
let crossReferenceHigh = highA.reduce(into: [String: [Cig]]()) {
$0[$1.date!.returnFirstNcharacters(n: 5), default: []].append($1)}
let sortedKeysHigh = Array(crossReferenceHigh.keys).sorted(by: <)
for key in sortedKeysHigh {
let matchingTerms = values.filter({
$0.range(of: key, options: .caseInsensitive) != nil
})
if matchingTerms.isEmpty {
print("no element found in \(key)")
} else {
let index = values.index(of: matchingTerms[0])
let value = ChartDataEntry(x: Double(index!), y: Double((crossReferenceHigh[key]?.count)!))
highSeverityDataEntry.append(value)
}
}
let highSeverityLine = LineChartDataSet(values: highSeverityDataEntry, label: "Alta")
highSeverityLine.colors = [NSUIColor.red]
highSeverityLine.mode = .cubicBezier
highSeverityLine.lineCapType = self.lineCap
highSeverityLine.lineWidth = self.lineWidth
highSeverityLine.circleRadius = self.circleRadius
highSeverityLine.circleColors = [NSUIColor.red]
highSeverityLine.circleHoleColor = NSUIColor.white
highSeverityLine.circleHoleRadius = self.circleHoleRadius
highSeverityLine.drawValuesEnabled = false
let data = LineChartData()
data.addDataSet(lowSeverityLine)
data.addDataSet(midSeverityLine)
data.addDataSet(highSeverityLine)
lineChartView.data = data
lineChartView.notifyDataSetChanged()
lineChartView.data!.notifyDataChanged()
//graphic configuration
let myXaxis = lineChartView.xAxis
myXaxis.granularity = 1.0
myXaxis.axisMinimum = 0.0
myXaxis.axisMaximum = Double(values.count)
myXaxis.labelPosition = .bottom
myXaxis.gridLineWidth = 0.2
myXaxis.axisLineWidth = 1.0
myXaxis.axisLineColor = UIColor.black
myXaxis.valueFormatter = IndexAxisValueFormatter(values: values)
let yLeftAxis = lineChartView.leftAxis
yLeftAxis.granularity = 1.0
yLeftAxis.axisMinimum = 0.0
yLeftAxis.gridLineWidth = 0.2
yLeftAxis.axisLineWidth = 1.0
yLeftAxis.axisLineColor = UIColor.black
lineChartView.rightAxis.enabled = false
lineChartView.chartDescription?.text = ""
lineChartView.animate(xAxisDuration: 1.0, easingOption: .linear)
} else {
lineChartView.noDataText = "Nessuna sigaretta fumata nei scorsi 7 giorni"
barChartView.noDataText = "Nessuna sigaretta fumata nei scorsi 7 giorni"
}
p.s. the func emptyArrays() just gives removeAll() to the arrays low, mid, high, lowA, midA and highA

Charts, HorizontalBarChartView, how set values alignment = Center?

Swift 3.1, Charts, Multiple cells in tableView with HorizontalBarChartView.
Is it possible to align the value - centered?
Setup charts data:.
func refreshData() {
guard let item = self.item, !item.tasks.isEmpty else {
return
}
self.titleName.text = item.name
self.leftNameMargin.constant = CGFloat(30 * item.level)
self.titleName.textColor = UIColor(hexString: item.color)
let font = UIFont.systemFont(ofSize: 17.0, weight: UIFontWeightSemibold)
var colors: [UIColor] = []
var yValues: [Double] = []
var count = 0.0
for task in item.tasks {
count += Double(task.count)
yValues.append(Double(task.count))
colors.append(UIColor(hexString: task.valueColor))
}
let suffix = String(format: NSXLocalization.string(forKey: KEY_STR_PERCENT)) //fixes '%' duplication
let formatter = NumberFormatter()
formatter.roundingMode = .floor
formatter.numberStyle = .percent
formatter.positiveSuffix = suffix
formatter.negativeSuffix = suffix
formatter.zeroSymbol = ""
let dataEntry = BarChartDataEntry(x: 0.0, yValues: yValues.map { ($0 / count) })
let dataSet = BarChartDataSet(values: [dataEntry], label: nil)
dataSet.colors = colors
dataSet.valueTextColor = .white
dataSet.barBorderColor = .black
dataSet.barBorderWidth = 1.0
dataSet.drawValuesEnabled = true
dataSet.valueFormatter = DefaultValueFormatter(formatter: formatter)
let data = BarChartData(dataSets: [dataSet])
data.setValueFont(font)
data.setDrawValues(true)
data.highlightEnabled = true
self.chart.data = data
}
I Reviewed all internal methods in the charts, but never found a way to center the y values.

Resources