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

iReport / jFreeChart - 组合获取项油漆() 覆盖和系列颜色

周翰池
2023-03-14

我正在尝试创建一个条形图,需要为N个类别使用特定的系列颜色,为1个其他类别使用单独的颜色。下面是一个示例:

在模型中,类别1-3使用5种颜色的集合来渲染其系列,而类别4使用单一的灰色。我的第一种方法是使用定制类覆盖getItemPaint()方法,但我只能在类别级别而不是系列级别定义颜色。是否可以在类别和/或系列级别上定义颜色?比如,

If category != "Category4"
    Use colors A, B, C, D, and E in category's series
Else
    Use color F in category's series

我的另一个想法是将iReport的系列颜色条形图属性和getItemPaint()覆盖结合起来;这样我就可以定义iReport中使用的5种颜色,并且仅在类别等于“类别4”的情况下使用getItemPaint()覆盖。到目前为止,我还没有幸运地将两者结合起来;如果定义了覆盖,它将覆盖iReport的系列颜色属性。

用代码更新:

import java.awt.Color;
import java.awt.Paint;

import net.sf.jasperreports.engine.JRAbstractChartCustomizer;
import net.sf.jasperreports.engine.JRChart;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.data.category.CategoryDataset;

public class CustomSeriesColors extends JRAbstractChartCustomizer {

    static class CustomRenderer extends BarRenderer {

        private final Paint[] colors1;
        private final Paint[] colors2;

        public CustomRenderer(Paint[] colors1, Paint[] colors2) {
            this.colors1 = colors1;
            this.colors2 = colors2;
        }

        //Set custom colors for series according to category    
        @Override
        public Paint getItemPaint(int row, int column) {
            CategoryDataset l_jfcDataset = getPlot().getDataset();
            String l_rowKey = (String)l_jfcDataset.getRowKey(row);
            String l_colKey = (String)l_jfcDataset.getColumnKey(column);

            if ("Insufficient Data".equalsIgnoreCase(l_colKey)) {
                return this.colors2[row % this.colors1.length];
            } else {
                return this.colors1[row % this.colors1.length];
            }
        }
    }

    public void customize(JFreeChart chart, JRChart jasperChart) {

        // Get plot data.
        CategoryPlot categoryPlot = chart.getCategoryPlot();

        // Define colors to be used by series.
        Color[] color1 = new Color[]{new Color(238,0,0), new Color(255,153,0), new Color(211,190,91), new Color(153,204,102), new Color(0,170,0)};
        Color[] color2 = new Color[]{new Color(200,200,200)};

        // Call CustomRenderer using defined color sets.
        categoryPlot.setRenderer(new CustomRenderer(color1,color2));
    }
}

共有1个答案

钱选
2023-03-14

您需要编写自定义渲染器,通过覆盖getItemPaint来根据系列和类别选择“绘制”

@Override
public Paint getItemPaint(int series, int category) {
  if (category == 4)
    return this.colors2[series % this.colors1.length];
  else
    return this.colors1[series % this.colors1.length];
}

使用渲染器更新绘图:

Color[] color1 = new Color[]{Color.red, Color.green,Color.blue};
Color[] color2 = new Color[]{Color.gray,Color.gray.darker()};
plot.setRenderer(new CustomRenderer(color1,color2));

这是完整的代码

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Paint;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.axis.SymbolAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;


public class BarChartDemo7 extends ApplicationFrame {

    static class CustomRenderer extends BarRenderer {

        private final Paint[] colors1;
        private final Paint[] colors2;

        public CustomRenderer(Paint[] colors1,Paint[] colors2) {
            this.colors1 = colors1;
            this.colors2 = colors2;
        }

        @Override
        public Paint getItemPaint(int series, int category) {
            if (category == 4)
                return this.colors2[series % this.colors1.length];
            else
                return this.colors1[series % this.colors1.length];
        }
    }


    public BarChartDemo7(String title) {
        super(title);
        CategoryDataset dataSet=createDataset();
        JFreeChart chart=createChart(dataSet);
        ChartPanel panel=new ChartPanel(chart);
        panel.setPreferredSize(new Dimension(800,800));
        setContentPane(panel);
    }


    private static CategoryDataset createDataset() {
        // row keys...
        final String series1 = "ABC";
        final String series2 = "XYZ";

        // column keys...
        final String category1 = "A";
        final String category2 = "B";
        final String category3 = "C";
        final String category4 = "D";
        final String category5 = "E";
        final String category6 = "F";

        // create the dataset...
        final DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        dataset.addValue(35, series1, category1);
        dataset.addValue(37, series1, category2);
        dataset.addValue(40, series1, category3);
        dataset.addValue(52, series1, category4);
        dataset.addValue(52, series1, category5);
        dataset.addValue(52, series1, category6);


        dataset.addValue(30, series2, category1);
        dataset.addValue(32, series2, category2);
        dataset.addValue(35, series2, category3);
        dataset.addValue(45, series2, category4);
        dataset.addValue(30, series2, category1);
        dataset.addValue(32, series2, category2);
        dataset.addValue(35, series2, category5);
        dataset.addValue(45, series2, category4);

        return dataset;
    }



