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