iOS Charts - single values not showing Swift

2019-05-21 15:52发布

问题:

When I have multiple points in an array for a line on a line graph, everything shows perfectly. But when there is only one point, the dot does not show. I dont know why? the delegate is being set elsewhere, but this doesnt seem to be the issue.

The below examples shows Test 2 and Test exercise. The first image is where each has one value, the second they each have 2.

heres my code

    func startChart(){

        chart.dragEnabled = true
        chart.legend.form = .circle
        chart.drawGridBackgroundEnabled = false

        let xaxis = chart.xAxis

        xaxis.valueFormatter = axisFormatDelegate
        xaxis.labelCount = dataSets.count
        xaxis.labelPosition = .bottom

        xaxis.granularityEnabled = true
        xaxis.granularity = 1.0
        xaxis.avoidFirstLastClippingEnabled = true
        xaxis.forceLabelsEnabled = true
        let rightAxis = chart.rightAxis

        rightAxis.enabled = false
        rightAxis.axisMinimum = 0

        let leftAxis = chart.leftAxis
        leftAxis.drawGridLinesEnabled = true
        leftAxis.axisMinimum = 0

        let chartData = LineChartData(dataSets: dataSets)
        chart.data = chartData
 }

If I add

chart.setVisibleXRangeMinimum(myMinDate)

the value will show correctly. however it squashes the value to the left and overlaps 2 x value dates

回答1:

The only way I could get around this was to add an additional invisible line.

I created a clear line that started the day before and ended the day after my single values.

As long as there is a line on the chart that goes from one point to another, the other single values show.

  var singleValue = false
    for i in 0...(dataSets.count - 1) {
        if dataSets[i].values.count > 1{
            singleValue = true
        }
    }
    var data = dataSets
    if singleValue == false {
        let minNS = Calendar.current.date(byAdding: .day, value: -1, to: minNSDate as! Date)
        let maxNS =  Calendar.current.date(byAdding: .day, value: 1, to: maxNSDate as! Date)

        var dataEntries: [ChartDataEntry] = []

        let dataEntry1 = ChartDataEntry(x:Double(String(format: "%.2f",Double((minNS?.timeIntervalSince1970)!)))!,y:00.00)
        let dataEntry2 = ChartDataEntry(x:Double(String(format: "%.2f",Double((maxNS?.timeIntervalSince1970)!)))!,y:00.00)
        dataEntries.append(dataEntry1)
        dataEntries.append(dataEntry2)
        let set = LineChartDataSet(values: dataEntries, label: "")
        set.setCircleColor(UIColor.clear)
        set.circleHoleColor = UIColor.clear
        set.setColor(UIColor.white, alpha: 0.0)
        set.drawValuesEnabled = false
        data.append(set)

    }
    chart.chartDescription?.text = ""
    let chartData = LineChartData(dataSets: data)
    chart.data = chartData



回答2:

I think I found a better solution. Single point is not enough to draw a line (you need at least two points) so LineChartView can't render your data. You can fix that by replace LineChartView with CombinedChartView. CombinedChartView give a possibility to mix different types of data on one chart. You can check how many data entires do you have and decide which type of DataSet will be proper.

Code example:

    if dataEntry.count == 1 {
        let scatterDataSet = ScatterChartDataSet(values: dataEntry, label: title)
        scatterDataSet.setColor(UIColor.pmd_darkBlue)
        scatterDataSet.setScatterShape(.circle)
        scatterDataSet.drawValuesEnabled = false

        combinedChartData.scatterData = ScatterChartData(dataSets: [scatterDataSet])
    }
    else {
        let lineDataSet = LineChartDataSet(values: dataEntry, label: title)
        lineDataSet.setColor(UIColor.pmd_darkBlue)
        lineDataSet.lineWidth = 3.0
        lineDataSet.drawCirclesEnabled = false
        lineDataSet.drawValuesEnabled = false

        combinedChartData.lineData = LineChartData(dataSets: [lineDataSet])
    }

    combinedChart.data = combinedChartData 

You can also combine two and more types DataSets in one chart.

Important

Don't forget to add this line:

combinedChart.drawOrder = [DrawOrder.line.rawValue, DrawOrder.scatter.rawValue]

You must to write types of data types you use otherwise data will not render.