问题
I'm using iOS Chart to display line graph in my application. I have facing one issue while display xAxis.
I have following code which are used to configure chart and display data on it.
import UIKit
import Charts
class TotalSalesVC: BaseVC {
//------------------------------------------------------------------------------
// MARK:-
// MARK:- Outlets
//------------------------------------------------------------------------------
@IBOutlet weak var lineChartView : LineChartView!
//------------------------------------------------------------------------------
// MARK:-
// MARK:- Variables
//------------------------------------------------------------------------------
var lineChartData : LineChartDataWeb?
//------------------------------------------------------------------------------
// MARK:-
// MARK:- Custom Methods
//------------------------------------------------------------------------------
func setupLineChart() {
self.lineChartView.delegate = self
self.lineChartView.chartDescription?.enabled = false
self.lineChartView.dragEnabled = true
self.lineChartView.setScaleEnabled(true)
self.lineChartView.pinchZoomEnabled = true
// X-Axis Limit Line
let leftAxis = self.lineChartView.leftAxis
leftAxis.removeAllLimitLines()
leftAxis.axisMaximum = 300000
leftAxis.axisMinimum = 0
leftAxis.drawLimitLinesBehindDataEnabled = false
let l = self.lineChartView.legend
l.form = .line
l.font = self.isPhone ? Typography.robotoRegular14 : Typography.robotoRegular18
l.textColor = .black
l.horizontalAlignment = .left
l.verticalAlignment = .bottom
l.orientation = .horizontal
l.drawInside = false
let xAxis = self.lineChartView.xAxis
xAxis.labelFont = self.isPhone ? Typography.robotoRegular14 : Typography.robotoRegular18
xAxis.labelTextColor = .black
xAxis.drawAxisLineEnabled = false
xAxis.labelPosition = .bottom
xAxis.drawGridLinesEnabled = false
self.lineChartView.rightAxis.enabled = false
let marker = BalloonMarker(color: UIColor(white: 180/255, alpha: 1),
font: .systemFont(ofSize: 12),
textColor: .white,
insets: UIEdgeInsets(top: 8, left: 8, bottom: 20, right: 8))
marker.chartView = self.lineChartView
marker.minimumSize = CGSize(width: 80, height: 40)
self.lineChartView.marker = marker
self.lineChartView.legend.form = .line
}
//------------------------------------------------------------------------------
func setupData() {
if lineChartData != nil {
var arrCurrentYear = [ChartDataEntry]()
// Current year data
if let arrCurrentYearData = lineChartData?.currentYear {
let formatter = BarChartFormatter()
let xAxis = XAxis()
for (index, value) in arrCurrentYearData.enumerated() {
let dataEntry = ChartDataEntry(x: Double(index), y: Double(value))
arrCurrentYear.append(dataEntry)
_ = formatter.stringForValue(Double(index), axis: xAxis)
}
xAxis.valueFormatter = formatter
self.lineChartView.xAxis.valueFormatter = xAxis.valueFormatter
}
let currentYear = Calendar.current.component(.year, from: Date())
// Set 1 - Current year
let set1 = LineChartDataSet(values: arrCurrentYear, label: "\(currentYear)")
set1.drawIconsEnabled = false
set1.setColor(.barColor)
set1.setCircleColor(.barColor)
set1.lineWidth = 1
set1.circleRadius = 3
set1.drawCirclesEnabled = true
set1.valueFont = self.isPhone ? Typography.robotoRegular14 : Typography.robotoRegular18
set1.formLineWidth = 2
set1.formSize = 15
set1.drawValuesEnabled = false
set1.fillAlpha = 1
set1.fill = Fill(color: ChartColorTemplates.colorFromString("#028ed3").withAlphaComponent(0.6))
set1.drawFilledEnabled = true
var arrPreviousYear = [ChartDataEntry]()
// Previous year data
if let arrPreviousYearData = lineChartData?.previousYear {
let formatter = BarChartFormatter()
let xAxis = XAxis()
for (index, value) in arrPreviousYearData.enumerated() {
let dataEntry = ChartDataEntry(x: Double(index), y: Double(value))
arrPreviousYear.append(dataEntry)
_ = formatter.stringForValue(Double(index), axis: xAxis)
}
xAxis.valueFormatter = formatter
self.lineChartView.xAxis.valueFormatter = xAxis.valueFormatter
}
// Set 2 - Previous year
let previousYear = Calendar.current.component(.year, from: Calendar.current.date(byAdding: .year, value: -1, to: Date())!)
let set2 = LineChartDataSet(values: arrPreviousYear, label: "\(previousYear)")
set2.drawIconsEnabled = false
set2.setColor(.subTitleColor)
set2.setCircleColor(.black)
set2.lineWidth = 1
set2.circleRadius = 3
set2.drawCirclesEnabled = true
set2.valueFont = self.isPhone ? Typography.robotoRegular14 : Typography.robotoRegular18
set2.formLineWidth = 2
set2.formSize = 15
set2.drawValuesEnabled = false
set2.fillAlpha = 1
set2.fill = Fill(color: ChartColorTemplates.colorFromString("#4c5b61").withAlphaComponent(0.6))
set2.drawFilledEnabled = true
set2.drawCirclesEnabled = false
let data = LineChartData(dataSets: [set1, set2])
self.lineChartView.data = data
}
}
//------------------------------------------------------------------------------
// MARK:-
// MARK:- View Life Cycle Methods
//------------------------------------------------------------------------------
override func viewDidLoad() {
super.viewDidLoad()
self.setupLineChart()
self.initSetup()
self.setupData()
}
//------------------------------------------------------------------------------
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.lineChartView.animate(xAxisDuration: 2.0, yAxisDuration: 2.0)
}
}
//------------------------------------------------------------------------------
// MARK:-
// MARK:- Extension - ChartViewDelegate Methods
//------------------------------------------------------------------------------
extension TotalSalesVC: ChartViewDelegate {
func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
self.lineChartView.centerViewToAnimated(xValue: entry.x, yValue: entry.y,
axis: self.lineChartView.data!.getDataSetByIndex(highlight.dataSetIndex).axisDependency,
duration: 1)
}
}
//------------------------------------------------------------------------------
// MARK:-
// MARK:- BarChartFormatter
//------------------------------------------------------------------------------
@objc(BarChartFormatter)
public class BarChartFormatter: NSObject, IAxisValueFormatter
{
var arrXAxisQuarter1: [String]! = ["Jan", "Feb", "Mar"]
public func stringForValue(_ value: Double, axis: AxisBase?) -> String
{
return arrXAxisQuarter1[Int(value)]
}
}
I have tried this code to configure line chart and display data.
The issue is, I have configure chart for three month, but it display ambiguous month label on chart.
Output:
Expectation:
How can I achieve this ?
回答1:
You can set label count like so
xAxis.setLabelCount(3, force: true)
You'll probably also want this too
xAxis.centerAxisLabelsEnabled = true
回答2:
I hope this library can help you
https://github.com/danielgindi/Charts
import Charts
@IBOutlet weak var chartView: LineChartView!
var options: [Option]!
let dayOfWeeks = ["mon", "tue", "wen", "thu", "fri", "sat", "sun"]
func settingsChart() -> Void {
self.options = [.toggleValues,
.toggleFilled,
.toggleCircles,
.toggleCubic,
.toggleHorizontalCubic,
.toggleIcons,
.toggleStepped,
.toggleHighlight,
.animateX,
.animateY,
.animateXY,
.saveToGallery,
.togglePinchZoom,
.toggleAutoScaleMinMax,
.toggleData]
chartView.chartDescription?.enabled = false
chartView.dragEnabled = true
chartView.setScaleEnabled(true)
chartView.pinchZoomEnabled = true
chartView.legend.form = .line
chartView.rightAxis.enabled = false
let xAxis = chartView.xAxis
xAxis.labelPosition = .bottom
xAxis.granularity = 1
xAxis.gridLineDashLengths = [10, 10]
xAxis.gridLineDashPhase = 0
xAxis.valueFormatter = self
}
func showDataOnChartView() -> Void {
let data = [5000.0, 5100.0, 5200.0] // In your case, this array must have only 3 elements!
let values = (0..<data.count).map { (i) -> ChartDataEntry in
let val:Double = data[i]
return ChartDataEntry(x: Double(i), y: val, icon: UIImage(named: "ic_test"))
}
let set1 = LineChartDataSet(values: values, label: "Test")
set1.drawIconsEnabled = false
set1.lineDashLengths = [5, 0.5]
set1.highlightLineDashLengths = [5, 2.5]
set1.setColor(Utility.mainBlueColor)
set1.setCircleColor(Utility.mainBlueColor)
set1.lineWidth = 1
set1.circleRadius = 3
set1.drawCircleHoleEnabled = false
set1.valueFont = .systemFont(ofSize: 9)
set1.formLineDashLengths = [5, 2.5]
set1.formLineWidth = 1
set1.formSize = 15
let gradientColors = [ChartColorTemplates.colorFromString("#00ff0000").cgColor,
ChartColorTemplates.colorFromString("#ffff0000").cgColor]
let gradient = CGGradient(colorsSpace: nil, colors: gradientColors as CFArray, locations: nil)!
set1.fillAlpha = 1
set1.fill = Fill(linearGradient: gradient, angle: 90) //.linearGradient(gradient, angle: 90)
set1.drawFilledEnabled = true
let chartData = LineChartData(dataSets: [set1])
chartView.data = chartData
for set in chartView.data!.dataSets as! [LineChartDataSet] {
set.drawValuesEnabled = false
}
chartView.animate(yAxisDuration: 2.5)
}
And DataSource:
extension TotalSalesVC: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
if value != -1 && !value.isNaN{
return NSLocalizedString(dayOfWeeks[Int(value) % dayOfWeeks.count] , comment: "")
}
return ""
}
}
来源:https://stackoverflow.com/questions/54348390/display-three-label-on-xaxis-of-chart