在AChartEngine图表中添加新值

时间:2013-07-04 09:19:10

标签: android achartengine

有没有办法动态地将数据添加到图表中的原始系列中(现在,我正在尝试在平移时将新数据添加到折线图但问题更广泛)?添加系列可以正常工作,我可以创建新的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);

2 个答案:

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

这个解决方法似乎现在解决了我的问题,但是如果我以后发现任何问题,我会报告回来。