程式扎記: [ Java 常見問題 ] JFreeChart: Apply a color to a single bar of single series graph

標籤

2014年6月10日 星期二

[ Java 常見問題 ] JFreeChart: Apply a color to a single bar of single series graph

來源自 這裡 
Question: 
In my chart I only have one serie, and I would like -according to the value- to set a different color for the bar. For exemple : 
0-20 -> RED, 20-80 -> YELLOW, 80-100 -> GREEN

  1. CategoryPlot plot = chart.getCategoryPlot();  
  2. CategoryDataset dataset = plot.getDataset(0);  
  3.   
  4. Number value = dataset.getValue(dataset.getRowKey(0), dataset.getColumnKey(0));  
  5. Double val = value.doubleValue();  
  6.   
  7. if (val <= 20.0) {  
  8.     BarRenderer renderer = (BarRenderer) plot.getRenderer();  
  9.     Paint tmp = renderer.getItemPaint(row, column);  
  10.   
  11.     /* 
  12.     ** Help Please 
  13.     */        
  14. }  
  15.   
  16. return chart;  
This is where I reached, I am then blocked and don't know really where to go. I saw in the documentation that Paint is an interface but none of the class implementing this interface does provide a setXXX() method. So my two question are : 
1. How do I set a color to a single Bar ? 
2. How do I apply that to my chart ? 

Answer: 
You'll need to create your own subclass of BarRenderer and override getItemPaint(). Instead of choosing a color based on column, choose it based on your value. Here's an outline to show how the existing BarRenderer works. 
  1. plot.setRenderer(new MyRender());  
  2. ...  
  3. class MyRender extends BarRenderer {  
  4.   
  5.     @Override  
  6.     public Paint getItemPaint(int row, int col) {  
  7.         System.out.println(row + " " + col + " " + super.getItemPaint(row, col));  
  8.         return super.getItemPaint(row, col);  
  9.     }  
  10. }  
Example: 
底下範例將 Bar Chart 定義下面的數值範圍使用不同的顏色顯示: 
* <100: br="" green="" nbsp="">* 100~2xx: Yellow
* 3xx~4xx: Orange
* >499: Red

