【问题标题】:iReport / jFreeChart - Combining getItemPaint() override and series colorsiReport / jFreeChart - 结合 getItemPaint() 覆盖和系列颜色
【发布时间】:2012-12-04 17:29:39
【问题描述】:

我正在尝试创建一个条形图,该条形图需要为 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 的 Series Color 属性。

更新代码:

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

【问题讨论】:

    标签: java jasper-reports ireport jfreechart series


    【解决方案1】:

    您需要编写一个自定义渲染器,通过覆盖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);
        }
    }
    

    【讨论】:

    • BarRender 类的更新是否与 JRAbstractCharCustomizer 兼容?请原谅我的无知;我对 Java 非常生疏,并且正在使用以前的开发人员编写的代码。我不确定的一件事是如何更新 plot 方法调用的类。当前的自定义程序类(按原样工作,但没有自定义颜色渲染)没有指定绘图方法。我已经用我对嵌入在我当前代码中的代码的解释更新了我的问题。它看起来不好吗?
    • 我现在不在电脑旁,但看起来没问题。您不需要在类别图之后对自定义渲染器进行子类化
    • 所以我可以从categoryPlot.setRenderer() 中删除(new CustomRenderer()? categoryPlot 会知道从新的 CustomRenderer 类而不是默认的 BarRenderer 类进行渲染?
    • 否,但后面不需要 {}。它不执行任何操作,因为它在 {} 中没有代码。
    • 做到了。感谢您所有的帮助。看起来 Jasper 会迫使我把旧的 Java 知识掸掉,哈。对于那些感兴趣的人,我已经用完整版本更新了我的问题中的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 2011-04-11
    • 2014-02-16
    • 2020-11-28
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多