Display three label on XAxis of chart

旧城冷巷雨未停 提交于 2019-12-11 12:05:48

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!