Swift图表库.如何在正确的位置显示X轴日期 [英] Swift chart library. How to display X axis dates in a right places

查看:153
本文介绍了Swift图表库.如何在正确的位置显示X轴日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已这也是一个调试视频.

我使用这个在我的Swift iOS应用中显示图表.这是我的图表:

X轴代表日期,Y轴代表运动员的举重.

图表中间的海蓝色圆点是日期与举重之间的交集.但是我不确定图表如何在日期中间显示两个相同的日期和一个点.

我的问题是我如何设置X轴以将8月23日也移动到屏幕中间,或适应一个点,不管它是否移动,我不在乎,我只想在其中显示一个点相同的日期.像下面的图片一样:

该想法是在所有点下显示日期,而不是现在显示一个日期之间某个时间范围的灵活的X轴.

这是我的代码,您可以看到我循环搜索结果并从中创建日期列表以及Y轴的总举升重量.从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
    }

解决方案

如果x轴指定为Date,则图表库会将您的数据集视为连续数据.如果数据分布不充分,则会在x轴上产生奇怪的插值行为.

相反,您需要创建一个离散数据集,例如(1,2000),(2,2025),其中x值{1,2}不是Date类型,而是相对于特定日期的偏移量.

然后,您必须使用以下方法将可见"标签的格式设置为所需的日期(通过将偏移量添加到先前选择的日期):

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

通过这种方式请注意,图表将显示离散数据,并且不会对x轴进行插值,但是格式将显示正确的x轴日期,而不是{1、2、3,...}之类的值

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
    }

解决方案

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, ...}

这篇关于Swift图表库.如何在正确的位置显示X轴日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