制作包含值和日期的折线图

时间:2015-11-09 22:40:09

标签: mpandroidchart ios-charts

在我的应用程序中,我使用ios-charts库(快速替代MPAndroidChart)。 我只需要显示包含日期和值的折线图。

现在我使用此功能显示图表

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      
}

这是我的数据:

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

但是你可以看到 - xItems是“dd.mm”格式的日期。因为它们是字符串,所以它们之间具有相同的填充。我希望他们在实际日期更准确。例如19.09和20.09应该非常接近。我知道我应该每天都用一些数字来匹配才能完成它。但我不知道下一步该做什么 - 我如何调整x标签边距?

更新 经过小规模的研究,我发现许多开发人员已经询问过这个功能,但没有发生任何事情 - 对于我的情况,我发现Swift中这个库的替代品非常有趣 - PNChart。它易于使用,它解决了我的问题。

4 个答案:

答案 0 :(得分:2)

最简单的解决方案是循环访问您的数据,并为每个缺少的日期添加值为0的ChartDataEntry和相应的标签。

回答这里的评论中的问题是我的一个应用程序的屏幕截图,其中我填写0值的日期空白:

Chart Gaps

在我的情况下,我想要0值而不是从数据点到数据点的平均线,因为它清楚地表明在跳过的日期没有数据(例如8/11)。

来自@Philipp Jahoda的评论听起来你可以跳过0值条目,只需将你拥有的数据索引到正确的标签。

我修改了MPAndroidChart示例程序以跳过一些数据点,这就是结果:

Chart Gaps Non Zero

正如@Philipp Jahoda在评论中提到的,图表只需连接到下一个数据点即可处理缺失的Entry。从下面的代码中你可以看到我正在为整个数据集生成x值(标签),但是跳过索引11 - 29的y值(数据点),这就是你想要的。唯一剩下的就是处理x标签,因为听起来你不想让我的例子中的15,20和25出现。

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));
}

答案 1 :(得分:2)

我所做的是完全提供x数据的日期,甚至没有y数据,只是不添加特定xIndex的数据条目,然后它不会为xIndex绘制y值来实现你想要的,这是最简单的方法,因为你只需编写for循环并继续,如果你没有检测到y值。

我不建议使用0或者nan,因为如果它是折线图,它将连接0数据或者将会发生不良事情。你可能想要打破这些界限,但是ios-charts还不支持它(我还要求一个功能),你需要编写自己的代码来打破这一行,或者你可以接受连接0数据或只需连接到下一个有效数据。

不利的一面是,由于许多xIndex存在性能下降,但我尝试了~1000,这是可以接受的。我很久以前就已经问过这个功能,但是花了很多时间来思考它。

答案 2 :(得分:1)

这是我根据Wingzero的回答编写的函数(我为值数组中的条目传递NaNs为空):

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
}

答案 3 :(得分:0)

对我有用的解决方案是将Linedataset分成2个Linedatasets。首先是将yvals保持到空白区域,然后是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);