2

在我的应用程序中,我使用 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

4 回答 4

2

最简单的解决方案是遍历您的数据并ChartDataEntry为每个缺失的日期添加一个值为 0 和一个相应的标签。

为了回答评论中的问题,这里是我的一个应用程序的屏幕截图,我用 0 值填充日期间隙:

图表差距

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

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

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

图表间隙非零

正如@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));
}
于 2015-11-09T22:58:46.247 回答
2

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

我不建议使用 0 或 nan,因为如果是折线图,它将连接 0 数据,否则会对 nan 造成不好的事情。您可能想换行,但 ios-charts 还不支持它(我还为此请求了一个功能),您需要编写自己的代码来换行,或者您可以忍受连接 0 数据或只需连接到下一个有效数据。

不利的一面是,由于那里有许多 xIndex,它可能会出现性能下降,但我尝试了 ~1000,这是可以接受的。我很久以前就已经要求过这样的功能了,但是花了很多时间来考虑它。

于 2015-11-11T01:33:06.477 回答
1

这是我根据 Wingzero 的回答编写的一个函数(我为 values 数组中为空的条目传递了 NaN):

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
}
于 2016-05-16T09:10:03.920 回答
0

对我有用的解决方案是将 Linedataset 拆分为 2 Linedataset。首先将保留 yvals 直到空白空间,然后在空白空间之后。

//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);
于 2016-04-20T13:50:24.720 回答