- BarChartDemo5.java 
  1. package charts.bar.category;  
  2.   
  3. import java.awt.Color;  
  4. import java.awt.Dimension;  
  5. import java.awt.Font;  
  6. import java.awt.Paint;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. import javax.swing.JPanel;  
  11.   
  12. import org.jfree.chart.ChartFactory;  
  13. import org.jfree.chart.ChartPanel;  
  14. import org.jfree.chart.JFreeChart;  
  15. import org.jfree.chart.axis.AxisLocation;  
  16. import org.jfree.chart.axis.CategoryAxis;  
  17. import org.jfree.chart.axis.NumberAxis;  
  18. import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;  
  19. import org.jfree.chart.plot.CategoryPlot;  
  20. import org.jfree.chart.plot.PlotOrientation;  
  21. import org.jfree.chart.renderer.category.BarRenderer;  
  22. import org.jfree.chart.title.TextTitle;  
  23. import org.jfree.data.category.CategoryDataset;  
  24. import org.jfree.data.category.DefaultCategoryDataset;  
  25. import org.jfree.ui.ApplicationFrame;  
  26. import org.jfree.ui.RefineryUtilities;  
  27.   
  28. // https://code.google.com/p/test-chart/source/browse/trunk/src/main/java/es/efor/plandifor/demo/BarChartDemo5.java?r=2  
  29. public class BarChartDemo5 extends ApplicationFrame  
  30. {  
  31.     public static List Values = new ArrayList();  
  32.     public BarChartDemo5(String s)  
  33.     {  
  34.             super(s);  
  35.             JPanel jpanel = createDemoPanel();  
  36.             jpanel.setPreferredSize(new Dimension(600400));  
  37.             setContentPane(jpanel);  
  38.     }  
  39.   
  40.     private static CategoryDataset createDataset()  
  41.     {  
  42.             DefaultCategoryDataset defaultcategorydataset = new DefaultCategoryDataset();  
  43.             String s = "Prison Population Rates";  
  44.             defaultcategorydataset.addValue(59D, s, "Norway"); Values.add(59D);  
  45.             defaultcategorydataset.addValue(69D, s, "Switzerland"); Values.add(69D);  
  46.             defaultcategorydataset.addValue(85D, s, "France"); Values.add(85D);  
  47.             defaultcategorydataset.addValue(93D, s, "Syria"); Values.add(93D);  
  48.             defaultcategorydataset.addValue(96D, s, "Germany"); Values.add(96D);  
  49.             defaultcategorydataset.addValue(111D, s, "China"); Values.add(111D);  
  50.             defaultcategorydataset.addValue(116D, s, "Australia"); Values.add(116D);  
  51.             defaultcategorydataset.addValue(121D, s, "Egypt"); Values.add(121D);  
  52.             defaultcategorydataset.addValue(129D, s, "England & Wales"); Values.add(129D);  
  53.             defaultcategorydataset.addValue(157D, s, "New Zealand"); Values.add(157D);  
  54.             defaultcategorydataset.addValue(205D, s, "Chile"); Values.add(205D);  
  55.             defaultcategorydataset.addValue(229D, s, "Iran"); Values.add(229D);  
  56.             defaultcategorydataset.addValue(359D, s, "Singapore"); Values.add(359D);  
  57.             defaultcategorydataset.addValue(404D, s, "South Africa"); Values.add(404D);  
  58.             defaultcategorydataset.addValue(406D, s, "Ukraine"); Values.add(406D);  
  59.             defaultcategorydataset.addValue(686D, s, "USA"); Values.add(686D);  
  60.             return defaultcategorydataset;  
  61.     }  
  62.   
  63.       
  64.     private static JFreeChart createChart(CategoryDataset categorydataset)  
  65.     {  
  66.             JFreeChart jfreechart = ChartFactory.createBarChart("Prison Population Rates - Selected Countries""Country""Prisoners Per 100,000 National Population", categorydataset, PlotOrientation.HORIZONTAL, truetruefalse);  
  67.             jfreechart.addSubtitle(new TextTitle("Source: http://www.homeoffice.gov.uk/rds/pdfs2/r188.pdf"new Font("Dialog"210)));  
  68.             jfreechart.setBackgroundPaint(Color.white);  
  69.             CategoryPlot categoryplot = (CategoryPlot)jfreechart.getPlot();  
  70.             categoryplot.setBackgroundPaint(Color.lightGray);  
  71.             categoryplot.setRangeGridlinePaint(Color.white);  
  72.             categoryplot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);  
  73.             MyRender barrenderer = new MyRender(Values);  
  74.             //BarRenderer or = (BarRenderer)categoryplot.getRenderer();              
  75.             categoryplot.setRenderer(barrenderer);  
  76.             //barrenderer.setBaseItemLabelsVisible(true);  
  77.             barrenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());  
  78.             CategoryAxis categoryaxis = categoryplot.getDomainAxis();  
  79.             categoryaxis.setCategoryMargin(0.0D);  
  80.             categoryaxis.setUpperMargin(0.02D);  
  81.             categoryaxis.setLowerMargin(0.02D);  
  82.             NumberAxis numberaxis = (NumberAxis)categoryplot.getRangeAxis();  
  83.             numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());  
  84.             numberaxis.setUpperMargin(0.10000000000000001D);  
  85.             return jfreechart;  
  86.     }  
  87.   
  88.     public static JPanel createDemoPanel()  
  89.     {  
  90.             JFreeChart jfreechart = createChart(createDataset());  
  91.             return new ChartPanel(jfreechart);  
  92.     }  
  93.   
  94.     public static void main(String args[])  
  95.     {  
  96.             BarChartDemo5 barchartdemo5 = new BarChartDemo5("Bar Chart Demo 5");  
  97.             barchartdemo5.pack();  
  98.             RefineryUtilities.centerFrameOnScreen(barchartdemo5);  
  99.             barchartdemo5.setVisible(true);  
  100.     }  
  101.       
  102.     public static class MyRender extends BarRenderer {    
  103.         List values;  
  104.           
  105.         public MyRender(List values){this.values = values;}  
  106.             
  107.         @Override    
  108.         public Paint getItemPaint(int row, int col) {             
  109.            double value = values.get(col);  
  110.            int h = ((int)value)/100;  
  111.            if(value<100return Color.GREEN;  
  112.            else if(h<3return Color.yellow;  
  113.            else if(h<5return Color.orange;  
  114.            else return Color.red;  
  115.         }    
  116.     }   
  117. }  
執行結果: 

沒有留言:

張貼留言

網誌存檔