Header Ads Widget

Responsive Advertisement

How to generate legend wise and custom pie chart


A pie chart (or a circle chart) is a circular statistical graphic which is divided into slices to illustrate numerical proportion. In a pie chart, the arc length of each slice (and consequently its central angle and area), is proportional to the quantity it represents.

  1. jfreeChart-1.0.19.jar
  2. jcommon-1.0.8.jar

 

The provided code consists of three Java classes that are part of a pie chart visualization application. Here's a breakdown of each class:

 

1. DemoData Class

package com.kartik.pie;

 

public class DemoData {

 

  private String name;

 

 private String description;

 

 private double data;

 

 public String getName() {

 

  return name;

 

 }

 

 public void setName(String name) {

 

  this.name = name;

 

 }

 

 public String getDescription() {

 

  return description;

 

 }

 

 public void setDescription(String description) {

 

  this.description = description;

 

 }

 

 public double getData() {

 

  return data;

 

 }

}

 

This is a simple data model that holds information for each slice of the pie chart. It has three attributes: name, description, and data.

Ø  name: The name of the data item.

Ø  description: A description of the data item (currently not utilized in the code).

Ø  data: A double value representing the size of the pie slice.

Methods:

Ø  Getters and setters for each field (getName(), setName(), getDescription(), setDescription(), getData(), and setData()).

2. CustomRingPlot Class

package com.kartik.pie;

 

import java.awt.Color;

 

import java.awt.Font;

 

import java.awt.Graphics2D;

 

import java.awt.geom.Rectangle2D;

 

import org.jfree.chart.plot.PiePlotState;

 

import org.jfree.chart.plot.RingPlot;

 

import org.jfree.data.general.PieDataset;

 

import org.jfree.text.TextUtilities;

 

import org.jfree.ui.TextAnchor;

 

public class CustomRingPlot extends RingPlot {

 

  /**

 

  *

 

  */

 

 private static final long serialVersionUID = 1L;

 

  private Font centerTextFont;

 

 private Color centerTextColor;

 

 private int total;

 

  public CustomRingPlot(PieDataset dataset, Font centerTextFont,

 

   Color centerTextColor) {

 

   super(dataset);

 

  this.centerTextFont = centerTextFont;

 

  this.centerTextColor = centerTextColor;

 

  }

 

  public CustomRingPlot(PieDataset dataset, Font centerTextFont,

 

   Color centerTextColor, int total) {

 

   super(dataset);

 

  this.centerTextFont = centerTextFont;

 

  this.centerTextColor = centerTextColor;

 

  this.total = total;

 

 }

 

  protected void drawItem(Graphics2D g2, int section, Rectangle2D dataArea,

 

   PiePlotState state, int currentPass) {

 

  super.drawItem(g2, section, dataArea, state, currentPass);

 

  g2.setFont(this.centerTextFont);

 

  g2.setPaint(Color.BLACK);

 

  TextUtilities.drawAlignedString("Total Spendings", g2,

 

    (float) dataArea.getCenterX(), (float) dataArea.getCenterY(),

 

    TextAnchor.BOTTOM_CENTER);

 

  g2.setPaint(this.centerTextColor);

 

  g2.setFont(new Font(Font.SANS_SERIF, Font.HANGING_BASELINE, 14));

 

  TextUtilities.drawAlignedString("$" + this.total, g2,

 

    (float) dataArea.getCenterX(), (float) dataArea.getCenterY(),

 

    TextAnchor.TOP_CENTER);

 

 }

 

  /*

 

  * protected void drawItem(Graphics2D g2, int section, Rectangle2D dataArea,

 

  * PiePlotState state, int currentPass) { super.drawItem(g2, section,

 

  * dataArea, state, currentPass); g2.setFont(this.centerTextFont);

 

  * g2.setPaint(Color.BLACK);

 

  * TextUtilities.drawAlignedString("Total Spendings", g2, (float)

 

  * dataArea.getCenterX(), (float) dataArea.getCenterY(),

 

  * TextAnchor.BOTTOM_CENTER); g2.setPaint(this.centerTextColor);

 

  * g2.setFont(new Font(Font.SANS_SERIF, Font.HANGING_BASELINE, 14));

 

  * TextUtilities.drawAlignedString("$", g2, (float) dataArea.getCenterX(),

 

  * (float) dataArea.getCenterY(), TextAnchor.TOP_CENTER); }

 

  */

 

}

 

 

This class extends RingPlot from the JFreeChart library to create a custom pie chart. It adds additional features such as custom text in the center of the ring plot (like total spendings).

