java - 如何仅更改移动平均曲线的颜色

标签 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. 将以下内容添加到 createChart()(注意索引 1,这意味着该渲染器只会影响索引 1< 处的数据集)/strong>,不是索引 0 处的默认数据集):

    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);
    
  2. 您的复选框监听器可以简化为:

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

(将第二个数据集设置回 null 会将图表恢复为 XYZ)

关于java - 如何仅更改移动平均曲线的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31727257/

相关文章:

java - Lua 到 JVM 编译器?

java - 为什么 Java 8 中托管 main 的接口(interface)不必是公共(public)的?

java - 使用谷歌应用程序引擎中托管的java程序调用facebook api(php)

java - ListView 适配器行为异常。在我单击同一个 ListView 中的按钮后,ListView 中不相关的按钮被单击

java - 如何构建和使用 TimeSeriesCollections

java - 简单的透明度示例在 Java 3D 中不起作用

Java 延迟事件处理

java - 更高质量的 JFreeChart 图表

java - 在 stackedarechart 上设置刻度间隔

java - 带有日期作为 x 标签的 JFreeChart