All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jadex.tools.comanalyzer.chart.ChartMultiplePiePlot Maven / Gradle / Ivy

Go to download

The Jadex tools comanalyzer package contains the ComAnalyzer JCC plugin for observing the communication between Jadex components.

The newest version!
package jadex.tools.comanalyzer.chart;

import jadex.tools.comanalyzer.PaintMaps;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.LegendItem;
import org.jfree.chart.LegendItemCollection;
import org.jfree.chart.event.PlotChangeEvent;
import org.jfree.chart.labels.CategoryItemLabelGenerator;
import org.jfree.chart.labels.CategoryToolTipGenerator;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.DefaultDrawingSupplier;
import org.jfree.chart.plot.DrawingSupplier;
import org.jfree.chart.plot.MultiplePiePlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.PlotState;
import org.jfree.chart.urls.CategoryURLGenerator;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.CategoryToPieDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.general.PieDataset;
import org.jfree.ui.RectangleInsets;
import org.jfree.util.TableOrder;


/**
 * Subclass that implements the use of the paint maps for providing the
 * predefined shared colors for all tooltabs by overriding serveral methods. In
 * addition the use of label generators was introduced, cause the superclass
 * dont support that facility.
 */
public class ChartMultiplePiePlot extends MultiplePiePlot
{

	// -------- attributes --------

	/** The base item label generator. */
	private CategoryItemLabelGenerator baseItemLabelGenerator;

	/** The base tool tip generator. */
	private CategoryToolTipGenerator baseToolTipGenerator;

	/** The base item label generator. */
	private CategoryURLGenerator baseItemURLGenerator;

	/** The legend item label generator. */
	private CategoryItemLabelGenerator legendItemLabelGenerator;

	/** JFreeChart Sandard DrawingSupplier (Not used) */
	protected DrawingSupplier drawingSupplier;

	/** Supplies stored paint maps for the other distributions (e.g. performativ) */
	protected PaintMaps paintMaps;

	/** The type of distribution currently used */
	protected int paintMode;

	/** Stored paintMaps for sections. */
	protected Map sectionPaints;

	// -------- constructors --------

//	/**
//	 * Creates a new plot with no data.
//	 */
//	public ChartMultiplePiePlot(PaintMaps paintMaps)
//	{
//		this(null, paintMaps);
//
//	}

	/**
	 * Creates a new plot with a given dataset and paint maps.
	 * 
	 * @param dataset The dataset.
	 * @param paintMaps The paint maps..
	 */
	public ChartMultiplePiePlot(CategoryDataset dataset, PaintMaps paintMaps)
	{
		super(dataset);

		this.paintMaps = paintMaps;
		this.sectionPaints = new HashMap();
		this.drawingSupplier = new DefaultDrawingSupplier();

		this.baseItemLabelGenerator = new StandardCategoryItemLabelGenerator();
		this.legendItemLabelGenerator = new StandardCategoryItemLabelGenerator();

		// important: listen to change events from dataset
		dataset.addChangeListener(this);
	}

	// -------- ChartMultiplePiePlot methods --------