Key Features:

Ø  Custom Font and Color: The constructor accepts a dataset (PieDataset), a font for the center text, a color for the text, and the total value for display.

Ø  Custom Rendering: The drawItem method is overridden to draw custom text at the center of the ring plot, showing the label "Total Spendings" and the total value.

Ø  Item Drawing: It draws text using the TextUtilities.drawAlignedString() method, positioning it relative to the pie chart's center.

3. PieChartDemo2 Class

Code 3:

 

package com.kartik.pie;

 

import java.awt.BasicStroke;

 

import java.awt.Color;

 

import java.awt.Font;

 

import java.awt.GradientPaint;

 

import java.awt.Point;

 

import java.awt.geom.Rectangle2D;

 

import java.io.File;

 

import java.io.FileNotFoundException;

 

import java.io.FileOutputStream;

 

import java.io.IOException;

 

import java.text.DecimalFormat;

 

import java.util.ArrayList;

 

import java.util.List;

 

import javax.swing.JPanel;

 

import org.jfree.chart.ChartPanel;

 

import org.jfree.chart.ChartUtilities;

 

import org.jfree.chart.JFreeChart;

 

import org.jfree.chart.labels.PieSectionLabelGenerator;

 

import org.jfree.chart.labels.StandardPieSectionLabelGenerator;

 

import org.jfree.chart.plot.RingPlot;

 

import org.jfree.chart.title.LegendTitle;

 

import org.jfree.data.general.DefaultPieDataset;

 

import org.jfree.data.general.PieDataset;

 

import org.jfree.ui.ApplicationFrame;

 

import org.jfree.ui.RectangleEdge;

 

import org.jfree.ui.RectangleInsets;

 

import org.jfree.ui.RefineryUtilities;

 

import org.jfree.util.Rotation;

 

/**

 

 * A simple demonstration application showing how to create a pie chart using

 

 * data from a {@link DefaultPieDataset}.

 

 */

 

public class PieChartDemo2 extends ApplicationFrame {

 

  private static int totalAmount=0;

 

    /**

 

  *

 

  */

 

 private static final long serialVersionUID = 1L;

 

 

 

 private static int maxSize=0;

 

  /**

 

     * Default constructor.

 

     *

 

     * @param title  the frame title.

 

     */

 

    public PieChartDemo2(String title) {

 

        super(title);

 

        setContentPane(createDemoPanel());

 

    }

 

    /**

 

     *

 

     *

 

     * @return A sample dataset.

 

     */

 

    private static PieDataset createDataset() {

 

        DefaultPieDataset dataset = new DefaultPieDataset();

 

        /*dataset.setValue("one", new Double(43.2));

 

        dataset.setValue("two", new Double(10.0));

 

        dataset.setValue("three", new Double(27.5));

 

        dataset.setValue("four", new Double(17.5));

 

        dataset.setValue("five", new Double(11.0));

 

        dataset.setValue("six", new Double(19.4));

 

        dataset.setValue("seven", new Double(43.2));*/

 

        List<DemoData> data=setData();

 

        totalAmount=sumOfValue(data);

 

        dataset=getdata(data);

 

        return dataset;       

 

    }

 

    private static DefaultPieDataset getdata(List<DemoData> data){

 

     DefaultPieDataset dataSet=new DefaultPieDataset();

 

     for (DemoData demoData : data) {

 

      dataSet.setValue(demoData.getName(), demoData.getData());

 

     }

 

  return dataSet;

 

    }

 

   private static int sumOfValue(List<DemoData> data){

 

    int sum=0;

 

 for (DemoData demoData : data) {

 

  sum+=demoData.getData();

 

 }

 

     return sum;

 

    }

 

    private static List<DemoData> setData(){

 

     List<DemoData> list=new ArrayList<DemoData>();

 

     DemoData one=new DemoData();

 

     one.setName("ONE");

 

     one.setData( new Double(43.2));

 

     list.add(one);

 

     DemoData two=new DemoData();

 

     two.setName("TWO");

 

     two.setData(new Double(10.0));

 

     list.add(two);

 

     DemoData three=new DemoData();

 

     three.setName("THREE");

 

     three.setData( new Double(27.5));

 

     list.add(three);

 

     DemoData four=new DemoData();

 

     four.setName("FOUR");

 

     four.setData( new Double(17.5));

 

     list.add(four);

 

     DemoData five=new DemoData();

 

     five.setName("FIVE");

 

     five.setData( new Double(11.0));

 

     list.add(five);

 

     DemoData six=new DemoData();

 

     six.setName("SIX");

 

     six.setData(  new Double(19.4));

 

     list.add(six);

 

     DemoData seven=new DemoData();

 

     seven.setName("SEVEN");

 

     seven.setData( new Double(9.2));

 

     list.add(seven);

 

     DemoData twenty=new DemoData();

 

     twenty.setName("twentyOne");

 

     twenty.setData( new Double(65.0));

 

     list.add(twenty);

 

  return list;

 

    }

 

