Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you can use Java 7, then check out the JavaFX APIs. There is a stock ticker that comes with Oracle's Ensemble samples (chart -> lines -> advanced stock). It is a good start for what you are trying to achieve. Here is the code provided by Oracle:</p> <pre><code>import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.stage.Stage; import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.chart.LineChart; import javafx.scene.chart.NumberAxis; import javafx.scene.chart.XYChart; import javafx.util.Duration; /** * A simulated stock line chart. * * @see javafx.scene.chart.Chart * @see javafx.scene.chart.LineChart * @see javafx.scene.chart.NumberAxis * @see javafx.scene.chart.XYChart */ public class AdvancedStockLineChartSample extends Application { private XYChart.Series&lt;Number,Number&gt; hourDataSeries; private XYChart.Series&lt;Number,Number&gt; minuteDataSeries; 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; private void init(Stage primaryStage) { Group root = new Group(); primaryStage.setScene(new Scene(root)); root.getChildren().add(createChart()); // create timeline to add new data every 60th of second animation = new Timeline(); animation.getKeyFrames().add(new KeyFrame(Duration.millis(1000/60), new EventHandler&lt;ActionEvent&gt;() { @Override public void handle(ActionEvent actionEvent) { // 6 minutes data per frame for(int count=0; count &lt; 6; count++) { nextTime(); plotTime(); } } })); animation.setCycleCount(Animation.INDEFINITE); } protected LineChart&lt;Number, Number&gt; createChart() { xAxis = new NumberAxis(0,24,3); final NumberAxis yAxis = new NumberAxis(0,100,10); final LineChart&lt;Number,Number&gt; lc = new LineChart&lt;Number,Number&gt;(xAxis,yAxis); // setup chart lc.setId("lineStockDemo"); lc.setCreateSymbols(false); lc.setAnimated(false); lc.setLegendVisible(false); lc.setTitle("ACME Company Stock"); xAxis.setLabel("Time"); xAxis.setForceZeroInRange(false); yAxis.setLabel("Share Price"); yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis,"$",null)); // add starting data hourDataSeries = new XYChart.Series&lt;Number,Number&gt;(); hourDataSeries.setName("Hourly Data"); minuteDataSeries = new XYChart.Series&lt;Number,Number&gt;(); minuteDataSeries.setName("Minute Data"); // create some starting data hourDataSeries.getData().add(new XYChart.Data&lt;Number,Number&gt;(timeInHours,prevY)); minuteDataSeries.getData().add(new XYChart.Data&lt;Number,Number&gt;(timeInHours,prevY)); for (double m=0; m&lt;(60); m++) { nextTime(); plotTime(); } lc.getData().add(minuteDataSeries); lc.getData().add(hourDataSeries); return lc; } private void nextTime() { if (minutes == 59) { hours ++; minutes = 0; } else { minutes ++; } timeInHours = hours + ((1d/60d)*minutes); } private void plotTime() { if ((timeInHours % 1) == 0) { // change of hour double oldY = y; y = prevY - 10 + (Math.random()*20); prevY = oldY; while (y &lt; 10 || y &gt; 90) y = y - 10 + (Math.random()*20); hourDataSeries.getData().add(new XYChart.Data&lt;Number, Number&gt;(timeInHours, prevY)); // after 25hours delete old data if (timeInHours &gt; 25) hourDataSeries.getData().remove(0); // every hour after 24 move range 1 hour if (timeInHours &gt; 24) { xAxis.setLowerBound(xAxis.getLowerBound()+1); xAxis.setUpperBound(xAxis.getUpperBound()+1); } } double min = (timeInHours % 1); double randomPickVariance = Math.random(); if (randomPickVariance &lt; 0.3) { double minY = prevY + ((y-prevY) * min) - 4 + (Math.random()*8); minuteDataSeries.getData().add(new XYChart.Data&lt;Number,Number&gt;(timeInHours,minY)); } else if (randomPickVariance &lt; 0.7) { double minY = prevY + ((y-prevY) * min) - 6 + (Math.random()*12); minuteDataSeries.getData().add(new XYChart.Data&lt;Number,Number&gt;(timeInHours,minY)); } else if (randomPickVariance &lt; 0.95) { double minY = prevY + ((y-prevY) * min) - 10 + (Math.random()*20); minuteDataSeries.getData().add(new XYChart.Data&lt;Number,Number&gt;(timeInHours,minY)); } else { double minY = prevY + ((y-prevY) * min) - 15 + (Math.random()*30); minuteDataSeries.getData().add(new XYChart.Data&lt;Number,Number&gt;(timeInHours,minY)); } // after 25hours delete old data if (timeInHours &gt; 25) minuteDataSeries.getData().remove(0); } public void play() { animation.play(); } @Override public void stop() { animation.pause(); } @Override public void start(Stage primaryStage) throws Exception { init(primaryStage); primaryStage.show(); play(); } public static void main(String[] args) { launch(args); } } </code></pre> <p>Screen shot: <img src="https://i.stack.imgur.com/wvR1Z.png" alt="enter image description here"></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload