sabato 8 dicembre 2012

JFreeChart, esempi realizzazione grafici

In questo posto vediamo come generare 4 tipologie di grafici con JFreeChart, in particolare:

  • Tachimetro (grafico a lancetta);
  • Torta;
  • Istogramma semplice;
  • Istogramma multiplo.
Ho creato un semplice Java Project includendo le seguenti librerie nel classpath:

  • jfreechart-1.0.9.jar;
  • jcommon-1.0.12.jar;
  • iText-2.0.8.jar.
Di seguito incollo la classe main principale, con dei metodi statici che generano delle immagini png per ciascun tipo grafico definito:


package chart.example;
import java.awt.BasicStroke;
import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.PieSectionLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.DialShape;
import org.jfree.chart.plot.MeterInterval;
import org.jfree.chart.plot.MeterPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.Range;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.DefaultValueDataset;
import org.jfree.ui.TextAnchor;
import com.lowagie.text.Font;
public class ChartCreator {
 public static int myFontStyle = Font.UNDEFINED;
 public static Font baseFont = new Font ( myFontStyle, 12, Font.NORMAL );
 public static void main(String[] args) throws Exception {
   creaGraficoATorta();
        creaIstogrammaMultiplo();
        creaTachimetro();
        creaIstogrammaSemplice();
 }
 private static void creaGraficoATorta() throws Exception{
  OutputStream fos=new FileOutputStream(new File("out/torta.png"));
  String[] componenti=new String[]{"Inter","Milan","Rubentus"};
  double[] valori=new double[]{18.0,18.0,28.0};
  JFreeChart chart=creaGraficoATorta(componenti, valori, false);
  ChartUtilities.writeChartAsPNG(fos, chart, 500, 300);
 }
 private static void creaIstogrammaMultiplo() throws Exception{
  OutputStream fos=new FileOutputStream(new File("out/istoMul.png"));
  double[] valori=new double[9];
  valori[0]=20.0;
  valori[1]=65.0;
  valori[2]=15.0;
  valori[3]=30.0;
  valori[4]=50.0;
  valori[5]=20.0;
  valori[6]=25.0;
  valori[7]=60.0;
  valori[8]=15.0;
  String[] componenti=new String[3];
  componenti[0]="Lazio";
  componenti[1]="Lombardia";
  componenti[2]="Toscana";
  String[] sottocomponenti=new String[3];
  sottocomponenti[0]="Ricchi";
  sottocomponenti[1]="Classe Media";
  sottocomponenti[2]="Poveri";
  JFreeChart chart=creaIstogramma(componenti,sottocomponenti, valori, "Ripartizione classi sociali", "Regioni", "Percentuali");
   ChartUtilities.writeChartAsPNG(fos, chart, 500, 300);
 }
 
 private static void creaIstogrammaSemplice() throws Exception
 {
  OutputStream fos=new FileOutputStream(new File("out/isto.png"));
  String[] componenti=new String[]{"Alto","Medio","Basso"};
  double[] valori=new double[]{85.5,75.12,45.56};
  JFreeChart chart=creaIstogramma(componenti, valori, "Andamenti", "", "");
  ChartUtilities.writeChartAsPNG(fos, chart, 500, 300);
 }
 private static void creaTachimetro() throws Exception{
  OutputStream fos=new FileOutputStream(new File("out/tachimetro.png"));
  BigDecimal a=new BigDecimal(37.0);
  BigDecimal b=new BigDecimal(49.0);
  BigDecimal res=a.divide(b,2,RoundingMode.HALF_UP);
  double v=res.doubleValue()*(double)100;
  JFreeChart chart=creaTachimetro(new Double(v), "Esempio", "", Color.WHITE);
  ChartUtilities.writeChartAsPNG(fos, chart, 500, 300);
 }