 private static JFreeChart createChart(PieDataset dataset) {

 

   //RingPlot plot = new RingPlot(dataset);

 

  RingPlot plot = null;

 

        //PiePlot plot = (PiePlot) chart.getPlot();

 

       // plot = (RingPlot) chart.getPlot();

 

        plot = new CustomRingPlot((PieDataset)dataset, new Font(Font.SANS_SERIF, Font.BOLD, 13), Color.BLUE,totalAmount);

 

     

 

  JFreeChart chart = new JFreeChart("", JFreeChart.DEFAULT_TITLE_FONT,

 

    plot, true);

 

  chart.setBackgroundPaint(new GradientPaint(new Point(100, 100),

 

    Color.WHITE, new Point(100, 100), Color.WHITE));

 

  plot.setNoDataMessage("No data available");

 

  plot.setDirection(Rotation.ANTICLOCKWISE);

 

  plot.setSectionDepth(0.50D); //this is required for circle radios

 

  plot.setBaseSectionOutlineStroke(new BasicStroke(0.5f));

 

  plot.setCircular(true);

 

  plot.setSeparatorsVisible(false); //this is required otherwise inside circle lot of straight line will come

 

  plot.setForegroundAlpha(1.0f); //this is required to display deep color inside pie chart

 

  plot.setOutlinePaint(null); //this is required for circle border if comment this line

 

  plot.setShadowPaint(null);

 

  plot.setOuterSeparatorExtension(50);

 

  plot.setInnerSeparatorExtension(50);

 

  plot = setSectionPaintColors(plot);

 

  

 

  LegendTitle legend = chart.getLegend();

 

  legend.setPosition(RectangleEdge.RIGHT);//this is also required to display legend label

 

  //legend.setFrame(BlockBorder.NONE);  //this is required legend border if you need otherwise comments this line 

 

  Rectangle2D r2DD = new Rectangle2D.Double(0, 0, 5, 15);

 

        plot.setLegendItemShape(r2DD);

 

   /*StandardPieSectionLabelGenerator standardPieSectionLabelGenerator = new StandardPieSectionLabelGenerator(("{0}:{2}"),NumberFormat.getNumberInstance(), new DecimalFormat("0.0%"));

 

      plot.setLabelGenerator(standardPieSectionLabelGenerator);*/

 

  @SuppressWarnings("unchecked")

 

  List<String> key=dataset.getKeys();

 

  for (String string : key) {

 

   if(string.length()>maxSize){

 

    maxSize=string.length();

 

   }

 

  }

 

  

 

  PieSectionLabelGenerator labelGenerator = new StandardPieSectionLabelGenerator("{2}{1}{0}", new DecimalFormat("0.00"), new DecimalFormat("0%") ){

 

    private static final long serialVersionUID = 1L;

 

    @SuppressWarnings("rawtypes")

 

    @Override

 

          protected Object[] createItemArray(PieDataset dataset, Comparable key) {

 

              Object[] array = super.createItemArray(dataset, key);

 

              Object[] array1 = new Object[array.length];

 

              int count=0;

 

              for (Object object : array) {

 

               StringBuffer sss=new StringBuffer();

 

            if(count == 1){

 

            sss.append(object.toString());

 

               sss=charSpace(sss,object.toString().length(),9);

 

            }else if(count == 2){

 

            sss=charDigit(sss,object.toString().length(),5);

 

            sss.append(object.toString());

 

            if(object.toString().length()==2){

 

            sss=charSpaceDigit(sss,object.toString().length()+1,6);

 

            }

 

            else{

 

             sss=charSpace(sss,object.toString().length(),6);

 

            }

 

            }else if(count == 0){

 

             sss.append(object.toString().substring(0, 1).toUpperCase() + object.toString().substring(1,object.toString().length()).toLowerCase());

 

            }else{

 

             sss.append(object.toString());

 

            }

 

               array1[count] = sss.toString();

 

               count++;

 

     }

 

              return array1;

 

          }

 

      };

 

   plot.setLabelGenerator(null);

 

  //plot.setLabelGenerator(labelGenerator); //this is required if you need display inside circle your description otherwise put null

 

   plot.setLegendLabelGenerator(labelGenerator); //this is required to display legend label

 

  chart.setPadding(new RectangleInsets(-6, 0, 0, 20)); //this is required for right side of legend space

 

  chart.setBorderVisible(true);

 

  chart.setBorderPaint(Color.WHITE);

 

  chart.setBorderStroke(new BasicStroke(0.3f));

 

  return chart;

 

  }

 

