
// StackedBarChartExample.java
// http://www.java2s.com/Code/Java/Chart/JFreeChartStackedBarChartDemo4.htm
// Modified by Andrew Davison, ad@coe.psu.ac.th, Nov 2022

/* Draws three groups, each group made up of three stacked bars.
   Each stack is made up of four pieces of data, each colored separately. 

    Usage:
      > compile StackedBarChartExample.java
      > run StackedBarChartExample
*/

import java.awt.*;
import javax.swing.*;

import org.jfree.chart.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.renderer.category.*;

import org.jfree.data.*;
import org.jfree.data.category.*;

import org.jfree.chart.ui.*;



public class StackedBarChartExample extends JFrame
{

  public StackedBarChartExample()
  {
    super("Stacked Bar Chart Example");

    CategoryDataset ds = createDataset();
    JFreeChart chart = createChart(ds);

    ChartPanel cp = new ChartPanel(chart);
    setContentPane(cp);

    // pack();
    setSize(800, 400);
    setResizable(false);
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setVisible(true);
  }  // end of StackedBarChartExample()


  private CategoryDataset createDataset()
  /* There are three groups: Jan 22, Feb 22, Mar 22.

     Each group is made up of three bars: Product 1, 2, 3.

     Each bar is a stack of four colors representing the
     US, Europe, Asia, and Middle East. 

     The stacked data uses the row key format: <product>(<country>)
  */
  {
    DefaultCategoryDataset ds = new DefaultCategoryDataset();

    // value, row key, column key
    // -------- row key: product 1; all countries ---------------
    ds.addValue(20.3, "Product 1 (US)", "Jan 22"); 
    ds.addValue(27.2, "Product 1 (US)", "Feb 22");
    ds.addValue(19.7, "Product 1 (US)", "Mar 22");
    ds.addValue(19.4, "Product 1 (Europe)", "Jan 22");
    ds.addValue(10.9, "Product 1 (Europe)", "Feb 22");
    ds.addValue(18.4, "Product 1 (Europe)", "Mar 22");
    ds.addValue(16.5, "Product 1 (Asia)", "Jan 22");
    ds.addValue(15.9, "Product 1 (Asia)", "Feb 22");
    ds.addValue(16.1, "Product 1 (Asia)", "Mar 22");
    ds.addValue(13.2, "Product 1 (Middle East)", "Jan 22");
    ds.addValue(14.4, "Product 1 (Middle East)", "Feb 22");
    ds.addValue(13.7, "Product 1 (Middle East)", "Mar 22");

    // -------- row key: product 2; all countries ---------------
    ds.addValue(23.3, "Product 2 (US)", "Jan 22");
    ds.addValue(16.2, "Product 2 (US)", "Feb 22");
    ds.addValue(28.7, "Product 2 (US)", "Mar 22");

    ds.addValue(12.7, "Product 2 (Europe)", "Jan 22");
    ds.addValue(17.9, "Product 2 (Europe)", "Feb 22");
    ds.addValue(12.6, "Product 2 (Europe)", "Mar 22");

    ds.addValue(15.4, "Product 2 (Asia)", "Jan 22");
    ds.addValue(21.0, "Product 2 (Asia)", "Feb 22");
    ds.addValue(11.1, "Product 2 (Asia)", "Mar 22");

    ds.addValue(23.8, "Product 2 (Middle East)", "Jan 22");
    ds.addValue(23.4, "Product 2 (Middle East)", "Feb 22");
    ds.addValue(19.3, "Product 2 (Middle East)", "Mar 22");

    // -------- row key: product 3; all countries ---------------
    ds.addValue(11.9, "Product 3 (US)", "Jan 22");
    ds.addValue(31.0, "Product 3 (US)", "Feb 22");
    ds.addValue(22.7, "Product 3 (US)", "Mar 22");

    ds.addValue(15.3, "Product 3 (Europe)", "Jan 22");
    ds.addValue(14.4, "Product 3 (Europe)", "Feb 22");
    ds.addValue(25.3, "Product 3 (Europe)", "Mar 22");

    ds.addValue(23.9, "Product 3 (Asia)", "Jan 22");
    ds.addValue(19.0, "Product 3 (Asia)", "Feb 22");
    ds.addValue(10.1, "Product 3 (Asia)", "Mar 22");

    ds.addValue(13.2, "Product 3 (Middle East)", "Jan 22");
    ds.addValue(15.5, "Product 3 (Middle East)", "Feb 22");
    ds.addValue(10.1, "Product 3 (Middle East)", "Mar 22");

    return ds;
  } /* createDataset */


