0001: /*
0002: * Copyright 2006 Pentaho Corporation. All rights reserved.
0003: * This software was developed by Pentaho Corporation and is provided under the terms
0004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
0005: * this file except in compliance with the license. If you need a copy of the license,
0006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
0007: * BI Platform. The Initial Developer is Pentaho Corporation.
0008: *
0009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
0010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
0011: * the license for the specific language governing your rights and limitations.
0012: *
0013: * @created Aug 15, 2005
0014: * @author James Dixon
0015: *
0016: */
0017:
0018: package org.pentaho.plugin.jfreechart;
0019:
0020: import java.awt.BasicStroke;
0021: import java.awt.Color;
0022: import java.awt.Font;
0023: import java.awt.GradientPaint;
0024: import java.awt.Image;
0025: import java.awt.Paint;
0026: import java.awt.Stroke;
0027: import java.awt.TexturePaint;
0028: import java.awt.geom.Rectangle2D;
0029: import java.awt.image.BufferedImage;
0030: import java.io.File;
0031: import java.io.FileOutputStream;
0032: import java.io.IOException;
0033: import java.io.InputStream;
0034: import java.io.OutputStreamWriter;
0035: import java.io.PrintWriter;
0036: import java.io.Writer;
0037: import java.text.DecimalFormat;
0038: import java.text.SimpleDateFormat;
0039: import java.util.Iterator;
0040: import java.util.List;
0041: import java.util.TimeZone;
0042:
0043: import javax.imageio.ImageIO;
0044:
0045: import org.apache.batik.dom.GenericDOMImplementation;
0046: import org.apache.batik.svggen.SVGGraphics2D;
0047: import org.dom4j.Node;
0048: import org.jfree.chart.ChartRenderingInfo;
0049: import org.jfree.chart.ChartUtilities;
0050: import org.jfree.chart.JFreeChart;
0051: import org.jfree.chart.axis.AxisLocation;
0052: import org.jfree.chart.axis.CategoryAxis;
0053: import org.jfree.chart.axis.DateAxis;
0054: import org.jfree.chart.axis.NumberAxis;
0055: import org.jfree.chart.axis.NumberAxis3D;
0056: import org.jfree.chart.axis.ValueAxis;
0057: import org.jfree.chart.block.BlockBorder;
0058: import org.jfree.chart.labels.ItemLabelAnchor;
0059: import org.jfree.chart.labels.ItemLabelPosition;
0060: import org.jfree.chart.labels.PieToolTipGenerator;
0061: import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
0062: import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
0063: import org.jfree.chart.labels.StandardPieToolTipGenerator;
0064: import org.jfree.chart.labels.StandardXYToolTipGenerator;
0065: import org.jfree.chart.labels.StandardXYZToolTipGenerator;
0066: import org.jfree.chart.labels.XYToolTipGenerator;
0067: import org.jfree.chart.plot.CategoryPlot;
0068: import org.jfree.chart.plot.DatasetRenderingOrder;
0069: import org.jfree.chart.plot.DefaultDrawingSupplier;
0070: import org.jfree.chart.plot.MeterInterval;
0071: import org.jfree.chart.plot.MeterPlot;
0072: import org.jfree.chart.plot.MultiplePiePlot;
0073: import org.jfree.chart.plot.PiePlot;
0074: import org.jfree.chart.plot.PiePlot3D;
0075: import org.jfree.chart.plot.Plot;
0076: import org.jfree.chart.plot.PlotOrientation;
0077: import org.jfree.chart.plot.XYPlot;
0078: import org.jfree.chart.renderer.category.AreaRenderer;
0079: import org.jfree.chart.renderer.category.BarRenderer;
0080: import org.jfree.chart.renderer.category.BarRenderer3D;
0081: import org.jfree.chart.renderer.category.LineAndShapeRenderer;
0082: import org.jfree.chart.renderer.category.LineRenderer3D;
0083: import org.jfree.chart.renderer.category.StackedAreaRenderer;
0084: import org.jfree.chart.renderer.category.StackedBarRenderer;
0085: import org.jfree.chart.renderer.category.StackedBarRenderer3D;
0086: import org.jfree.chart.renderer.xy.StackedXYAreaRenderer;
0087: import org.jfree.chart.renderer.xy.XYAreaRenderer;
0088: import org.jfree.chart.renderer.xy.XYDifferenceRenderer;
0089: import org.jfree.chart.renderer.xy.XYDotRenderer;
0090: import org.jfree.chart.renderer.xy.XYItemRenderer;
0091: import org.jfree.chart.renderer.xy.XYLine3DRenderer;
0092: import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
0093: import org.jfree.chart.renderer.xy.XYStepAreaRenderer;
0094: import org.jfree.chart.renderer.xy.XYStepRenderer;
0095: import org.jfree.chart.title.TextTitle;
0096: import org.jfree.chart.urls.PieURLGenerator;
0097: import org.jfree.chart.urls.StandardCategoryURLGenerator;
0098: import org.jfree.chart.urls.StandardPieURLGenerator;
0099: import org.jfree.chart.urls.StandardXYURLGenerator;
0100: import org.jfree.data.Range;
0101: import org.jfree.data.general.Dataset;
0102: import org.jfree.ui.RectangleEdge;
0103: import org.jfree.ui.TextAnchor;
0104: import org.jfree.util.TableOrder;
0105: import org.pentaho.core.repository.ISolutionRepository;
0106: import org.pentaho.core.session.IPentahoSession;
0107: import org.pentaho.core.system.PentahoSystem;
0108: import org.pentaho.messages.Messages;
0109: import org.pentaho.messages.util.LocaleHelper;
0110: import org.pentaho.util.logging.ILogger;
0111: import org.w3c.dom.Document;
0112:
0113: public class JFreeChartEngine {
0114:
0115: public static final int OUTPUT_CHART = 3;
0116:
0117: public static final int OUTPUT_PNG = 1;
0118:
0119: public static final int OUTPUT_SVG = 2;
0120:
0121: public static final int OUTPUT_PNG_BYTES = 4;
0122:
0123: // Node names
0124: private static final String X1_NODE_NAME = "x1"; //$NON-NLS-1$
0125:
0126: private static final String Y1_NODE_NAME = "y1"; //$NON-NLS-1$
0127:
0128: private static final String X2_NODE_NAME = "x2"; //$NON-NLS-1$
0129:
0130: private static final String Y2_NODE_NAME = "y2"; //$NON-NLS-1$
0131:
0132: private static final String COLOR1_NODE_NAME = "color1"; //$NON-NLS-1$
0133:
0134: private static final String COLOR2_NODE_NAME = "color2"; //$NON-NLS-1$
0135:
0136: private static final String CYCLIC_NODE_NAME = "cyclic"; //$NON-NLS-1$
0137:
0138: private static final String TEXTURE_IMAGE_NODE_NAME = "texture-image"; //$NON-NLS-1$
0139:
0140: private static final String FONT_FAMILY_NODE_NAME = "font-family"; //$NON-NLS-1$
0141:
0142: private static final String SIZE_NODE_NAME = "size"; //$NON-NLS-1$
0143:
0144: private static final String IS_ITALIC_NODE_NAME = "is-italic"; //$NON-NLS-1$
0145:
0146: private static final String IS_BOLD_NODE_NAME = "is-bold"; //$NON-NLS-1$
0147:
0148: public static final int UNDEFINED_CHART_TYPE = -1;
0149:
0150: public static final int DIAL_CHART_TYPE = 0;
0151:
0152: public static final int THERMOMETER_CHART_TYPE = 1;
0153:
0154: public static final int PIE_CHART_TYPE = 2;
0155:
0156: public static final int PIE_GRID_CHART_TYPE = 3;
0157:
0158: public static final int BAR_CHART_TYPE = 4;
0159:
0160: public static final int LINE_CHART_TYPE = 5;
0161:
0162: public static final int AREA_CHART_TYPE = 6;
0163:
0164: public static final int STEP_CHART_TYPE = 7;
0165:
0166: public static final int STEP_AREA_CHART_TYPE = 8;
0167:
0168: public static final int DIFFERENCE_CHART_TYPE = 9;
0169:
0170: public static final int DOT_CHART_TYPE = 10;
0171:
0172: //new chart types
0173: public static final int BAR_LINE_CHART_TYPE = 11;
0174:
0175: public static final int BUBBLE_CHART_TYPE = 12;
0176:
0177: // end new chart type
0178:
0179: /**
0180: * Creates a JFreeChart object from a dial definition object. All of the
0181: * settings for the dial image are defined by the dial definition.
0182: *
0183: * @param widget
0184: * The dial definition object.
0185: * @param title
0186: * The dial title.
0187: * @param units
0188: * The dial units
0189: * @return A JFreeChart object for the dial
0190: */
0191: private static JFreeChart createDial(DialWidgetDefinition widget,
0192: String title, String units) {
0193: MeterPlot meter = new MeterPlot(widget);
0194:
0195: updatePlot(meter, widget);
0196: meter.setUnits(units);
0197:
0198: meter.setValuePaint(widget.getValuePaint());
0199: meter.setTickPaint(widget.getTickPaint());
0200: int tickSize = widget.getTickSize();
0201: if (tickSize == 0) {
0202: meter.setTickLabelsVisible(false);
0203: } else {
0204: meter.setTickLabelsVisible(true);
0205: meter.setTickSize(tickSize);
0206: }
0207: if (widget.getValueFont() != null) {
0208: meter.setValueFont(widget.getValueFont());
0209: } else {
0210: meter.setValuePaint(getTransparent());
0211: }
0212: // TODO support title fonts in the definition
0213: Font titleFont = widget.getTitleFont();
0214:
0215: JFreeChart chart = new JFreeChart(title, titleFont, meter,
0216: false);
0217:
0218: // TODO support any other MeterPlot properties
0219:
0220: return chart;
0221: }
0222:
0223: /*
0224: * New char types based on the XYZSeriesCollectionChartDefinition
0225: */
0226: private static JFreeChart createXYZSeriesCollectionChart(
0227: XYZSeriesCollectionChartDefinition chartDefinition) {
0228: JFreeChart chart = null;
0229: // TODO Make the following accessible from the chartDefinition
0230: String domainAxisLabel = null;
0231: String rangeAxisLabel = null;
0232: boolean tooltips = true;
0233: boolean urls = true;
0234: // -----------------------------------------------------------
0235:
0236: String title = chartDefinition.getTitle();
0237: boolean legend = chartDefinition.isLegendIncluded();
0238:
0239: NumberAxis domainAxis = chartDefinition.isThreeD() ? new NumberAxis3D(
0240: domainAxisLabel)
0241: : new NumberAxis(domainAxisLabel);
0242: domainAxis.setAutoRangeIncludesZero(chartDefinition
0243: .isDomainIncludesZero());
0244: domainAxis.setAutoRangeStickyZero(chartDefinition
0245: .isDomainStickyZero());
0246:
0247: NumberAxis rangeAxis = new NumberAxis(rangeAxisLabel);
0248: rangeAxis.setAutoRangeIncludesZero(chartDefinition
0249: .isRangeIncludesZero());
0250: rangeAxis.setAutoRangeStickyZero(chartDefinition
0251: .isRangeStickyZero());
0252:
0253: BubbleRenderer renderer = null;
0254:
0255: //So far only Bubble charts are supported
0256: switch (chartDefinition.getChartType()) {
0257: case BUBBLE_CHART_TYPE:
0258: renderer = new BubbleRenderer();
0259: break;
0260: default:
0261: break;
0262: }
0263:
0264: if (tooltips) {
0265: // creating the label definition
0266:
0267: renderer
0268: .setToolTipGenerator(new StandardXYZToolTipGenerator(
0269: chartDefinition.getBubbleLabelContent(),
0270: chartDefinition.getXFormat(),
0271: chartDefinition.getYFormat(),
0272: chartDefinition.getZFormat()));
0273: }
0274: if (urls) {
0275: renderer.setURLGenerator(new StandardBubbleURLGenerator());
0276: }
0277:
0278: renderer.setMaxSize(chartDefinition.getMaxBubbleSize());
0279: renderer.setMaxZ(chartDefinition.getMaxZValue());
0280:
0281: XYPlot plot = new XYPlot(chartDefinition, domainAxis,
0282: rangeAxis, renderer);
0283: updatePlot(plot, chartDefinition);
0284:
0285: chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
0286: plot, legend);
0287:
0288: return chart;
0289: }
0290:
0291: private static JFreeChart createXYSeriesCollectionChart(
0292: XYSeriesCollectionChartDefinition chartDefinition) {
0293: JFreeChart chart = null;
0294: // TODO Make the following accessible from the chartDefinition
0295: String domainAxisLabel = null;
0296: String rangeAxisLabel = null;
0297: boolean tooltips = true;
0298: boolean urls = true;
0299: // -----------------------------------------------------------
0300:
0301: String title = chartDefinition.getTitle();
0302: boolean legend = chartDefinition.isLegendIncluded();
0303:
0304: NumberAxis domainAxis = chartDefinition.isThreeD() ? new NumberAxis3D(
0305: domainAxisLabel)
0306: : new NumberAxis(domainAxisLabel);
0307: domainAxis.setAutoRangeIncludesZero(chartDefinition
0308: .isDomainIncludesZero());
0309: domainAxis.setAutoRangeStickyZero(chartDefinition
0310: .isDomainStickyZero());
0311: ValueAxis rangeAxis = new NumberAxis(rangeAxisLabel);
0312:
0313: XYItemRenderer renderer = null;
0314: switch (chartDefinition.getChartType()) {
0315: case LINE_CHART_TYPE:
0316: renderer = chartDefinition.isThreeD() ? new XYLine3DRenderer()
0317: : new XYLineAndShapeRenderer(true, false);
0318: ((XYLineAndShapeRenderer) renderer)
0319: .setShapesVisible(chartDefinition
0320: .isMarkersVisible());
0321: ((XYLineAndShapeRenderer) renderer)
0322: .setBaseShapesFilled(chartDefinition
0323: .isMarkersVisible());
0324: break;
0325: case AREA_CHART_TYPE:
0326: renderer = new XYAreaRenderer();
0327: break;
0328: case STEP_CHART_TYPE:
0329: renderer = new XYStepRenderer();
0330: break;
0331: case STEP_AREA_CHART_TYPE:
0332: renderer = new XYStepAreaRenderer();
0333: break;
0334: case DIFFERENCE_CHART_TYPE:
0335: renderer = new XYDifferenceRenderer();
0336: break;
0337: case DOT_CHART_TYPE:
0338: renderer = new XYDotRenderer();
0339: ((XYDotRenderer) renderer).setDotHeight(chartDefinition
0340: .getDotHeight());
0341: ((XYDotRenderer) renderer).setDotWidth(chartDefinition
0342: .getDotWidth());
0343: break;
0344: default:
0345: break;
0346: }
0347: if (tooltips) {
0348: XYToolTipGenerator generator = new StandardXYToolTipGenerator(
0349: chartDefinition.getTooltipContent(),
0350: new DecimalFormat(chartDefinition
0351: .getTooltipXFormat()), new DecimalFormat(
0352: chartDefinition.getTooltipYFormat()));
0353: renderer.setToolTipGenerator(generator);
0354: }
0355:
0356: if (urls) {
0357: renderer.setURLGenerator(new StandardXYURLGenerator());
0358: }
0359:
0360: renderer.setStroke(getLineStyleStroke(chartDefinition
0361: .getLineStyle(), chartDefinition.getLineWidth()));
0362:
0363: XYPlot plot = new XYPlot(chartDefinition, domainAxis,
0364: rangeAxis, renderer);
0365: updatePlot(plot, chartDefinition);
0366:
0367: chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
0368: plot, legend);
0369:
0370: return chart;
0371:
0372: }
0373:
0374: private static JFreeChart createTimeSeriesCollectionChart(
0375: TimeSeriesCollectionChartDefinition chartDefinition) {
0376: JFreeChart chart = null;
0377: // TODO Make the following accessible from the chartDefinition
0378: String domainAxisLabel = null;
0379: String rangeAxisLabel = null;
0380: boolean tooltips = true;
0381: boolean urls = true;
0382: // -----------------------------------------------------------
0383:
0384: String title = chartDefinition.getTitle();
0385: boolean legend = chartDefinition.isLegendIncluded();
0386:
0387: DateAxis domainAxis = new DateAxis(domainAxisLabel, TimeZone
0388: .getDefault());
0389: ValueAxis rangeAxis = new NumberAxis(rangeAxisLabel);
0390:
0391: XYItemRenderer renderer = null;
0392: switch (chartDefinition.getChartType()) {
0393: case LINE_CHART_TYPE:
0394: renderer = chartDefinition.isThreeD() ? new XYLine3DRenderer()
0395: : new XYLineAndShapeRenderer(true, false);
0396: ((XYLineAndShapeRenderer) renderer)
0397: .setShapesVisible(chartDefinition
0398: .isMarkersVisible());
0399: ((XYLineAndShapeRenderer) renderer)
0400: .setBaseShapesFilled(chartDefinition
0401: .isMarkersVisible());
0402: break;
0403: case AREA_CHART_TYPE:
0404: renderer = new XYAreaRenderer();
0405: break;
0406: case STEP_CHART_TYPE:
0407: renderer = new XYStepRenderer();
0408: break;
0409: case STEP_AREA_CHART_TYPE:
0410: renderer = new XYStepAreaRenderer();
0411: break;
0412: case DIFFERENCE_CHART_TYPE:
0413: renderer = new XYDifferenceRenderer();
0414: break;
0415: case DOT_CHART_TYPE:
0416: renderer = new XYDotRenderer();
0417: ((XYDotRenderer) renderer).setDotHeight(chartDefinition
0418: .getDotHeight());
0419: ((XYDotRenderer) renderer).setDotWidth(chartDefinition
0420: .getDotWidth());
0421: break;
0422: default:
0423: break;
0424: }
0425: if (tooltips) {
0426: XYToolTipGenerator generator = new StandardXYToolTipGenerator(
0427: chartDefinition.getTooltipContent(),
0428: new SimpleDateFormat(chartDefinition
0429: .getTooltipXFormat()), new DecimalFormat(
0430: chartDefinition.getTooltipYFormat()));
0431: renderer.setToolTipGenerator(generator);
0432: }
0433: if (urls) {
0434: renderer.setURLGenerator(new StandardXYURLGenerator());
0435: }
0436:
0437: renderer.setStroke(getLineStyleStroke(chartDefinition
0438: .getLineStyle(), chartDefinition.getLineWidth()));
0439:
0440: XYPlot plot = new XYPlot(chartDefinition, domainAxis,
0441: rangeAxis, renderer);
0442: updatePlot(plot, chartDefinition);
0443:
0444: chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
0445: plot, legend);
0446:
0447: return chart;
0448:
0449: }
0450:
0451: /*
0452: * The only type of chart this method will produce is a stacked XY area chart with a time series dimension.
0453: * This is because the dataset that jFreeChart expects is different than the regular TimeSeriesCOllection.
0454: * More lipstick on this homely pig.
0455: */
0456: private static JFreeChart createStackedTimeSeriesChart(
0457: TimeTableXYDatasetChartDefinition chartDefinition) {
0458: JFreeChart chart = null;
0459: // TODO Make the following accessible from the chartDefinition
0460: String domainAxisLabel = null;
0461: String rangeAxisLabel = null;
0462: boolean tooltips = true;
0463: boolean urls = true;
0464: // -----------------------------------------------------------
0465:
0466: String title = chartDefinition.getTitle();
0467: boolean legend = chartDefinition.isLegendIncluded();
0468:
0469: DateAxis domainAxis = new DateAxis(domainAxisLabel, TimeZone
0470: .getDefault());
0471: ValueAxis rangeAxis = new NumberAxis(rangeAxisLabel);
0472:
0473: XYItemRenderer renderer = null;
0474: switch (chartDefinition.getChartType()) {
0475: case AREA_CHART_TYPE:
0476: renderer = chartDefinition.isStacked() ? new StackedXYAreaRenderer()
0477: : new XYAreaRenderer();
0478: break;
0479: default:
0480: break;
0481: }
0482: if (tooltips) {
0483: XYToolTipGenerator generator = new StandardXYToolTipGenerator(
0484: chartDefinition.getTooltipContent(),
0485: new SimpleDateFormat(chartDefinition
0486: .getTooltipXFormat()), new DecimalFormat(
0487: chartDefinition.getTooltipYFormat()));
0488: renderer.setToolTipGenerator(generator);
0489: }
0490: if (urls) {
0491: renderer.setURLGenerator(new StandardXYURLGenerator());
0492: }
0493:
0494: renderer.setStroke(getLineStyleStroke(chartDefinition
0495: .getLineStyle(), chartDefinition.getLineWidth()));
0496:
0497: XYPlot plot = new XYPlot(chartDefinition, domainAxis,
0498: rangeAxis, renderer);
0499: updatePlot(plot, chartDefinition);
0500:
0501: chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
0502: plot, legend);
0503:
0504: return chart;
0505:
0506: }
0507:
0508: private static JFreeChart createCategoryDatasetChart(
0509: CategoryDatasetChartDefinition chartDefinition) {
0510: JFreeChart chart = null;
0511: switch (chartDefinition.getChartType()) {
0512: case BAR_CHART_TYPE:
0513: chart = createBarChart(chartDefinition);
0514: break;
0515: case LINE_CHART_TYPE:
0516: chart = createLineChart(chartDefinition);
0517: break;
0518: case PIE_GRID_CHART_TYPE:
0519: chart = createMultiplePieChart(chartDefinition);
0520: break;
0521: case AREA_CHART_TYPE:
0522: chart = createAreaChart(chartDefinition);
0523: break;
0524: default:
0525: break;
0526: }
0527: return chart;
0528: }
0529:
0530: private static JFreeChart createPieDatasetChart(
0531: PieDatasetChartDefinition chartDefinition) {
0532: // TODO Make the following accessible from the chartDefinition
0533: boolean tooltips = true;
0534: boolean urls = true;
0535: // -----------------------------------------------------------
0536:
0537: String title = chartDefinition.getTitle();
0538: boolean legend = chartDefinition.isLegendIncluded();
0539:
0540: PiePlot plot = null;
0541: plot = chartDefinition.isThreeD() ? new PiePlot3D(
0542: chartDefinition) : new PiePlot(chartDefinition);
0543: updatePlot(plot, chartDefinition);
0544: JFreeChart pieChart = new JFreeChart(title, chartDefinition
0545: .getTitleFont(), plot, legend);
0546: TextTitle seriesTitle = new TextTitle(
0547: "Series Title", new Font("SansSerif", Font.BOLD, 12)); //$NON-NLS-1$ //$NON-NLS-2$
0548: seriesTitle.setPosition(RectangleEdge.BOTTOM);
0549: pieChart.setTitle(title);
0550: pieChart.setBackgroundPaint(chartDefinition
0551: .getChartBackgroundPaint());
0552:
0553: if (tooltips) {
0554: PieToolTipGenerator tooltipGenerator = new StandardPieToolTipGenerator();
0555: plot.setToolTipGenerator(tooltipGenerator);
0556: }
0557:
0558: if (urls) {
0559: PieURLGenerator urlGenerator = new StandardPieURLGenerator();
0560: plot.setURLGenerator(urlGenerator);
0561: }
0562:
0563: return pieChart;
0564: }
0565:
0566: private static void updatePlot(Plot plot,
0567: ChartDefinition chartDefinition) {
0568: plot.setBackgroundPaint(chartDefinition
0569: .getPlotBackgroundPaint());
0570: plot.setBackgroundImage(chartDefinition
0571: .getPlotBackgroundImage());
0572:
0573: plot.setNoDataMessage(chartDefinition.getNoDataMessage());
0574:
0575: // create a custom palette if it was defined
0576: if (chartDefinition.getPaintSequence() != null) {
0577: DefaultDrawingSupplier drawingSupplier = new DefaultDrawingSupplier(
0578: chartDefinition.getPaintSequence(),
0579: DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE,
0580: DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE,
0581: DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,
0582: DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE);
0583: plot.setDrawingSupplier(drawingSupplier);
0584: }
0585: plot.setOutlineStroke(null); // TODO define outline stroke
0586:
0587: if (plot instanceof CategoryPlot) {
0588: CategoryPlot categoryPlot = (CategoryPlot) plot;
0589: CategoryDatasetChartDefinition categoryDatasetChartDefintion = (CategoryDatasetChartDefinition) chartDefinition;
0590: categoryPlot.setOrientation(categoryDatasetChartDefintion
0591: .getOrientation());
0592: CategoryAxis domainAxis = categoryPlot.getDomainAxis();
0593: if (domainAxis != null) {
0594: domainAxis.setLabel(categoryDatasetChartDefintion
0595: .getDomainTitle());
0596: domainAxis.setLabelFont(categoryDatasetChartDefintion
0597: .getDomainTitleFont());
0598: if (categoryDatasetChartDefintion.getDomainTickFont() != null) {
0599: domainAxis
0600: .setTickLabelFont(categoryDatasetChartDefintion
0601: .getDomainTickFont());
0602: }
0603: domainAxis
0604: .setCategoryLabelPositions(categoryDatasetChartDefintion
0605: .getCategoryLabelPositions());
0606: }
0607: NumberAxis numberAxis = (NumberAxis) categoryPlot
0608: .getRangeAxis();
0609: if (numberAxis != null) {
0610: numberAxis.setLabel(categoryDatasetChartDefintion
0611: .getRangeTitle());
0612: numberAxis.setLabelFont(categoryDatasetChartDefintion
0613: .getRangeTitleFont());
0614: if (categoryDatasetChartDefintion.getRangeMinimum() != ValueAxis.DEFAULT_LOWER_BOUND) {
0615: numberAxis
0616: .setLowerBound(categoryDatasetChartDefintion
0617: .getRangeMinimum());
0618: }
0619: if (categoryDatasetChartDefintion.getRangeMaximum() != ValueAxis.DEFAULT_UPPER_BOUND) {
0620: numberAxis
0621: .setUpperBound(categoryDatasetChartDefintion
0622: .getRangeMaximum());
0623: }
0624:
0625: if (categoryDatasetChartDefintion.getRangeTickFormat() != null) {
0626: numberAxis
0627: .setNumberFormatOverride(categoryDatasetChartDefintion
0628: .getRangeTickFormat());
0629: }
0630: if (categoryDatasetChartDefintion.getRangeTickFont() != null) {
0631: numberAxis
0632: .setTickLabelFont(categoryDatasetChartDefintion
0633: .getRangeTickFont());
0634: }
0635: }
0636:
0637: }
0638: if (plot instanceof PiePlot) {
0639: PiePlot pie = (PiePlot) plot;
0640: PieDatasetChartDefinition pieDefinition = (PieDatasetChartDefinition) chartDefinition;
0641: pie.setInteriorGap(pieDefinition.getInteriorGap());
0642: pie.setStartAngle(pieDefinition.getStartAngle());
0643: pie.setLabelFont(pieDefinition.getLabelFont());
0644: if (pieDefinition.getLabelPaint() != null) {
0645: pie.setLabelPaint(pieDefinition.getLabelPaint());
0646: }
0647: pie.setLabelBackgroundPaint(pieDefinition
0648: .getLabelBackgroundPaint());
0649: if (pieDefinition.isLegendIncluded()) {
0650: StandardPieSectionLabelGenerator labelGen = new StandardPieSectionLabelGenerator(
0651: "{0}"); //$NON-NLS-1$
0652: pie.setLegendLabelGenerator(labelGen);
0653: }
0654: if (pieDefinition.getExplodedSlices() != null) {
0655: for (Iterator iter = pieDefinition.getExplodedSlices()
0656: .iterator(); iter.hasNext();) {
0657: pie
0658: .setExplodePercent(
0659: (Comparable) iter.next(), .30);
0660: }
0661: }
0662: pie.setLabelGap(pieDefinition.getLabelGap());
0663: if (!pieDefinition.isDisplayLabels()) {
0664: pie.setLabelGenerator(null);
0665: } else {
0666: if (pieDefinition.isLegendIncluded()) {
0667: StandardPieSectionLabelGenerator labelGen = new StandardPieSectionLabelGenerator(
0668: "{1} ({2})"); //$NON-NLS-1$
0669: pie.setLabelGenerator(labelGen);
0670: } else {
0671: StandardPieSectionLabelGenerator labelGen = new StandardPieSectionLabelGenerator(
0672: "{0} = {1} ({2})"); //$NON-NLS-1$
0673: pie.setLabelGenerator(labelGen);
0674: }
0675: }
0676: }
0677: if (plot instanceof MultiplePiePlot) {
0678: MultiplePiePlot pies = (MultiplePiePlot) plot;
0679: CategoryDatasetChartDefinition categoryDatasetChartDefintion = (CategoryDatasetChartDefinition) chartDefinition;
0680: pies.setDataset(categoryDatasetChartDefintion);
0681: }
0682: if (plot instanceof MeterPlot) {
0683: MeterPlot meter = (MeterPlot) plot;
0684: DialWidgetDefinition widget = (DialWidgetDefinition) chartDefinition;
0685: List intervals = widget.getIntervals();
0686: Iterator intervalIterator = intervals.iterator();
0687: while (intervalIterator.hasNext()) {
0688: MeterInterval interval = (MeterInterval) intervalIterator
0689: .next();
0690: meter.addInterval(interval);
0691: }
0692:
0693: meter.setNeedlePaint(widget.getNeedlePaint());
0694: meter.setDialShape(widget.getDialShape());
0695: meter.setDialBackgroundPaint(widget
0696: .getPlotBackgroundPaint());
0697: meter.setRange(new Range(widget.getMinimum(), widget
0698: .getMaximum()));
0699:
0700: }
0701: if (plot instanceof XYPlot) {
0702: XYPlot xyPlot = (XYPlot) plot;
0703: if (chartDefinition instanceof XYSeriesCollectionChartDefinition) {
0704: XYSeriesCollectionChartDefinition xySeriesCollectionChartDefintion = (XYSeriesCollectionChartDefinition) chartDefinition;
0705: xyPlot.setOrientation(xySeriesCollectionChartDefintion
0706: .getOrientation());
0707: ValueAxis domainAxis = xyPlot.getDomainAxis();
0708: if (domainAxis != null) {
0709: domainAxis
0710: .setLabel(xySeriesCollectionChartDefintion
0711: .getDomainTitle());
0712: domainAxis
0713: .setLabelFont(xySeriesCollectionChartDefintion
0714: .getDomainTitleFont());
0715: domainAxis
0716: .setVerticalTickLabels(xySeriesCollectionChartDefintion
0717: .isDomainVerticalTickLabels());
0718: if (xySeriesCollectionChartDefintion
0719: .getDomainTickFormat() != null) {
0720: ((NumberAxis) domainAxis)
0721: .setNumberFormatOverride(xySeriesCollectionChartDefintion
0722: .getDomainTickFormat());
0723: }
0724: if (xySeriesCollectionChartDefintion
0725: .getDomainTickFont() != null) {
0726: domainAxis
0727: .setTickLabelFont(xySeriesCollectionChartDefintion
0728: .getDomainTickFont());
0729: }
0730: if (xySeriesCollectionChartDefintion
0731: .getDomainMinimum() != ValueAxis.DEFAULT_LOWER_BOUND) {
0732: domainAxis
0733: .setLowerBound(xySeriesCollectionChartDefintion
0734: .getDomainMinimum());
0735: }
0736: if (xySeriesCollectionChartDefintion
0737: .getDomainMaximum() != ValueAxis.DEFAULT_UPPER_BOUND) {
0738: domainAxis
0739: .setUpperBound(xySeriesCollectionChartDefintion
0740: .getDomainMaximum());
0741: }
0742: }
0743:
0744: ValueAxis rangeAxis = xyPlot.getRangeAxis();
0745: if (rangeAxis != null) {
0746: rangeAxis.setLabel(xySeriesCollectionChartDefintion
0747: .getRangeTitle());
0748: rangeAxis
0749: .setLabelFont(xySeriesCollectionChartDefintion
0750: .getRangeTitleFont());
0751: if (xySeriesCollectionChartDefintion
0752: .getRangeMinimum() != ValueAxis.DEFAULT_LOWER_BOUND) {
0753: rangeAxis
0754: .setLowerBound(xySeriesCollectionChartDefintion
0755: .getRangeMinimum());
0756: }
0757: if (xySeriesCollectionChartDefintion
0758: .getRangeMaximum() != ValueAxis.DEFAULT_UPPER_BOUND) {
0759: rangeAxis
0760: .setUpperBound(xySeriesCollectionChartDefintion
0761: .getRangeMaximum());
0762: }
0763: if (xySeriesCollectionChartDefintion
0764: .getRangeMinimum() != ValueAxis.DEFAULT_LOWER_BOUND) {
0765: rangeAxis
0766: .setLowerBound(xySeriesCollectionChartDefintion
0767: .getRangeMinimum());
0768: }
0769: if (xySeriesCollectionChartDefintion
0770: .getRangeMaximum() != ValueAxis.DEFAULT_UPPER_BOUND) {
0771: rangeAxis
0772: .setUpperBound(xySeriesCollectionChartDefintion
0773: .getRangeMaximum());
0774: }
0775: if (xySeriesCollectionChartDefintion
0776: .getRangeTickFormat() != null) {
0777: ((NumberAxis) rangeAxis)
0778: .setNumberFormatOverride(xySeriesCollectionChartDefintion
0779: .getRangeTickFormat());
0780: }
0781: if (xySeriesCollectionChartDefintion
0782: .getRangeTickFont() != null) {
0783: rangeAxis
0784: .setTickLabelFont(xySeriesCollectionChartDefintion
0785: .getRangeTickFont());
0786: }
0787: }
0788:
0789: } else if (chartDefinition instanceof TimeSeriesCollectionChartDefinition) {
0790: TimeSeriesCollectionChartDefinition timeSeriesCollectionChartDefintion = (TimeSeriesCollectionChartDefinition) chartDefinition;
0791: xyPlot
0792: .setOrientation(timeSeriesCollectionChartDefintion
0793: .getOrientation());
0794: ValueAxis domainAxis = xyPlot.getDomainAxis();
0795: if (domainAxis != null) {
0796: domainAxis
0797: .setLabel(timeSeriesCollectionChartDefintion
0798: .getDomainTitle());
0799: domainAxis
0800: .setLabelFont(timeSeriesCollectionChartDefintion
0801: .getDomainTitleFont());
0802: domainAxis
0803: .setVerticalTickLabels(timeSeriesCollectionChartDefintion
0804: .isDomainVerticalTickLabels());
0805: if (domainAxis instanceof DateAxis) {
0806: DateAxis da = (DateAxis) domainAxis;
0807: if (timeSeriesCollectionChartDefintion
0808: .getDateMinimum() != null) {
0809: da
0810: .setMinimumDate(timeSeriesCollectionChartDefintion
0811: .getDateMinimum());
0812: }
0813: if (timeSeriesCollectionChartDefintion
0814: .getDateMaximum() != null) {
0815: da
0816: .setMaximumDate(timeSeriesCollectionChartDefintion
0817: .getDateMaximum());
0818: }
0819: }
0820: }
0821:
0822: ValueAxis rangeAxis = xyPlot.getRangeAxis();
0823: if (rangeAxis != null) {
0824: rangeAxis
0825: .setLabel(timeSeriesCollectionChartDefintion
0826: .getRangeTitle());
0827: rangeAxis
0828: .setLabelFont(timeSeriesCollectionChartDefintion
0829: .getRangeTitleFont());
0830: if (timeSeriesCollectionChartDefintion
0831: .getRangeMinimum() != ValueAxis.DEFAULT_LOWER_BOUND) {
0832: rangeAxis
0833: .setLowerBound(timeSeriesCollectionChartDefintion
0834: .getRangeMinimum());
0835: }
0836: if (timeSeriesCollectionChartDefintion
0837: .getRangeMaximum() != ValueAxis.DEFAULT_UPPER_BOUND) {
0838: rangeAxis
0839: .setUpperBound(timeSeriesCollectionChartDefintion
0840: .getRangeMaximum());
0841: }
0842: }
0843: } else if (chartDefinition instanceof XYZSeriesCollectionChartDefinition) {
0844: XYZSeriesCollectionChartDefinition xyzSeriesCollectionChartDefintion = (XYZSeriesCollectionChartDefinition) chartDefinition;
0845: xyPlot.setOrientation(xyzSeriesCollectionChartDefintion
0846: .getOrientation());
0847: ValueAxis domainAxis = xyPlot.getDomainAxis();
0848: if (domainAxis != null) {
0849: domainAxis
0850: .setLabel(xyzSeriesCollectionChartDefintion
0851: .getDomainTitle());
0852: domainAxis
0853: .setLabelFont(xyzSeriesCollectionChartDefintion
0854: .getDomainTitleFont());
0855: domainAxis
0856: .setVerticalTickLabels(xyzSeriesCollectionChartDefintion
0857: .isDomainVerticalTickLabels());
0858: if (xyzSeriesCollectionChartDefintion
0859: .getDomainMinimum() != ValueAxis.DEFAULT_LOWER_BOUND) {
0860: domainAxis
0861: .setLowerBound(xyzSeriesCollectionChartDefintion
0862: .getDomainMinimum());
0863: }
0864: if (xyzSeriesCollectionChartDefintion
0865: .getDomainMaximum() != ValueAxis.DEFAULT_UPPER_BOUND) {
0866: domainAxis
0867: .setUpperBound(xyzSeriesCollectionChartDefintion
0868: .getDomainMaximum());
0869: }
0870: if (xyzSeriesCollectionChartDefintion
0871: .getDomainTickFormat() != null) {
0872: ((NumberAxis) domainAxis)
0873: .setNumberFormatOverride(xyzSeriesCollectionChartDefintion
0874: .getDomainTickFormat());
0875: }
0876: if (xyzSeriesCollectionChartDefintion
0877: .getDomainTickFont() != null) {
0878: domainAxis
0879: .setTickLabelFont(xyzSeriesCollectionChartDefintion
0880: .getDomainTickFont());
0881: }
0882: }
0883:
0884: ValueAxis rangeAxis = xyPlot.getRangeAxis();
0885: if (rangeAxis != null) {
0886: rangeAxis
0887: .setLabel(xyzSeriesCollectionChartDefintion
0888: .getRangeTitle());
0889: rangeAxis
0890: .setLabelFont(xyzSeriesCollectionChartDefintion
0891: .getRangeTitleFont());
0892: rangeAxis
0893: .setLowerBound(xyzSeriesCollectionChartDefintion
0894: .getRangeMinimum());
0895: if (xyzSeriesCollectionChartDefintion
0896: .getRangeMinimum() != ValueAxis.DEFAULT_LOWER_BOUND) {
0897: rangeAxis
0898: .setLowerBound(xyzSeriesCollectionChartDefintion
0899: .getRangeMinimum());
0900: }
0901: if (xyzSeriesCollectionChartDefintion
0902: .getRangeMaximum() != ValueAxis.DEFAULT_UPPER_BOUND) {
0903: rangeAxis
0904: .setUpperBound(xyzSeriesCollectionChartDefintion
0905: .getRangeMaximum());
0906: }
0907: if (xyzSeriesCollectionChartDefintion
0908: .getRangeTickFormat() != null) {
0909: ((NumberAxis) rangeAxis)
0910: .setNumberFormatOverride(xyzSeriesCollectionChartDefintion
0911: .getRangeTickFormat());
0912: }
0913: if (xyzSeriesCollectionChartDefintion
0914: .getRangeTickFont() != null) {
0915: rangeAxis
0916: .setTickLabelFont(xyzSeriesCollectionChartDefintion
0917: .getRangeTickFont());
0918: }
0919: }
0920:
0921: }
0922: }
0923: }
0924:
0925: private static JFreeChart createMultiplePieChart(
0926: CategoryDatasetChartDefinition chartDefinition) {
0927: // TODO Make the following accessible from the chartDefinition
0928: TableOrder order = TableOrder.BY_ROW;
0929: // boolean tooltips = true;
0930: // boolean urls = true;
0931: // -----------------------------------------------------------
0932:
0933: String title = chartDefinition.getTitle();
0934: boolean legend = chartDefinition.isLegendIncluded();
0935:
0936: if (order == null) {
0937: throw new IllegalArgumentException(
0938: Messages
0939: .getString("JFreeChartEngine.ERROR_0001_NULL_ORDER_ARGUMENT")); //$NON-NLS-1$
0940: }
0941: MultiplePiePlot plot = new MultiplePiePlot(chartDefinition);
0942: updatePlot(plot, chartDefinition);
0943: plot.setDataExtractOrder(order);
0944:
0945: JFreeChart pieCharts = new JFreeChart(title, chartDefinition
0946: .getTitleFont(), plot, legend);
0947: JFreeChart pieChart = plot.getPieChart();
0948: TextTitle seriesTitle = new TextTitle(
0949: "Series Title", new Font("SansSerif", Font.BOLD, 12)); //$NON-NLS-1$ //$NON-NLS-2$
0950: seriesTitle.setPosition(RectangleEdge.BOTTOM);
0951: pieChart.setTitle(seriesTitle);
0952: pieChart.setBackgroundPaint(chartDefinition
0953: .getChartBackgroundPaint());
0954: plot.setPieChart(pieChart);
0955:
0956: // if (tooltips) {
0957: // PieToolTipGenerator tooltipGenerator = new
0958: // StandardPieToolTipGenerator();
0959: // PiePlot pp = (PiePlot) plot.getPieChart().getPlot();
0960: // pp.setToolTipGenerator(tooltipGenerator);
0961: // }
0962:
0963: // if (urls) {
0964: // PieURLGenerator urlGenerator = new StandardPieURLGenerator();
0965: // PiePlot pp = (PiePlot) plot.getPieChart().getPlot();
0966: // pp.setURLGenerator(urlGenerator);
0967: // }
0968:
0969: return pieCharts;
0970: }
0971:
0972: private static JFreeChart createLineChart(
0973: CategoryDatasetChartDefinition chartDefinition) {
0974: // TODO Make the following accessible from the chartDefinition
0975: String categoryAxisLabel = null;
0976: String valueAxisLabel = null;
0977: boolean tooltips = true;
0978: boolean urls = true;
0979: // -----------------------------------------------------------
0980:
0981: String title = chartDefinition.getTitle();
0982: boolean legend = chartDefinition.isLegendIncluded();
0983:
0984: CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
0985: ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
0986: LineAndShapeRenderer renderer = chartDefinition.isThreeD() ? new LineRenderer3D()
0987: : new LineAndShapeRenderer(true, false);
0988: if (tooltips) {
0989: renderer
0990: .setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
0991: }
0992: if (urls) {
0993: renderer
0994: .setBaseItemURLGenerator(new StandardCategoryURLGenerator());
0995: }
0996:
0997: renderer.setStroke(getLineStyleStroke(chartDefinition
0998: .getLineStyle(), chartDefinition.getLineWidth()));
0999: renderer.setShapesVisible(chartDefinition.isMarkersVisible());
1000: renderer
1001: .setBaseShapesFilled(chartDefinition.isMarkersVisible());
1002:
1003: CategoryPlot plot = new CategoryPlot(chartDefinition,
1004: categoryAxis, valueAxis, renderer);
1005: updatePlot(plot, chartDefinition);
1006:
1007: JFreeChart chart = new JFreeChart(title,
1008: JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
1009:
1010: return chart;
1011:
1012: }
1013:
1014: private static JFreeChart createBarChart(
1015: CategoryDatasetChartDefinition chartDefinition) {
1016: // TODO Make the following accessible from the chartDefinition
1017: String categoryAxisLabel = null;
1018: String valueAxisLabel = null;
1019: boolean tooltips = true;
1020: boolean urls = true;
1021: // -----------------------------------------------------------
1022:
1023: String title = chartDefinition.getTitle();
1024: boolean legend = chartDefinition.isLegendIncluded();
1025: PlotOrientation orientation = chartDefinition.getOrientation();
1026:
1027: CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
1028: ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
1029: BarRenderer renderer = null;
1030: // Determine the type of renderer to use
1031: if (chartDefinition.isStacked() || chartDefinition.isThreeD()) {
1032: if (chartDefinition.isStacked()
1033: && chartDefinition.isThreeD()) {
1034: renderer = new StackedBarRenderer3D();
1035: } else if (chartDefinition.isStacked()) {
1036: renderer = new StackedBarRenderer();
1037: } else {
1038: renderer = new BarRenderer3D();
1039: }
1040: } else {
1041: renderer = new BarRenderer();
1042: }
1043: if (orientation == PlotOrientation.HORIZONTAL) {
1044: ItemLabelPosition position1 = new ItemLabelPosition(
1045: ItemLabelAnchor.OUTSIDE3, TextAnchor.CENTER_LEFT);
1046: renderer.setPositiveItemLabelPosition(position1);
1047: ItemLabelPosition position2 = new ItemLabelPosition(
1048: ItemLabelAnchor.OUTSIDE9, TextAnchor.CENTER_RIGHT);
1049: renderer.setNegativeItemLabelPosition(position2);
1050: } else if (orientation == PlotOrientation.VERTICAL) {
1051: ItemLabelPosition position1 = new ItemLabelPosition(
1052: ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER);
1053: renderer.setPositiveItemLabelPosition(position1);
1054: ItemLabelPosition position2 = new ItemLabelPosition(
1055: ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER);
1056: renderer.setNegativeItemLabelPosition(position2);
1057: }
1058: if (tooltips) {
1059: renderer
1060: .setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
1061: }
1062: if (urls) {
1063: renderer
1064: .setBaseItemURLGenerator(new StandardCategoryURLGenerator());
1065: }
1066:
1067: if (chartDefinition.getMaxBarWidth() != null) {
1068: renderer.setMaximumBarWidth(chartDefinition
1069: .getMaxBarWidth().doubleValue());
1070: }
1071:
1072: CategoryPlot plot = new CategoryPlot(chartDefinition,
1073: categoryAxis, valueAxis, renderer);
1074: updatePlot(plot, chartDefinition);
1075:
1076: JFreeChart chart = new JFreeChart(title,
1077: JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
1078:
1079: return chart;
1080:
1081: }
1082:
1083: private static JFreeChart createBarLineChart(
1084: BarLineChartDefinition chartDefinition) {
1085: //TODO Make the following accessible from the chartDefinition
1086: String categoryAxisLabel = null;
1087: String valueAxisLabel = null;
1088: String secondValueAxisLabel = null;
1089: boolean tooltips = true;
1090: boolean urls = true;
1091: // -----------------------------------------------------------
1092: String title = chartDefinition.getTitle();
1093: boolean legend = chartDefinition.isLegendIncluded();
1094: PlotOrientation orientation = chartDefinition.getOrientation();
1095:
1096: //split BarLineChartDefinition in two Definitions
1097: CategoryDatasetChartDefinition barsDataset = new CategoryDatasetChartDefinition(
1098: chartDefinition.getSession(), chartDefinition
1099: .getChartAttributes());
1100: CategoryDatasetChartDefinition linesDataset = new CategoryDatasetChartDefinition(
1101: chartDefinition.getSession(), chartDefinition
1102: .getChartAttributes());
1103:
1104: /*try{
1105: barsDataset = (CategoryDatasetChartDefinition)chartDefinition.clone();
1106: linesDataset = (CategoryDatasetChartDefinition)chartDefinition.clone();
1107: }catch(Exception e){}*/
1108:
1109: //get column and row count of the data set
1110: int iColumnCount = chartDefinition.getColumnCount();
1111: int iRowCount = chartDefinition.getRowCount();
1112:
1113: if (iRowCount <= 0) {
1114: chartDefinition.setNoDataMessage(Messages
1115: .getString("CHART.USER_NO_DATA_AVAILABLE")); //$NON-NLS-1$
1116: }
1117:
1118: /*
1119: * Copy data to the two new data sets
1120: */
1121: //Loop through columns
1122: for (int r = 0; r < iRowCount; r++) {
1123:
1124: //check if measure should be include in bar or line dataset
1125: String strMeasureName = (String) chartDefinition
1126: .getRowKey(r);
1127: boolean bIsBarColumn = isBarColumn(chartDefinition
1128: .getBarColumns(), strMeasureName);
1129: boolean bIsLineColumn = isLineColumn(chartDefinition
1130: .getLineColumns(), strMeasureName);
1131:
1132: //getting all values
1133: for (int c = 0; c < iColumnCount; c++) {
1134: Comparable compColumnName = chartDefinition
1135: .getColumnKey(c);
1136: Number nValue = chartDefinition.getValue(
1137: strMeasureName, compColumnName);
1138: if (bIsBarColumn) {
1139: barsDataset.addValue(nValue, strMeasureName,
1140: compColumnName);
1141: }
1142: if (bIsLineColumn) {
1143: linesDataset.addValue(nValue, strMeasureName,
1144: compColumnName);
1145: }
1146: }
1147:
1148: }
1149:
1150: if ((iRowCount > 0) && (barsDataset.getRowCount() <= 0)
1151: && (linesDataset.getRowCount() <= 0)) {
1152: chartDefinition.setNoDataMessage(Messages
1153: .getString("CHART.USER_INCORRECT_DATA_FORMAT")); //$NON-NLS-1$
1154: }
1155:
1156: //Create Axis Objects
1157: CategoryAxis catAxis = new CategoryAxis(categoryAxisLabel);
1158: NumberAxis barsAxis = new NumberAxis(valueAxisLabel);
1159: NumberAxis linesAxis = new NumberAxis(secondValueAxisLabel);
1160:
1161: //set title and font for lines Axis
1162: linesDataset
1163: .setRangeTitle(chartDefinition.getLinesRangeTitle());
1164: linesDataset.setRangeTitleFont(chartDefinition
1165: .getLinesRangeTitleFont());
1166: if (chartDefinition.getLinesRangeTickFormat() != null) {
1167: linesAxis.setNumberFormatOverride(chartDefinition
1168: .getLinesRangeTickFormat());
1169: }
1170:
1171: //create renderer
1172: BarRenderer barRenderer = null;
1173: LineAndShapeRenderer lineRenderer = null;
1174: // Determine the type of renderer to use
1175: if (chartDefinition.isStacked() || chartDefinition.isThreeD()) {
1176: if (chartDefinition.isStacked()
1177: && chartDefinition.isThreeD()) {
1178: barRenderer = new StackedBarRenderer3D();
1179: lineRenderer = new LineRenderer3D();
1180: } else if (chartDefinition.isStacked()) {
1181: barRenderer = new StackedBarRenderer();
1182: lineRenderer = new LineAndShapeRenderer();
1183: } else {
1184: barRenderer = new BarRenderer3D();
1185: lineRenderer = new LineRenderer3D();
1186: }
1187: } else {
1188: barRenderer = new BarRenderer();
1189: lineRenderer = new LineAndShapeRenderer();
1190: }
1191: if (orientation == PlotOrientation.HORIZONTAL) {
1192: ItemLabelPosition position1 = new ItemLabelPosition(
1193: ItemLabelAnchor.OUTSIDE3, TextAnchor.CENTER_LEFT);
1194: barRenderer.setPositiveItemLabelPosition(position1);
1195: lineRenderer.setPositiveItemLabelPosition(position1);
1196: ItemLabelPosition position2 = new ItemLabelPosition(
1197: ItemLabelAnchor.OUTSIDE9, TextAnchor.CENTER_RIGHT);
1198: barRenderer.setNegativeItemLabelPosition(position2);
1199: lineRenderer.setNegativeItemLabelPosition(position2);
1200: } else if (orientation == PlotOrientation.VERTICAL) {
1201: ItemLabelPosition position1 = new ItemLabelPosition(
1202: ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER);
1203: barRenderer.setPositiveItemLabelPosition(position1);
1204: lineRenderer.setPositiveItemLabelPosition(position1);
1205: ItemLabelPosition position2 = new ItemLabelPosition(
1206: ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER);
1207: barRenderer.setNegativeItemLabelPosition(position2);
1208: lineRenderer.setNegativeItemLabelPosition(position2);
1209: }
1210: if (tooltips) {
1211: barRenderer
1212: .setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
1213: lineRenderer
1214: .setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
1215: }
1216: if (urls) {
1217: barRenderer
1218: .setBaseItemURLGenerator(new StandardCategoryURLGenerator());
1219: lineRenderer
1220: .setBaseItemURLGenerator(new StandardCategoryURLGenerator());
1221: }
1222:
1223: if (chartDefinition.getMaxBarWidth() != null) {
1224: barRenderer.setMaximumBarWidth(chartDefinition
1225: .getMaxBarWidth().doubleValue());
1226: }
1227:
1228: //setting some line attributes
1229: lineRenderer.setStroke(getLineStyleStroke(chartDefinition
1230: .getLineStyle(), chartDefinition.getLineWidth()));
1231: lineRenderer.setShapesVisible(chartDefinition
1232: .isMarkersVisible());
1233: lineRenderer.setBaseShapesFilled(chartDefinition
1234: .isMarkersVisible());
1235:
1236: /*
1237: * Create plot and make necessary adjustments for overlaid chart
1238: */
1239: //create the plot with bar chart
1240: CategoryPlot plot = new CategoryPlot(barsDataset, catAxis,
1241: barsAxis, barRenderer);
1242: //add line renderer
1243: plot.setRenderer(1, lineRenderer);
1244: //add lines dataset, renderer and axis to plot
1245: plot.setDataset(1, linesDataset);
1246: plot.setRangeAxis(1, linesAxis);
1247: //map lines to second axis
1248: plot.mapDatasetToRangeAxis(1, 1);
1249: //set rendering order
1250: plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
1251: //set location of second axis
1252: plot.setRangeAxisLocation(1, AxisLocation.BOTTOM_OR_RIGHT);
1253:
1254: //standard settings for plots
1255: updatePlot(plot, barsDataset);
1256: //additional settings for second axis
1257: ValueAxis secondValueAxis = plot.getRangeAxis(1);
1258:
1259: if (secondValueAxis != null) {
1260: if (chartDefinition.getLinesRangeTitle() != null) {
1261: secondValueAxis.setLabel(chartDefinition
1262: .getLinesRangeTitle());
1263: }
1264: if (chartDefinition.getLinesRangeTitleFont() != null) {
1265: secondValueAxis.setLabelFont(chartDefinition
1266: .getLinesRangeTitleFont());
1267: }
1268: if (chartDefinition.getLinesRangeTickFont() != null) {
1269: secondValueAxis.setTickLabelFont(chartDefinition
1270: .getLinesRangeTickFont());
1271: }
1272: if (chartDefinition.getLinesRangeMinimum() != ValueAxis.DEFAULT_LOWER_BOUND) {
1273: secondValueAxis.setLowerBound(chartDefinition
1274: .getLinesRangeMinimum());
1275: }
1276: if (chartDefinition.getLinesRangeMaximum() != ValueAxis.DEFAULT_UPPER_BOUND) {
1277: secondValueAxis.setUpperBound(chartDefinition
1278: .getLinesRangeMaximum());
1279: }
1280: }
1281:
1282: JFreeChart chart = new JFreeChart(title,
1283: JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
1284:
1285: return chart;
1286: }
1287:
1288: private static JFreeChart createAreaChart(
1289: CategoryDatasetChartDefinition chartDefinition) {
1290: // TODO Make the following accessible from the chartDefinition
1291: String categoryAxisLabel = null;
1292: String valueAxisLabel = null;
1293: boolean tooltips = true;
1294: boolean urls = true;
1295: // -----------------------------------------------------------
1296:
1297: String title = chartDefinition.getTitle();
1298: boolean legend = chartDefinition.isLegendIncluded();
1299:
1300: CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
1301: ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
1302:
1303: AreaRenderer renderer = chartDefinition.isStacked() ? new StackedAreaRenderer()
1304: : new AreaRenderer();
1305: if (tooltips) {
1306: renderer
1307: .setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
1308: }
1309: if (urls) {
1310: renderer
1311: .setBaseItemURLGenerator(new StandardCategoryURLGenerator());
1312: }
1313:
1314: CategoryPlot plot = new CategoryPlot(chartDefinition,
1315: categoryAxis, valueAxis, renderer);
1316: updatePlot(plot, chartDefinition);
1317:
1318: JFreeChart chart = new JFreeChart(title,
1319: JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
1320:
1321: return chart;
1322: }
1323:
1324: /**
1325: * Create a PNG image file from a JFreeChart object
1326: *
1327: * @param chart
1328: * The chart object to create an image from
1329: * @param path
1330: * The path and name of the image file to create
1331: * @param width
1332: * The width of the image in pixels
1333: * @param height
1334: * The height of the image in pixels
1335: * @param writer
1336: * A writer for the iamge map to be written to
1337: * @throws IOException
1338: */
1339: private static void saveChartAsPNG(JFreeChart chart, String path,
1340: int width, int height, PrintWriter writer,
1341: ChartRenderingInfo info) throws IOException {
1342: File file = new File(path + ".png"); //$NON-NLS-1$
1343: ChartUtilities.saveChartAsPNG(file, chart, width, height, info);
1344:
1345: // TODO support tool tip generators
1346:
1347: // TODO support URL fragment generators
1348:
1349: // TODO: make the image map name unique on the page
1350: if (writer != null) {
1351: ChartUtilities
1352: .writeImageMap(writer, "map-name", info, true); //$NON-NLS-1$
1353: }
1354: }
1355:
1356: /**
1357: * Create an SVG image file from a JFreeChart object
1358: *
1359: * @param chart
1360: * The chart object to create an image from
1361: * @param path
1362: * The path and name of the image file to create
1363: * @param width
1364: * The width of the image in pixels
1365: * @param height
1366: * The height of the image in pixels
1367: * @throws IOException
1368: */
1369: private static void saveChartAsSVG(JFreeChart chart, String path,
1370: int width, int height, ChartRenderingInfo info)
1371: throws IOException {
1372: // THE FOLLOWING CODE BASED ON THE EXAMPLE IN THE BATIK DOCUMENTATION...
1373: // Get a DOMImplementation
1374: org.w3c.dom.DOMImplementation domImpl = GenericDOMImplementation
1375: .getDOMImplementation();
1376: // Create an instance of org.w3c.dom.Document
1377: Document document = domImpl.createDocument(null, "svg", null); //$NON-NLS-1$
1378: // Create an instance of the SVG Generator
1379: SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
1380: // set the precision to avoid a null pointer exception in Batik 1.5
1381: svgGenerator.getGeneratorContext().setPrecision(6);
1382: // Ask the chart to render into the SVG Graphics2D implementation
1383: chart.draw(svgGenerator, new Rectangle2D.Double(0, 0, width,
1384: height), info);
1385: // Finally, stream out SVG to a file using UTF-8 character to byte
1386: // encoding
1387: boolean useCSS = true;
1388: Writer out = new OutputStreamWriter(
1389: new FileOutputStream(new File(path + ".svg")), LocaleHelper.getSystemEncoding()); //$NON-NLS-1$
1390: svgGenerator.stream(out, useCSS);
1391: }
1392:
1393: /**
1394: * Create an image file from a JFreeChart object
1395: *
1396: * @param chart
1397: * The chart object to create an image from
1398: * @param path
1399: * The path and name of the image file to create
1400: * @param width
1401: * The width of the image in pixels
1402: * @param height
1403: * The height of the image in pixels
1404: * @param outputType
1405: * The type of the image to create, OUPUT_PNG or OUTPUT_SVG
1406: * @param writer
1407: * @throws IOException
1408: */
1409: private static void saveChart(JFreeChart chart, String path,
1410: int width, int height, int outputType, PrintWriter writer,
1411: ChartRenderingInfo info) throws IOException {
1412: if (outputType == OUTPUT_PNG) {
1413: saveChartAsPNG(chart, path, width, height, writer, info);
1414: } else if (outputType == OUTPUT_SVG) {
1415: saveChartAsSVG(chart, path, width, height, info);
1416: }
1417: // TODO support other image types, e.g. JPG, GIF
1418: }
1419:
1420: /**
1421: * Create an image file using dataset object. This method takes a dataset
1422: * object, e.g. a DialWidgetDefinition, creates a JFreeChart object from it,
1423: * and then creates an image file.
1424: *
1425: * @param dataset
1426: * The
1427: * @param title
1428: * The title of the chart
1429: * @param units
1430: * The units of the chart value
1431: * @param fileName
1432: * The path and file of the image to create
1433: * @param width
1434: * The width of the image to create
1435: * @param height
1436: * The height of the image to create
1437: * @param outputType
1438: * The type of the image to create
1439: * @param writer
1440: * A writer to writer the image map into
1441: * @param logger
1442: * The logger to log any messages to
1443: */
1444: public static void saveChart(Dataset dataset, String title,
1445: String units, String fileName, int width, int height,
1446: int outputType, PrintWriter writer, ILogger logger) {
1447: ChartRenderingInfo info = new ChartRenderingInfo();
1448: saveChart(dataset, title, units, fileName, width, height,
1449: outputType, writer, info, logger);
1450: }
1451:
1452: /**
1453: * Create an image file using dataset object. This method takes a dataset
1454: * object, e.g. a DialWidgetDefinition, creates a JFreeChart object from it,
1455: * and then creates an image file.
1456: *
1457: * @param dataset
1458: * The
1459: * @param title
1460: * The title of the chart
1461: * @param units
1462: * The units of the chart value
1463: * @param fileName
1464: * The path and file of the image to create
1465: * @param width
1466: * The width of the image to create
1467: * @param height
1468: * The height of the image to create
1469: * @param outputType
1470: * The type of the image to create
1471: * @param writer
1472: * A writer to writer the image map into
1473: * @param logger
1474: * The logger to log any messages to
1475: */
1476: public static void saveChart(Dataset dataset, String title,
1477: String units, String fileName, int width, int height,
1478: int outputType, PrintWriter writer,
1479: ChartRenderingInfo info, ILogger logger) {
1480:
1481: JFreeChart chart = getChart(dataset, title, units, width,
1482: height, logger);
1483:
1484: try {
1485: String filePath = PentahoSystem.getApplicationContext()
1486: .getFileOutputPath(fileName);
1487: saveChart(chart, filePath, width, height, outputType,
1488: writer, info);
1489: } catch (IOException e) {
1490: logger
1491: .error(
1492: Messages
1493: .getString("ChartEngine.ERROR_0001_COULD_NOT_CREATE_CHART"), e); //$NON-NLS-1$
1494: }
1495: }
1496:
1497: /**
1498: * Create a chart-object using dataset object. This method takes a dataset
1499: * object, e.g. a DialWidgetDefinition, and creates and returns a JFreeChart
1500: * object from it.
1501: *
1502: * @param dataset
1503: * The dataset
1504: * @param title
1505: * The title of the chart
1506: * @param units
1507: * The units of the chart value
1508: * @param width
1509: * The width of the image to create
1510: * @param height
1511: * The height of the image to create
1512: * @param logger
1513: * The logger to log any messages to
1514: *
1515: * @return JFreeChart the generated chart object
1516: */
1517: public static JFreeChart getChart(Dataset dataset, String title,
1518: String units, int width, int height, ILogger logger) {
1519:
1520: JFreeChart chart = null;
1521: if (dataset instanceof DialWidgetDefinition) {
1522: chart = createDial((DialWidgetDefinition) dataset, title,
1523: units);
1524: } else if (dataset instanceof TimeSeriesCollectionChartDefinition) {
1525: chart = createTimeSeriesCollectionChart((TimeSeriesCollectionChartDefinition) dataset);
1526: } else if (dataset instanceof TimeTableXYDatasetChartDefinition) {
1527: chart = createStackedTimeSeriesChart((TimeTableXYDatasetChartDefinition) dataset);
1528: } else if (dataset instanceof XYSeriesCollectionChartDefinition) {
1529: chart = createXYSeriesCollectionChart((XYSeriesCollectionChartDefinition) dataset);
1530: } else if (dataset instanceof BarLineChartDefinition) {
1531: chart = createBarLineChart((BarLineChartDefinition) dataset);
1532: } else if (dataset instanceof CategoryDatasetChartDefinition) {
1533: chart = createCategoryDatasetChart((CategoryDatasetChartDefinition) dataset);
1534: } else if (dataset instanceof PieDatasetChartDefinition) {
1535: chart = createPieDatasetChart((PieDatasetChartDefinition) dataset);
1536: } else if (dataset instanceof XYZSeriesCollectionChartDefinition) {
1537: chart = createXYZSeriesCollectionChart((XYZSeriesCollectionChartDefinition) dataset);
1538: }
1539: if (chart == null) {
1540: logger
1541: .error(Messages
1542: .getString("ChartEngine.ERROR_0002_COULD_NOT_CREATE_CHART")); //$NON-NLS-1$
1543: } else {
1544: // TODO implement the ability to have "ImageTitle"s for subtitles
1545: ChartDefinition chartDefinition = (ChartDefinition) dataset;
1546: Iterator iter = chartDefinition.getSubtitles().iterator();
1547: while (iter.hasNext()) {
1548: chart
1549: .addSubtitle(new TextTitle(iter.next()
1550: .toString()));
1551: }
1552: chart.setBackgroundPaint(chartDefinition
1553: .getChartBackgroundPaint());
1554: chart.setBackgroundImage(chartDefinition
1555: .getChartBackgroundImage());
1556: chart.setBorderVisible(chartDefinition.isBorderVisible());
1557: chart.setBorderPaint(chartDefinition.getBorderPaint());
1558: if (chart.getTitle() != null) {
1559: chart.getTitle().setPosition(
1560: chartDefinition.getTitlePosition());
1561: chart.getTitle()
1562: .setFont(chartDefinition.getTitleFont());
1563: }
1564:
1565: // TODO implement
1566: // chart.setBorderStroke(chartDefintion.getBorderStroke());
1567: }
1568:
1569: // format legend
1570: ChartDefinition chartDefinition = (ChartDefinition) dataset;
1571: if (chartDefinition.getLegendFont() != null) {
1572: chart.getLegend().setItemFont(
1573: chartDefinition.getLegendFont());
1574: }
1575: if (!chartDefinition.isLegendBorderVisible()) {
1576: chart.getLegend().setBorder(BlockBorder.NONE);
1577: }
1578: return (chart);
1579: }
1580:
1581: /**
1582: *
1583: * @param typeStr String name for chart
1584: * @return int representing the chart string passed in; -1 if invalid chart name
1585: * @see ChartDefinition for valid chart name strings and integers
1586: */
1587: public static int getChartType(String typeStr) {
1588: if (typeStr != null) {
1589: if (ChartDefinition.PIE_CHART_STR.equalsIgnoreCase(typeStr)) {
1590: return JFreeChartEngine.PIE_CHART_TYPE;
1591: } else if (ChartDefinition.PIE_GRID_CHART_STR
1592: .equalsIgnoreCase(typeStr)) {
1593: return JFreeChartEngine.PIE_GRID_CHART_TYPE;
1594: } else if (ChartDefinition.BAR_CHART_STR
1595: .equalsIgnoreCase(typeStr)) {
1596: return JFreeChartEngine.BAR_CHART_TYPE;
1597: } else if (ChartDefinition.LINE_CHART_STR
1598: .equalsIgnoreCase(typeStr)) {
1599: return JFreeChartEngine.LINE_CHART_TYPE;
1600: } else if (ChartDefinition.AREA_CHART_STR
1601: .equalsIgnoreCase(typeStr)) {
1602: return JFreeChartEngine.AREA_CHART_TYPE;
1603: } else if (ChartDefinition.BAR_LINE_CHART_STR
1604: .equalsIgnoreCase(typeStr)) {
1605: return JFreeChartEngine.BAR_LINE_CHART_TYPE;
1606: } else if (ChartDefinition.BUBBLE_CHART_STR
1607: .equalsIgnoreCase(typeStr)) {
1608: return JFreeChartEngine.BUBBLE_CHART_TYPE;
1609: } else if (ChartDefinition.DIAL_CHART_STR
1610: .equalsIgnoreCase(typeStr)) {
1611: return JFreeChartEngine.DIAL_CHART_TYPE;
1612: } else if (ChartDefinition.DIFFERENCE_CHART_STR
1613: .equalsIgnoreCase(typeStr)) {
1614: return JFreeChartEngine.DIFFERENCE_CHART_TYPE;
1615: } else if (ChartDefinition.DOT_CHART_STR
1616: .equalsIgnoreCase(typeStr)) {
1617: return JFreeChartEngine.DOT_CHART_TYPE;
1618: } else if (ChartDefinition.STEP_AREA_CHART_STR
1619: .equalsIgnoreCase(typeStr)) {
1620: return JFreeChartEngine.STEP_AREA_CHART_TYPE;
1621: } else if (ChartDefinition.STEP_CHART_STR
1622: .equalsIgnoreCase(typeStr)) {
1623: return JFreeChartEngine.STEP_CHART_TYPE;
1624: }
1625: }
1626: return JFreeChartEngine.UNDEFINED_CHART_TYPE;
1627: }
1628:
1629: /**
1630: *
1631: * @param type int type for chart
1632: * @return String representing the chart
1633: * @see ChartDefinition for valid chart name strings
1634: */
1635: public static String getChartTypeName(int type) {
1636:
1637: String rtn = ""; //$NON-NLS-1$
1638:
1639: switch (type) {
1640: case JFreeChartEngine.PIE_CHART_TYPE:
1641: rtn = ChartDefinition.PIE_CHART_STR;
1642: break;
1643: case JFreeChartEngine.PIE_GRID_CHART_TYPE:
1644: rtn = ChartDefinition.PIE_GRID_CHART_STR;
1645: break;
1646: case JFreeChartEngine.BAR_CHART_TYPE:
1647: rtn = ChartDefinition.BAR_CHART_STR;
1648: break;
1649: case JFreeChartEngine.LINE_CHART_TYPE:
1650: rtn = ChartDefinition.LINE_CHART_STR;
1651: break;
1652: case JFreeChartEngine.BAR_LINE_CHART_TYPE:
1653: rtn = ChartDefinition.BAR_LINE_CHART_STR;
1654: break;
1655: case JFreeChartEngine.BUBBLE_CHART_TYPE:
1656: rtn = ChartDefinition.BUBBLE_CHART_STR;
1657: break;
1658: case JFreeChartEngine.DIAL_CHART_TYPE:
1659: rtn = ChartDefinition.DIAL_CHART_STR;
1660: break;
1661: case JFreeChartEngine.DIFFERENCE_CHART_TYPE:
1662: rtn = ChartDefinition.DIFFERENCE_CHART_STR;
1663: break;
1664: case JFreeChartEngine.DOT_CHART_TYPE:
1665: rtn = ChartDefinition.DOT_CHART_STR;
1666: break;
1667: case JFreeChartEngine.STEP_AREA_CHART_TYPE:
1668: rtn = ChartDefinition.STEP_AREA_CHART_STR;
1669: break;
1670: case JFreeChartEngine.STEP_CHART_TYPE:
1671: rtn = ChartDefinition.STEP_CHART_STR;
1672: break;
1673: case JFreeChartEngine.AREA_CHART_TYPE:
1674: rtn = ChartDefinition.AREA_CHART_STR;
1675: break;
1676: default:
1677: }
1678:
1679: return rtn;
1680: }
1681:
1682: /**
1683: * Creates a java.awt.Color object from an HTML color definition, eg #80dd3f
1684: *
1685: * @param htmlColor
1686: * The color string
1687: * @return A Color object
1688: */
1689: public static Color getColor(String htmlColor) {
1690:
1691: return new Color(Integer
1692: .parseInt(htmlColor.substring(1, 3), 16), Integer
1693: .parseInt(htmlColor.substring(3, 5), 16), Integer
1694: .parseInt(htmlColor.substring(5), 16));
1695: }
1696:
1697: public static Color getTransparent() {
1698: return new Color(0, 0, 0, 0);
1699: }
1700:
1701: /**
1702: * Creates a java.awt.Paint object from an XML node from the dial definition
1703: * document
1704: *
1705: * @param width
1706: * of the chart
1707: * @param height
1708: * of the chart
1709: * @param node
1710: * XML Node from the dial definition
1711: * @return Paint object defined by the node
1712: */
1713: public static Paint getPaint(Node node, int width, int height,
1714: IPentahoSession session) {
1715: if (node == null) {
1716: return null;
1717: }
1718: // TODO support gradient and texture paints
1719: if (null != node.selectSingleNode("gradient")) { //$NON-NLS-1$
1720: return getGradientPaint(
1721: (node.selectSingleNode("gradient")), width, height); //$NON-NLS-1$
1722: } else if (null != node.selectSingleNode("texture")) { //$NON-NLS-1$
1723: return getTexturePaint(
1724: (node.selectSingleNode("texture")), width, height, session); //$NON-NLS-1$
1725: } else {
1726: String htmlColor = node.getText();
1727: return getPaint(htmlColor);
1728: }
1729:
1730: }
1731:
1732: /**
1733: * Creates a java.awt.GradientPaint object from an XML node from the dial
1734: * definition document
1735: *
1736: * @param XML
1737: * Node from the dial definition
1738: * @param width
1739: * of the chart
1740: * @param height
1741: * of the chart
1742: * @return Paint object defined by the node / public static Paint
1743: * getGradientPaint( Node node,int width, int height ) {
1744: *
1745: * if( node == null ) { return null; } Color
1746: * firstColor=getColor((node.selectSingleNode("first-color")).getText().toString());
1747: * //$NON-NLS-1$ Color
1748: * secondColor=getColor((node.selectSingleNode("second-color")).getText().toString());
1749: * //$NON-NLS-1$ boolean cyclic=true;
1750: * if((node.selectSingleNode("cyclic")).getText().trim().equals("false")) {
1751: * //$NON-NLS-1$ //$NON-NLS-2$ cyclic=false; } return new
1752: * GradientPaint(0,0,firstColor,width-(width/2),height,secondColor,cyclic); }
1753: */
1754: /**
1755: * Creates a java.awt.TexturePaint object from an XML node from the dial
1756: * definition document
1757: *
1758: * @param XML
1759: * Node from the dial definition
1760: * @param width
1761: * of the chart
1762: * @param height
1763: * of the chart
1764: * @return Paint object defined by the node / public static Paint
1765: * getTexturePaint( Node node, int width, int height ) {
1766: *
1767: * if( node == null ) { return null; } int rectWidth=width; int
1768: * rectHeight=height; int x=0; int y=0; // Get Image try{ Node imageNode =
1769: * node.selectSingleNode( "background-image" ); //$NON-NLS-1$ if( imageNode !=
1770: * null ) { String imageName = imageNode.getText().toString(); String
1771: * fileName = PentahoSystem.getApplicationContext().getSolutionPath(
1772: * imageName ); int offset = fileName.lastIndexOf( "." ); //$NON-NLS-1$
1773: * String type = offset == -1 ? "jpg" : fileName.substring(offset + 1);
1774: * //$NON-NLS-1$
1775: *
1776: * BufferedImage image = new BufferedImage( width, height,
1777: * BufferedImage.TYPE_INT_ARGB);
1778: *
1779: * ImageIO.write(image, type, new File( fileName ));
1780: *
1781: * Node rectangle= node.selectSingleNode("rectangle"); //$NON-NLS-1$ if(
1782: * rectangle != null ) { Node tmpNode = rectangle.selectSingleNode("width");
1783: * //$NON-NLS-1$ if( tmpNode != null ) {
1784: * rectWidth=Integer.parseInt(tmpNode.getText().toString().trim());
1785: * //$NON-NLS-1$ } tmpNode = rectangle.selectSingleNode("height");
1786: * //$NON-NLS-1$ if( tmpNode != null ) {
1787: * rectHeight=Integer.parseInt(tmpNode.getText().toString().trim());
1788: * //$NON-NLS-1$ } tmpNode = rectangle.selectSingleNode("x"); //$NON-NLS-1$
1789: * if( tmpNode != null ) {
1790: * x=Integer.parseInt(tmpNode.getText().toString().trim()); //$NON-NLS-1$ }
1791: * tmpNode = rectangle.selectSingleNode("y"); //$NON-NLS-1$ if( tmpNode !=
1792: * null ) { y=Integer.parseInt(tmpNode.getText().toString().trim());
1793: * //$NON-NLS-1$ } }
1794: *
1795: * Rectangle2D rect = new Rectangle2D.Double(x,y,rectWidth,rectHeight);
1796: *
1797: * return new TexturePaint(image,rect); }
1798: *
1799: * }catch(Exception e){e.printStackTrace();} return null; }
1800: */
1801: public static Font getFont(Node fontNode) {
1802: Font font = null;
1803: if (fontNode != null) {
1804: String fontFamily = TextTitle.DEFAULT_FONT.getFamily();
1805: int fontStyle = Font.PLAIN;
1806: int fontSize = TextTitle.DEFAULT_FONT.getSize();
1807:
1808: Node fontFamilyNode = fontNode
1809: .selectSingleNode(FONT_FAMILY_NODE_NAME);
1810: if (fontFamilyNode != null
1811: && fontFamilyNode.getText().length() > 0) {
1812: fontFamily = fontFamilyNode.getText();
1813: }
1814: Node isBoldNode = fontNode
1815: .selectSingleNode(IS_BOLD_NODE_NAME);
1816: if (isBoldNode != null) {
1817: boolean bold = Boolean.valueOf(isBoldNode.getText())
1818: .booleanValue();
1819: if (bold) {
1820: fontStyle += Font.BOLD;
1821: }
1822: }
1823: Node isItalicNode = fontNode
1824: .selectSingleNode(IS_ITALIC_NODE_NAME);
1825: if (isItalicNode != null) {
1826: boolean italic = Boolean
1827: .valueOf(isItalicNode.getText()).booleanValue();
1828: if (italic) {
1829: fontStyle += Font.ITALIC;
1830: }
1831: }
1832: Node sizeNode = fontNode.selectSingleNode(SIZE_NODE_NAME);
1833: if (sizeNode != null && sizeNode.getText().length() > 0) {
1834: fontSize = Integer.parseInt(sizeNode.getText());
1835: }
1836: font = new Font(fontFamily, fontStyle, fontSize);
1837: }
1838: return font;
1839: }
1840:
1841: /**
1842: * Creates a java.awt.Paint object from an XML node from the dial definition
1843: * document
1844: *
1845: * @param node
1846: * XML Node from the chart definition
1847: * @return Paint object defined by the node
1848: */
1849: public static Paint getPaint(Node node) {
1850: if (node == null) {
1851: return null;
1852: }
1853: // TODO support gradient and texture paints
1854: String htmlColor = node.getText();
1855: return getPaint(htmlColor);
1856: }
1857:
1858: /**
1859: * Creates a java.awt.Paint object from an HTML color definition, eg #80ff3f
1860: *
1861: * @param htmlColor
1862: * The color string
1863: * @return Paint The Paint object for the requested color
1864: */
1865: public static Paint getPaint(String htmlColor) {
1866:
1867: Color color = getColor(htmlColor);
1868:
1869: return color;
1870: }
1871:
1872: /**
1873: * @param gradientNode
1874: * root node that hold gradient information
1875: * @return a gradientPaint implementation of Paint
1876: */
1877: public static Paint getGradientPaint(Node gradientNode, int width,
1878: int height) {
1879:
1880: if (gradientNode == null) {
1881: return null;
1882: }
1883: float x1 = 0;
1884: float y1 = 0;
1885: float x2 = width;
1886: float y2 = height;
1887:
1888: if (gradientNode.selectSingleNode(X1_NODE_NAME) != null) {
1889: x1 = Float.parseFloat(gradientNode.selectSingleNode(
1890: X1_NODE_NAME).getText());
1891: }
1892: if (gradientNode.selectSingleNode(Y1_NODE_NAME) != null) {
1893: y1 = Float.parseFloat(gradientNode.selectSingleNode(
1894: Y1_NODE_NAME).getText());
1895: }
1896: if (gradientNode.selectSingleNode(X2_NODE_NAME) != null) {
1897: x2 = Float.parseFloat(gradientNode.selectSingleNode(
1898: X2_NODE_NAME).getText());
1899: }
1900: if (gradientNode.selectSingleNode(Y2_NODE_NAME) != null) {
1901: y2 = Float.parseFloat(gradientNode.selectSingleNode(
1902: Y2_NODE_NAME).getText());
1903: }
1904: Color color1 = getColor(gradientNode.selectSingleNode(
1905: COLOR1_NODE_NAME).getText());
1906: Color color2 = getColor(gradientNode.selectSingleNode(
1907: COLOR2_NODE_NAME).getText());
1908: boolean cyclic = false;
1909: if (gradientNode.selectSingleNode(CYCLIC_NODE_NAME) != null) {
1910: cyclic = Boolean.valueOf(
1911: gradientNode.selectSingleNode(CYCLIC_NODE_NAME)
1912: .getText()).booleanValue();
1913: }
1914:
1915: Paint paint = new GradientPaint(x1, y1, color1, x2, y2, color2,
1916: cyclic);
1917: return paint;
1918: }
1919:
1920: /**
1921: * @param textureNode
1922: * root node that holds texture information
1923: * @return
1924: */
1925: public static Paint getTexturePaint(Node textureNode, int width,
1926: int height, IPentahoSession session) {
1927:
1928: if (textureNode == null) {
1929: return null;
1930: }
1931: double x1 = 0.0;
1932: double y1 = 0.0;
1933: double x2 = width;
1934: double y2 = height;
1935: BufferedImage texture = (BufferedImage) getImage(textureNode
1936: .selectSingleNode(TEXTURE_IMAGE_NODE_NAME), session);
1937: if (textureNode.selectSingleNode(X1_NODE_NAME) != null) {
1938: x1 = Double.parseDouble(textureNode.selectSingleNode(
1939: X1_NODE_NAME).getText());
1940: }
1941: if (textureNode.selectSingleNode(Y1_NODE_NAME) != null) {
1942: y1 = Double.parseDouble(textureNode.selectSingleNode(
1943: Y1_NODE_NAME).getText());
1944: }
1945: if (textureNode.selectSingleNode(X2_NODE_NAME) != null) {
1946: x2 = Double.parseDouble(textureNode.selectSingleNode(
1947: X2_NODE_NAME).getText());
1948: }
1949: if (textureNode.selectSingleNode(Y2_NODE_NAME) != null) {
1950: y2 = Double.parseDouble(textureNode.selectSingleNode(
1951: Y2_NODE_NAME).getText());
1952: }
1953: Rectangle2D anchor = new Rectangle2D.Double(x1, y1, x2, y2);
1954:
1955: Paint paint = new TexturePaint(texture, anchor);
1956: return paint;
1957: }
1958:
1959: public static Stroke getLineStyleStroke(String lineStyle,
1960: float lineWidth) {
1961:
1962: BasicStroke stroke = null;
1963: float[] strokeSteps = null;
1964:
1965: // Negative linewidths not allowed; reset to default;
1966: if (lineWidth < 0) {
1967: lineWidth = 1.0f;
1968: }
1969:
1970: if (lineStyle != null) {
1971: if (lineStyle.equals(ChartDefinition.LINE_STYLE_DASH_STR)) {
1972: strokeSteps = new float[] { 6.0f, 6.0f };
1973: } else if (lineStyle
1974: .equals(ChartDefinition.LINE_STYLE_DOT_STR)) {
1975: strokeSteps = new float[] { 2.0f, 6.0f };
1976: } else if (lineStyle
1977: .equals(ChartDefinition.LINE_STYLE_DASHDOT_STR)) {
1978: strokeSteps = new float[] { 10.0f, 6.0f, 2.0f, 6.0f };
1979: } else if (lineStyle
1980: .equals(ChartDefinition.LINE_STYLE_DASHDOTDOT_STR)) {
1981: strokeSteps = new float[] { 10.0f, 6.0f, 2.0f, 6.0f,
1982: 2.0f, 6.0f };
1983: }
1984: }
1985:
1986: if (strokeSteps != null) {
1987: stroke = new BasicStroke(lineWidth, BasicStroke.CAP_ROUND,
1988: BasicStroke.JOIN_ROUND, 1.0f, strokeSteps, 0.0f);
1989: } else {
1990: stroke = new BasicStroke(lineWidth);
1991: }
1992: return stroke;
1993: }
1994:
1995: /**
1996: * @param chartBackgroundImageNode -
1997: * Node that contains a path to the images in its text element
1998: * @return the image
1999: */
2000: public static Image getImage(Node chartBackgroundImageNode,
2001: IPentahoSession session) {
2002: Image image = null;
2003: if (chartBackgroundImageNode != null
2004: && chartBackgroundImageNode.getText().length() > 0) {
2005: return getImage(chartBackgroundImageNode.getText(), session);
2006: }
2007: return image;
2008: }
2009:
2010: /**
2011: * @param imageName
2012: * String that contains a path to the image
2013: * @return the image
2014: */
2015: public static Image getImage(String imageName,
2016: IPentahoSession session) {
2017: Image image = null;
2018: ISolutionRepository repository = PentahoSystem
2019: .getSolutionRepository(session);
2020: try {
2021: InputStream is = repository.getResourceInputStream(
2022: imageName, true);
2023: image = ImageIO.read(is);
2024: } catch (IOException e) {
2025: // TODO Auto-generated catch block
2026: e.printStackTrace();
2027: }
2028: return image;
2029: }
2030:
2031: /*
2032: * Two methods for the BarLineChart - Determine if a column of the data set
2033: * is part of the defined bar or line char columns
2034: */
2035: public static boolean isBarColumn(String[] barColumns,
2036: String columnName) {
2037: boolean bIsBarColumn = false;
2038:
2039: for (int i = 0; i < barColumns.length; i++) {
2040: bIsBarColumn = columnName.equalsIgnoreCase(barColumns[i]);
2041: if (bIsBarColumn)
2042: break;
2043: }
2044: return bIsBarColumn;
2045: }
2046:
2047: public static boolean isLineColumn(String[] lineColumns,
2048: String columnName) {
2049: boolean bIsLineColumn = false;
2050:
2051: for (int i = 0; i < lineColumns.length; i++) {
2052: bIsLineColumn = columnName.equalsIgnoreCase(lineColumns[i]);
2053: if (bIsLineColumn)
2054: break;
2055: }
2056: return bIsLineColumn;
2057: }
2058:
2059: }
|