如何仅更改“移动平均线”曲线的颜色

时间:2015-07-30 14:57:58

标签: java jfreechart

我想只改变移动平均线的颜色,同时保持原始数据集的颜色相同。我该怎么做?

此外,是否可以在取消JCheckbox后将图例恢复为XYZ?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.*;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

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.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.data.time.MovingAverage;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

import com.opencsv.CSVReader;

public class Test2 extends ApplicationFrame 
{
XYSeriesCollection dataset;
JFreeChart chart;
final ChartPanel chartPanel;
final int CHART_WIDTH = 560;
final int CHART_HEIGHT = 367;
CSVReader reader;
String[] readNextLine;
XYSeries seriesX, seriesY, seriesZ;
double Time, X, Y, Z;
JPanel panel;


/**
 * 
 * @param applicationTitle
 * @throws IOException
 */
public Test2(String applicationTitle) throws IOException 
{
    super(applicationTitle); 
    chart = createChart(dataset);   
    chartPanel = new ChartPanel(chart);  

    panel = new JPanel();
    this.add(chartPanel, BorderLayout.CENTER);
    this.add(panel, BorderLayout.PAGE_START);

    createMenuBar();

    panel.add(createSmoothingPanel(), BorderLayout.PAGE_END);
    panel.add(Box.createHorizontalStrut(50));
    panel.add(Box.createHorizontalStrut(50));
    panel.add(createSaveLoadPanel(), BorderLayout.PAGE_END);
}


/**
 * @
 * @return
 * @throws NumberFormatException
 * @throws IOException
 */
public XYDataset createDataset() throws NumberFormatException, IOException
{
    dataset = new XYSeriesCollection();
    try
    {
        reader = new CSVReader(new FileReader("data.csv")); //change to load file

        //Before your while loop, set up the series you want to add to
        //add to them row by row.
        seriesX = new XYSeries("X");
        seriesY = new XYSeries("Y");
        seriesZ = new XYSeries("Z");

        //read the heading row and ignore.
        readNextLine = reader.readNext();

        //while the string array is not empty
        //go through the elements of the array where each element will contain the value 
        //from file for a given row.
        //Turn these values into variables.
        while((readNextLine = reader.readNext()) != null) 
        {
            Time = Double.valueOf(readNextLine[0]);
            X = Double.valueOf(readNextLine[1]);
            Y = Double.valueOf(readNextLine[2]);
            Z = Double.valueOf(readNextLine[3]);
            seriesX.add(Time, X);
            seriesY.add(Time, Y);
            seriesZ.add(Time, Z);
        }

        //add the 3 series to the collection
        dataset.addSeries(seriesX);
        dataset.addSeries(seriesY);
        dataset.addSeries(seriesZ);
    } 
    catch (FileNotFoundException e)
    {
        System.out.println("File not found!");
    }
    return dataset;
}


/**
 * 
 * @param dataset
 * @return
 * @throws NumberFormatException
 * @throws IOException
 */
public JFreeChart createChart(XYDataset dataset) throws NumberFormatException, IOException
{
    chart = ChartFactory.createXYLineChart(
            "Acceleration vs Time",     //chart title 
            "Time (secs)",              //domain axis label
            "Acceleration (g)",         //range axis label
            createDataset(),            //data
            PlotOrientation.VERTICAL,   //the plot orientation
            true,                       //legend
            true,                       //tooltips
            false);                     //urls

    XYPlot plot = (XYPlot) chart.getPlot();
    plot.getRenderer().setSeriesPaint(0, Color.RED);
    plot.getRenderer().setSeriesPaint(1, Color.BLUE);
    plot.getRenderer().setSeriesPaint(2, Color.GREEN);

    return chart;
}


/**
 * 
 * @return
 */
private JPanel createSmoothingPanel()
{
    JPanel smoothingPanel = new JPanel();

    final JCheckBox chkMovAve = new JCheckBox("Moving Average");

    panel.add(chkMovAve);

    chkMovAve.addItemListener(new ItemListener() 
    {
        @Override
        public void itemStateChanged(ItemEvent e) 
        {
            if(e.getStateChange() == ItemEvent.SELECTED) 
            {
                final XYDataset datasetMA = MovingAverage.createMovingAverage(
                        dataset, "-MAVG", 3 * 24 * 60 * 60 * 1000L, 0L
                    );
                final XYPlot movingAveragePlot = (XYPlot) chart.getPlot();
                movingAveragePlot.setDataset(1, datasetMA);
                final XYLineAndShapeRenderer movingAverageRenderer = new XYLineAndShapeRenderer(true,false);
                movingAverageRenderer.setSeriesPaint(0, Color.white);
                movingAverageRenderer.setSeriesPaint(1, Color.orange);
                movingAverageRenderer.setSeriesPaint(2, Color.yellow);
                movingAveragePlot.setRenderer(0, movingAverageRenderer);
            } else 
            {
                XYPlot plot = (XYPlot) chart.getPlot();
                plot.setDataset(1, dataset);
                final XYLineAndShapeRenderer movingAverageRenderer = new XYLineAndShapeRenderer(true,false); 
                plot.getRenderer().setSeriesPaint(0, Color.RED);
                plot.getRenderer().setSeriesPaint(1, Color.BLUE);
                plot.getRenderer().setSeriesPaint(2, Color.GREEN);
            }
        }
    });
    return smoothingPanel;  
}

/**
 * 
 * @return
 */
private JPanel createSaveLoadPanel()
{
    JPanel saveLoadPanel = new JPanel();

    JButton saveButton = new JButton("Save");
    saveButton.setToolTipText("Save");

    JButton importButton = new JButton("Import");
    importButton.setToolTipText("Import (csv file only)");

    panel.add(saveButton);
    panel.add(importButton);

    return saveLoadPanel;
}


/**
 * 
 */
private void createMenuBar() 
{
    JMenuBar menubar = new JMenuBar();

    JMenu file = new JMenu("File");
    file.setMnemonic(KeyEvent.VK_F);

    JMenuItem importMenu = new JMenuItem("Open File...");
    JMenuItem saveMenu = new JMenuItem("Save");

    JMenuItem eMenuItem = new JMenuItem("Exit");
    eMenuItem.setMnemonic(KeyEvent.VK_E);
    eMenuItem.setToolTipText("Exit application");
    eMenuItem.addActionListener(new ActionListener() 
    {
        @Override
        public void actionPerformed(ActionEvent event) 
        {
            System.exit(0);
        }
    });

    /**
     * 
     */
    JMenu view = new JMenu("View");
    file.setMnemonic(KeyEvent.VK_G);

    JMenu help = new JMenu("Help");
    file.setMnemonic(KeyEvent.VK_H);

    file.add(importMenu);
    file.addSeparator();
    file.add(saveMenu);
    file.addSeparator();
    file.add(eMenuItem);

    menubar.add(file);
    menubar.add(view);
    menubar.add(help);

    setJMenuBar(menubar);
}


/**
 * 
 * @param args
 * @throws IOException
 */
public static void main(String[] args) throws IOException
{
    final Test2 demo = new Test2("Test");
    System.out.println("Processing... Ok");
    demo.pack();
    RefineryUtilities.centerFrameOnScreen(demo);
    demo.setVisible(true);
}
}

