简体   繁体   English

jfreechart xylinechart排序时间未更新

[英]jfreechart xylinechart sorting times isn't updated

I'm making a simple sorting benchmark in Java Swing and I want it to display a graph that changes with time. 我正在Java Swing中建立一个简单的排序基准,希望它显示随时间变化的图形。 But the graph is not updating when the algorithm runs. 但是当算法运行时图形不会更新。 I'm really confused. 我真的很困惑 Can someone please explain what I'm doing wrong? 有人可以解释我在做什么错吗?

The array is filled with random data when the GUI is running 当GUI运行时,数组中填充了随机数据

int A[]=null;int [] copyOfA=null; 

chart 图表

   final XYSeriesCollection dataset = new XYSeriesCollection();
   private ChartPanel createDemoPanel() {  
       JFreeChart jfreechart = ChartFactory.createXYLineChart(title, "array", "time",dataset ,
            PlotOrientation.VERTICAL, true, true, false);
    jfreechart.setBackgroundPaint(Color.white);
    XYPlot plot = (XYPlot) jfreechart.getPlot();
    plot.getDomainAxis().setRange(0, 1000); //array
    plot.getRangeAxis().setRange(-1,1);//time

    //plot.getDomainAxis().setFixedAutoRange(20);
    //plot.getRangeAxis().setFixedAutoRange(100);
    // render shapes and lines
    XYLineAndShapeRenderer renderer =
        new XYLineAndShapeRenderer(true, true);
    plot.setRenderer(renderer);
    renderer.setBaseShapesVisible(true);
    renderer.setBaseShapesFilled(true);

    return new ChartPanel(jfreechart);
}

inside ActionPerformed 内部动作执行

   private void insSortActionPerformed(java.awt.event.ActionEvent evt) {       
   XYSeries series = new XYSeries("ins sort");

    if( insSort.isEnabled()) {

   long startTime = System.currentTimeMillis();
   insSort(A);
   long endTime = System.currentTimeMillis();
   totalRuntime += (endTime - startTime);
                             }

    series.add(totalRuntime,A.length);
    dataset.addSeries(series);                                         
     }

At this line the Y axis range is set to (-1,1) interval: 在此行, Y轴范围设置为(-1,1)间隔:

plot.getDomainAxis().setRange(0, 1000); //array
plot.getRangeAxis().setRange(-1,1);//time

But Y axis is intended to take the value from totalRuntime which is a time difference given in millis: 但是Y轴旨在从totalRuntime获取值,这是以totalRuntime为单位的时间差:

if( insSort.isEnabled()) {
   long startTime = System.currentTimeMillis();
   insSort(A);
   long endTime = System.currentTimeMillis();
   totalRuntime += (endTime - startTime); // this is certainly > 1
}
series.add(totalRuntime,A.length);
dataset.addSeries(series); 

This value will be certainly > 1 (unless you have the most powerful computer ever :). 该值肯定大于1(除非您拥有有史以来功能最强大的计算机:)。 So you can see which value is getting totalRuntime and adjust the Y axis range accordingly. 因此,您可以查看哪个值正在获取totalRuntime并相应地调整Y轴范围。

You might also check: 您可能还会检查:

  • Domain axis range: if the array has more than 1000 elements then you won't see the graphic either. 域轴范围:如果数组包含1000个以上的元素,那么您也将看不到图形。
  • Is insSort.isEnabled() actually true ? insSort.isEnabled()实际上是true吗? If not so then you'll be adding garbage to dataset . 如果不是这样,那么您将向dataset添加垃圾。

Addendum 附录

I want to graph sorting time versus the number of elements 我想用图表显示排序时间与元素数量

Well you can take a look to the example below. 好吧,您可以看一下下面的示例。 As I haven't the sort methods implementation the example emulates the times using Swing timer . 由于我还没有实现sort方法,因此该示例使用Swing timer模拟时间。 The key is adding the values to the series properly and having the right ranges set. 关键是将值正确添加到系列中并设置正确的范围。

Note: as times are random generated then the shown info is garbage. 注意:由于时间是随机生成的,因此显示的信息是垃圾。 The example tries to illustrate the process you should follow to make the graphic work. 该示例试图说明使图形工作应遵循的过程。 Pay special attention to fillChart() method: it makes the trick. 要特别注意fillChart()方法:它可以解决问题。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class Demo {

    private final XYSeries _timeSeries = new XYSeries("Time Series");
    boolean _shouldPaint;

    private void createAndShowGUI() {

        JToggleButton fillChart = new JToggleButton("Fill chart") ;
        fillChart.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JToggleButton toggleButton = (JToggleButton)e.getSource();
                if(toggleButton.isSelected()) {
                    _timeSeries.clear();
                    _shouldPaint = true;
                    fillChart();
                } else {
                    _shouldPaint = false;
                }
            }
        });

        JPanel content = new JPanel(new BorderLayout());
        content.add(getFreeChartPanel(), BorderLayout.CENTER);
        content.add(fillChart, BorderLayout.SOUTH);

        JFrame frame = new JFrame("Demo");      
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JPanel getFreeChartPanel() {
        String title = "Time series example";

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(_timeSeries); // series is added only once!

        JFreeChart chart = ChartFactory.createXYLineChart(title, "Array elements", "Time (in millis)", dataset, 
                                                         PlotOrientation.VERTICAL, true, true, false);       
        XYPlot plot = chart.getXYPlot();
        plot.setRenderer(new XYLineAndShapeRenderer(true, true));
        plot.setDomainCrosshairVisible(true);
        plot.setRangeCrosshairVisible(true);
        plot.getDomainAxis().setRange(0, 1000); // Number of elements - top visible: 1000
        plot.getRangeAxis().setRange(0, 4000); // Time employed to do the sort - top visible: 4 seconds (4k millis)        

        return new ChartPanel(chart);
    }

    /**
     * You should do your own implementation of this method.
     */
    private void fillChart() {
        Timer timer = new Timer(500, new ActionListener() {

            long lastTimeMillis = System.currentTimeMillis();
            int domainAxis = 0;

            @Override
            public void actionPerformed(ActionEvent e) {
                if(_shouldPaint) {
                    long currentTimeMillis = System.currentTimeMillis();
                    long rangeAxisValue = (long)((currentTimeMillis - lastTimeMillis) * Math.random());
                    int domainAxisValue = domainAxis + 100;

                    _timeSeries.add(domainAxisValue, rangeAxisValue);
                    // Note this is the unique line that has an effect on the graphic

                    lastTimeMillis = currentTimeMillis;
                    domainAxis = domainAxisValue;

                } else {
                    Timer timer = (Timer)e.getSource();
                    timer.stop();
                }
            }
        });

        timer.setDelay(1500);
        timer.start();
    }

    public static void main(String[] args) {   
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().createAndShowGUI();
            }
        });
    }    
}

Picture 图片

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM