【问题标题】:jfreechart xylinechart sorting times isn't updatedjfreechart xylinechart 排序时间未更新
【发布时间】:2014-01-14 00:23:05
【问题描述】:

我正在 Java Swing 中制作一个简单的排序基准,我希望它显示一个随时间变化的图表。但是当算法运行时,图表并没有更新。我真的很困惑。有人可以解释一下我做错了什么吗?

当 GUI 运行时,数组填充随机数据

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

图表

   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);
}

在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);                                         
     }

【问题讨论】:

  • insortA(A) 是负责排序的方法吗?如果是这样,那么当此方法完成时,您的图形将只更新一次。如果此方法花费的时间太长,那么您的 GUI 将冻结,因为它会阻止 Event Dispatch Thread 直到完成其执行。
  • 不幸的是,屏幕上什么也没有出现..
  • 我找不到解决方法,有什么建议吗?
  • 尝试设置渲染器的系列绘制:renderer.setSeriesPaint(0, Color.BLACK);。不确定哪个是默认绘制,可能是nullColor.WHITE
  • 这就是我得到的。IMG]i44.tinypic.com/2ry0axv.jpg[/IMG]

标签: java swing plot jfreechart


【解决方案1】:

在这一行,Y 轴范围设置为 (-1,1) 区间:

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

Y 轴旨在从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); 

这个值肯定会 > 1(除非您拥有有史以来最强大的计算机 :)。所以你可以看到哪个值得到totalRuntime 并相应地调整Y 轴范围。

您也可以检查:

  • 域轴范围:如果数组有超过 1000 个元素,那么您也不会看到图形。
  • insSort.isEnabled() 真的是true 吗?如果不是这样,那么您将向dataset 添加垃圾。

附录

我想绘制排序时间与元素数量的关系

你可以看看下面的例子。由于我没有实现排序方法,因此示例使用Swing timer 模拟时间。关键是将值正确添加到系列中并设置正确的范围。

注意:因为时间是随机生成的,所以显示的信息是垃圾。该示例试图说明您应该遵循以使图形工作的过程。特别注意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();
            }
        });
    }    
}

图片

【讨论】:

  • 感谢您的帮助,但问题是窗口中没有出现“系列”行。应该是这样的[IMG]i44.tinypic.com/29o3mur.png[/IMG]
  • @user3136729 该图显示了一个进度图,其中范围轴显示了给定时间段内同一现象的给定值。那你想做什么? 1)您是否想要图形化数组(范围)排序所用时间与元素数量(域)的关系? 2)相反:元素数量(范围)与时间(域)?
  • 是的,我想绘制排序时间与元素数量的关系。
  • 你能给我一个例子如何用插入排序做到这一点吗? public void insSort(int[] a) { for (int j = 1; j = 0 && a[i]
  • 不,如果你愿意,我可以给你一个关于制作图形的例子。排序方法的实现在数百个站点上在线,只需选择一个。 @user3136729
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多