我的数据集的前10行:

time      x       y      z
0.003   -0.13   0.83    0.6
0.009   -0.12   0.83    0.61
0.012   -0.12   0.82    0.6
0.018   -0.13   0.81    0.61
0.021   -0.13   0.8 0.61
0.025   -0.12   0.8 0.61
0.033   -0.12   0.79    0.6
0.034   -0.11   0.79    0.6
0.039   -0.11   0.79    0.58
0.044   -0.11   0.77    0.57

1 个答案:

答案 0 :(得分:1)

如果我理解你的问题,这应该可以解决问题:

  1. 将以下内容添加到XYLineAndShapeRenderer movingAverageRenderer = new XYLineAndShapeRenderer(true,false); movingAverageRenderer.setSeriesPaint(0, Color.white); movingAverageRenderer.setSeriesPaint(1, Color.orange); movingAverageRenderer.setSeriesPaint(2, Color.yellow); plot.setRenderer(1, movingAverageRenderer); (请注意索引 1 ,这意味着此渲染器只会影响索引 1 的数据集,而不是索引 0 时的默认数据集:

    @Override
    public void itemStateChanged(ItemEvent e) 
    {
        ((XYPlot) chart.getPlot())
            .setDataset(1, e.getStateChange() == ItemEvent.SELECTED ? 
                    MovingAverage.createMovingAverage(dataset, "-MAVG", 3 * 24 * 60 * 60 * 1000L, 0L) : 
                    null);
    }
    
  2. 您的复选框监听器可简化为:

    {{1}}
  3. (将第二个数据集设置回null将图表恢复为XYZ)