Make line chart with values and dates

青春壹個敷衍的年華 提交于 2019-12-10 22:19:37

问题


In my app i use ios-charts library (swift alternative of MPAndroidChart). All i need is to display line chart with dates and values.

Right now i use this function to display chart

func setChart(dataPoints: [String], values: [Double]) {       

    var dataEntries: [ChartDataEntry] = []

    for i in 0..<dataPoints.count {
        let dataEntry = ChartDataEntry(value: values[i], xIndex: i)
        dataEntries.append(dataEntry)
    }        

    let lineChartDataSet = LineChartDataSet(yVals: dataEntries, label: "Items count")
    let lineChartData = LineChartData(xVals: dataPoints, dataSet: lineChartDataSet)
    dateChartView.data = lineChartData      
}

And this is my data:

xItems = ["27.05", "03.06", "17.07", "19.09", "20.09"] //String    
let unitsSold = [25.0, 30.0, 45.0, 60.0, 20.0] //Double

But as you can see - xItems are dates in "dd.mm" format. As they are strings they have same paddings between each other. I want them to be more accurate with real dates. For example 19.09 and 20.09 should be very close. I know that i should match each day with some number in order to accomplish it. But i don't know what to do next - how i can adjust x labels margins?

UPDATE After small research where i found out that many developers had asked about this feature but nothing happened - for my case i found very interesting alternative to this library in Swift - PNChart. It is easy to use, it solves my problem.


回答1:


The easiest solution will be to loop through your data and add a ChartDataEntry with a value of 0 and a corresponding label for each missing date.

In response to the question in the comments here is a screenshot from one of my applications where I am filling in date gaps with 0 values:

In my case I wanted the 0 values rather than an averaged line from data point to data point as it clearly indicates there is no data on the days skipped (8/11 for instance).

From @Philipp Jahoda's comments it sounds like you could skip the 0 value entries and just index the data you have to the correct labels.

I modified the MPAndroidChart example program to skip a few data points and this is the result:

As @Philipp Jahoda mentioned in the comments the chart handles missing Entry by just connecting to the next data point. From the code below you can see that I am generating x values (labels) for the entire data set but skipping y values (data points) for index 11 - 29 which is what you want. The only thing remaining would be to handle the x labels as it sounds like you don't want 15, 20, and 25 in my example to show up.

ArrayList<String> xVals = new ArrayList<String>();
for (int i = 0; i < count; i++) {
    xVals.add((i) + "");
}

ArrayList<Entry> yVals = new ArrayList<Entry>();

for (int i = 0; i < count; i++) {

    if (i > 10 && i < 30) {
        continue;
    }

    float mult = (range + 1);
    float val = (float) (Math.random() * mult) + 3;// + (float)
    // ((mult *
    // 0.1) / 10);
    yVals.add(new Entry(val, i));
}



回答2:


What I did is fully feed the dates for x data even no y data for it, and just not add the data entry for the specific xIndex, then it will not draw the y value for the xIndex to achieve what you want, this is the easiest way since you just write a for loop and continue if you detect no y value there.

I don't suggest use 0 or nan, since if it is a line chart, it will connect the 0 data or bad things will happen for nan. You might want to break the lines, but again ios-charts does not support it yet (I also asked a feature for this), you need to write your own code to break the line, or you can live with connecting the 0 data or just connect to the next valid data.

The down side is it may has performance drop since many xIndex there, but I tried ~1000 and it is acceptable. I already asked for such feature a long time ago, but it took lot of time to think about it.




回答3:


Here's a function I wrote based on Wingzero's answer (I pass NaNs for the entries in the values array that are empty) :

func populateLineChartView(lineChartView: LineChartView, labels: [String], values: [Float]) {
    var dataEntries: [ChartDataEntry] = []

    for i in 0..<labels.count {
        if !values[i].isNaN {
            let dataEntry = ChartDataEntry(value: Double(values[i]), xIndex: i)
            dataEntries.append(dataEntry)
        }
    }

    let lineChartDataSet = LineChartDataSet(yVals: dataEntries, label: "Label")
    let lineChartData = LineChartData(xVals: labels, dataSet: lineChartDataSet)
    lineChartView.data = lineChartData
}



回答4:


The solution which worked for me is splitting Linedataset into 2 Linedatasets. First would hold yvals till empty space and second after emptyspace.

//create 2 LineDataSets. set1- till empty space set2 after empty space

set1 = new LineDataSet(yVals1, "DataSet 1");
set2= new LineDataSet(yVals2,"DataSet 1");

//load datasets into datasets array 

ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
dataSets.add(set1);
dataSets.add(set2);

//create a data object with the datasets

LineData data = new LineData(xVals, dataSets);

// set data
mChart.setData(data);


来源:https://stackoverflow.com/questions/33619679/make-line-chart-with-values-and-dates

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