当前位置: 首页 > 知识库问答 >
问题:

动态更改JFreeChart直方图颜色?

尹承业
2023-03-14

我试图显示一个图像的直方图,只显示一些颜色。我已经用JFreeChart和createXYLineChart实现了这一点,并通过遍历所有像素来获取所有数据。

为了加快速度,我尝试用“createhistogram”来完成它。我遵循了这个准则。

为了用新值更新图表,我使用了以下两种方法:

XYPlot plot = (XYPlot) chart.getPlot();
plot.setDataset(setHistogram(red, green, blue));

setHistogram是一种方法,它根据激活的复选框(布尔红色、绿色和蓝色)返回HistogramDataset。

private void setHistogramColors(boolean red, boolean green, boolean blue) {
    XYPlot plot = (XYPlot) chart.getPlot();
    XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer();
    renderer.setBarPainter(new StandardXYBarPainter());
    Paint[] paintArray = null;
    if (red) {
        if (green) {
            if (blue) {
                paintArray = new Paint[3];
                paintArray[0] = new Color(0x80ff0000, true);// translucent red, green & blue
                paintArray[1] = new Color(0x8000ff00, true);
                paintArray[2] = new Color(0x800000ff, true);
            } else {
                paintArray = new Paint[2];
                paintArray[0] = new Color(0x80ff0000, true);
                paintArray[1] = new Color(0x8000ff00, true);
            }
        } else {
            paintArray = new Paint[1];
            paintArray[0] = new Color(0x80ff0000, true);
        }
    } else if (green) {
        if (blue) {
            paintArray = new Paint[2];
            paintArray[0] = new Color(0x8000ff00, true);
            paintArray[1] = new Color(0x800000ff, true);
        } else {
            paintArray = new Paint[1];
            paintArray[0] = new Color(0x8000ff00, true);
        }
    } else if (blue){
        paintArray = new Paint[1];
        paintArray[0] = new Color(0x800000ff, true);
    }
    else {
        return;
    }
    plot.setDrawingSupplier(new DefaultDrawingSupplier(
            paintArray,
            DefaultDrawingSupplier.DEFAULT_FILL_PAINT_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE));
}

共有1个答案

翁翰墨
2023-03-14

根据您的片段和此注释,您似乎试图通过在复选框处理程序中从数据集中添加和删除系列来更改显示。不是改变模型,而是改变视图中序列的可见性。在这种情况下,您可以给每个复选框一个合适的操作,如下所示。请特别注意,VisibleAction使用与自定义DrawingSupplier中相应颜色匹配的系列索引。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Paint;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.DefaultDrawingSupplier;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYBarPainter;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.statistics.HistogramDataset;

/**
 * @see https://stackoverflow.com/q/40537278/230513
 * @see https://stackoverflow.com/q/11870416/230513
 * @see https://stackoverflow.com/a/28519356/230513
 */
public class Histogram {

    private static final int BINS = 256;
    private final BufferedImage image = getImage();
    private HistogramDataset dataset;
    private XYBarRenderer renderer;

    private BufferedImage getImage() {
        try {
            return ImageIO.read(new URL(
                "http://i.imgur.com/kxXhIH1.jpg"));
        } catch (IOException e) {
            e.printStackTrace(System.err);
        }
        return null;
    }

