我的任务是构建实时图表,用户可以在该图表上停止绘制(动画)并借助鼠标下注(左侧)返回到旧数据。我尝试从Ensemle Oracle示例中开发股票折线图示例。
我编写了两个方法:updateXAxisBounds和addScrollAndMouseDragListeners,拖动效果很好,但是旧数据不在图表中(只有新数据已更新,而旧数据却消失了,您可以在图片中看到-底部的链接,新值之前的图表为空图表广场)。帮助,请在用户拖动到左侧时显示可见的旧数据。可能需要添加更多动画吗?
public class StockLineChartApp extends Application {
private LineChart<Number, Number> chart;
private Series<Number, Number> hourDataSeries;
private NumberAxis xAxis;
private Timeline animation;
private double hours = 0;
private double minutes = 0;
private double timeInHours = 0;
private double prevY = 10;
private double y = 10;
public StockLineChartApp() {
// 6 minutes data per frame
final KeyFrame frame =
new KeyFrame(Duration.millis(1000 / 60),
(ActionEvent actionEvent) -> {
for (int count = 0; count < 6; count++) {
nextTime();
plotTime();
}
});
// create timeline to add new data every 60th of second
animation = new Timeline();
animation.getKeyFrames().add(frame);
animation.setCycleCount(Animation.INDEFINITE);
}
public Parent createContent() {
xAxis = new NumberAxis(0, 24, 3);
final NumberAxis yAxis = new NumberAxis(0, 100, 10);
chart = new LineChart<>(xAxis, yAxis);
// setup chart
// final String stockLineChartCss = getClass().getResource("StockLineChart.css").toExternalForm();
// chart.getStylesheets().add(stockLineChartCss);
chart.setCreateSymbols(false);
chart.setAnimated(false);
chart.setLegendVisible(false);
chart.setTitle("ACME Company Stock");
xAxis.setLabel("Time");
xAxis.setForceZeroInRange(false);
yAxis.setLabel("Share Price");
yAxis.setTickLabelFormatter(new DefaultFormatter(yAxis, "$", null));
// add starting data
hourDataSeries = new Series<>();
hourDataSeries.setName("Hourly Data");
// create some starting data
hourDataSeries.getData().add(new Data<Number, Number>(timeInHours,
prevY));
for (double m = 0; m < (60); m++) {
nextTime();
plotTime();
}
chart.getData().add(hourDataSeries);
return chart;
}
private void nextTime() {
if (minutes == 59) {
hours++;
minutes = 0;
} else {
minutes++;
}
timeInHours = hours + ((1d / 60d) * minutes);
}
private void plotTime() {
//HERE there is the random algorithm of y calculation
// every hour after 24 move range 1 hour
if (timeInHours > 24) {
xAxis.setLowerBound(xAxis.getLowerBound() + 1);
xAxis.setUpperBound(xAxis.getUpperBound() + 1);
}
}
}
public void play() {
animation.play();
}
@Override
public void stop() {
animation.pause();
}
@Override public void start(Stage primaryStage) throws Exception {
VBox vBox = new VBox();
vBox.getChildren().add(createContent());
addScrollAndMouseDragListeners(chart,xAxis,vBox);
primaryStage.setScene(new Scene(vBox));
primaryStage.show();
play();
}
private static void addScrollAndMouseDragListeners(final LineChart<Number, Number> chart, final NumberAxis xAxis, final Pane chartsPanel) {
chart.setOnScroll((ScrollEvent event) -> {
event.consume();
if (event.getDeltaY() == 0)
return;
final double SCALE_DELTA = 50;
double scaleFactor = (event.getDeltaY() > 0) ? SCALE_DELTA : -SCALE_DELTA;
double delta = (xAxis.getUpperBound() - xAxis.getLowerBound()) / scaleFactor;
updateXAxisBounds(xAxis.getLowerBound() + delta, xAxis.getUpperBound() - delta, chartsPanel);
});
final double[] startValues = new double[3];
chart.setOnMousePressed((MouseEvent event) -> {
event.consume();
startValues[0] = event.getX();
startValues[1] = xAxis.getLowerBound();
startValues[2] = xAxis.getUpperBound();
});
chart.setOnMouseDragged((MouseEvent event) -> {
event.consume();
final double unitPerPixel = (xAxis.getUpperBound() - xAxis.getLowerBound()) / xAxis.getWidth();
final double dx = (event.getX() - startValues[0]) * unitPerPixel;
updateXAxisBounds(startValues[1] - dx, startValues[2] - dx, chartsPanel);
});
}
private static void updateXAxisBounds(final double lowerBound, final double upperBound, final Pane chartsPanel) {
for (final Node child : chartsPanel.getChildren()) {
final NumberAxis axis = (NumberAxis) ((LineChart) child).getXAxis();
axis.setAutoRanging(false);
axis.setLowerBound(lowerBound);
axis.setUpperBound(upperBound);
}
}
/**
* Java main for when running without JavaFX launcher
* @param args command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
上药期间图表的屏幕截图如下:https://i.stack.imgur.com/Cdz8s.png