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

Change the Chart point color according to value - JFreeChart

我有一个如下所示的 CSV 文件 (the file can be be downloaded 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);
    }
}

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

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

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

您还应该使用 SymbolAxis 作为 Y 轴。在您的 FastScatterPlot 上调用 setRangeAxis 以使用创建的 SymbolAxis.

感谢 Robin Green 的回答,但我使用了 Trash god 描述的方法。 为了接近我的目标,我必须根据 datastore 的值覆盖 getItemPaint()。我发在这里是因为 Trash god 只评论了它。

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