    private ChartPanel createChartPanel() {
        // dataset
        dataset = new HistogramDataset();
        Raster raster = image.getRaster();
        final int w = image.getWidth();
        final int h = image.getHeight();
        double[] r = new double[w * h];
        r = raster.getSamples(0, 0, w, h, 0, r);
        dataset.addSeries("Red", r, BINS);
        r = raster.getSamples(0, 0, w, h, 1, r);
        dataset.addSeries("Green", r, BINS);
        r = raster.getSamples(0, 0, w, h, 2, r);
        dataset.addSeries("Blue", r, BINS);
        // chart
        JFreeChart chart = ChartFactory.createHistogram("Histogram", "Value",
            "Count", dataset, PlotOrientation.VERTICAL, true, true, false);
        XYPlot plot = (XYPlot) chart.getPlot();
        renderer = (XYBarRenderer) plot.getRenderer();
        renderer.setBarPainter(new StandardXYBarPainter());
        // translucent red, green & blue
        Paint[] paintArray = {
            new Color(0x80ff0000, true),
            new Color(0x8000ff00, true),
            new Color(0x800000ff, true)
        };
        plot.setDrawingSupplier(new DefaultDrawingSupplier(
            paintArray,
            DefaultDrawingSupplier.DEFAULT_FILL_PAINT_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,
            DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE));
        ChartPanel panel = new ChartPanel(chart);
        panel.setMouseWheelEnabled(true);
        return panel;
    }

    private JPanel createControlPanel() {
        JPanel panel = new JPanel();
        panel.add(new JCheckBox(new VisibleAction(0)));
        panel.add(new JCheckBox(new VisibleAction(1)));
        panel.add(new JCheckBox(new VisibleAction(2)));
        return panel;
    }

    private class VisibleAction extends AbstractAction {

        private final int i;

        public VisibleAction(int i) {
            this.i = i;
            this.putValue(NAME, (String) dataset.getSeriesKey(i));
            this.putValue(SELECTED_KEY, true);
            renderer.setSeriesVisible(i, true);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            renderer.setSeriesVisible(i, !renderer.getSeriesVisible(i));
        }
    }

    private void display() {
        JFrame f = new JFrame("Histogram");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(createChartPanel());
        f.add(createControlPanel(), BorderLayout.SOUTH);
        f.add(new JLabel(new ImageIcon(image)), BorderLayout.WEST);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new Histogram().display();
        });
    }
}
 类似资料:
  • 是否可以动态更改Gnuplot脚本中条的颜色?我有以下脚本 这将生成此绘图: 有没有可能使零度以下的色条变成红色? 谢谢, 斯文

  • 我正在用GnuplotPy绘制一些直方图,我想更改直方图条的颜色。(默认情况下,条形图为红色。)这篇StackOverflow文章中的答案给出了几个在普通Gnuplot中如何更改直方图条颜色的选项,但是我还无法让这些解决方案在GnuplotPy中工作。 以下是我使用的基本设置: 上面的代码没有尝试设置直方图条的颜色,它生成了一个带有红色条的直方图: 我尝试了几种方法将直方图条颜色更改为蓝色,但都没

  • 我正在使用RangeSeekBar为3种情况设置一些值(即绿色=OK,琥珀色=警告,红色=撤离)...我正在使用xml绘图来设置背景 我知道我可以通过编程更改渐变,但如何缩小起始颜色并增加结束颜色?有人能解决这个问题吗? 谢谢

  • 问题内容: 我正在使用json数据创建列类型图。这是我调用的JS函数,用于使用ajax调用获取数据并绘制图表。 如果计数大于特定值(例如10),我希望能够在一天中修改条形的颜色。 这就是json输入到函数的方式。 任何建议我该怎么做? 问题答案: 您可以使用颜色区域(API)根据列的值来具有不同的颜色。 值低于/高于10的示例具有不同的颜色(JSFiddle):

  • 如何根据android edittext的背景颜色(动态)更改android edittext光标颜色?。如果我选择深色背景颜色编辑文本,光标将是浅色。如果我选择深色背景颜色编辑文本,光标将是暗色。基于edittext颜色更改,光标颜色将在运行时更改。如何实现?任何想法都欢迎。

  • 我正在尝试根据行标准更改背景行颜色。我离得很近,但有些事情我不能完全理解。(我相信这是因为我从底层列表中提取对象,而不是动态地获取数据。我标记了下面代码的这一部分) 在下面的示例中,每一行颜色都基于一个具有成功或失败值的对象(MyObj)。如果myObj有一个成功值,行应该是绿色的。如果myObj有一个失败值,那么行应该是红色的。如果myObj没有值,则应使用默认行颜色。