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)
]