  private JFreeChart createChart(CategoryDataset ds)
  {
    JFreeChart chart = ChartFactory.createStackedBarChart(
              "Stacked Bar Chart Example", "Category", "Value", ds);

    GroupedStackedBarRenderer rend = new GroupedStackedBarRenderer();

    KeyToGroupMap map = new KeyToGroupMap("G1");  // map keys --> groups
    map.mapKeyToGroup("Product 1 (US)", "G1");
    map.mapKeyToGroup("Product 1 (Europe)", "G1");
    map.mapKeyToGroup("Product 1 (Asia)", "G1");
    map.mapKeyToGroup("Product 1 (Middle East)", "G1");

    map.mapKeyToGroup("Product 2 (US)", "G2");
    map.mapKeyToGroup("Product 2 (Europe)", "G2");
    map.mapKeyToGroup("Product 2 (Asia)", "G2");
    map.mapKeyToGroup("Product 2 (Middle East)", "G2");

    map.mapKeyToGroup("Product 3 (US)", "G3");
    map.mapKeyToGroup("Product 3 (Europe)", "G3");
    map.mapKeyToGroup("Product 3 (Asia)", "G3");
    map.mapKeyToGroup("Product 3 (Middle East)", "G3");

    rend.setSeriesToGroupMap(map);

    rend.setItemMargin(0.1);   // space between bars in a group
    rend.setBarPainter(new StandardBarPainter());  // bars are solid colors
    rend.setDrawBarOutline(false);
    rend.setShadowVisible(false);

    // specifies the color of the stacks making up a single group
    /* the group here has 3 bars, each with 4 colors, so the
       indicies are 0-11
    */
    rend.setSeriesPaint(0, Color.RED);
    rend.setSeriesPaint(4, Color.RED);
    rend.setSeriesPaint(8, Color.RED);

    rend.setSeriesPaint(1, Color.GREEN);
    rend.setSeriesPaint(5, Color.GREEN);
    rend.setSeriesPaint(9, Color.GREEN);

    rend.setSeriesPaint(2, Color.BLUE);
    rend.setSeriesPaint(6, Color.BLUE);
    rend.setSeriesPaint(10, Color.BLUE);

    rend.setSeriesPaint(3, Color.ORANGE);
    rend.setSeriesPaint(7, Color.ORANGE);
    rend.setSeriesPaint(11, Color.ORANGE);

    SubCategoryAxis domainAxis = new SubCategoryAxis("Product / Month");
    domainAxis.setCategoryMargin(0.2);   // space between bar groups
    domainAxis.addSubCategory("Product 1");  // label each bar in a group
    domainAxis.addSubCategory("Product 2");
    domainAxis.addSubCategory("Product 3");

    CategoryPlot plot = (CategoryPlot) chart.getPlot();
    plot.setDomainAxis(domainAxis);
    plot.setRenderer(rend);
    plot.setFixedLegendItems(createLegendItems());

    return chart;
  } /* createChart */


  private LegendItemCollection createLegendItems()
  // only want legend items for the stack colors
  {
    LegendItemCollection ds = new LegendItemCollection();

    ds.add( new LegendItem("US", Color.RED));
    ds.add( new LegendItem("Europe", Color.GREEN));
    ds.add( new LegendItem("Asia", Color.BLUE));
    ds.add( new LegendItem("Middle East", Color.ORANGE));

    return ds;
  } /* createLegendItems */


  // --------------------------------------------------

  public static void main(String[] args)
  {  new StackedBarChartExample(); } 


}  // end of StackedBarChartExample class