	/**
	 * Draws the plot on a Java 2D graphics device (such as the screen or a
	 * printer).
	 * 
	 * @param g2 the graphics device.
	 * @param area the area within which the plot should be drawn.
	 * @param anchor the anchor point (null permitted).
	 * @param parentState the state from the parent plot, if there is one.
	 * @param info collects info about the drawing.
	 */
	public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor, PlotState parentState, PlotRenderingInfo info)
	{

		// adjust the drawing area for the plot insets (if any)...
		RectangleInsets insets = getInsets();
		insets.trim(area);
		drawBackground(g2, area);
		drawOutline(g2, area);

		// check that there is some data to display...
		if(DatasetUtilities.isEmptyOrNull(getDataset()))
		{
			drawNoDataMessage(g2, area);
			return;
		}

		int pieCount = 0;
		if(getDataExtractOrder() == TableOrder.BY_ROW)
		{
			pieCount = getDataset().getRowCount();
		}
		else
		{
			pieCount = getDataset().getColumnCount();
		}

		// the columns variable is always >= rows
		int displayCols = (int)Math.ceil(Math.sqrt(pieCount));
		int displayRows = (int)Math.ceil((double)pieCount / (double)displayCols);

		// swap rows and columns to match plotArea shape
		if(displayCols > displayRows && area.getWidth() < area.getHeight())
		{
			int temp = displayCols;
			displayCols = displayRows;
			displayRows = temp;
		}

		prefetchSectionPaints();

		int x = (int)area.getX();
		int y = (int)area.getY();
		int width = ((int)area.getWidth()) / displayCols;
		int height = ((int)area.getHeight()) / displayRows;
		int row = 0;
		int column = 0;
		int diff = (displayRows * displayCols) - pieCount;
		int xoffset = 0;
		Rectangle rect = new Rectangle();

		for(int pieIndex = 0; pieIndex < pieCount; pieIndex++)
		{
			rect.setBounds(x + xoffset + (width * column), y + (height * row), width, height);

			String title = null;
			if(getDataExtractOrder() == TableOrder.BY_ROW)
			{
				title = getDataset().getRowKey(pieIndex).toString();
			}
			else
			{
				title = getDataset().getColumnKey(pieIndex).toString();
			}
			getPieChart().setTitle(title);

			PieDataset piedataset = null;
			PieDataset dd = new CategoryToPieDataset(getDataset(), getDataExtractOrder(), pieIndex);
			if(getLimit() > 0.0)
			{
				piedataset = DatasetUtilities.createConsolidatedPieDataset(dd, getAggregatedItemsKey(), getLimit());
			}
			else
			{
				piedataset = dd;
			}
			PiePlot piePlot = (PiePlot)getPieChart().getPlot();
			piePlot.setDataset(piedataset);
			piePlot.setPieIndex(pieIndex);

			// update the section colors to match the global colors...
			for(int i = 0; i < piedataset.getItemCount(); i++)
			{
				Comparable key = piedataset.getKey(i);
				Paint p;
				if(key.equals(getAggregatedItemsKey()))
				{
					p = getAggregatedItemsPaint();
				}
				else
				{
					p = (Paint)this.sectionPaints.get(key);
				}
				piePlot.setSectionPaint(key, p);
			}

			ChartRenderingInfo subinfo = null;
			if(info != null)
			{
				subinfo = new ChartRenderingInfo();
			}
			getPieChart().draw(g2, rect, subinfo);
			if(info != null)
			{
				info.getOwner().getEntityCollection().addAll(subinfo.getEntityCollection());
				info.addSubplotInfo(subinfo.getPlotInfo());
			}

			++column;
			if(column == displayCols)
			{
				column = 0;
				++row;

				if(row == displayRows - 1 && diff != 0)
				{
					xoffset = (diff * width) / 2;
				}
			}
		}

	}

	/**
	 * For each key in the dataset, check the sectionPaints cache
	 * to see if a paint is associated with that key and, if not, fetch one from
	 * the paint maps. These colors are cached so that the legend and all the
	 * subplots use consistent colors.
	 */
	private void prefetchSectionPaints()
	{

		// pre-fetch the colors for each key...this is because the subplots
		// may not display every key, but we need the coloring to be
		// consistent...

//		PiePlot piePlot = (PiePlot)getPieChart().getPlot();

		if(getDataExtractOrder() == TableOrder.BY_ROW)
		{
			// column keys provide potential keys for individual pies
			for(int c = 0; c < getDataset().getColumnCount(); c++)
			{
				Comparable key = getDataset().getColumnKey(c);
				Paint p = null; // piePlot.getSectionPaint(key);
				if(p == null)
				{
					p = (Paint)lookupSectionPaint(key);
					if(p == null)
					{
						p = getDrawingSupplier().getNextPaint();
					}
				}
				this.sectionPaints.put(key, p);

			}
		}
		else
		{
			// row keys provide potential keys for individual pies
			for(int r = 0; r < getDataset().getRowCount(); r++)
			{
				Comparable key = getDataset().getRowKey(r);
				Paint p = null; // piePlot.getSectionPaint(key);
				if(p == null)
				{
					p = (Paint)lookupSectionPaint(key);
					if(p == null)
					{
						p = getDrawingSupplier().getNextPaint();
					}
				}
				this.sectionPaints.put(key, p);

			}
		}

	}

	/**
	 * Returns a collection of legend items for the pie chart. The text for the
	 * labels is generated by the provided label generators
	 * 
	 * @return The legend items.
	 */
	public LegendItemCollection getLegendItems()
	{

		LegendItemCollection result = new LegendItemCollection();

		if(getDataset() != null)
		{
			List keys = null;

			prefetchSectionPaints();
			if(getDataExtractOrder() == TableOrder.BY_ROW)
			{
				keys = getDataset().getColumnKeys();
			}
			else if(getDataExtractOrder() == TableOrder.BY_COLUMN)
			{
				keys = getDataset().getRowKeys();
			}

			if(keys != null)
			{
//				int section = 0;
				Iterator iterator = keys.iterator();
				while(iterator.hasNext())
				{
					Comparable key = (Comparable)iterator.next();
					String label = null;

					// Use legend label generator !!!
					if(getDataExtractOrder() == TableOrder.BY_COLUMN)
					{
						int row = getDataset().getRowIndex(key);
						label = getLegendItemLabelGenerator().generateRowLabel(getDataset(), row);
					}
					else if(getDataExtractOrder() == TableOrder.BY_ROW)
					{
						int column = getDataset().getColumnIndex(key);
						label = getLegendItemLabelGenerator().generateColumnLabel(getDataset(), column);
					}

					if(label != null)
					{
						String description = label;
						Paint paint = (Paint)sectionPaints.get(key);
						LegendItem item = new LegendItem(label, description, null, null, Plot.DEFAULT_LEGEND_ITEM_CIRCLE, paint, Plot.DEFAULT_OUTLINE_STROKE, paint);
						item.setDataset(getDataset());
						result.add(item);
					}

//					section++;
				}
			}
			if(getLimit() > 0.0)
			{
				result.add(new LegendItem(getAggregatedItemsKey().toString(), getAggregatedItemsKey().toString(), null, null, Plot.DEFAULT_LEGEND_ITEM_CIRCLE, getAggregatedItemsPaint(),
						Plot.DEFAULT_OUTLINE_STROKE, getAggregatedItemsPaint()));
			}
		}
		return result;
	}

	/**
	 * Returns the paint for the specified key from the paint maps.
	 * 
	 * @param key The key.
	 * 
	 * @return The paint.
	 */
	protected Paint lookupSectionPaint(Comparable key)
	{
		// return the paint defined for the specified key
		// dont use black as default for unknown values
		return paintMaps.getPaint(key, paintMode, Color.LIGHT_GRAY);
	}

	// -------- setter and getter --------

	/**
	 * @return The pieplot from the piechart.
	 */
	public PiePlot getPiePlot()
	{
		return (PiePlot)getPieChart().getPlot();
	}

	/**
	 * @return The paint mode.
	 */
	public int getPaintMode()
	{
		return paintMode;
	}

	/**
	 * @param paintMode The paint mode to set.
	 */
	public void setPaintMode(int paintMode)
	{
		this.paintMode = paintMode;
		// clear paintMaps and use a new "reset" drawing supplier
		this.sectionPaints.clear();
		this.drawingSupplier = new DefaultDrawingSupplier();
	}

	/**
	 * @return The BaseItemLabelGenerator.
	 */
	public CategoryItemLabelGenerator getBaseItemLabelGenerator()
	{
		return baseItemLabelGenerator;
	}

	/**
	 * @param baseItemLabelGenerator The BaseItemLabelGenerator to set.
	 */
	public void setBaseItemLabelGenerator(CategoryItemLabelGenerator baseItemLabelGenerator)
	{
		this.baseItemLabelGenerator = baseItemLabelGenerator;
		notifyListeners(new PlotChangeEvent(this));
	}

	/**
	 * @return The BaseItemURLGenerator.
	 */
	public CategoryURLGenerator getBaseItemURLGenerator()
	{
		return baseItemURLGenerator;
	}

	/**
	 * @param baseItemURLGenerator The BaseItemURLGenerator to set.
	 */
	public void setBaseItemURLGenerator(CategoryURLGenerator baseItemURLGenerator)
	{
		this.baseItemURLGenerator = baseItemURLGenerator;
		notifyListeners(new PlotChangeEvent(this));
	}

	/**
	 * @return The BaseToolTipGenerator.
	 */
	public CategoryToolTipGenerator getBaseToolTipGenerator()
	{
		return baseToolTipGenerator;
	}

	/**
	 * @param baseToolTipGenerator The BaseToolTipGenerator to set.
	 */
	public void setBaseToolTipGenerator(CategoryToolTipGenerator baseToolTipGenerator)
	{
		this.baseToolTipGenerator = baseToolTipGenerator;
		notifyListeners(new PlotChangeEvent(this));
	}

	/**
	 * @return The LegendItemLabelGenerator.
	 */
	public CategoryItemLabelGenerator getLegendItemLabelGenerator()
	{
		return legendItemLabelGenerator;
	}

	/**
	 * @param legendItemLabelGenerator The LegendItemLabelGenerator to set.
	 */
	public void setLegendItemLabelGenerator(CategoryItemLabelGenerator legendItemLabelGenerator)
	{
		this.legendItemLabelGenerator = legendItemLabelGenerator;
		notifyListeners(new PlotChangeEvent(this));
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy