使用JFreeChart的动态图表

我有一个100,000个样本的数组,都是双重类型。 我想显示或绘制这个数组,以便我得到一个移动的图表/图表(动态)而不是一次显示它。 谁能帮我吗。 在图ee []和y []是在一些处理之后获得的。

private byte[] FileR(String filename) { byte[] data = null; AudioInputStream ais; try { File fileIn = new File(filename); if (fileIn.exists()) { ais = AudioSystem.getAudioInputStream(fileIn); data = new byte[ais.available()]; ais.read(data); } } catch (UnsupportedAudioFileException | IOException e) { System.out.println(e.getMessage()); throw new RuntimeException("Could not read " + filename); } return data; } private byte[] Capture(double t) throws LineUnavailableException { AudioFormat format = new AudioFormat(48000, 16, 2, true, false); DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); line = (TargetDataLine) AudioSystem.getLine(info); line.open(format); line.open(); int size = (int) (line.getBufferSize() * t); byte[] b = new byte[size]; line.start(); line.read(b, 0, size); return b; } private void plot(double[] ee, double[] y) { XYSeries see = new XYSeries("Filtered"); for (int i = 0; i < ee.length; i++) { see.add(i, ee[i]); } XYSeriesCollection cee = new XYSeriesCollection(); cee.addSeries(see); XYItemRenderer ree = new StandardXYItemRenderer(); NumberAxis rangeAxisee = new NumberAxis("Filtered"); XYPlot subplot1 = new XYPlot(cee, null, rangeAxisee, ree); subplot1.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT); XYSeries sy = new XYSeries("Noisy"); for (int i = 0; i < y.length; i++) { sy.add(i, y[i]); } XYSeriesCollection cy = new XYSeriesCollection(); cy.addSeries(sy); XYItemRenderer ry = new StandardXYItemRenderer(); NumberAxis rangeAxisy = new NumberAxis("Noisy"); XYPlot subplot2 = new XYPlot(cy, null, rangeAxisy, ry); subplot2.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT); CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Domain")); plot.setGap(10.0); plot.add(subplot1); plot.add(subplot2); plot.setOrientation(PlotOrientation.VERTICAL); JFreeChart chart = new JFreeChart("Adaptive Filter", JFreeChart.DEFAULT_TITLE_FONT, plot, true); panel = new ChartPanel(chart, true, true, true, false, true); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(750, 500); frame.add(panel, BorderLayout.CENTER); frame.setVisible(true); } 

您需要有一个所有这些数据来自的线程 。 例如从你的后端。 然后,每当图表有一组新数据时,您需要通过事件调度线程更新图表。 如果您的图表数据是定期进行的,那么相当容易(即拉动),但如果它是推送(即数据更随机),并且可能会变得更加棘手。

从绘图方法中删除所有GUI创建:

 JFreeChart chart = new JFreeChart("Adaptive Filter", JFreeChart.DEFAULT_TITLE_FONT, plot, true); panel = new ChartPanel(chart, true, true, true, false, true); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(750, 500); frame.add(panel, BorderLayout.CENTER); frame.setVisible(true); 

这只需要调用一次。 每次有新数据时都会调用绘图方法。

这是一个简单的方法:

 public void startCharting() { final MySoundCard card = new MySoundCard(); final MyJFreeChart chart = new MyJFreeChart(); Runnable r = new Runnable() { @Override public void run() { while(true) { int[] i = card.FileR(); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { chart.plot(); } }); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread t = new Thread(r); t.start(); } 

线程每秒调用一次数据源,然后更新图表。 在事件调度线程中调用更新。