    /**

 

     * Creates a panel for the demo (used by SuperDemo.java).

 

     *

 

     * @return A panel.

 

     */

 

    public static JPanel createDemoPanel() {

 

        JFreeChart chart = createChart(createDataset());

 

        try {

 

   ChartUtilities.writeChartAsPNG(new FileOutputStream(new File("D:\\sampleChart.png")) , chart, 400, 300);

 

  } catch (FileNotFoundException e) {

 

   e.printStackTrace();

 

  } catch (IOException e) {

 

   e.printStackTrace();

 

  }

 

        return new ChartPanel(chart);

 

    }

 

    private static RingPlot setSectionPaintColors(RingPlot plot) {

 

  List<?> listOfData = plot.getDataset().getKeys();

 

  String[] color = getColors();

 

  if (color != null && color.length > 0) {

 

   int count=0;

 

   for (Object string : listOfData) {

 

    plot.setSectionPaint((String)string,Color.decode(color[count]));

 

    count++;

 

   }

 

  }

 

  return plot;

 

 }

 

  private static String[] getColors() {

 

      String[] colors ={"#41f46e", "#f47f41", "#5b2a44","#DF0096","#CF0096","#EE0096","#BBCCCC","#4286f4"};

 

  return colors;

 

 }

 

 

 private static StringBuffer charSpace(StringBuffer sb,int datalength,int MaxSize){

 

  if(datalength==MaxSize){

 

   sb.append("  ");

 

   return sb;

 

  }else{

 

   sb.append("  ");

 

   return charSpace(sb,datalength+1,MaxSize);

 

  } 

 

 }

 

 private static StringBuffer charSpaceDigit(StringBuffer sb,int datalength,int MaxSize){

 

  if(datalength==MaxSize){

 

   sb.append("  ");

 

   return sb;

 

  }else{

 

   sb.append("  ");

 

   return charSpaceDigit(sb,datalength+1,MaxSize);

 

  }

 

 }

 

 private static StringBuffer charDigit(StringBuffer sb,int datalength,int MaxSize){

 

      if(datalength==2){

 

   sb.append("  ");

 

   return sb;

 

  }

 

  return sb; 

 

 }

 

 

 

    /**

 

     * Starting point for the demonstration application.

 

     *

 

     * @param args  ignored.

 

     */

 

    public static void main(String[] args) {

 

        PieChartDemo2 demo = new PieChartDemo2("Pie Chart Demo 1");

 

        demo.pack();

 

        RefineryUtilities.centerFrameOnScreen(demo);

 

        demo.setVisible(true);

 

    }

}

 

 

This class sets up the pie chart using JFreeChart and renders it using a dataset created with the DemoData class.

Key Features:

Ø  createDataset(): This method creates a pie dataset by using data from DemoData instances. The dataset is populated with values like "ONE", "TWO", etc., each with its respective data.

Ø  createChart(): This method builds the actual pie chart using a RingPlot, and it applies the CustomRingPlot for custom drawing.

ü  It configures the look of the pie chart, including section depth, legend placement, and colors for different sections.

ü  A custom label generator is used to space out the chart's sections and add specific formatting.

Ø  setSectionPaintColors(): This method applies custom colors to each section of the pie chart. Colors are fetched from a predefined array of hex color codes.

Ø  Main Method: The entry point for the application, where the pie chart is displayed in a Swing frame using ChartPanel and exported to a PNG file.

Enhancements and Customizations:

  1. Custom Labels and Center Text: The ring chart has text at its center ("Total Spendings"), with additional data displayed in the legend. This enhances the user interface, providing quick summary information.
  2. Color Customization: The pie chart sections are colored with custom colors for better visualization.
  3. Exporting Chart to PNG: The chart can be exported as a PNG file by saving it to disk using ChartUtilities.writeChartAsPNG().

If you have specific questions, feel free to let me know!

 



generate legend wise and custom pie chart
generate legend wise and custom pie chart

Post a Comment

0 Comments