よくわからないので、データを間引きしたい場合の話をします。
最善の解決策は、入力データと時間ベクトルを再サンプリングすることです。
しかし、シンプルにしたい場合は、次のようなことを試すことができます。
- 常に始点終点のデータポイントを追加
- 内部データ ポイントについては、デシメーションを計算します
例
この例では、入力配列に含まれるデータ ポイントの数に関係なく、常にLineChart
20 ノードの が生成されます。
注:このソリューションは、可能な限り最善の方法ではなく、入力データ ベクトルが同じ時間ベクトルを持つことに大きく依存しています。時間ベクトルのステップ サイズが固定されていることも結果に影響します。
public class ChartingApp extends Application {
@Override
public void start(Stage stage) throws Exception {
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
final LineChart<Number, Number> lineChart = new LineChart<Number, Number>(xAxis, yAxis);
// Size of the input data
int dataCount = 777;
// One X axis two Y axis
double[] xValues = new double[dataCount];
double[] y1Values = new double[dataCount];
double[] y2Values = new double[dataCount];
// Generate some initial data
Random randomGenerator = new Random();
for (int i = 0; i < dataCount; i++) {
xValues[i] = i;
y1Values[i] = randomGenerator.nextInt(200);
y2Values[i] = randomGenerator.nextInt(200);
}
// Amount of nodes to display
int valueCountToDisplay = 20;
Series<Number, Number> series1 = new Series<Number, Number>();
Series<Number, Number> series2 = new Series<Number, Number>();
// The first element is always added
series1.getData().add(new Data<Number, Number>(xValues[0], y1Values[0]));
series2.getData().add(new Data<Number, Number>(xValues[0], y2Values[0]));
// Generate the inner nodes
double elementToPick = Math.floor((dataCount - 2) / (valueCountToDisplay - 2));
for (int i = 1; i < dataCount - 1; i++) {
if (i % elementToPick == 0) {
series1.getData().add(new Data<Number, Number>(xValues[i], y1Values[i]));
series2.getData().add(new Data<Number, Number>(xValues[i], y2Values[i]));
}
}
// The last element is always added
series1.getData().add(new Data<Number, Number>(xValues[dataCount - 1], y1Values[dataCount - 1]));
series2.getData().add(new Data<Number, Number>(xValues[dataCount - 1], y2Values[dataCount - 1]));
Scene scene = new Scene(lineChart, 800, 600);
lineChart.getData().addAll(series1, series2);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
結果は次のとおりです。

背後にあるロジックは、次のように要約できます。
double[] createSparseArray(double[] inputData, int arraySize) {
List<Double> sparseList = new ArrayList<Double>();
sparseList.add(inputData[0]);
double elementToPick = Math.floor((inputData.length - 2) / (arraySize - 2));
for (int i = 1; i < inputData.length - 1; i++) {
if (i % elementToPick == 0)
sparseList.add(inputData[i]);
}
sparseList.add(inputData[arraySize - 1]);
return sparseList.stream().mapToDouble(d -> d).toArray();
}
この例では配列を使用してデータを格納していますが、実際のデータ構造と似ています ( size ofSet
を使用し、古き良き for ループでループします)。