2

我正在尝试创建一个条形图,该条形图需要为 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));
    }
}
4

1 回答 1

3

您将需要编写一个自定义渲染器以通过覆盖来根据系列和类别选择“绘画”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);
    }
}
于 2012-12-17T17:01:02.593 回答