0

グラフの元のシリーズにデータを動的に追加する方法はありますか(現在、パンしたときに折れ線グラフに新しいデータを追加しようとしていますが、問題はより広範です)。新しいシリーズを追加しても問題ありません。新しいシリーズを作成して、同じ表示にするために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);
4

2 に答える 2

0

新しいシリーズの開始点が古いシリーズの終了点である場合、おそらく私と同じ問題に遭遇しました。

また、前のペアと同じ x 値を持つ 2 番目の x/y ペアを追加するときに、XYSeries.add(x,y) で無限ループに遭遇しました。私の場合、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 ループの条件は変わりません。(増分が小さすぎる場合、double は実際には変化しません。)

同じ x 値を 2 回追加しないようにすることで、問題を回避しました。

于 2013-09-23T19:58:32.077 に答える
0

問題を取り戻すには: 問題のチャートは ですXYChart。右にパンし、既存の値の前にXYSeries.add()その位置を使用して新しい項目をシリーズに追加すると、更新中のチャート ライン自体は [OK] と表示されますが、個々のチャート ポイントの上に表示されるチャート値は、新しい値と同期しなくなります。これは、ソースを変更して解決した方法です。

ソースの問題は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);

次の関数を呼び出すときにそれを渡します(これはソースで2回発生します):

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

この回避策は今のところ問題を解決しているようですが、後で問題が見つかった場合は報告します。

于 2014-10-12T18:53:43.133 に答える