根据值更改图表点颜色 - JFreeChart

时间:2015-12-30 10:58:46

标签: java csv jfreechart jfreereport

我有一个CSV文件,如下所示(the file can be be downloaded here)

enter image description here

我想用X轴表示时间(电子表格中的第一列)和Y轴上的开关名称(除了第一列以外的所有列的标题)。我希望在Y轴上为每列创建一个点。该列将与X轴水平,但颜色应根据值TRUE或FALSE或0,1,2更改。

这是我迄今为止开发的内容:

package democsv;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
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.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class DemoCSV extends ApplicationFrame {

    public static List<Object> sections = new ArrayList<>();
    public static String[] switchNames = null;
    public static ArrayList<String> time = new ArrayList<>();
    public static ArrayList<ArrayList<String>> datastore = new ArrayList<>();

    public DemoCSV(String applicationTitle, String chartTitle) throws IOException {
        super(applicationTitle);
        InputStream in = DemoCSV.class.getResourceAsStream("/files/Electrical.csv");
        InputStream in2 = DemoCSV.class.getResourceAsStream("/files/Electrical.csv");

        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        BufferedReader read = new BufferedReader(new InputStreamReader(in2));
        String line, line2;
        int cnt = 0;

        while ((line = reader.readLine()) != null) {
            String[] dataIn = line.split(",");

            if (cnt == 0) {
                switchNames = sNames(dataIn);
            } else if (cnt != 0) {
                time.add(dataIn[0]);
            }
            cnt++;
        }

        cnt = 0;

        int dsize = switchNames.length;

        while (datastore.size() < dsize) {
            datastore.add(new ArrayList<>());
        }


        while ((line2 = read.readLine()) != null) {
            String[] dataIn2 = line2.split(",");

            if (cnt != 0) {
                for (int i = 1; i <= dsize; i++) {
                    datastore.get(i - 1).add(dataIn2[i]);
                }
            }
            cnt++;
        }

        for (String sn : switchNames) {
            sections.add(new XYSeries(sn));
        }

        JFreeChart xylineChart = ChartFactory.createXYLineChart(
                chartTitle,
                "Category",
                "Score",
                createDataset(),
                PlotOrientation.VERTICAL,
                true, true, false);

        ChartPanel chartPanel = new ChartPanel(xylineChart);
        chartPanel.setPreferredSize(new java.awt.Dimension(1366, 768));
        final XYPlot plot = xylineChart.getXYPlot();
        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();

        plot.setRenderer(renderer);
        setContentPane(chartPanel);

    }

    private XYDataset createDataset() {


        ArrayList<Object> xystore = new ArrayList<>();

        for (String sn : switchNames) {
            xystore.add(new XYSeries(sn));
        }

        for (int i = 1; i <= switchNames.length; i++) {
            for (String x : time) {
                double y = Double.parseDouble(x);
                ((XYSeries)xystore.get(i-1)).add(y, i);
            }
        }

        final XYSeriesCollection dataset = new XYSeriesCollection();
        for (Object xy : xystore) {
            dataset.addSeries((XYSeries)xy);
        }

        System.out.println(dataset);
        return dataset;

    }

    public static String[] sNames(String[] names) {
        String[] arr = Arrays.copyOfRange(names, 1, names.length);
        return arr;

    }

    public static void DataClear() throws IOException, NullPointerException {

    }

    public static void main(String[] args) throws IOException {

        DemoCSV test = new DemoCSV("Test", "second");

        test.pack();
        RefineryUtilities.centerFrameOnScreen(test);
        test.setVisible(true);
    }
}

当它运行时,它会生成如下所示的内容:

graph

我希望在csv文件中的列中的值发生变化时更改点的颜色(不管颜色是什么,它是我们想要看到的颜色变化看它)。如果这是不可能的,那么为每个节点设置值的方法就足够了(具有悬停效果)。

2 个答案:

答案 0 :(得分:1)

使用XYPlot似乎无法做到这一点。但是,您可以使用散点图(FastScatterPlot)代替。不要将开关设为系列,而是将值(TRUE,FALSE等)串联起来,并保持X和Y位置不变。

此外,您应该使用SymbolAxis作为Y轴。致电setRangeAxis上的FastScatterPlot,以使用创建的SymbolAxis

答案 1 :(得分:0)

感谢Robin Green的答案,但我使用了Trash god描述的方法。 要实现我的目标,我必须根据getItemPaint()的值覆盖datastore。我在这里发布了它,因为垃圾之神只评论了它。

How to set different colors to the bars in stacked bar chart in ireport?