    private static JFreeChart createChart(CategoryDataset dataset) {

        // create the chart...
        JFreeChart chart = ChartFactory.createBarChart(
            "ABC",             
            "",                      
            "",                         
            dataset,                         
            PlotOrientation.VERTICAL,        
            true,                            
            true,                            
            false                            
        );

        chart.setBackgroundPaint(Color.white);

        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        plot.setBackgroundPaint(Color.WHITE);
        plot.setDomainGridlinePaint(Color.BLACK);
        plot.setRangeGridlinePaint(Color.BLACK);

        //Provide a new Symbol Axis
        String[] grade =  new String[101];
        for (int i = 0 ; i < grade.length ; i ++){
            grade[i] = Integer.toString(i);
        }
        grade[0] = "Poor    0";
        grade[50] = "Avg.   50";
        grade[100] = "Best   100";
        SymbolAxis rangeAxis = new SymbolAxis("", grade);
        rangeAxis.setTickUnit(new NumberTickUnit(10));
        rangeAxis.setAutoRange(false);
        rangeAxis.setRange(0, 100);
        plot.setRangeAxis(rangeAxis);


        Color[] color1 = new Color[]{Color.red, Color.green,Color.blue};
        Color[] color2 = new Color[]{Color.gray,Color.gray.darker()};
        plot.setRenderer(new CustomRenderer(color1,color2));
        return chart;
    }

    public static void main(String[] args) {
        BarChartDemo7 demo = new BarChartDemo7("ABC");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }
}
 类似资料:
  • 我试图编写一个小迷宫运行程序,遇到了一些与绘图组件()相关的麻烦。我已经完成了调试,出于某种原因,我的绘图组件()从未被调用,即使是由我的计时器调用的重新绘制()。 这些是我的frame和jpanel init方法。 这是我的paintComponent,图像确实已缓冲并已存储。 这就是我的ActionExecuted,它是用我的计时器调用的,默认设置为5秒的间隔。 } 如果你感兴趣,这是我的完整

  • 问题内容: 对不起,我进行了大量搜索,以查找这3个功能(绘画,重绘,paintComponent)之间如何相互作用,但我不知道。您能准确解释一下它们何时被调用(因为有时java会在没有我问他的情况下调用它),它们到底在做什么,它们之间有什么区别。谢谢 问题答案: 我不确定“ paint”,但是我可以解释repaint()和paintComponent()之间的关系。 根据我在Java方面的有限经验

  • 本章介绍Canvas组件,用它来生成简单的二维(2D)图形,目标是创建一个PaintPot(油漆桶)应用,让用户在手机屏幕上绘制图画,并让用户用手机给自己拍照,然后在自己的照片上绘图。回顾历史,早在20世纪70年代,PaintPot是最早运行在个人电脑上的应用之一,目的是为了证明个人电脑的潜力。那时候,开发这样一款简单的绘图应用是一项极其复杂的工作,而且绘图效果也略显粗糙。但现在,使用App In

  • 我们正在使用Nimbus LaF开发Swing应用程序。我们已经更改了许多Nimbus默认值(控件、文本、NimbusLightbackground等)以具有黑暗主题。 现在,我们在呈现JLists和JComboxes时遇到了很大的麻烦,因为呈现程序显然使用了NimbusLightBackground颜色作为所选文本的前景。这会导致深蓝色背景上出现深灰色文本-不好。 我曾尝试通过UIManager

  • 自从发布以来,我将大部分java测试代码从移到文件夹,因为JVM测试要快得多。但我不能移动所有的测试。我确实需要设备测试,因为有些的东西。 在我开始迁移之前,我已经有了100%的代码覆盖率。当我当前运行jacoco代码覆盖率时,文件夹的覆盖率为40%,文件夹的覆盖率为71%。我的代码是100%测试,但我没有报告证明这一点。 有没有办法把这两份报告结合起来?我找到了JacocoMerge,但无法让它

  • 假设我们有自定义的,它通过在其中绘制一些矩形来扩展方法。 绘制的位图表示某种矩形玻璃,其宽度等于listview的宽度,并且具有一定的高度。我想要的是,当列表项滚动到这个矩形中时,用于绘制文本的颜色(不是所有带有背景等的项)将被改变成另一种颜色。因此,例如,当列表项适合到中时,只有一半高度的文本适合时,列表项的外部部分应保持序号颜色,而内部的部分应更改其文本颜色。列表项是没有任何背景的简单文本视图