5

我有一个描述管道压力的数组的时间历史。因此,对于每个增量 t,我沿管道长度都有一组压力值。我想用 JFreeChart 绘制沿管道长度的压力,并选择使用滑块绘制哪个 delta t,以便每当用户移动滑块时,图形都会使用来自不同 delta t 的值进行更新。我还将瓷砖重置为管道最后部分的压力。发生的情况是标题是更新,这意味着数据正在正确更新,但曲线保持不变。我已经阅读了论坛上所有可能的主题,并尝试了我能想到的一切,但它不起作用!这是我的扩展 JPanel 的类的代码,其中方法 jSlider1StateChanged 听到滑块位置的变化,

public class MyMainPanel extends JPanel {

  private JFreeChart jc;
  private OutputPipe op;
  private DefaultXYDataset ds; 
  private javax.swing.JFrame jFrame1;
  private javax.swing.JSlider jSlider1;
  private pipevisualizer.MyChartPanel pnlChartPanel;                       

  private void jSlider1StateChanged(javax.swing.event.ChangeEvent evt) {                                      
        int ndt = ((JSlider) evt.
                getSource()).
                getValue();
        System.out.println("Slider1: " + ((JSlider) evt.
                getSource()).
                getValue());

        dataSetGen(ndt);
        int a = 0;
        jc.fireChartChanged();
  }                

  private void dataSetGen(int ndt) {
        ArrayList<OutputPipeDt> opDtArray = op.getOpLit();
        OutputPipeDt opDt = opDtArray.get(ndt);

        double[] H = opDt.getH();
        double[] l = new double[H.length];
        double[] p = new double[H.length];
        double dX = op.getPipeLength() / H.length;
        double slope = op.getPipeSlope();
        double el = op.getPipeUSElev();

        for (int i = 0; i < H.length; i++) {
              l[i] = dX * i;
              p[i] = el - dX * slope * i;
        }

        double[][] dataH = new double[2][H.length];
        dataH[0] = l;
        dataH[1] = H;

        double[][] dataP = new double[2][H.length];
        dataP[0] = l;
        dataP[1] = p;

        ds = new DefaultXYDataset();
        ds.addSeries("pipe head", dataH);
        ds.addSeries("pipe profile", dataP);

        jc.setTitle("H[end] = " + Double.toString(dataH[1][l.length - 1]));
        jc.fireChartChanged();
  }

  private JFreeChart createChart(OutputPipe op, int ndt) {

        ArrayList<OutputPipeDt> opDtArray = op.getOpLit();
        OutputPipeDt opDt = opDtArray.get(ndt);

        double[] H = opDt.getH();
        double[] l = new double[H.length];
        double[] p = new double[H.length];
        double dX = op.getPipeLength() / H.length;
        double slope = op.getPipeSlope();
        double el = op.getPipeUSElev();

        for (int i = 0; i < H.length; i++) {
              l[i] = dX * i;
              p[i] = el - dX * slope * i;
        }

        double[][] dataH = new double[2][H.length];
        dataH[0] = l;
        dataH[1] = H;

        double[][] dataP = new double[2][H.length];
        dataP[0] = l;
        dataP[1] = p;

        DefaultXYDataset ds = new DefaultXYDataset();
        ds.addSeries("pipe head", dataH);
        ds.addSeries("pipe profile", dataP);


        JFreeChart chart = ChartFactory.createXYLineChart(
                "t = " + Double.toString(op.getOpLit().get(ndt).getT()),
                // chart title
                "X",
                // x axis label
                "Y",
                // y axis label
                ds,
                // data
                PlotOrientation.VERTICAL,
                true,
                // include legend
                true,
                // tooltips
                false // urls
                );

        return chart;
  }
}

我认为对数据集的任何更改都会使图形重绘本身。抱歉,如果代码可能太大而无法发布,但我不确切知道应该粘贴哪些部分以或多或少地清晰。

4

1 回答 1

6

如果没有完整的示例,您可以使用此处显示的方法;它用于plot.setDataset()在接收每个事件时替换数据集。

附录:这个显示温度随时间变化的示例可能会让您入门。

ChartSliderTest

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
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.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 * @see https://stackoverflow.com/a/15207445/230513
 */
public class ChartSliderTest {

    private static final int N = 25;
    private static final double K = 273.15;
    private static final Random random = new Random();

    private static XYDataset getDataset(int n) {

        final XYSeries series = new XYSeries("Temp (K°)");
        double temperature;
        for (int length = 0; length < N; length++) {
            temperature = K + n * random.nextGaussian();
            series.add(length + 1, temperature);
        }
        return new XYSeriesCollection(series);
    }

    private static JFreeChart createChart(final XYDataset dataset) {
        JFreeChart chart = ChartFactory.createXYLineChart(
            "ChartSliderTest", "Length (m)", "Temp (K°)", dataset,
            PlotOrientation.VERTICAL, false, false, false);
        return chart;
    }

    private static void display() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final List<XYDataset> list = new ArrayList<XYDataset>();
        for (int i = 0; i <= 10; i++) {
            list.add(getDataset(i));
        }
        JFreeChart chart = createChart(list.get(5));
        final XYPlot plot = (XYPlot) chart.getPlot();
        plot.getRangeAxis().setRangeAboutValue(K, K / 5);
        ChartPanel chartPanel = new ChartPanel(chart) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(800, 400);
            }
        };
        f.add(chartPanel);
        final JSlider slider = new JSlider(0, 10);
        slider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                plot.setDataset(list.get(slider.getValue()));
            }
        });
        Box p = new Box(BoxLayout.X_AXIS);
        p.add(new JLabel("Time:"));
        p.add(slider);
        f.add(p, BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                display();
            }
        });
    }
}
于 2013-03-04T17:31:54.507 回答