有没有办法动态地将数据添加到图表中的原始系列中(现在,我正在尝试在平移时将新数据添加到折线图但问题更广泛)?添加新系列可以正常工作,我可以创建新的XYSeries
,甚至可以重复使用XYSeriesRenderer
来显示相同的内容。当添加到图表时,它将显示,但显然是一个新系列,这意味着它不会与之前的数据无缝连接,并且该行上方的显示值将被复制。
如果我保留数据集,系列渲染器和系列本身并稍后尝试重新使用它们,当我尝试series.add(x, y)
我的新值时,我得到一个看似无穷无尽的循环,程序永远不会返回。在再次添加新值和dataset.removeSeries(series)
之前,我还尝试dataset.addSeries(series)
但是徒劳无功。
使用代码进行更新:
图表设置如下:
renderer = new XYMultipleSeriesRenderer();
renderer.setAntialiasing(true);
...
renderer.setZoomEnabled(false, false);
dataset = new XYMultipleSeriesDataset();
seriesRenderer = new XYSeriesRenderer();
seriesRenderer.setColor(chartColor);
...
seriesRenderer.setChartValuesTextSize(...);
renderer.addSeriesRenderer(seriesRenderer);
series = new XYSeries("");
...
series.add(x, y);
...
dataset.addSeries(series);
在PanListener.panApplied:
中调用dataset.removeSeries(series);
...
series.add(x, y);
...
dataset.addSeries(series);
答案 0 :(得分:0)
如果新系列的起点是旧系列的终点,你可能遇到了和我一样的问题:
我还在XYSeries.add(x,y)中遇到无限循环,当添加第二个x / y对时,它具有与前一对相同的x值。在我的情况下,x的类型为long,表示时间戳。 无限循环的原因可以在方法的源代码中找到:
public synchronized void add(double x, double y) {
while (mXY.get(x) != null) {
// add a very small value to x such as data points sharing the same x will
// still be added
x += getPadding(); // Defined as constant: PADDING = 0.000000000001
}
mXY.put(x, y);
updateRange(x, y);
}
如果x太大,添加非常小的“填充”不会改变x的值,while循环中的条件永远不会改变。 (如果增量太小,则双精度不会真正改变。)
我通过确保两次不添加相同的x值来避免这个问题。
答案 1 :(得分:0)
要解决问题:相关图表为XYChart
。当我向右平移并使用位于之前>>现有值的XYSeries.add()
向系列中添加新项目时,尽管更新图表行本身显示正常,但图表值显示在个人上方图表点不再与新值保持同步。这就是我通过修改源来解决它的方法。
源代码中的问题是XYChart.drawChartValuesText()
收到startIndex
参数并使用它来查找要使用XYSeries.getY()
显示的标签的值,这就是出错的地方。所以,在大型XYChart.draw()
函数中,在我们实际调用drawSeries()
之前,我设置了一个新变量:
final List<Double> chartValues = new ArrayList<Double>();
除了values
列表之后,我还将实际值添加到此列表中:
values.add(xValue);
values.add(yValue);
chartValues.add(yValue);
并在调用下一个函数时传递它(这在源中发生两次):
drawSeries(series, canvas, paint, points, seriesRenderer, yAxisValue, i, or, startIndex, chartValues);
反过来, XYChart.drawSeries()
将其传递给:
drawChartValuesText(canvas, series, seriesRenderer, paint, pointsList, seriesIndex, startIndex, values);
最后,XYChart.drawChartValuesText()
使用这些新值而不是基于startIndex
的查找:
protected void drawChartValuesText(Canvas canvas, XYSeries series, XYSeriesRenderer renderer, Paint paint, List<Float> points, int seriesIndex, int startIndex, List<Double> values) {
if (points.size() > 2) { // there are more than one point
// record the first point's position
float previousPointX = points.get(0);
float previousPointY = points.get(1);
for (int k = 0; k < points.size(); k += 2)
if (k == 2) { // decide whether to display first two points' values or not
if (Math.abs(points.get(2) - points.get(0)) > renderer.getDisplayChartValuesDistance() || Math.abs(points.get(3) - points.get(1)) > renderer.getDisplayChartValuesDistance()) {
// first point
drawText(canvas, getLabel(renderer.getChartValuesFormat(), values.get(k)), points.get(0), points.get(1) - renderer.getChartValuesSpacing(), paint, 0);
// second point
drawText(canvas, getLabel(renderer.getChartValuesFormat(), values.get(k + 1)), points.get(2), points.get(3) - renderer.getChartValuesSpacing(), paint, 0);
previousPointX = points.get(2);
previousPointY = points.get(3);
}
}
else if (k > 2)
// compare current point's position with the previous point's, if they are not too close, display
if (Math.abs(points.get(k) - previousPointX) > renderer.getDisplayChartValuesDistance() || Math.abs(points.get(k + 1) - previousPointY) > renderer.getDisplayChartValuesDistance()) {
drawText(canvas, getLabel(renderer.getChartValuesFormat(), values.get(k / 2)), points.get(k), points.get(k + 1) - renderer.getChartValuesSpacing(), paint, 0);
previousPointX = points.get(k);
previousPointY = points.get(k + 1);
}
}
else
for (int k = 0; k < points.size(); k += 2)
drawText(canvas, getLabel(renderer.getChartValuesFormat(), values.get(k / 2)), points.get(k), points.get(k + 1) - renderer.getChartValuesSpacing(), paint, 0);
}
这个解决方法似乎现在解决了我的问题,但是如果我以后发现任何问题,我会报告回来。