/* =============================================================================== * * Part of the InfoGlue Content Management Platform (www.infoglue.org) * * =============================================================================== * * Copyright (C) * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2, as published by the * Free Software Foundation. See the file LICENSE.html for more information. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc. / 59 Temple * Place, Suite 330 / Boston, MA 02111-1307 / USA. * * =============================================================================== */ package org.infoglue.deliver.util.charts; import java.awt.Color; import java.text.SimpleDateFormat; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import org.infoglue.cms.util.dom.DOMBuilder; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.DateTickMarkPosition; import org.jfree.chart.axis.DateTickUnit; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.StandardXYItemRenderer; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.title.LegendTitle; import org.jfree.data.time.Month; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.data.time.Week; import org.jfree.data.xy.XYDataset; import org.jfree.ui.RectangleInsets; import org.jfree.util.UnitType; /** * An example of a time series chart. For the most part, default settings are used, except that * the renderer is modified to show filled shapes (as well as lines) at each data point. * * @author David Gilbert */ public class TimeSeriesDiagram implements XMLDataDiagram { private JFreeChart chart; private String xmlData; private String dateFormat; private String header; private String axisYHeader; private String axisXHeader; private String timeGranulariry; public JFreeChart getChart() { return chart; } public void setChart(JFreeChart chart) { this.chart = chart; } public void renderChart() throws Exception { XYDataset dataset = createDataset(); JFreeChart chart = createChart(dataset); this.chart = chart; } /** * Creates a chart. * * @param dataset a dataset. * * @return A chart. */ private JFreeChart createChart(XYDataset dataset) { JFreeChart chart = ChartFactory.createTimeSeriesChart(header, axisXHeader, axisYHeader, dataset, true, true, false); chart.setBackgroundPaint(Color.white); LegendTitle legend = chart.getLegend(); //legend.set .setDisplaySeriesShapes(true); XYPlot plot = chart.getXYPlot(); plot.setBackgroundPaint(Color.lightGray); plot.setDomainGridlinePaint(Color.white); plot.setRangeGridlinePaint(Color.white); plot.setAxisOffset(new RectangleInsets(UnitType.ABSOLUTE, 5.0, 5.0, 5.0, 5.0)); plot.setDomainCrosshairVisible(true); plot.setRangeCrosshairVisible(true); XYItemRenderer renderer = plot.getRenderer(); if (renderer instanceof StandardXYItemRenderer) { StandardXYItemRenderer rr = (StandardXYItemRenderer) renderer; //rr.setPlotShapes(true); rr.setShapesFilled(true); } DateAxis axis = (DateAxis) plot.getDomainAxis(); if(this.timeGranulariry.equalsIgnoreCase("Week")) { DateTickUnit unit = new DateTickUnit(DateTickUnit.DAY, 7, new SimpleDateFormat(this.dateFormat)); axis.setTickUnit(unit); axis.setTickMarkPosition(DateTickMarkPosition.START); axis.setDateFormatOverride(new SimpleDateFormat(this.dateFormat)); } else { axis.setDateFormatOverride(new SimpleDateFormat(this.dateFormat)); } /* DateAxis axis = (DateAxis) plot.getDomainAxis(); axis.setDateFormatOverride(new SimpleDateFormat(this.dateFormat)); */ return chart; } /** * Creates a dataset, consisting of two series of monthly data. * * @return the dataset. */ private XYDataset createDataset() throws Exception { TimeSeriesCollection timeSeriesDataset = new TimeSeriesCollection(); Document document = new DOMBuilder().getDocument(this.xmlData); this.writeDebug(document); Element headerElement = (Element)document.selectSingleNode("//chartHeader"); this.header = headerElement.getText(); Element axisYHeaderElement = (Element)document.selectSingleNode("//axisYHeader"); this.axisYHeader = axisYHeaderElement.getText(); Element axisXHeaderElement = (Element)document.selectSingleNode("//axisXHeader"); this.axisXHeader = axisXHeaderElement.getText(); Element timeGranularityElement = (Element)document.selectSingleNode("//timeGranularity"); this.timeGranulariry = timeGranularityElement.getText(); Element dateFormatElement = (Element)document.selectSingleNode("//dateFormat"); this.dateFormat = dateFormatElement.getText(); List series = document.selectNodes("//Series"); Iterator seriesIterator = series.iterator(); while(seriesIterator.hasNext()) { Element serieElement = (Element)seriesIterator.next(); String serieName = serieElement.attributeValue("name"); TimeSeries s1 = null; if(this.timeGranulariry.equalsIgnoreCase("Month")) s1 = new TimeSeries(serieName, Month.class); else if(this.timeGranulariry.equalsIgnoreCase("Week")) s1 = new TimeSeries(serieName, Week.class); List items = serieElement.selectNodes("Item"); Iterator itemsIterator = items.iterator(); while(itemsIterator.hasNext()) { Element itemElement = (Element)itemsIterator.next(); Element yearElement = (Element)itemElement.selectSingleNode("yearId"); Element timeElement = (Element)itemElement.selectSingleNode("timeId"); Element valueElement = (Element)itemElement.selectSingleNode("value"); String year = yearElement.getText(); String time = timeElement.getText(); String value = valueElement.getText(); if(this.timeGranulariry.equalsIgnoreCase("Month")) s1.add(new Month(new Integer(time).intValue(), new Integer(year).intValue()), new Float(value)); else if(this.timeGranulariry.equalsIgnoreCase("Week")) s1.add(new Week(new Integer(time).intValue(), new Integer(year).intValue()), new Float(value)); } timeSeriesDataset.addSeries(s1); //timeSeriesDataset.addSeries(s2); timeSeriesDataset.setDomainIsPointsInTime(true); } return timeSeriesDataset; } /** * This method takes xml as input for the diagram. */ public void setDiagramData(String xmlData) { this.xmlData = xmlData; } /** * This method writes a document to sysout. */ public void writeDebug(Document document) throws Exception { OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter( System.out, format ); writer.write( document ); } }