franta-hg@1: /* ================================================================
franta-hg@1: * Cewolf : Chart enabling Web Objects Framework
franta-hg@1: * ================================================================
franta-hg@1: *
franta-hg@1: * Project Info: http://cewolf.sourceforge.net
franta-hg@1: * Project Lead: Guido Laures (guido@laures.de);
franta-hg@1: *
franta-hg@1: * (C) Copyright 2002, by Guido Laures
franta-hg@1: *
franta-hg@1: * This library is free software; you can redistribute it and/or modify it under the terms
franta-hg@1: * of the GNU Lesser General Public License as published by the Free Software Foundation;
franta-hg@1: * either version 2.1 of the License, or (at your option) any later version.
franta-hg@1: *
franta-hg@1: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
franta-hg@1: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
franta-hg@1: * See the GNU Lesser General Public License for more details.
franta-hg@1: *
franta-hg@1: * You should have received a copy of the GNU Lesser General Public License along with this
franta-hg@1: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
franta-hg@1: * Boston, MA 02111-1307, USA.
franta-hg@1: */
franta-hg@1:
franta-hg@1: package de.laures.cewolf.taglib;
franta-hg@1:
franta-hg@1: import java.util.HashMap;
franta-hg@1: import java.util.List;
franta-hg@1: import java.util.Map;
franta-hg@1:
franta-hg@1: import org.jfree.chart.ChartFactory;
franta-hg@1: import org.jfree.chart.JFreeChart;
franta-hg@1: import org.jfree.chart.axis.CategoryAxis;
franta-hg@1: import org.jfree.chart.axis.DateAxis;
franta-hg@1: import org.jfree.chart.axis.NumberAxis;
franta-hg@1: import org.jfree.chart.axis.ValueAxis;
franta-hg@1: import org.jfree.chart.plot.CategoryPlot;
franta-hg@1: import org.jfree.chart.plot.CombinedDomainXYPlot;
franta-hg@1: import org.jfree.chart.plot.CombinedRangeXYPlot;
franta-hg@1: import org.jfree.chart.plot.MeterPlot;
franta-hg@1: import org.jfree.chart.plot.Plot;
franta-hg@1: import org.jfree.chart.plot.PlotOrientation;
franta-hg@1: import org.jfree.chart.plot.XYPlot;
franta-hg@1: import org.jfree.chart.renderer.category.CategoryItemRenderer;
franta-hg@1: import org.jfree.chart.renderer.xy.XYItemRenderer;
franta-hg@1: import org.jfree.data.category.CategoryDataset;
franta-hg@1: import org.jfree.data.category.IntervalCategoryDataset;
franta-hg@1: import org.jfree.data.general.Dataset;
franta-hg@1: import org.jfree.data.general.PieDataset;
franta-hg@1: import org.jfree.data.general.ValueDataset;
franta-hg@1: import org.jfree.data.xy.IntervalXYDataset;
franta-hg@1: import org.jfree.data.xy.OHLCDataset;
franta-hg@1: import org.jfree.data.xy.WindDataset;
franta-hg@1: import org.jfree.data.xy.XYDataset;
franta-hg@1: import org.jfree.data.xy.XYZDataset;
franta-hg@1:
franta-hg@1: import de.laures.cewolf.ChartValidationException;
franta-hg@1: import de.laures.cewolf.DatasetProduceException;
franta-hg@1:
franta-hg@1: /**
franta-hg@1: * Chart factory creates Jfreechart instances. To add a new factory use the
franta-hg@1: *
franta-hg@1: * CewolfChartFactory.registerFactory(new CewolfChartFactory() {...});
franta-hg@1: *
franta-hg@1: * method.
franta-hg@1: *
franta-hg@1: * @author Guido Laures
franta-hg@1: */
franta-hg@1: public abstract class CewolfChartFactory implements ChartConstants, AxisConstants, LayoutConstants {
franta-hg@1:
franta-hg@1: // chart type string
franta-hg@1: protected String chartType;
franta-hg@1: // map contains registered factories, (String) chartType->CewolfChartFactory mappings
franta-hg@1: private static Map factories = new HashMap();
franta-hg@1:
franta-hg@1: /** Creates a new instance of ChartFactory */
franta-hg@1: protected CewolfChartFactory(String chartType) {
franta-hg@1: this.chartType = chartType;
franta-hg@1: }
franta-hg@1:
franta-hg@1: /**
franta-hg@1: * Callback when the chart instance to be created.
franta-hg@1: * @param title The title of chart
franta-hg@1: * @param xAxisLabel label on x axis
franta-hg@1: * @param yAxisLabel label on y axis
franta-hg@1: * @param data The dataset to create chart for
franta-hg@1: * @return The newly created JFreeChart instance
franta-hg@1: *
franta-hg@1: * @throws IncompatibleDatasetException If the incoming data is not compatible with this factory
franta-hg@1: */
franta-hg@1: public abstract JFreeChart getChartInstance(String title, String xAxisLabel, String yAxisLabel, Dataset data) throws IncompatibleDatasetException;
franta-hg@1:
franta-hg@1: //////////////// static part ///////////////////////
franta-hg@1:
franta-hg@1: /**
franta-hg@1: * Register a new chart factory instance.
franta-hg@1: * @param factory The factory to register
franta-hg@1: */
franta-hg@1: public static void registerFactory(CewolfChartFactory factory) {
franta-hg@1: factories.put(factory.chartType, factory);
franta-hg@1: }
franta-hg@1:
franta-hg@1: private static final int getChartTypeConstant(String type) {
franta-hg@1: final int res = ChartTypes.typeList.indexOf(type.toLowerCase());
franta-hg@1: if (res < 0) {
franta-hg@1: throw new RuntimeException("unsupported chart type " + type);
franta-hg@1: }
franta-hg@1: return res;
franta-hg@1: }
franta-hg@1:
franta-hg@1: private static final int getLayoutConstant(String layout) {
franta-hg@1: return LayoutTypes.typeList.indexOf(layout.toLowerCase());
franta-hg@1: }
franta-hg@1:
franta-hg@1: static {
franta-hg@1: // histogram chart type
franta-hg@1: registerFactory(new CewolfChartFactory("histogram") {
franta-hg@1: public JFreeChart getChartInstance(String title, String xAxisLabel, String yAxisLabel, Dataset data) throws IncompatibleDatasetException {
franta-hg@1: check(data, IntervalXYDataset.class, this.chartType);
franta-hg@1: return ChartFactory.createHistogram(title, xAxisLabel, yAxisLabel, (IntervalXYDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: }
franta-hg@1: });
franta-hg@1: }
franta-hg@1:
franta-hg@1: public static JFreeChart getChartInstance(String chartType, String title, String xAxisLabel, String yAxisLabel, Dataset data) throws ChartValidationException {
franta-hg@1: // first check the dynamically registered chart types
franta-hg@1: CewolfChartFactory factory = (CewolfChartFactory) factories.get(chartType);
franta-hg@1: if (factory != null) {
franta-hg@1: // custom factory found, use it
franta-hg@1: return factory.getChartInstance(title, xAxisLabel, yAxisLabel, data);
franta-hg@1: }
franta-hg@1:
franta-hg@1: switch (getChartTypeConstant(chartType)) {
franta-hg@1: case XY :
franta-hg@1: check(data, XYDataset.class, chartType);
franta-hg@1: return ChartFactory.createXYLineChart(title, xAxisLabel, yAxisLabel, (XYDataset) data, PlotOrientation.VERTICAL, true, true, true);
franta-hg@1: case PIE :
franta-hg@1: check(data, PieDataset.class, chartType);
franta-hg@1: return ChartFactory.createPieChart(title, (PieDataset) data, true, true, true);
franta-hg@1: case AREA_XY :
franta-hg@1: check(data, XYDataset.class, chartType);
franta-hg@1: return ChartFactory.createXYAreaChart(title, xAxisLabel, yAxisLabel, (XYDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: case SCATTER :
franta-hg@1: check(data, XYDataset.class, chartType);
franta-hg@1: return ChartFactory.createScatterPlot(title, xAxisLabel, yAxisLabel, (XYDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: case AREA :
franta-hg@1: check(data, CategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createAreaChart(title, xAxisLabel, yAxisLabel, (CategoryDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: case HORIZONTAL_BAR :
franta-hg@1: check(data, CategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createBarChart(title, xAxisLabel, yAxisLabel, (CategoryDataset) data, PlotOrientation.HORIZONTAL, true, false, false);
franta-hg@1: case HORIZONTAL_BAR_3D :
franta-hg@1: check(data, CategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createBarChart3D(title, xAxisLabel, yAxisLabel, (CategoryDataset) data, PlotOrientation.HORIZONTAL, true, false, false);
franta-hg@1: case LINE :
franta-hg@1: check(data, CategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createLineChart(title, xAxisLabel, yAxisLabel, (CategoryDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: case STACKED_HORIZONTAL_BAR :
franta-hg@1: check(data, CategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createStackedBarChart(title, xAxisLabel, yAxisLabel, (CategoryDataset) data, PlotOrientation.HORIZONTAL, true, false, false);
franta-hg@1: case STACKED_VERTICAL_BAR :
franta-hg@1: check(data, CategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createStackedBarChart(title, xAxisLabel, yAxisLabel, (CategoryDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: case STACKED_VERTICAL_BAR_3D :
franta-hg@1: check(data, CategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createStackedBarChart3D(title, xAxisLabel, yAxisLabel, (CategoryDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: case VERTICAL_BAR :
franta-hg@1: check(data, CategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createBarChart(title, xAxisLabel, yAxisLabel, (CategoryDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: case VERTICAL_BAR_3D :
franta-hg@1: check(data, CategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createBarChart3D(title, xAxisLabel, yAxisLabel, (CategoryDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: case TIME_SERIES :
franta-hg@1: check(data, XYDataset.class, chartType);
franta-hg@1: return ChartFactory.createTimeSeriesChart(title, xAxisLabel, yAxisLabel, (XYDataset) data, true, false, false);
franta-hg@1: case CANDLE_STICK :
franta-hg@1: check(data, OHLCDataset.class, chartType);
franta-hg@1: return ChartFactory.createCandlestickChart(title, xAxisLabel, yAxisLabel, (OHLCDataset) data, true);
franta-hg@1: case HIGH_LOW :
franta-hg@1: check(data, OHLCDataset.class, chartType);
franta-hg@1: return ChartFactory.createHighLowChart(title, xAxisLabel, yAxisLabel, (OHLCDataset) data, true);
franta-hg@1: case GANTT :
franta-hg@1: check(data, IntervalCategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createGanttChart(title, xAxisLabel, yAxisLabel, (IntervalCategoryDataset) data, true, false, false);
franta-hg@1: case WIND :
franta-hg@1: check(data, WindDataset.class, chartType);
franta-hg@1: return ChartFactory.createWindPlot(title, xAxisLabel, yAxisLabel, (WindDataset) data, true, false, false);
franta-hg@1: //case SIGNAL :
franta-hg@1: // check(data, SignalsDataset.class, chartType);
franta-hg@1: // return ChartFactory.createSignalChart(title, xAxisLabel, yAxisLabel, (SignalsDataset) data, true);
franta-hg@1: case VERRTICAL_XY_BAR :
franta-hg@1: check(data, IntervalXYDataset.class, chartType);
franta-hg@1: return ChartFactory.createXYBarChart(title, xAxisLabel, true,yAxisLabel, (IntervalXYDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: case PIE_3D :
franta-hg@1: check(data, PieDataset.class, chartType);
franta-hg@1: return ChartFactory.createPieChart3D(title, (PieDataset) data, true, false, false);
franta-hg@1: case METER :
franta-hg@1: check(data, ValueDataset.class, chartType);
franta-hg@1: MeterPlot plot = new MeterPlot((ValueDataset) data);
franta-hg@1: JFreeChart chart = new JFreeChart(title, plot);
franta-hg@1: return chart;
franta-hg@1: case STACKED_AREA :
franta-hg@1: check(data, CategoryDataset.class, chartType);
franta-hg@1: return ChartFactory.createStackedAreaChart(title, xAxisLabel, yAxisLabel, (CategoryDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: case BUBBLE :
franta-hg@1: check(data, XYZDataset.class, chartType);
franta-hg@1: return ChartFactory.createBubbleChart(title, xAxisLabel, yAxisLabel, (XYZDataset) data, PlotOrientation.VERTICAL, true, false, false);
franta-hg@1: default :
franta-hg@1: throw new UnsupportedChartTypeException(chartType + " is not supported.");
franta-hg@1: }
franta-hg@1: }
franta-hg@1:
franta-hg@1: public static JFreeChart getOverlaidChartInstance(String chartType, String title, String xAxisLabel, String yAxisLabel, int xAxisType, int yAxisType, List plotDefinitions)
franta-hg@1: throws ChartValidationException, DatasetProduceException {
franta-hg@1: final int chartTypeConst = getChartTypeConstant(chartType);
franta-hg@1: final AxisFactory axisFactory = AxisFactory.getInstance();
franta-hg@1: switch (chartTypeConst) {
franta-hg@1: case OVERLAY_XY :
franta-hg@1: ValueAxis domainAxis = (ValueAxis) axisFactory.createAxis(ORIENTATION_HORIZONTAL, xAxisType, xAxisLabel);
franta-hg@1: // get main plot
franta-hg@1: PlotDefinition mainPlotDef = (PlotDefinition) plotDefinitions.get(0);
franta-hg@1: check((Dataset) mainPlotDef.getDataset(), XYDataset.class, chartType);
franta-hg@1: XYPlot plot = (XYPlot) mainPlotDef.getPlot(chartTypeConst);
franta-hg@1: plot.setDomainAxis(domainAxis);
franta-hg@1: plot.setRangeAxis((ValueAxis) axisFactory.createAxis(ORIENTATION_VERTICAL, yAxisType, yAxisLabel));
franta-hg@1: //plot.setRenderer(new StandardXYItemRenderer());
franta-hg@1: // add second and later datasets to main plot
franta-hg@1: for (int plotidx = 1;plotidx