Swift chart library. How to display X axis dates in a right places

安稳与你 提交于 2019-12-08 07:26:30

问题


EDITED: This is a debug video as well.

I use this library to show charts in my Swift iOS app. This is my chart:

X axis is for dates and Y axis is for lifted weight for my athletes.

The ocean blue dots in the middle of the charts that you see it is an intersection between a date and lifted weight. But I am not sure how a chart shows two the same dates and a dot at the middle of dates.

My question is how can I set up X axis to shift Aug 23 to the middle of the screen as well or to fit a dot I don't care should it be shifted or not, I just want to show a dot in the same line of date. Like on image below:

The idea is to show dates under all dots, instead of flexible X axis which right now shows some range of time between one date.

This is my code as you can see I loop my result and create dates list from it and total lifted weight for Y axis. Dates are retrieved from dateValue.timeIntervalSince1970

func setupGraphicWithResults(_ results: [ExerciseSetResult]) {

        var oneRMValuesList = [Double]()
        var dateList = [Int]()

        for exerciseResult in prepareResults(results) {           
            let oneRMValue = ExeciseResultsService().calculateOneRMValueForResult(exerciseResult)
            let formattedOneRMValue = UnitMeasurementService().convertWeightValueToCurrentMeasurementUnit(oneRMValue)
            oneRMValuesList.append(formattedOneRMValue)

            let dateValue = exerciseResult.date.formatStringToDate()
            let dateInt = dateValue.timeIntervalSince1970
            dateList.append(Int(dateInt))
        }

        setChart(datePoints: dateList, values: oneRMValuesList)
    }


func setChart(datePoints: [Int], values: [Double]) {

        let yAxis = chartView.leftAxis
        yAxis.labelFont = UIFont.mainAppFont(11)
        yAxis.setLabelCount(5, force: true)
        yAxis.labelTextColor = .white
        yAxis.labelPosition = .outsideChart
        yAxis.axisLineColor = .stackedTipTextColor
        yAxis.granularity = 5.0
        yAxis.granularityEnabled = true
        yAxis.drawGridLinesEnabled = true
        yAxis.drawAxisLineEnabled = false

        let xAxis = chartView.xAxis
        xAxis.labelFont = UIFont.mainAppFont(11)
        xAxis.labelTextColor = .white
        xAxis.labelPosition = .bottom
        xAxis.drawAxisLineEnabled = false
        xAxis.drawGridLinesEnabled = false
        xAxis.setLabelCount(datePoints.count, force: true)
        xAxis.valueFormatter = DateValueFormatter()
        xAxis.yOffset = 20.0

        chartView.rightAxis.enabled = false
        chartView.legend.enabled = false
        chartView.chartDescription?.enabled = false
        chartView.setExtraOffsets(left: 10, top: 0, right: 20, bottom: 0)

        var dataEntries: [ChartDataEntry] = []

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

        let lineChartDataSet = LineChartDataSet(entries: dataEntries, label: "")

        lineChartDataSet.mode = .cubicBezier
        lineChartDataSet.drawCirclesEnabled = true
        lineChartDataSet.lineWidth = 2.8
        lineChartDataSet.circleRadius = 4
        lineChartDataSet.circleHoleRadius = 3.8
        lineChartDataSet.circleHoleColor = .stackedLightBlue
        lineChartDataSet.setCircleColor(.white)
        lineChartDataSet.highlightColor = .stackedLightBlue
        //lineChartDataSet.fillColor = .stackedLightBlue
        //lineChartDataSet.fillAlpha = 0.2
        lineChartDataSet.drawFilledEnabled = true
        lineChartDataSet.drawHorizontalHighlightIndicatorEnabled = false
        lineChartDataSet.drawVerticalHighlightIndicatorEnabled = false

        let gradientColors = [UIColor.stackedLightBlue.cgColor, UIColor.clear.cgColor] as CFArray // Colors of the gradient
        let colorLocations:[CGFloat] = [1.0, 0.0] // Positioning of the gradient
        let gradient = CGGradient.init(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: gradientColors, locations: colorLocations) // Gradient Object
        lineChartDataSet.fill = Fill.fillWithLinearGradient(gradient!, angle: 90.0)

        let lineChartData = LineChartData(dataSet: lineChartDataSet)

        lineChartData.setDrawValues(false)
        chartView.data = lineChartData
    }

回答1:


I suspect that your date values (which are integers, seconds since 1970) have non-zero hour/min/sec component to them. I would suggest that you truncate the time portion such that the time is always 00:00:00. Then, I would rebase your X-axis to work in days. You would divide each of the x values by 24. That way each integer on the X axis is equal to one day.

To get back to proper time format for the X axis, you can update your DateFormatter() class and multiply the value by 24:

public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
    var date = Date(timeIntervalSince1970: value * 24)
    let format = dateFormatter.string(from: date)
    return format
}

Also set your x-axis granularity to 1 so that each day is shown.

Also, be careful with timezones. When you truncate your time to 0 you may have to add back hours such that your time is 00:00:00 in your local timezone - DateFormatter is formatting based on timezone.




回答2:


The chart library will treat your data set as continuous if the x-axis is given as Date. This will cause weird interpolation behavior in the x-axis if the data is not well spread out.

Instead, you need to create a discrete data set such as (1,2000), (2, 2025) where the x values {1,2} are not Date types but offsets from a particular day.

You will then have to format the "visible" label to a Date which is what you need (by adding to offset to your previously selected date), using the following method:

func stringForValue(_ value: Double, axis: AxisBase?) -> String

Note by this way, the chart will show discrete data and will not interpolate the x-axis but the formatting will show the proper x-axis date rather than values like {1, 2, 3, ...}



来源:https://stackoverflow.com/questions/57828172/swift-chart-library-how-to-display-x-axis-dates-in-a-right-places

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