 public static JFreeChart creaTachimetro(Double valore, String titolo, String sottotitolo, Color bgcolor)
 {
  DefaultValueDataset ds = new DefaultValueDataset();
  ds.setValue(valore);
  MeterPlot plot = new MeterPlot(ds);
  plot.setUnits("%");
  plot.setRange(new Range(0, 100));
  plot.setMeterAngle(210);
  plot.addInterval(new MeterInterval("Intervallo1", new Range(90.0, 100.0), Color.LIGHT_GRAY, new BasicStroke(1.0f), new Color(255, 0, 0, 200)));
  plot.addInterval(new MeterInterval("Intervallo2", new Range(80.0, 90.0), Color.LIGHT_GRAY, new BasicStroke(1.0f), new Color(255, 51, 0, 200)));
  plot.addInterval(new MeterInterval("Intervallo3", new Range(70.0, 80.0), Color.LIGHT_GRAY, new BasicStroke(1.0f), new Color(255, 102, 0, 200)));
  plot.addInterval(new MeterInterval("Intervallo4", new Range(60.0, 70.0), Color.LIGHT_GRAY, new BasicStroke(1.0f), new Color(255, 153, 0, 200)));
  plot.addInterval(new MeterInterval("Intervallo5", new Range(50.0, 60.0), Color.LIGHT_GRAY, new BasicStroke(1.0f), new Color(255, 204, 0, 200)));
  plot.addInterval(new MeterInterval("Intervallo6", new Range(40.0, 50.0), Color.LIGHT_GRAY, new BasicStroke(1.0f), new Color(255, 255, 0, 200)));
  plot.addInterval(new MeterInterval("Intervallo7", new Range(30.0, 40.0), Color.LIGHT_GRAY, new BasicStroke(1.0f), new Color(192, 255, 0, 200)));
  plot.addInterval(new MeterInterval("Intervallo8", new Range(20.0, 30.0), Color.LIGHT_GRAY, new BasicStroke(1.0f), new Color(128, 255, 0, 200)));
  plot.addInterval(new MeterInterval("Intervallo9", new Range(10.0, 20.0), Color.LIGHT_GRAY, new BasicStroke(1.0f), new Color(64, 255, 0, 200)));
  plot.addInterval(new MeterInterval("Intervallo10", new Range(0.0, 10.0), Color.LIGHT_GRAY, new BasicStroke(1.0f), new Color(0, 255, 0, 200)));
  plot.setBackgroundPaint(bgcolor);
  plot.setNeedlePaint(Color.BLACK);
  plot.setDialBackgroundPaint(bgcolor);
  plot.setDialOutlinePaint(bgcolor);
  plot.setDialShape(DialShape.CIRCLE);
  plot.setTickLabelsVisible(false);
  plot.setTickSize(100.0);
  plot.setTickPaint(Color.GRAY);
  plot.setValueFont(new java.awt.Font("Dialog", Font.BOLD, 14));
  plot.setValuePaint(Color.BLACK);
  JFreeChart chart = new JFreeChart(null, null, plot, false);
  chart.setBackgroundPaint(bgcolor);
  if (!titolo.equals("")) {
   TextTitle title = new TextTitle(titolo);
   title.setFont(new java.awt.Font("Verdana", Font.BOLD, 12));
   title.setPaint(new Color(0x2684B3));
   chart.setTitle(title);
  }
  if (!sottotitolo.equals("")) {
   TextTitle subtitle = new TextTitle(sottotitolo);
   subtitle.setFont(new java.awt.Font("Verdana", java.awt.Font.ITALIC, 11));
   subtitle.setPaint(new Color(0x2684B3));
   chart.addSubtitle(subtitle);
  }
  return chart;
 }
 public static JFreeChart creaIstogramma(String[] componenti,String[] sottocomponenti,double[] valori,String titolo,String ascissa,String ordinata){
  DefaultCategoryDataset cds=new DefaultCategoryDataset();
  int j=0;
  int cambioComponente=sottocomponenti.length;
  String comp=componenti[j];
  int sottoComp=0;
        for(int i=0;i 1) {
   for (int i = 0; i < componenti.length; i++) {
    renderer.setSeriesItemLabelsVisible(i, true);
    renderer.setSeriesItemLabelGenerator(i, new SeriesLabelGenerator());
   }
  } else {
   renderer.setSeriesItemLabelsVisible(0, true);
   renderer.setSeriesItemLabelGenerator(0, new LabelGenerator(null));
  }
      return chart;
 }
 public static JFreeChart creaIstogramma(String[] componenti,double[] valori,String titolo,String ascissa,String ordinata){
  DefaultCategoryDataset cds=new DefaultCategoryDataset();
        for(int i=0;i

Nel codice sono utilizzate due classi (LabelGenerator e SeriesLabelGenerator) che servono a mostrare nei grafici a torta e a istogramma semplice (LabelGenerator) e nel grafico a istogramma multiplo (SeriesLabelGenerator) i valori con le percentuali.

LabelGenerator


package chart.example;
import java.text.NumberFormat;
import org.jfree.chart.labels.AbstractCategoryItemLabelGenerator;
import org.jfree.chart.labels.CategoryItemLabelGenerator;
import org.jfree.data.category.CategoryDataset;
public class LabelGenerator extends AbstractCategoryItemLabelGenerator implements CategoryItemLabelGenerator {

 private static final long serialVersionUID = 7389531138610633787L;
 private Integer category;
 private NumberFormat formatter = NumberFormat.getPercentInstance();
 public LabelGenerator(int category) {
  this(new Integer(category));
 }
 public LabelGenerator(Integer category) {
  super("", NumberFormat.getInstance());
 this.category = category;
 }
 public String generateLabel(CategoryDataset dataset, int series, int category ) {
  String result = null;
  double base = 0.0;
  if (this.category != null) {
   final Number b = dataset.getValue(series, this.category.intValue());
   base = b.doubleValue();
  }
  else {
   base = calculateSeriesTotal(dataset, series);
  }
  Number value = dataset.getValue(series, category);
  if (value != null) {
   final double v = value.doubleValue();
   //  you could apply some formatting here
   result = "     "+ value.toString() + " (" + this.formatter.format(v / base) + ")";
  }
  return result;
 }
 private double calculateSeriesTotal(CategoryDataset dataset, int series) {
  double result = 0.0;
  for (int i = 0; i < dataset.getColumnCount(); i++) {
   Number value = dataset.getValue(series, i);
   if (value != null) {
    result = result + value.doubleValue();
    }
  }
  return result;
 }
}



SeriesLabelGenerator



package chart.example;
import java.text.NumberFormat;
import org.jfree.chart.labels.AbstractCategoryItemLabelGenerator;
import org.jfree.chart.labels.CategoryItemLabelGenerator;
import org.jfree.data.category.CategoryDataset;
public class SeriesLabelGenerator extends AbstractCategoryItemLabelGenerator implements CategoryItemLabelGenerator {
 private static final long serialVersionUID = 7389531138610633787L;
 private NumberFormat formatter = NumberFormat.getPercentInstance();
 public SeriesLabelGenerator() {
  super("", NumberFormat.getInstance());
 }
 public String generateLabel(CategoryDataset dataset, int series, int category ) {
  String result = null;
  double base = 0.0;
  base = calculateCategoryTotal(dataset, category);
  Number value = dataset.getValue(series, category);
  if (value != null) {
   final double v = value.doubleValue();
   result = "     "+ value.toString() + " (" + this.formatter.format(v / base) + ")";
  }
  return result;
 }
 private double calculateCategoryTotal(CategoryDataset dataset, int category) {
  double result = 0.0;
  for (int i = 0; i < dataset.getRowCount(); i++) {
   Number value = dataset.getValue(i,category);
   if (value != null) {
    result = result + value.doubleValue();
    }
  }
  return result;
 }
}



Il risultato del codice è la generazione delle seguenti immagini:

Torta





Istogramma semplice


Istogramma multiplo


Grafico a lancetta




Nessun commento:

Posta un commento