JFreeChart : a free chart library for the Java(tm) platform

001/* ===========================================================
002 * JFreeChart : a free chart library for the Java(tm) platform
003 * ===========================================================
004 *
005 * (C) Copyright 2000-2011, by Object Refinery Limited and Contributors.
006 *
007 * Project Info:  http://www.jfree.org/jfreechart/index.html
008 *
009 * This library is free software; you can redistribute it and/or modify it
010 * under the terms of the GNU Lesser General Public License as published by
011 * the Free Software Foundation; either version 2.1 of the License, or
012 * (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but
015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017 * License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this library; if not, write to the Free Software
021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
022 * USA.
023 *
024 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 
025 * Other names may be trademarks of their respective owners.]
026 *
027 * -----------------
028 * ChartFactory.java
029 * -----------------
030 * (C) Copyright 2001-2009, by Object Refinery Limited and Contributors.
031 *
032 * Original Author:  David Gilbert (for Object Refinery Limited);
033 * Contributor(s):   Serge V. Grachov;
034 *                   Joao Guilherme Del Valle;
035 *                   Bill Kelemen;
036 *                   Jon Iles;
037 *                   Jelai Wang;
038 *                   Richard Atkinson;
039 *                   David Browning (for Australian Institute of Marine
040 *                       Science);
041 *                   Benoit Xhenseval;
042 *
043 * Changes
044 * -------
045 * 19-Oct-2001 : Version 1, most methods transferred from JFreeChart.java (DG);
046 * 22-Oct-2001 : Added methods to create stacked bar charts (DG);
047 *               Renamed DataSource.java --> Dataset.java etc. (DG);
048 * 31-Oct-2001 : Added 3D-effect vertical bar and stacked-bar charts,
049 *               contributed by Serge V. Grachov (DG);
050 * 07-Nov-2001 : Added a flag to control whether or not a legend is added to
051 *               the chart (DG);
052 * 17-Nov-2001 : For pie chart, changed dataset from CategoryDataset to
053 *               PieDataset (DG);
054 * 30-Nov-2001 : Removed try/catch handlers from chart creation, as the
055 *               exception are now RuntimeExceptions, as suggested by Joao
056 *               Guilherme Del Valle (DG);
057 * 06-Dec-2001 : Added createCombinableXXXXXCharts methods (BK);
058 * 12-Dec-2001 : Added createCandlestickChart() method (DG);
059 * 13-Dec-2001 : Updated methods for charts with new renderers (DG);
060 * 08-Jan-2002 : Added import for
061 *               com.jrefinery.chart.combination.CombinedChart (DG);
062 * 31-Jan-2002 : Changed the createCombinableVerticalXYBarChart() method to use
063 *               renderer (DG);
064 * 06-Feb-2002 : Added new method createWindPlot() (DG);
065 * 23-Apr-2002 : Updates to the chart and plot constructor API (DG);
066 * 21-May-2002 : Added new method createAreaChart() (JI);
067 * 06-Jun-2002 : Added new method createGanttChart() (DG);
068 * 11-Jun-2002 : Renamed createHorizontalStackedBarChart()
069 *               --> createStackedHorizontalBarChart() for consistency (DG);
070 * 06-Aug-2002 : Updated Javadoc comments (DG);
071 * 21-Aug-2002 : Added createPieChart(CategoryDataset) method (DG);
072 * 02-Oct-2002 : Fixed errors reported by Checkstyle (DG);
073 * 09-Oct-2002 : Added methods including tooltips and URL flags (DG);
074 * 06-Nov-2002 : Moved renderers into a separate package (DG);
075 * 18-Nov-2002 : Changed CategoryDataset to TableDataset (DG);
076 * 21-Mar-2003 : Incorporated HorizontalCategoryAxis3D, see bug id 685501 (DG);
077 * 13-May-2003 : Merged some horizontal and vertical methods (DG);
078 * 24-May-2003 : Added support for timeline in createHighLowChart (BK);
079 * 07-Jul-2003 : Added createHistogram() method contributed by Jelai Wang (DG);
080 * 27-Jul-2003 : Added createStackedAreaXYChart() method (RA);
081 * 05-Aug-2003 : added new method createBoxAndWhiskerChart (DB);
082 * 08-Sep-2003 : Changed ValueAxis API (DG);
083 * 07-Oct-2003 : Added stepped area XY chart contributed by Matthias Rose (DG);
084 * 06-Nov-2003 : Added createWaterfallChart() method (DG);
085 * 20-Nov-2003 : Set rendering order for 3D bar charts to fix overlapping
086 *               problems (DG);
087 * 25-Nov-2003 : Added createWaferMapChart() method (DG);
088 * 23-Dec-2003 : Renamed createPie3DChart() --> createPieChart3D for
089 *               consistency (DG);
090 * 20-Jan-2004 : Added createPolarChart() method (DG);
091 * 28-Jan-2004 : Fixed bug (882890) with axis range in
092 *               createStackedXYAreaChart() method (DG);
093 * 25-Feb-2004 : Renamed XYToolTipGenerator --> XYItemLabelGenerator (DG);
094 * 11-Mar-2004 : Updated for pie chart changes (DG);
095 * 27-Apr-2004 : Added new createPieChart() method contributed by Benoit
096 *               Xhenseval (see RFE 942195) (DG);
097 * 11-May-2004 : Split StandardCategoryItemLabelGenerator
098 *               --> StandardCategoryToolTipGenerator and
099 *               StandardCategoryLabelGenerator (DG);
100 * 06-Jan-2005 : Removed deprecated methods (DG);
101 * 27-Jan-2005 : Added new constructor to LineAndShapeRenderer (DG);
102 * 28-Feb-2005 : Added docs to createBubbleChart() method (DG);
103 * 17-Mar-2005 : Added createRingPlot() method (DG);
104 * 21-Apr-2005 : Replaced Insets with RectangleInsets (DG);
105 * 29-Nov-2005 : Removed signal chart (DG);
106 * ------------- JFREECHART 1.0.x ---------------------------------------------
107 * 26-Jan-2006 : Corrected API docs for createScatterPlot() (DG);
108 * 23-Aug-2006 : Modified createStackedXYAreaChart() to use
109 *               StackedXYAreaRenderer2, because StackedXYAreaRenderer doesn't
110 *               handle negative values (DG);
111 * 27-Sep-2006 : Update createPieChart() method for deprecated code (DG);
112 * 29-Nov-2006 : Update createXYBarChart() to use a time based tool tip
113 *               generator is a DateAxis is requested (DG);
114 * 17-Jan-2007 : Added createBoxAndWhiskerChart() method from patch 1603937
115 *               submitted by Darren Jung (DG);
116 * 10-Jul-2007 : Added new methods to create pie charts with locale for
117 *               section label and tool tip formatting (DG);
118 * 14-Aug-2008 : Added ChartTheme facility (DG);
119 * 23-Oct-2008 : Check for legacy theme in setChartTheme() and reset default
120 *               bar painters (DG);
121 * 20-Dec-2008 : In createStackedAreaChart(), set category margin to 0.0 (DG);
122 *
123 */
124
125package org.jfree.chart;
126
127import java.awt.Color;
128import java.awt.Font;
129import java.text.DateFormat;
130import java.text.NumberFormat;
131import java.util.Iterator;
132import java.util.List;
133import java.util.Locale;
134
135import org.jfree.chart.axis.CategoryAxis;
136import org.jfree.chart.axis.CategoryAxis3D;
137import org.jfree.chart.axis.DateAxis;
138import org.jfree.chart.axis.NumberAxis;
139import org.jfree.chart.axis.NumberAxis3D;
140import org.jfree.chart.axis.Timeline;
141import org.jfree.chart.axis.ValueAxis;
142import org.jfree.chart.labels.BoxAndWhiskerToolTipGenerator;
143import org.jfree.chart.labels.HighLowItemLabelGenerator;
144import org.jfree.chart.labels.IntervalCategoryToolTipGenerator;
145import org.jfree.chart.labels.ItemLabelAnchor;
146import org.jfree.chart.labels.ItemLabelPosition;
147import org.jfree.chart.labels.PieToolTipGenerator;
148import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
149import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
150import org.jfree.chart.labels.StandardPieToolTipGenerator;
151import org.jfree.chart.labels.StandardXYToolTipGenerator;
152import org.jfree.chart.labels.StandardXYZToolTipGenerator;
153import org.jfree.chart.labels.XYToolTipGenerator;
154import org.jfree.chart.plot.CategoryPlot;
155import org.jfree.chart.plot.Marker;
156import org.jfree.chart.plot.MultiplePiePlot;
157import org.jfree.chart.plot.PiePlot;
158import org.jfree.chart.plot.PiePlot3D;
159import org.jfree.chart.plot.PlotOrientation;
160import org.jfree.chart.plot.PolarPlot;
161import org.jfree.chart.plot.RingPlot;
162import org.jfree.chart.plot.ValueMarker;
163import org.jfree.chart.plot.WaferMapPlot;
164import org.jfree.chart.plot.XYPlot;
165import org.jfree.chart.renderer.DefaultPolarItemRenderer;
166import org.jfree.chart.renderer.WaferMapRenderer;
167import org.jfree.chart.renderer.category.AreaRenderer;
168import org.jfree.chart.renderer.category.BarRenderer;
169import org.jfree.chart.renderer.category.BarRenderer3D;
170import org.jfree.chart.renderer.category.BoxAndWhiskerRenderer;
171import org.jfree.chart.renderer.category.CategoryItemRenderer;
172import org.jfree.chart.renderer.category.GanttRenderer;
173import org.jfree.chart.renderer.category.GradientBarPainter;
174import org.jfree.chart.renderer.category.LineAndShapeRenderer;
175import org.jfree.chart.renderer.category.LineRenderer3D;
176import org.jfree.chart.renderer.category.StackedAreaRenderer;
177import org.jfree.chart.renderer.category.StackedBarRenderer;
178import org.jfree.chart.renderer.category.StackedBarRenderer3D;
179import org.jfree.chart.renderer.category.StandardBarPainter;
180import org.jfree.chart.renderer.category.WaterfallBarRenderer;
181import org.jfree.chart.renderer.xy.CandlestickRenderer;
182import org.jfree.chart.renderer.xy.GradientXYBarPainter;
183import org.jfree.chart.renderer.xy.HighLowRenderer;
184import org.jfree.chart.renderer.xy.StackedXYAreaRenderer2;
185import org.jfree.chart.renderer.xy.StandardXYBarPainter;
186import org.jfree.chart.renderer.xy.WindItemRenderer;
187import org.jfree.chart.renderer.xy.XYAreaRenderer;
188import org.jfree.chart.renderer.xy.XYBarRenderer;
189import org.jfree.chart.renderer.xy.XYBoxAndWhiskerRenderer;
190import org.jfree.chart.renderer.xy.XYBubbleRenderer;
191import org.jfree.chart.renderer.xy.XYItemRenderer;
192import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
193import org.jfree.chart.renderer.xy.XYStepAreaRenderer;
194import org.jfree.chart.renderer.xy.XYStepRenderer;
195import org.jfree.chart.title.TextTitle;
196import org.jfree.chart.urls.PieURLGenerator;
197import org.jfree.chart.urls.StandardCategoryURLGenerator;
198import org.jfree.chart.urls.StandardPieURLGenerator;
199import org.jfree.chart.urls.StandardXYURLGenerator;
200import org.jfree.chart.urls.StandardXYZURLGenerator;
201import org.jfree.chart.urls.XYURLGenerator;
202import org.jfree.data.category.CategoryDataset;
203import org.jfree.data.category.IntervalCategoryDataset;
204import org.jfree.data.general.DefaultPieDataset;
205import org.jfree.data.general.PieDataset;
206import org.jfree.data.general.WaferMapDataset;
207import org.jfree.data.statistics.BoxAndWhiskerCategoryDataset;
208import org.jfree.data.statistics.BoxAndWhiskerXYDataset;
209import org.jfree.data.xy.IntervalXYDataset;
210import org.jfree.data.xy.OHLCDataset;
211import org.jfree.data.xy.TableXYDataset;
212import org.jfree.data.xy.WindDataset;
213import org.jfree.data.xy.XYDataset;
214import org.jfree.data.xy.XYZDataset;
215import org.jfree.ui.Layer;
216import org.jfree.ui.RectangleEdge;
217import org.jfree.ui.RectangleInsets;
218import org.jfree.ui.TextAnchor;
219import org.jfree.util.SortOrder;
220import org.jfree.util.TableOrder;
221
222/**
223 * A collection of utility methods for creating some standard charts with
224 * JFreeChart.
225 */
226public abstract class ChartFactory {
227
228    /** The chart theme. */
229    private static ChartTheme currentTheme = new StandardChartTheme("JFree");
230
231    /**
232     * Returns the current chart theme used by the factory.
233     *
234     * @return The chart theme.
235     *
236     * @see #setChartTheme(ChartTheme)
237     * @see ChartUtilities#applyCurrentTheme(JFreeChart)
238     *
239     * @since 1.0.11
240     */
241    public static ChartTheme getChartTheme() {
242        return currentTheme;
243    }
244
245    /**
246     * Sets the current chart theme.  This will be applied to all new charts
247     * created via methods in this class.
248     *
249     * @param theme  the theme (<code>null</code> not permitted).
250     *
251     * @see #getChartTheme()
252     * @see ChartUtilities#applyCurrentTheme(JFreeChart)
253     *
254     * @since 1.0.11
255     */
256    public static void setChartTheme(ChartTheme theme) {
257        if (theme == null) {
258            throw new IllegalArgumentException("Null 'theme' argument.");
259        }
260        currentTheme = theme;
261
262        // here we do a check to see if the user is installing the "Legacy"
263        // theme, and reset the bar painters in that case...
264        if (theme instanceof StandardChartTheme) {
265            StandardChartTheme sct = (StandardChartTheme) theme;
266            if (sct.getName().equals("Legacy")) {
267                BarRenderer.setDefaultBarPainter(new StandardBarPainter());
268                XYBarRenderer.setDefaultBarPainter(new StandardXYBarPainter());
269            }
270            else {
271                BarRenderer.setDefaultBarPainter(new GradientBarPainter());
272                XYBarRenderer.setDefaultBarPainter(new GradientXYBarPainter());
273            }
274        }
275    }
276
277    /**
278     * Creates a pie chart with default settings.
279     * <P>
280     * The chart object returned by this method uses a {@link PiePlot} instance
281     * as the plot.
282     *
283     * @param title  the chart title (<code>null</code> permitted).
284     * @param dataset  the dataset for the chart (<code>null</code> permitted).
285     * @param legend  a flag specifying whether or not a legend is required.
286     * @param tooltips  configure chart to generate tool tips?
287     * @param locale  the locale (<code>null</code> not permitted).
288     *
289     * @return A pie chart.
290     *
291     * @since 1.0.7
292     */
293    public static JFreeChart createPieChart(String title, PieDataset dataset,
294            boolean legend, boolean tooltips, Locale locale) {
295
296        PiePlot plot = new PiePlot(dataset);
297        plot.setLabelGenerator(new StandardPieSectionLabelGenerator(locale));
298        plot.setInsets(new RectangleInsets(0.0, 5.0, 5.0, 5.0));
299        if (tooltips) {
300            plot.setToolTipGenerator(new StandardPieToolTipGenerator(locale));
301        }
302        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
303                plot, legend);
304        currentTheme.apply(chart);
305        return chart;
306
307    }
308
309    /**
310     * Creates a pie chart with default settings.
311     * <P>
312     * The chart object returned by this method uses a {@link PiePlot} instance
313     * as the plot.
314     *
315     * @param title  the chart title (<code>null</code> permitted).
316     * @param dataset  the dataset for the chart (<code>null</code> permitted).
317     * @param legend  a flag specifying whether or not a legend is required.
318     * @param tooltips  configure chart to generate tool tips?
319     * @param urls  configure chart to generate URLs?
320     *
321     * @return A pie chart.
322     */
323    public static JFreeChart createPieChart(String title,
324                                            PieDataset dataset,
325                                            boolean legend,
326                                            boolean tooltips,
327                                            boolean urls) {
328
329        PiePlot plot = new PiePlot(dataset);
330        plot.setLabelGenerator(new StandardPieSectionLabelGenerator());
331        plot.setInsets(new RectangleInsets(0.0, 5.0, 5.0, 5.0));
332        if (tooltips) {
333            plot.setToolTipGenerator(new StandardPieToolTipGenerator());
334        }
335        if (urls) {
336            plot.setURLGenerator(new StandardPieURLGenerator());
337        }
338        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
339                plot, legend);
340        currentTheme.apply(chart);
341        return chart;
342    }
343
344    /**
345     * Creates a pie chart with default settings that compares 2 datasets.
346     * The colour of each section will be determined by the move from the value
347     * for the same key in <code>previousDataset</code>. ie if value1 > value2
348     * then the section will be in green (unless <code>greenForIncrease</code>
349     * is <code>false</code>, in which case it would be <code>red</code>).
350     * Each section can have a shade of red or green as the difference can be
351     * tailored between 0% (black) and percentDiffForMaxScale% (bright
352     * red/green).
353     * <p>
354     * For instance if <code>percentDiffForMaxScale</code> is 10 (10%), a
355     * difference of 5% will have a half shade of red/green, a difference of
356     * 10% or more will have a maximum shade/brightness of red/green.
357     * <P>
358     * The chart object returned by this method uses a {@link PiePlot} instance
359     * as the plot.
360     * <p>
361     * Written by <a href="mailto:opensource@objectlab.co.uk">Benoit
362     * Xhenseval</a>.
363     *
364     * @param title  the chart title (<code>null</code> permitted).
365     * @param dataset  the dataset for the chart (<code>null</code> permitted).
366     * @param previousDataset  the dataset for the last run, this will be used
367     *                         to compare each key in the dataset
368     * @param percentDiffForMaxScale scale goes from bright red/green to black,
369     *                               percentDiffForMaxScale indicate the change
370     *                               required to reach top scale.
371     * @param greenForIncrease  an increase since previousDataset will be
372     *                          displayed in green (decrease red) if true.
373     * @param legend  a flag specifying whether or not a legend is required.
374     * @param tooltips  configure chart to generate tool tips?
375     * @param locale  the locale (<code>null</code> not permitted).
376     * @param subTitle displays a subtitle with colour scheme if true
377     * @param showDifference  create a new dataset that will show the %
378     *                        difference between the two datasets.
379     *
380     * @return A pie chart.
381     *
382     * @since 1.0.7
383     */
384    public static JFreeChart createPieChart(String title, PieDataset dataset,
385            PieDataset previousDataset, int percentDiffForMaxScale,
386            boolean greenForIncrease, boolean legend, boolean tooltips,
387            Locale locale, boolean subTitle, boolean showDifference) {
388
389        PiePlot plot = new PiePlot(dataset);
390        plot.setLabelGenerator(new StandardPieSectionLabelGenerator(locale));
391        plot.setInsets(new RectangleInsets(0.0, 5.0, 5.0, 5.0));
392
393        if (tooltips) {
394            plot.setToolTipGenerator(new StandardPieToolTipGenerator(locale));
395        }
396
397        List keys = dataset.getKeys();
398        DefaultPieDataset series = null;
399        if (showDifference) {
400            series = new DefaultPieDataset();
401        }
402
403        double colorPerPercent = 255.0 / percentDiffForMaxScale;
404        for (Iterator it = keys.iterator(); it.hasNext();) {
405            Comparable key = (Comparable) it.next();
406            Number newValue = dataset.getValue(key);
407            Number oldValue = previousDataset.getValue(key);
408
409            if (oldValue == null) {
410                if (greenForIncrease) {
411                    plot.setSectionPaint(key, Color.green);
412                }
413                else {
414                    plot.setSectionPaint(key, Color.red);
415                }
416                if (showDifference) {
417                    series.setValue(key + " (+100%)", newValue);
418                }
419            }
420            else {
421                double percentChange = (newValue.doubleValue()
422                        / oldValue.doubleValue() - 1.0) * 100.0;
423                double shade
424                    = (Math.abs(percentChange) >= percentDiffForMaxScale ? 255
425                    : Math.abs(percentChange) * colorPerPercent);
426                if (greenForIncrease
427                        && newValue.doubleValue() > oldValue.doubleValue()
428                        || !greenForIncrease && newValue.doubleValue()
429                        < oldValue.doubleValue()) {
430                    plot.setSectionPaint(key, new Color(0, (int) shade, 0));
431                }
432                else {
433                    plot.setSectionPaint(key, new Color((int) shade, 0, 0));
434                }
435                if (showDifference) {
436                    series.setValue(key + " (" + (percentChange >= 0 ? "+" : "")
437                            + NumberFormat.getPercentInstance().format(
438                            percentChange / 100.0) + ")", newValue);
439                }
440            }
441        }
442
443        if (showDifference) {
444            plot.setDataset(series);
445        }
446
447        JFreeChart chart =  new JFreeChart(title,
448                JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
449
450        if (subTitle) {
451            TextTitle subtitle = null;
452            subtitle = new TextTitle("Bright " + (greenForIncrease ? "red"
453                    : "green") + "=change >=-" + percentDiffForMaxScale
454                    + "%, Bright " + (!greenForIncrease ? "red" : "green")
455                    + "=change >=+" + percentDiffForMaxScale + "%",
456                    new Font("SansSerif", Font.PLAIN, 10));
457            chart.addSubtitle(subtitle);
458        }
459        currentTheme.apply(chart);
460        return chart;
461    }
462
463    /**
464     * Creates a pie chart with default settings that compares 2 datasets.
465     * The colour of each section will be determined by the move from the value
466     * for the same key in <code>previousDataset</code>. ie if value1 > value2
467     * then the section will be in green (unless <code>greenForIncrease</code>
468     * is <code>false</code>, in which case it would be <code>red</code>).
469     * Each section can have a shade of red or green as the difference can be
470     * tailored between 0% (black) and percentDiffForMaxScale% (bright
471     * red/green).
472     * <p>
473     * For instance if <code>percentDiffForMaxScale</code> is 10 (10%), a
474     * difference of 5% will have a half shade of red/green, a difference of
475     * 10% or more will have a maximum shade/brightness of red/green.
476     * <P>
477     * The chart object returned by this method uses a {@link PiePlot} instance
478     * as the plot.
479     * <p>
480     * Written by <a href="mailto:opensource@objectlab.co.uk">Benoit
481     * Xhenseval</a>.
482     *
483     * @param title  the chart title (<code>null</code> permitted).
484     * @param dataset  the dataset for the chart (<code>null</code> permitted).
485     * @param previousDataset  the dataset for the last run, this will be used
486     *                         to compare each key in the dataset
487     * @param percentDiffForMaxScale scale goes from bright red/green to black,
488     *                               percentDiffForMaxScale indicate the change
489     *                               required to reach top scale.
490     * @param greenForIncrease  an increase since previousDataset will be
491     *                          displayed in green (decrease red) if true.
492     * @param legend  a flag specifying whether or not a legend is required.
493     * @param tooltips  configure chart to generate tool tips?
494     * @param urls  configure chart to generate URLs?
495     * @param subTitle displays a subtitle with colour scheme if true
496     * @param showDifference  create a new dataset that will show the %
497     *                        difference between the two datasets.
498     *
499     * @return A pie chart.
500     */
501    public static JFreeChart createPieChart(String title,
502                                            PieDataset dataset,
503                                            PieDataset previousDataset,
504                                            int percentDiffForMaxScale,
505                                            boolean greenForIncrease,
506                                            boolean legend,
507                                            boolean tooltips,
508                                            boolean urls,
509                                            boolean subTitle,
510                                            boolean showDifference) {
511
512        PiePlot plot = new PiePlot(dataset);
513        plot.setLabelGenerator(new StandardPieSectionLabelGenerator());
514        plot.setInsets(new RectangleInsets(0.0, 5.0, 5.0, 5.0));
515
516        if (tooltips) {
517            plot.setToolTipGenerator(new StandardPieToolTipGenerator());
518        }
519        if (urls) {
520            plot.setURLGenerator(new StandardPieURLGenerator());
521        }
522
523        List keys = dataset.getKeys();
524        DefaultPieDataset series = null;
525        if (showDifference) {
526            series = new DefaultPieDataset();
527        }
528
529        double colorPerPercent = 255.0 / percentDiffForMaxScale;
530        for (Iterator it = keys.iterator(); it.hasNext();) {
531            Comparable key = (Comparable) it.next();
532            Number newValue = dataset.getValue(key);
533            Number oldValue = previousDataset.getValue(key);
534
535            if (oldValue == null) {
536                if (greenForIncrease) {
537                    plot.setSectionPaint(key, Color.green);
538                }
539                else {
540                    plot.setSectionPaint(key, Color.red);
541                }
542                if (showDifference) {
543                    series.setValue(key + " (+100%)", newValue);
544                }
545            }
546            else {
547                double percentChange = (newValue.doubleValue()
548                        / oldValue.doubleValue() - 1.0) * 100.0;
549                double shade
550                    = (Math.abs(percentChange) >= percentDiffForMaxScale ? 255
551                    : Math.abs(percentChange) * colorPerPercent);
552                if (greenForIncrease
553                        && newValue.doubleValue() > oldValue.doubleValue()
554                        || !greenForIncrease && newValue.doubleValue()
555                        < oldValue.doubleValue()) {
556                    plot.setSectionPaint(key, new Color(0, (int) shade, 0));
557                }
558                else {
559                    plot.setSectionPaint(key, new Color((int) shade, 0, 0));
560                }
561                if (showDifference) {
562                    series.setValue(key + " (" + (percentChange >= 0 ? "+" : "")
563                            + NumberFormat.getPercentInstance().format(
564                            percentChange / 100.0) + ")", newValue);
565                }
566            }
567        }
568
569        if (showDifference) {
570            plot.setDataset(series);
571        }
572
573        JFreeChart chart =  new JFreeChart(title,
574                JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
575
576        if (subTitle) {
577            TextTitle subtitle = null;
578            subtitle = new TextTitle("Bright " + (greenForIncrease ? "red"
579                    : "green") + "=change >=-" + percentDiffForMaxScale
580                    + "%, Bright " + (!greenForIncrease ? "red" : "green")
581                    + "=change >=+" + percentDiffForMaxScale + "%",
582                    new Font("SansSerif", Font.PLAIN, 10));
583            chart.addSubtitle(subtitle);
584        }
585        currentTheme.apply(chart);
586        return chart;
587    }
588
589    /**
590     * Creates a ring chart with default settings.
591     * <P>
592     * The chart object returned by this method uses a {@link RingPlot}
593     * instance as the plot.
594     *
595     * @param title  the chart title (<code>null</code> permitted).
596     * @param dataset  the dataset for the chart (<code>null</code> permitted).
597     * @param legend  a flag specifying whether or not a legend is required.
598     * @param tooltips  configure chart to generate tool tips?
599     * @param locale  the locale (<code>null</code> not permitted).
600     *
601     * @return A ring chart.
602     *
603     * @since 1.0.7
604     */
605    public static JFreeChart createRingChart(String title, PieDataset dataset,
606            boolean legend, boolean tooltips, Locale locale) {
607
608        RingPlot plot = new RingPlot(dataset);
609        plot.setLabelGenerator(new StandardPieSectionLabelGenerator(locale));
610        plot.setInsets(new RectangleInsets(0.0, 5.0, 5.0, 5.0));
611        if (tooltips) {
612            plot.setToolTipGenerator(new StandardPieToolTipGenerator(locale));
613        }
614        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
615                plot, legend);
616        currentTheme.apply(chart);
617        return chart;
618    }
619
620    /**
621     * Creates a ring chart with default settings.
622     * <P>
623     * The chart object returned by this method uses a {@link RingPlot}
624     * instance as the plot.
625     *
626     * @param title  the chart title (<code>null</code> permitted).
627     * @param dataset  the dataset for the chart (<code>null</code> permitted).
628     * @param legend  a flag specifying whether or not a legend is required.
629     * @param tooltips  configure chart to generate tool tips?
630     * @param urls  configure chart to generate URLs?
631     *
632     * @return A ring chart.
633     */
634    public static JFreeChart createRingChart(String title,
635                                             PieDataset dataset,
636                                             boolean legend,
637                                             boolean tooltips,
638                                             boolean urls) {
639
640        RingPlot plot = new RingPlot(dataset);
641        plot.setLabelGenerator(new StandardPieSectionLabelGenerator());
642        plot.setInsets(new RectangleInsets(0.0, 5.0, 5.0, 5.0));
643        if (tooltips) {
644            plot.setToolTipGenerator(new StandardPieToolTipGenerator());
645        }
646        if (urls) {
647            plot.setURLGenerator(new StandardPieURLGenerator());
648        }
649        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
650                plot, legend);
651        currentTheme.apply(chart);
652        return chart;
653
654    }
655
656    /**
657     * Creates a chart that displays multiple pie plots.  The chart object
658     * returned by this method uses a {@link MultiplePiePlot} instance as the
659     * plot.
660     *
661     * @param title  the chart title (<code>null</code> permitted).
662     * @param dataset  the dataset (<code>null</code> permitted).
663     * @param order  the order that the data is extracted (by row or by column)
664     *               (<code>null</code> not permitted).
665     * @param legend  include a legend?
666     * @param tooltips  generate tooltips?
667     * @param urls  generate URLs?
668     *
669     * @return A chart.
670     */
671    public static JFreeChart createMultiplePieChart(String title,
672                                                    CategoryDataset dataset,
673                                                    TableOrder order,
674                                                    boolean legend,
675                                                    boolean tooltips,
676                                                    boolean urls) {
677
678        if (order == null) {
679            throw new IllegalArgumentException("Null 'order' argument.");
680        }
681        MultiplePiePlot plot = new MultiplePiePlot(dataset);
682        plot.setDataExtractOrder(order);
683        plot.setBackgroundPaint(null);
684        plot.setOutlineStroke(null);
685
686        if (tooltips) {
687            PieToolTipGenerator tooltipGenerator
688                = new StandardPieToolTipGenerator();
689            PiePlot pp = (PiePlot) plot.getPieChart().getPlot();
690            pp.setToolTipGenerator(tooltipGenerator);
691        }
692
693        if (urls) {
694            PieURLGenerator urlGenerator = new StandardPieURLGenerator();
695            PiePlot pp = (PiePlot) plot.getPieChart().getPlot();
696            pp.setURLGenerator(urlGenerator);
697        }
698
699        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
700                plot, legend);
701        currentTheme.apply(chart);
702        return chart;
703
704    }
705
706    /**
707     * Creates a 3D pie chart using the specified dataset.  The chart object
708     * returned by this method uses a {@link PiePlot3D} instance as the
709     * plot.
710     *
711     * @param title  the chart title (<code>null</code> permitted).
712     * @param dataset  the dataset for the chart (<code>null</code> permitted).
713     * @param legend  a flag specifying whether or not a legend is required.
714     * @param tooltips  configure chart to generate tool tips?
715     * @param locale  the locale (<code>null</code> not permitted).
716     *
717     * @return A pie chart.
718     *
719     * @since 1.0.7
720     */
721    public static JFreeChart createPieChart3D(String title, PieDataset dataset,
722            boolean legend, boolean tooltips, Locale locale) {
723
724        PiePlot3D plot = new PiePlot3D(dataset);
725        plot.setInsets(new RectangleInsets(0.0, 5.0, 5.0, 5.0));
726        if (tooltips) {
727            plot.setToolTipGenerator(new StandardPieToolTipGenerator(locale));
728        }
729        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
730                plot, legend);
731        currentTheme.apply(chart);
732        return chart;
733
734    }
735
736    /**
737     * Creates a 3D pie chart using the specified dataset.  The chart object
738     * returned by this method uses a {@link PiePlot3D} instance as the
739     * plot.
740     *
741     * @param title  the chart title (<code>null</code> permitted).
742     * @param dataset  the dataset for the chart (<code>null</code> permitted).
743     * @param legend  a flag specifying whether or not a legend is required.
744     * @param tooltips  configure chart to generate tool tips?
745     * @param urls  configure chart to generate URLs?
746     *
747     * @return A pie chart.
748     */
749    public static JFreeChart createPieChart3D(String title,
750                                              PieDataset dataset,
751                                              boolean legend,
752                                              boolean tooltips,
753                                              boolean urls) {
754
755        PiePlot3D plot = new PiePlot3D(dataset);
756        plot.setInsets(new RectangleInsets(0.0, 5.0, 5.0, 5.0));
757        if (tooltips) {
758            plot.setToolTipGenerator(new StandardPieToolTipGenerator());
759        }
760        if (urls) {
761            plot.setURLGenerator(new StandardPieURLGenerator());
762        }
763        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
764                plot, legend);
765        currentTheme.apply(chart);
766        return chart;
767
768    }
769
770    /**
771     * Creates a chart that displays multiple pie plots.  The chart object
772     * returned by this method uses a {@link MultiplePiePlot} instance as the
773     * plot.
774     *
775     * @param title  the chart title (<code>null</code> permitted).
776     * @param dataset  the dataset (<code>null</code> permitted).
777     * @param order  the order that the data is extracted (by row or by column)
778     *               (<code>null</code> not permitted).
779     * @param legend  include a legend?
780     * @param tooltips  generate tooltips?
781     * @param urls  generate URLs?
782     *
783     * @return A chart.
784     */
785    public static JFreeChart createMultiplePieChart3D(String title,
786                                                      CategoryDataset dataset,
787                                                      TableOrder order,
788                                                      boolean legend,
789                                                      boolean tooltips,
790                                                      boolean urls) {
791
792        if (order == null) {
793            throw new IllegalArgumentException("Null 'order' argument.");
794        }
795        MultiplePiePlot plot = new MultiplePiePlot(dataset);
796        plot.setDataExtractOrder(order);
797        plot.setBackgroundPaint(null);
798        plot.setOutlineStroke(null);
799
800        JFreeChart pieChart = new JFreeChart(new PiePlot3D(null));
801        TextTitle seriesTitle = new TextTitle("Series Title",
802                new Font("SansSerif", Font.BOLD, 12));
803        seriesTitle.setPosition(RectangleEdge.BOTTOM);
804        pieChart.setTitle(seriesTitle);
805        pieChart.removeLegend();
806        pieChart.setBackgroundPaint(null);
807        plot.setPieChart(pieChart);
808
809        if (tooltips) {
810            PieToolTipGenerator tooltipGenerator
811                = new StandardPieToolTipGenerator();
812            PiePlot pp = (PiePlot) plot.getPieChart().getPlot();
813            pp.setToolTipGenerator(tooltipGenerator);
814        }
815
816        if (urls) {
817            PieURLGenerator urlGenerator = new StandardPieURLGenerator();
818            PiePlot pp = (PiePlot) plot.getPieChart().getPlot();
819            pp.setURLGenerator(urlGenerator);
820        }
821
822        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
823                plot, legend);
824        currentTheme.apply(chart);
825        return chart;
826
827    }
828
829    /**
830     * Creates a bar chart.  The chart object returned by this method uses a
831     * {@link CategoryPlot} instance as the plot, with a {@link CategoryAxis}
832     * for the domain axis, a {@link NumberAxis} as the range axis, and a
833     * {@link BarRenderer} as the renderer.
834     *
835     * @param title  the chart title (<code>null</code> permitted).
836     * @param categoryAxisLabel  the label for the category axis
837     *                           (<code>null</code> permitted).
838     * @param valueAxisLabel  the label for the value axis
839     *                        (<code>null</code> permitted).
840     * @param dataset  the dataset for the chart (<code>null</code> permitted).
841     * @param orientation  the plot orientation (horizontal or vertical)
842     *                     (<code>null</code> not permitted).
843     * @param legend  a flag specifying whether or not a legend is required.
844     * @param tooltips  configure chart to generate tool tips?
845     * @param urls  configure chart to generate URLs?
846     *
847     * @return A bar chart.
848     */
849    public static JFreeChart createBarChart(String title,
850                                            String categoryAxisLabel,
851                                            String valueAxisLabel,
852                                            CategoryDataset dataset,
853                                            PlotOrientation orientation,
854                                            boolean legend,
855                                            boolean tooltips,
856                                            boolean urls) {
857
858        if (orientation == null) {
859            throw new IllegalArgumentException("Null 'orientation' argument.");
860        }
861        CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
862        ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
863
864        BarRenderer renderer = new BarRenderer();
865        if (orientation == PlotOrientation.HORIZONTAL) {
866            ItemLabelPosition position1 = new ItemLabelPosition(
867                    ItemLabelAnchor.OUTSIDE3, TextAnchor.CENTER_LEFT);
868            renderer.setBasePositiveItemLabelPosition(position1);
869            ItemLabelPosition position2 = new ItemLabelPosition(
870                    ItemLabelAnchor.OUTSIDE9, TextAnchor.CENTER_RIGHT);
871            renderer.setBaseNegativeItemLabelPosition(position2);
872         }
873        else if (orientation == PlotOrientation.VERTICAL) {
874            ItemLabelPosition position1 = new ItemLabelPosition(
875                    ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER);
876            renderer.setBasePositiveItemLabelPosition(position1);
877            ItemLabelPosition position2 = new ItemLabelPosition(
878                    ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER);
879            renderer.setBaseNegativeItemLabelPosition(position2);
880        }
881        if (tooltips) {
882            renderer.setBaseToolTipGenerator(
883                    new StandardCategoryToolTipGenerator());
884        }
885        if (urls) {
886            renderer.setBaseItemURLGenerator(
887                    new StandardCategoryURLGenerator());
888        }
889
890        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
891                renderer);
892        plot.setOrientation(orientation);
893        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
894                plot, legend);
895        currentTheme.apply(chart);
896        return chart;
897
898    }
899
900    /**
901     * Creates a stacked bar chart with default settings.  The chart object
902     * returned by this method uses a {@link CategoryPlot} instance as the
903     * plot, with a {@link CategoryAxis} for the domain axis, a
904     * {@link NumberAxis} as the range axis, and a {@link StackedBarRenderer}
905     * as the renderer.
906     *
907     * @param title  the chart title (<code>null</code> permitted).
908     * @param domainAxisLabel  the label for the category axis
909     *                         (<code>null</code> permitted).
910     * @param rangeAxisLabel  the label for the value axis
911     *                        (<code>null</code> permitted).
912     * @param dataset  the dataset for the chart (<code>null</code> permitted).
913     * @param orientation  the orientation of the chart (horizontal or
914     *                     vertical) (<code>null</code> not permitted).
915     * @param legend  a flag specifying whether or not a legend is required.
916     * @param tooltips  configure chart to generate tool tips?
917     * @param urls  configure chart to generate URLs?
918     *
919     * @return A stacked bar chart.
920     */
921    public static JFreeChart createStackedBarChart(String title,
922                                                   String domainAxisLabel,
923                                                   String rangeAxisLabel,
924                                                   CategoryDataset dataset,
925                                                   PlotOrientation orientation,
926                                                   boolean legend,
927                                                   boolean tooltips,
928                                                   boolean urls) {
929
930        if (orientation == null) {
931            throw new IllegalArgumentException("Null 'orientation' argument.");
932        }
933
934        CategoryAxis categoryAxis = new CategoryAxis(domainAxisLabel);
935        ValueAxis valueAxis = new NumberAxis(rangeAxisLabel);
936
937        StackedBarRenderer renderer = new StackedBarRenderer();
938        if (tooltips) {
939            renderer.setBaseToolTipGenerator(
940                    new StandardCategoryToolTipGenerator());
941        }
942        if (urls) {
943            renderer.setBaseItemURLGenerator(
944                    new StandardCategoryURLGenerator());
945        }
946
947        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
948                renderer);
949        plot.setOrientation(orientation);
950        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
951                plot, legend);
952        currentTheme.apply(chart);
953        return chart;
954
955    }
956
957    /**
958     * Creates a bar chart with a 3D effect. The chart object returned by this
959     * method uses a {@link CategoryPlot} instance as the plot, with a
960     * {@link CategoryAxis3D} for the domain axis, a {@link NumberAxis3D} as
961     * the range axis, and a {@link BarRenderer3D} as the renderer.
962     *
963     * @param title  the chart title (<code>null</code> permitted).
964     * @param categoryAxisLabel  the label for the category axis
965     *                           (<code>null</code> permitted).
966     * @param valueAxisLabel  the label for the value axis (<code>null</code>
967     *                        permitted).
968     * @param dataset  the dataset for the chart (<code>null</code> permitted).
969     * @param orientation  the plot orientation (horizontal or vertical)
970     *                     (<code>null</code> not permitted).
971     * @param legend  a flag specifying whether or not a legend is required.
972     * @param tooltips  configure chart to generate tool tips?
973     * @param urls  configure chart to generate URLs?
974     *
975     * @return A bar chart with a 3D effect.
976     */
977    public static JFreeChart createBarChart3D(String title,
978                                              String categoryAxisLabel,
979                                              String valueAxisLabel,
980                                              CategoryDataset dataset,
981                                              PlotOrientation orientation,
982                                              boolean legend,
983                                              boolean tooltips,
984                                              boolean urls) {
985
986        if (orientation == null) {
987            throw new IllegalArgumentException("Null 'orientation' argument.");
988        }
989        CategoryAxis categoryAxis = new CategoryAxis3D(categoryAxisLabel);
990        ValueAxis valueAxis = new NumberAxis3D(valueAxisLabel);
991
992        BarRenderer3D renderer = new BarRenderer3D();
993        if (tooltips) {
994            renderer.setBaseToolTipGenerator(
995                    new StandardCategoryToolTipGenerator());
996        }
997        if (urls) {
998            renderer.setBaseItemURLGenerator(
999                    new StandardCategoryURLGenerator());
1000        }
1001
1002        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
1003                renderer);
1004        plot.setOrientation(orientation);
1005        if (orientation == PlotOrientation.HORIZONTAL) {
1006            // change rendering order to ensure that bar overlapping is the
1007            // right way around
1008            plot.setRowRenderingOrder(SortOrder.DESCENDING);
1009            plot.setColumnRenderingOrder(SortOrder.DESCENDING);
1010        }
1011        plot.setForegroundAlpha(0.75f);
1012
1013        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1014                plot, legend);
1015        currentTheme.apply(chart);
1016        return chart;
1017
1018    }
1019
1020    /**
1021     * Creates a stacked bar chart with a 3D effect and default settings. The
1022     * chart object returned by this method uses a {@link CategoryPlot}
1023     * instance as the plot, with a {@link CategoryAxis3D} for the domain axis,
1024     * a {@link NumberAxis3D} as the range axis, and a
1025     * {@link StackedBarRenderer3D} as the renderer.
1026     *
1027     * @param title  the chart title (<code>null</code> permitted).
1028     * @param categoryAxisLabel  the label for the category axis
1029     *                           (<code>null</code> permitted).
1030     * @param valueAxisLabel  the label for the value axis (<code>null</code>
1031     *                        permitted).
1032     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1033     * @param orientation  the orientation (horizontal or vertical)
1034     *                     (<code>null</code> not permitted).
1035     * @param legend  a flag specifying whether or not a legend is required.
1036     * @param tooltips  configure chart to generate tool tips?
1037     * @param urls  configure chart to generate URLs?
1038     *
1039     * @return A stacked bar chart with a 3D effect.
1040     */
1041    public static JFreeChart createStackedBarChart3D(String title,
1042                                                    String categoryAxisLabel,
1043                                                    String valueAxisLabel,
1044                                                    CategoryDataset dataset,
1045                                                    PlotOrientation orientation,
1046                                                    boolean legend,
1047                                                    boolean tooltips,
1048                                                    boolean urls) {
1049
1050        if (orientation == null) {
1051            throw new IllegalArgumentException("Null 'orientation' argument.");
1052        }
1053        CategoryAxis categoryAxis = new CategoryAxis3D(categoryAxisLabel);
1054        ValueAxis valueAxis = new NumberAxis3D(valueAxisLabel);
1055
1056        // create the renderer...
1057        CategoryItemRenderer renderer = new StackedBarRenderer3D();
1058        if (tooltips) {
1059            renderer.setBaseToolTipGenerator(
1060                    new StandardCategoryToolTipGenerator());
1061        }
1062        if (urls) {
1063            renderer.setBaseItemURLGenerator(
1064                    new StandardCategoryURLGenerator());
1065        }
1066
1067        // create the plot...
1068        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
1069                renderer);
1070        plot.setOrientation(orientation);
1071        if (orientation == PlotOrientation.HORIZONTAL) {
1072            // change rendering order to ensure that bar overlapping is the
1073            // right way around
1074            plot.setColumnRenderingOrder(SortOrder.DESCENDING);
1075        }
1076
1077        // create the chart...
1078        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1079                plot, legend);
1080        currentTheme.apply(chart);
1081        return chart;
1082
1083    }
1084
1085    /**
1086     * Creates an area chart with default settings.  The chart object returned
1087     * by this method uses a {@link CategoryPlot} instance as the plot, with a
1088     * {@link CategoryAxis} for the domain axis, a {@link NumberAxis} as the
1089     * range axis, and an {@link AreaRenderer} as the renderer.
1090     *
1091     * @param title  the chart title (<code>null</code> permitted).
1092     * @param categoryAxisLabel  the label for the category axis
1093     *                           (<code>null</code> permitted).
1094     * @param valueAxisLabel  the label for the value axis (<code>null</code>
1095     *                        permitted).
1096     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1097     * @param orientation  the plot orientation (<code>null</code> not
1098     *                     permitted).
1099     * @param legend  a flag specifying whether or not a legend is required.
1100     * @param tooltips  configure chart to generate tool tips?
1101     * @param urls  configure chart to generate URLs?
1102     *
1103     * @return An area chart.
1104     */
1105    public static JFreeChart createAreaChart(String title,
1106                                             String categoryAxisLabel,
1107                                             String valueAxisLabel,
1108                                             CategoryDataset dataset,
1109                                             PlotOrientation orientation,
1110                                             boolean legend,
1111                                             boolean tooltips,
1112                                             boolean urls) {
1113
1114        if (orientation == null) {
1115            throw new IllegalArgumentException("Null 'orientation' argument.");
1116        }
1117        CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
1118        categoryAxis.setCategoryMargin(0.0);
1119
1120        ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
1121
1122        AreaRenderer renderer = new AreaRenderer();
1123        if (tooltips) {
1124            renderer.setBaseToolTipGenerator(
1125                    new StandardCategoryToolTipGenerator());
1126        }
1127        if (urls) {
1128            renderer.setBaseItemURLGenerator(
1129                    new StandardCategoryURLGenerator());
1130        }
1131
1132        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
1133                renderer);
1134        plot.setOrientation(orientation);
1135        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1136                plot, legend);
1137        currentTheme.apply(chart);
1138        return chart;
1139
1140    }
1141
1142    /**
1143     * Creates a stacked area chart with default settings.  The chart object
1144     * returned by this method uses a {@link CategoryPlot} instance as the
1145     * plot, with a {@link CategoryAxis} for the domain axis, a
1146     * {@link NumberAxis} as the range axis, and a {@link StackedAreaRenderer}
1147     * as the renderer.
1148     *
1149     * @param title  the chart title (<code>null</code> permitted).
1150     * @param categoryAxisLabel  the label for the category axis
1151     *                           (<code>null</code> permitted).
1152     * @param valueAxisLabel  the label for the value axis (<code>null</code>
1153     *                        permitted).
1154     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1155     * @param orientation  the plot orientation (horizontal or vertical)
1156     *                     (<code>null</code> not permitted).
1157     * @param legend  a flag specifying whether or not a legend is required.
1158     * @param tooltips  configure chart to generate tool tips?
1159     * @param urls  configure chart to generate URLs?
1160     *
1161     * @return A stacked area chart.
1162     */
1163    public static JFreeChart createStackedAreaChart(String title,
1164            String categoryAxisLabel, String valueAxisLabel,
1165            CategoryDataset dataset, PlotOrientation orientation,
1166            boolean legend, boolean tooltips, boolean urls) {
1167
1168        if (orientation == null) {
1169            throw new IllegalArgumentException("Null 'orientation' argument.");
1170        }
1171        CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
1172        categoryAxis.setCategoryMargin(0.0);
1173        ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
1174
1175        StackedAreaRenderer renderer = new StackedAreaRenderer();
1176        if (tooltips) {
1177            renderer.setBaseToolTipGenerator(
1178                    new StandardCategoryToolTipGenerator());
1179        }
1180        if (urls) {
1181            renderer.setBaseItemURLGenerator(
1182                    new StandardCategoryURLGenerator());
1183        }
1184
1185        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
1186                renderer);
1187        plot.setOrientation(orientation);
1188        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1189                plot, legend);
1190        currentTheme.apply(chart);
1191        return chart;
1192
1193    }
1194
1195    /**
1196     * Creates a line chart with default settings.  The chart object returned
1197     * by this method uses a {@link CategoryPlot} instance as the plot, with a
1198     * {@link CategoryAxis} for the domain axis, a {@link NumberAxis} as the
1199     * range axis, and a {@link LineAndShapeRenderer} as the renderer.
1200     *
1201     * @param title  the chart title (<code>null</code> permitted).
1202     * @param categoryAxisLabel  the label for the category axis
1203     *                           (<code>null</code> permitted).
1204     * @param valueAxisLabel  the label for the value axis (<code>null</code>
1205     *                        permitted).
1206     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1207     * @param orientation  the chart orientation (horizontal or vertical)
1208     *                     (<code>null</code> not permitted).
1209     * @param legend  a flag specifying whether or not a legend is required.
1210     * @param tooltips  configure chart to generate tool tips?
1211     * @param urls  configure chart to generate URLs?
1212     *
1213     * @return A line chart.
1214     */
1215    public static JFreeChart createLineChart(String title,
1216                                             String categoryAxisLabel,
1217                                             String valueAxisLabel,
1218                                             CategoryDataset dataset,
1219                                             PlotOrientation orientation,
1220                                             boolean legend,
1221                                             boolean tooltips,
1222                                             boolean urls) {
1223
1224        if (orientation == null) {
1225            throw new IllegalArgumentException("Null 'orientation' argument.");
1226        }
1227        CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
1228        ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
1229
1230        LineAndShapeRenderer renderer = new LineAndShapeRenderer(true, false);
1231        if (tooltips) {
1232            renderer.setBaseToolTipGenerator(
1233                    new StandardCategoryToolTipGenerator());
1234        }
1235        if (urls) {
1236            renderer.setBaseItemURLGenerator(
1237                    new StandardCategoryURLGenerator());
1238        }
1239        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
1240                renderer);
1241        plot.setOrientation(orientation);
1242        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1243                plot, legend);
1244        currentTheme.apply(chart);
1245        return chart;
1246
1247    }
1248
1249    /**
1250     * Creates a line chart with default settings. The chart object returned by
1251     * this method uses a {@link CategoryPlot} instance as the plot, with a
1252     * {@link CategoryAxis3D} for the domain axis, a {@link NumberAxis3D} as
1253     * the range axis, and a {@link LineRenderer3D} as the renderer.
1254     *
1255     * @param title  the chart title (<code>null</code> permitted).
1256     * @param categoryAxisLabel  the label for the category axis
1257     *                           (<code>null</code> permitted).
1258     * @param valueAxisLabel  the label for the value axis (<code>null</code>
1259     *                        permitted).
1260     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1261     * @param orientation  the chart orientation (horizontal or vertical)
1262     *                     (<code>null</code> not permitted).
1263     * @param legend  a flag specifying whether or not a legend is required.
1264     * @param tooltips  configure chart to generate tool tips?
1265     * @param urls  configure chart to generate URLs?
1266     *
1267     * @return A line chart.
1268     */
1269    public static JFreeChart createLineChart3D(String title,
1270                                               String categoryAxisLabel,
1271                                               String valueAxisLabel,
1272                                               CategoryDataset dataset,
1273                                               PlotOrientation orientation,
1274                                               boolean legend,
1275                                               boolean tooltips,
1276                                               boolean urls) {
1277
1278        if (orientation == null) {
1279            throw new IllegalArgumentException("Null 'orientation' argument.");
1280        }
1281        CategoryAxis categoryAxis = new CategoryAxis3D(categoryAxisLabel);
1282        ValueAxis valueAxis = new NumberAxis3D(valueAxisLabel);
1283
1284        LineRenderer3D renderer = new LineRenderer3D();
1285        if (tooltips) {
1286            renderer.setBaseToolTipGenerator(
1287                    new StandardCategoryToolTipGenerator());
1288        }
1289        if (urls) {
1290            renderer.setBaseItemURLGenerator(
1291                    new StandardCategoryURLGenerator());
1292        }
1293        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
1294                renderer);
1295        plot.setOrientation(orientation);
1296        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1297                plot, legend);
1298        currentTheme.apply(chart);
1299        return chart;
1300
1301    }
1302
1303    /**
1304     * Creates a Gantt chart using the supplied attributes plus default values
1305     * where required.  The chart object returned by this method uses a
1306     * {@link CategoryPlot} instance as the plot, with a {@link CategoryAxis}
1307     * for the domain axis, a {@link DateAxis} as the range axis, and a
1308     * {@link GanttRenderer} as the renderer.
1309     *
1310     * @param title  the chart title (<code>null</code> permitted).
1311     * @param categoryAxisLabel  the label for the category axis
1312     *                           (<code>null</code> permitted).
1313     * @param dateAxisLabel  the label for the date axis
1314     *                       (<code>null</code> permitted).
1315     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1316     * @param legend  a flag specifying whether or not a legend is required.
1317     * @param tooltips  configure chart to generate tool tips?
1318     * @param urls  configure chart to generate URLs?
1319     *
1320     * @return A Gantt chart.
1321     */
1322    public static JFreeChart createGanttChart(String title,
1323                                              String categoryAxisLabel,
1324                                              String dateAxisLabel,
1325                                              IntervalCategoryDataset dataset,
1326                                              boolean legend,
1327                                              boolean tooltips,
1328                                              boolean urls) {
1329
1330        CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
1331        DateAxis dateAxis = new DateAxis(dateAxisLabel);
1332
1333        CategoryItemRenderer renderer = new GanttRenderer();
1334        if (tooltips) {
1335            renderer.setBaseToolTipGenerator(
1336                    new IntervalCategoryToolTipGenerator(
1337                    "{3} - {4}", DateFormat.getDateInstance()));
1338        }
1339        if (urls) {
1340            renderer.setBaseItemURLGenerator(
1341                    new StandardCategoryURLGenerator());
1342        }
1343
1344        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, dateAxis,
1345                renderer);
1346        plot.setOrientation(PlotOrientation.HORIZONTAL);
1347        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1348                plot, legend);
1349        currentTheme.apply(chart);
1350        return chart;
1351
1352    }
1353
1354    /**
1355     * Creates a waterfall chart.  The chart object returned by this method
1356     * uses a {@link CategoryPlot} instance as the plot, with a
1357     * {@link CategoryAxis} for the domain axis, a {@link NumberAxis} as the
1358     * range axis, and a {@link WaterfallBarRenderer} as the renderer.
1359     *
1360     * @param title  the chart title (<code>null</code> permitted).
1361     * @param categoryAxisLabel  the label for the category axis
1362     *                           (<code>null</code> permitted).
1363     * @param valueAxisLabel  the label for the value axis (<code>null</code>
1364     *                        permitted).
1365     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1366     * @param orientation  the plot orientation (horizontal or vertical)
1367     *                     (<code>null</code> NOT permitted).
1368     * @param legend  a flag specifying whether or not a legend is required.
1369     * @param tooltips  configure chart to generate tool tips?
1370     * @param urls  configure chart to generate URLs?
1371     *
1372     * @return A waterfall chart.
1373     */
1374    public static JFreeChart createWaterfallChart(String title,
1375                                                  String categoryAxisLabel,
1376                                                  String valueAxisLabel,
1377                                                  CategoryDataset dataset,
1378                                                  PlotOrientation orientation,
1379                                                  boolean legend,
1380                                                  boolean tooltips,
1381                                                  boolean urls) {
1382
1383        if (orientation == null) {
1384            throw new IllegalArgumentException("Null 'orientation' argument.");
1385        }
1386        CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
1387        categoryAxis.setCategoryMargin(0.0);
1388
1389        ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
1390
1391        WaterfallBarRenderer renderer = new WaterfallBarRenderer();
1392        if (orientation == PlotOrientation.HORIZONTAL) {
1393            ItemLabelPosition position = new ItemLabelPosition(
1394                    ItemLabelAnchor.CENTER, TextAnchor.CENTER,
1395                    TextAnchor.CENTER, Math.PI / 2.0);
1396            renderer.setBasePositiveItemLabelPosition(position);
1397            renderer.setBaseNegativeItemLabelPosition(position);
1398         }
1399        else if (orientation == PlotOrientation.VERTICAL) {
1400            ItemLabelPosition position = new ItemLabelPosition(
1401                    ItemLabelAnchor.CENTER, TextAnchor.CENTER,
1402                    TextAnchor.CENTER, 0.0);
1403            renderer.setBasePositiveItemLabelPosition(position);
1404            renderer.setBaseNegativeItemLabelPosition(position);
1405        }
1406        if (tooltips) {
1407            StandardCategoryToolTipGenerator generator
1408                = new StandardCategoryToolTipGenerator();
1409            renderer.setBaseToolTipGenerator(generator);
1410        }
1411        if (urls) {
1412            renderer.setBaseItemURLGenerator(
1413                    new StandardCategoryURLGenerator());
1414        }
1415
1416        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
1417                renderer);
1418        plot.clearRangeMarkers();
1419        Marker baseline = new ValueMarker(0.0);
1420        baseline.setPaint(Color.black);
1421        plot.addRangeMarker(baseline, Layer.FOREGROUND);
1422        plot.setOrientation(orientation);
1423        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1424                plot, legend);
1425        currentTheme.apply(chart);
1426        return chart;
1427
1428    }
1429
1430    /**
1431     * Creates a polar plot for the specified dataset (x-values interpreted as
1432     * angles in degrees).  The chart object returned by this method uses a
1433     * {@link PolarPlot} instance as the plot, with a {@link NumberAxis} for
1434     * the radial axis.
1435     *
1436     * @param title  the chart title (<code>null</code> permitted).
1437     * @param dataset  the dataset (<code>null</code> permitted).
1438     * @param legend  legend required?
1439     * @param tooltips  tooltips required?
1440     * @param urls  URLs required?
1441     *
1442     * @return A chart.
1443     */
1444    public static JFreeChart createPolarChart(String title,
1445                                              XYDataset dataset,
1446                                              boolean legend,
1447                                              boolean tooltips,
1448                                              boolean urls) {
1449
1450        PolarPlot plot = new PolarPlot();
1451        plot.setDataset(dataset);
1452        NumberAxis rangeAxis = new NumberAxis();
1453        rangeAxis.setAxisLineVisible(false);
1454        rangeAxis.setTickMarksVisible(false);
1455        rangeAxis.setTickLabelInsets(new RectangleInsets(0.0, 0.0, 0.0, 0.0));
1456        plot.setAxis(rangeAxis);
1457        plot.setRenderer(new DefaultPolarItemRenderer());
1458        JFreeChart chart = new JFreeChart(
1459                title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
1460        currentTheme.apply(chart);
1461        return chart;
1462
1463    }
1464
1465    /**
1466     * Creates a scatter plot with default settings.  The chart object
1467     * returned by this method uses an {@link XYPlot} instance as the plot,
1468     * with a {@link NumberAxis} for the domain axis, a  {@link NumberAxis}
1469     * as the range axis, and an {@link XYLineAndShapeRenderer} as the
1470     * renderer.
1471     *
1472     * @param title  the chart title (<code>null</code> permitted).
1473     * @param xAxisLabel  a label for the X-axis (<code>null</code> permitted).
1474     * @param yAxisLabel  a label for the Y-axis (<code>null</code> permitted).
1475     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1476     * @param orientation  the plot orientation (horizontal or vertical)
1477     *                     (<code>null</code> NOT permitted).
1478     * @param legend  a flag specifying whether or not a legend is required.
1479     * @param tooltips  configure chart to generate tool tips?
1480     * @param urls  configure chart to generate URLs?
1481     *
1482     * @return A scatter plot.
1483     */
1484    public static JFreeChart createScatterPlot(String title, String xAxisLabel,
1485            String yAxisLabel, XYDataset dataset, PlotOrientation orientation,
1486            boolean legend, boolean tooltips, boolean urls) {
1487
1488        if (orientation == null) {
1489            throw new IllegalArgumentException("Null 'orientation' argument.");
1490        }
1491        NumberAxis xAxis = new NumberAxis(xAxisLabel);
1492        xAxis.setAutoRangeIncludesZero(false);
1493        NumberAxis yAxis = new NumberAxis(yAxisLabel);
1494        yAxis.setAutoRangeIncludesZero(false);
1495
1496        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
1497
1498        XYToolTipGenerator toolTipGenerator = null;
1499        if (tooltips) {
1500            toolTipGenerator = new StandardXYToolTipGenerator();
1501        }
1502
1503        XYURLGenerator urlGenerator = null;
1504        if (urls) {
1505            urlGenerator = new StandardXYURLGenerator();
1506        }
1507        XYItemRenderer renderer = new XYLineAndShapeRenderer(false, true);
1508        renderer.setBaseToolTipGenerator(toolTipGenerator);
1509        renderer.setURLGenerator(urlGenerator);
1510        plot.setRenderer(renderer);
1511        plot.setOrientation(orientation);
1512
1513        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1514                plot, legend);
1515        currentTheme.apply(chart);
1516        return chart;
1517
1518    }
1519
1520    /**
1521     * Creates and returns a default instance of an XY bar chart.
1522     * <P>
1523     * The chart object returned by this method uses an {@link XYPlot} instance
1524     * as the plot, with a {@link DateAxis} for the domain axis, a
1525     * {@link NumberAxis} as the range axis, and a {@link XYBarRenderer} as the
1526     * renderer.
1527     *
1528     * @param title  the chart title (<code>null</code> permitted).
1529     * @param xAxisLabel  a label for the X-axis (<code>null</code> permitted).
1530     * @param dateAxis  make the domain axis display dates?
1531     * @param yAxisLabel  a label for the Y-axis (<code>null</code> permitted).
1532     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1533     * @param orientation  the orientation (horizontal or vertical)
1534     *                     (<code>null</code> NOT permitted).
1535     * @param legend  a flag specifying whether or not a legend is required.
1536     * @param tooltips  configure chart to generate tool tips?
1537     * @param urls  configure chart to generate URLs?
1538     *
1539     * @return An XY bar chart.
1540     */
1541    public static JFreeChart createXYBarChart(String title,
1542                                              String xAxisLabel,
1543                                              boolean dateAxis,
1544                                              String yAxisLabel,
1545                                              IntervalXYDataset dataset,
1546                                              PlotOrientation orientation,
1547                                              boolean legend,
1548                                              boolean tooltips,
1549                                              boolean urls) {
1550
1551        if (orientation == null) {
1552            throw new IllegalArgumentException("Null 'orientation' argument.");
1553        }
1554        ValueAxis domainAxis = null;
1555        if (dateAxis) {
1556            domainAxis = new DateAxis(xAxisLabel);
1557        }
1558        else {
1559            NumberAxis axis = new NumberAxis(xAxisLabel);
1560            axis.setAutoRangeIncludesZero(false);
1561            domainAxis = axis;
1562        }
1563        ValueAxis valueAxis = new NumberAxis(yAxisLabel);
1564
1565        XYBarRenderer renderer = new XYBarRenderer();
1566        if (tooltips) {
1567            XYToolTipGenerator tt;
1568            if (dateAxis) {
1569                tt = StandardXYToolTipGenerator.getTimeSeriesInstance();
1570            }
1571            else {
1572                tt = new StandardXYToolTipGenerator();
1573            }
1574            renderer.setBaseToolTipGenerator(tt);
1575        }
1576        if (urls) {
1577            renderer.setURLGenerator(new StandardXYURLGenerator());
1578        }
1579
1580        XYPlot plot = new XYPlot(dataset, domainAxis, valueAxis, renderer);
1581        plot.setOrientation(orientation);
1582
1583        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1584                plot, legend);
1585        currentTheme.apply(chart);
1586        return chart;
1587
1588    }
1589
1590    /**
1591     * Creates an area chart using an {@link XYDataset}.
1592     * <P>
1593     * The chart object returned by this method uses an {@link XYPlot} instance
1594     * as the plot, with a {@link NumberAxis} for the domain axis, a
1595     * {@link NumberAxis} as the range axis, and a {@link XYAreaRenderer} as
1596     * the renderer.
1597     *
1598     * @param title  the chart title (<code>null</code> permitted).
1599     * @param xAxisLabel  a label for the X-axis (<code>null</code> permitted).
1600     * @param yAxisLabel  a label for the Y-axis (<code>null</code> permitted).
1601     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1602     * @param orientation  the plot orientation (horizontal or vertical)
1603     *                     (<code>null</code> NOT permitted).
1604     * @param legend  a flag specifying whether or not a legend is required.
1605     * @param tooltips  configure chart to generate tool tips?
1606     * @param urls  configure chart to generate URLs?
1607     *
1608     * @return An XY area chart.
1609     */
1610    public static JFreeChart createXYAreaChart(String title,
1611                                               String xAxisLabel,
1612                                               String yAxisLabel,
1613                                               XYDataset dataset,
1614                                               PlotOrientation orientation,
1615                                               boolean legend,
1616                                               boolean tooltips,
1617                                               boolean urls) {
1618
1619        if (orientation == null) {
1620            throw new IllegalArgumentException("Null 'orientation' argument.");
1621        }
1622        NumberAxis xAxis = new NumberAxis(xAxisLabel);
1623        xAxis.setAutoRangeIncludesZero(false);
1624        NumberAxis yAxis = new NumberAxis(yAxisLabel);
1625        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
1626        plot.setOrientation(orientation);
1627        plot.setForegroundAlpha(0.5f);
1628
1629        XYToolTipGenerator tipGenerator = null;
1630        if (tooltips) {
1631            tipGenerator = new StandardXYToolTipGenerator();
1632        }
1633
1634        XYURLGenerator urlGenerator = null;
1635        if (urls) {
1636            urlGenerator = new StandardXYURLGenerator();
1637        }
1638
1639        plot.setRenderer(new XYAreaRenderer(XYAreaRenderer.AREA, tipGenerator,
1640                urlGenerator));
1641        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1642                plot, legend);
1643        currentTheme.apply(chart);
1644        return chart;
1645
1646    }
1647
1648    /**
1649     * Creates a stacked XY area plot.  The chart object returned by this
1650     * method uses an {@link XYPlot} instance as the plot, with a
1651     * {@link NumberAxis} for the domain axis, a {@link NumberAxis} as the
1652     * range axis, and a {@link StackedXYAreaRenderer2} as the renderer.
1653     *
1654     * @param title  the chart title (<code>null</code> permitted).
1655     * @param xAxisLabel  a label for the X-axis (<code>null</code> permitted).
1656     * @param yAxisLabel  a label for the Y-axis (<code>null</code> permitted).
1657     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1658     * @param orientation  the plot orientation (horizontal or vertical)
1659     *                     (<code>null</code> NOT permitted).
1660     * @param legend  a flag specifying whether or not a legend is required.
1661     * @param tooltips  configure chart to generate tool tips?
1662     * @param urls  configure chart to generate URLs?
1663     *
1664     * @return A stacked XY area chart.
1665     */
1666    public static JFreeChart createStackedXYAreaChart(String title,
1667                                                    String xAxisLabel,
1668                                                    String yAxisLabel,
1669                                                    TableXYDataset dataset,
1670                                                    PlotOrientation orientation,
1671                                                    boolean legend,
1672                                                    boolean tooltips,
1673                                                    boolean urls) {
1674
1675        if (orientation == null) {
1676            throw new IllegalArgumentException("Null 'orientation' argument.");
1677        }
1678        NumberAxis xAxis = new NumberAxis(xAxisLabel);
1679        xAxis.setAutoRangeIncludesZero(false);
1680        xAxis.setLowerMargin(0.0);
1681        xAxis.setUpperMargin(0.0);
1682        NumberAxis yAxis = new NumberAxis(yAxisLabel);
1683        XYToolTipGenerator toolTipGenerator = null;
1684        if (tooltips) {
1685            toolTipGenerator = new StandardXYToolTipGenerator();
1686        }
1687
1688        XYURLGenerator urlGenerator = null;
1689        if (urls) {
1690            urlGenerator = new StandardXYURLGenerator();
1691        }
1692        StackedXYAreaRenderer2 renderer = new StackedXYAreaRenderer2(
1693                toolTipGenerator, urlGenerator);
1694        renderer.setOutline(true);
1695        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);
1696        plot.setOrientation(orientation);
1697
1698        plot.setRangeAxis(yAxis);  // forces recalculation of the axis range
1699
1700        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1701                plot, legend);
1702        currentTheme.apply(chart);
1703        return chart;
1704
1705    }
1706
1707    /**
1708     * Creates a line chart (based on an {@link XYDataset}) with default
1709     * settings.
1710     *
1711     * @param title  the chart title (<code>null</code> permitted).
1712     * @param xAxisLabel  a label for the X-axis (<code>null</code> permitted).
1713     * @param yAxisLabel  a label for the Y-axis (<code>null</code> permitted).
1714     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1715     * @param orientation  the plot orientation (horizontal or vertical)
1716     *                     (<code>null</code> NOT permitted).
1717     * @param legend  a flag specifying whether or not a legend is required.
1718     * @param tooltips  configure chart to generate tool tips?
1719     * @param urls  configure chart to generate URLs?
1720     *
1721     * @return The chart.
1722     */
1723    public static JFreeChart createXYLineChart(String title,
1724                                               String xAxisLabel,
1725                                               String yAxisLabel,
1726                                               XYDataset dataset,
1727                                               PlotOrientation orientation,
1728                                               boolean legend,
1729                                               boolean tooltips,
1730                                               boolean urls) {
1731
1732        if (orientation == null) {
1733            throw new IllegalArgumentException("Null 'orientation' argument.");
1734        }
1735        NumberAxis xAxis = new NumberAxis(xAxisLabel);
1736        xAxis.setAutoRangeIncludesZero(false);
1737        NumberAxis yAxis = new NumberAxis(yAxisLabel);
1738        XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false);
1739        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);
1740        plot.setOrientation(orientation);
1741        if (tooltips) {
1742            renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
1743        }
1744        if (urls) {
1745            renderer.setURLGenerator(new StandardXYURLGenerator());
1746        }
1747
1748        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1749                plot, legend);
1750        currentTheme.apply(chart);
1751        return chart;
1752
1753    }
1754
1755    /**
1756     * Creates a stepped XY plot with default settings.
1757     *
1758     * @param title  the chart title (<code>null</code> permitted).
1759     * @param xAxisLabel  a label for the X-axis (<code>null</code> permitted).
1760     * @param yAxisLabel  a label for the Y-axis (<code>null</code> permitted).
1761     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1762     * @param orientation  the plot orientation (horizontal or vertical)
1763     *                     (<code>null</code> NOT permitted).
1764     * @param legend  a flag specifying whether or not a legend is required.
1765     * @param tooltips  configure chart to generate tool tips?
1766     * @param urls  configure chart to generate URLs?
1767     *
1768     * @return A chart.
1769     */
1770    public static JFreeChart createXYStepChart(String title,
1771                                               String xAxisLabel,
1772                                               String yAxisLabel,
1773                                               XYDataset dataset,
1774                                               PlotOrientation orientation,
1775                                               boolean legend,
1776                                               boolean tooltips,
1777                                               boolean urls) {
1778
1779        if (orientation == null) {
1780            throw new IllegalArgumentException("Null 'orientation' argument.");
1781        }
1782        DateAxis xAxis = new DateAxis(xAxisLabel);
1783        NumberAxis yAxis = new NumberAxis(yAxisLabel);
1784        yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
1785
1786        XYToolTipGenerator toolTipGenerator = null;
1787        if (tooltips) {
1788            toolTipGenerator = new StandardXYToolTipGenerator();
1789        }
1790
1791        XYURLGenerator urlGenerator = null;
1792        if (urls) {
1793            urlGenerator = new StandardXYURLGenerator();
1794        }
1795        XYItemRenderer renderer = new XYStepRenderer(toolTipGenerator,
1796                urlGenerator);
1797
1798        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
1799        plot.setRenderer(renderer);
1800        plot.setOrientation(orientation);
1801        plot.setDomainCrosshairVisible(false);
1802        plot.setRangeCrosshairVisible(false);
1803        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1804                plot, legend);
1805        currentTheme.apply(chart);
1806        return chart;
1807
1808    }
1809
1810    /**
1811     * Creates a filled stepped XY plot with default settings.
1812     *
1813     * @param title  the chart title (<code>null</code> permitted).
1814     * @param xAxisLabel  a label for the X-axis (<code>null</code> permitted).
1815     * @param yAxisLabel  a label for the Y-axis (<code>null</code> permitted).
1816     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1817     * @param orientation  the plot orientation (horizontal or vertical)
1818     *                     (<code>null</code> NOT permitted).
1819     * @param legend  a flag specifying whether or not a legend is required.
1820     * @param tooltips  configure chart to generate tool tips?
1821     * @param urls  configure chart to generate URLs?
1822     *
1823     * @return A chart.
1824     */
1825    public static JFreeChart createXYStepAreaChart(String title,
1826                                                   String xAxisLabel,
1827                                                   String yAxisLabel,
1828                                                   XYDataset dataset,
1829                                                   PlotOrientation orientation,
1830                                                   boolean legend,
1831                                                   boolean tooltips,
1832                                                   boolean urls) {
1833
1834        if (orientation == null) {
1835            throw new IllegalArgumentException("Null 'orientation' argument.");
1836        }
1837        NumberAxis xAxis = new NumberAxis(xAxisLabel);
1838        xAxis.setAutoRangeIncludesZero(false);
1839        NumberAxis yAxis = new NumberAxis(yAxisLabel);
1840
1841        XYToolTipGenerator toolTipGenerator = null;
1842        if (tooltips) {
1843            toolTipGenerator = new StandardXYToolTipGenerator();
1844        }
1845
1846        XYURLGenerator urlGenerator = null;
1847        if (urls) {
1848            urlGenerator = new StandardXYURLGenerator();
1849        }
1850        XYItemRenderer renderer = new XYStepAreaRenderer(
1851                XYStepAreaRenderer.AREA_AND_SHAPES, toolTipGenerator,
1852                urlGenerator);
1853
1854        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
1855        plot.setRenderer(renderer);
1856        plot.setOrientation(orientation);
1857        plot.setDomainCrosshairVisible(false);
1858        plot.setRangeCrosshairVisible(false);
1859        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1860                plot, legend);
1861        currentTheme.apply(chart);
1862        return chart;
1863    }
1864
1865    /**
1866     * Creates and returns a time series chart.  A time series chart is an
1867     * {@link XYPlot} with a {@link DateAxis} for the x-axis and a
1868     * {@link NumberAxis} for the y-axis.  The default renderer is an
1869     * {@link XYLineAndShapeRenderer}.
1870     * <P>
1871     * A convenient dataset to use with this chart is a
1872     * {@link org.jfree.data.time.TimeSeriesCollection}.
1873     *
1874     * @param title  the chart title (<code>null</code> permitted).
1875     * @param timeAxisLabel  a label for the time axis (<code>null</code>
1876     *                       permitted).
1877     * @param valueAxisLabel  a label for the value axis (<code>null</code>
1878     *                        permitted).
1879     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1880     * @param legend  a flag specifying whether or not a legend is required.
1881     * @param tooltips  configure chart to generate tool tips?
1882     * @param urls  configure chart to generate URLs?
1883     *
1884     * @return A time series chart.
1885     */
1886    public static JFreeChart createTimeSeriesChart(String title,
1887                                                   String timeAxisLabel,
1888                                                   String valueAxisLabel,
1889                                                   XYDataset dataset,
1890                                                   boolean legend,
1891                                                   boolean tooltips,
1892                                                   boolean urls) {
1893
1894        ValueAxis timeAxis = new DateAxis(timeAxisLabel);
1895        timeAxis.setLowerMargin(0.02);  // reduce the default margins
1896        timeAxis.setUpperMargin(0.02);
1897        NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
1898        valueAxis.setAutoRangeIncludesZero(false);  // override default
1899        XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, null);
1900
1901        XYToolTipGenerator toolTipGenerator = null;
1902        if (tooltips) {
1903            toolTipGenerator
1904                = StandardXYToolTipGenerator.getTimeSeriesInstance();
1905        }
1906
1907        XYURLGenerator urlGenerator = null;
1908        if (urls) {
1909            urlGenerator = new StandardXYURLGenerator();
1910        }
1911
1912        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true,
1913                false);
1914        renderer.setBaseToolTipGenerator(toolTipGenerator);
1915        renderer.setURLGenerator(urlGenerator);
1916        plot.setRenderer(renderer);
1917
1918        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1919                plot, legend);
1920        currentTheme.apply(chart);
1921        return chart;
1922
1923    }
1924
1925    /**
1926     * Creates and returns a default instance of a candlesticks chart.
1927     *
1928     * @param title  the chart title (<code>null</code> permitted).
1929     * @param timeAxisLabel  a label for the time axis (<code>null</code>
1930     *                       permitted).
1931     * @param valueAxisLabel  a label for the value axis (<code>null</code>
1932     *                        permitted).
1933     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1934     * @param legend  a flag specifying whether or not a legend is required.
1935     *
1936     * @return A candlestick chart.
1937     */
1938    public static JFreeChart createCandlestickChart(String title,
1939                                                    String timeAxisLabel,
1940                                                    String valueAxisLabel,
1941                                                    OHLCDataset dataset,
1942                                                    boolean legend) {
1943
1944        ValueAxis timeAxis = new DateAxis(timeAxisLabel);
1945        NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
1946        XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, null);
1947        plot.setRenderer(new CandlestickRenderer());
1948        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1949                plot, legend);
1950        currentTheme.apply(chart);
1951        return chart;
1952
1953    }
1954
1955    /**
1956     * Creates and returns a default instance of a high-low-open-close chart.
1957     *
1958     * @param title  the chart title (<code>null</code> permitted).
1959     * @param timeAxisLabel  a label for the time axis (<code>null</code>
1960     *                       permitted).
1961     * @param valueAxisLabel  a label for the value axis (<code>null</code>
1962     *                        permitted).
1963     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1964     * @param legend  a flag specifying whether or not a legend is required.
1965     *
1966     * @return A high-low-open-close chart.
1967     */
1968    public static JFreeChart createHighLowChart(String title,
1969                                                String timeAxisLabel,
1970                                                String valueAxisLabel,
1971                                                OHLCDataset dataset,
1972                                                boolean legend) {
1973
1974        ValueAxis timeAxis = new DateAxis(timeAxisLabel);
1975        NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
1976        HighLowRenderer renderer = new HighLowRenderer();
1977        renderer.setBaseToolTipGenerator(new HighLowItemLabelGenerator());
1978        XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, renderer);
1979        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
1980                plot, legend);
1981        currentTheme.apply(chart);
1982        return chart;
1983
1984    }
1985
1986    /**
1987     * Creates and returns a default instance of a high-low-open-close chart
1988     * with a special timeline. This timeline can be a
1989     * {@link org.jfree.chart.axis.SegmentedTimeline} such as the Monday
1990     * through Friday timeline that will remove Saturdays and Sundays from
1991     * the axis.
1992     *
1993     * @param title  the chart title (<code>null</code> permitted).
1994     * @param timeAxisLabel  a label for the time axis (<code>null</code>
1995     *                       permitted).
1996     * @param valueAxisLabel  a label for the value axis (<code>null</code>
1997     *                        permitted).
1998     * @param dataset  the dataset for the chart (<code>null</code> permitted).
1999     * @param timeline  the timeline.
2000     * @param legend  a flag specifying whether or not a legend is required.
2001     *
2002     * @return A high-low-open-close chart.
2003     */
2004    public static JFreeChart createHighLowChart(String title,
2005                                                String timeAxisLabel,
2006                                                String valueAxisLabel,
2007                                                OHLCDataset dataset,
2008                                                Timeline timeline,
2009                                                boolean legend) {
2010
2011        DateAxis timeAxis = new DateAxis(timeAxisLabel);
2012        timeAxis.setTimeline(timeline);
2013        NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
2014        HighLowRenderer renderer = new HighLowRenderer();
2015        renderer.setBaseToolTipGenerator(new HighLowItemLabelGenerator());
2016        XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, renderer);
2017        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
2018                plot, legend);
2019        currentTheme.apply(chart);
2020        return chart;
2021
2022    }
2023
2024    /**
2025     * Creates a bubble chart with default settings.  The chart is composed of
2026     * an {@link XYPlot}, with a {@link NumberAxis} for the domain axis,
2027     * a {@link NumberAxis} for the range axis, and an {@link XYBubbleRenderer}
2028     * to draw the data items.
2029     *
2030     * @param title  the chart title (<code>null</code> permitted).
2031     * @param xAxisLabel  a label for the X-axis (<code>null</code> permitted).
2032     * @param yAxisLabel  a label for the Y-axis (<code>null</code> permitted).
2033     * @param dataset  the dataset for the chart (<code>null</code> permitted).
2034     * @param orientation  the orientation (horizontal or vertical)
2035     *                     (<code>null</code> NOT permitted).
2036     * @param legend  a flag specifying whether or not a legend is required.
2037     * @param tooltips  configure chart to generate tool tips?
2038     * @param urls  configure chart to generate URLs?
2039     *
2040     * @return A bubble chart.
2041     */
2042    public static JFreeChart createBubbleChart(String title,
2043                                               String xAxisLabel,
2044                                               String yAxisLabel,
2045                                               XYZDataset dataset,
2046                                               PlotOrientation orientation,
2047                                               boolean legend,
2048                                               boolean tooltips,
2049                                               boolean urls) {
2050
2051        if (orientation == null) {
2052            throw new IllegalArgumentException("Null 'orientation' argument.");
2053        }
2054        NumberAxis xAxis = new NumberAxis(xAxisLabel);
2055        xAxis.setAutoRangeIncludesZero(false);
2056        NumberAxis yAxis = new NumberAxis(yAxisLabel);
2057        yAxis.setAutoRangeIncludesZero(false);
2058
2059        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
2060
2061        XYItemRenderer renderer = new XYBubbleRenderer(
2062                XYBubbleRenderer.SCALE_ON_RANGE_AXIS);
2063        if (tooltips) {
2064            renderer.setBaseToolTipGenerator(new StandardXYZToolTipGenerator());
2065        }
2066        if (urls) {
2067            renderer.setURLGenerator(new StandardXYZURLGenerator());
2068        }
2069        plot.setRenderer(renderer);
2070        plot.setOrientation(orientation);
2071
2072        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
2073                plot, legend);
2074        currentTheme.apply(chart);
2075        return chart;
2076
2077    }
2078
2079    /**
2080     * Creates a histogram chart.  This chart is constructed with an
2081     * {@link XYPlot} using an {@link XYBarRenderer}.  The domain and range
2082     * axes are {@link NumberAxis} instances.
2083     *
2084     * @param title  the chart title (<code>null</code> permitted).
2085     * @param xAxisLabel  the x axis label (<code>null</code> permitted).
2086     * @param yAxisLabel  the y axis label (<code>null</code> permitted).
2087     * @param dataset  the dataset (<code>null</code> permitted).
2088     * @param orientation  the orientation (horizontal or vertical)
2089     *                     (<code>null</code> NOT permitted).
2090     * @param legend  create a legend?
2091     * @param tooltips  display tooltips?
2092     * @param urls  generate URLs?
2093     *
2094     * @return The chart.
2095     */
2096    public static JFreeChart createHistogram(String title,
2097            String xAxisLabel, String yAxisLabel, IntervalXYDataset dataset,
2098            PlotOrientation orientation, boolean legend, boolean tooltips,
2099            boolean urls) {
2100
2101        if (orientation == null) {
2102            throw new IllegalArgumentException("Null 'orientation' argument.");
2103        }
2104        NumberAxis xAxis = new NumberAxis(xAxisLabel);
2105        xAxis.setAutoRangeIncludesZero(false);
2106        ValueAxis yAxis = new NumberAxis(yAxisLabel);
2107
2108        XYItemRenderer renderer = new XYBarRenderer();
2109        if (tooltips) {
2110            renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
2111        }
2112        if (urls) {
2113            renderer.setURLGenerator(new StandardXYURLGenerator());
2114        }
2115
2116        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);
2117        plot.setOrientation(orientation);
2118        plot.setDomainZeroBaselineVisible(true);
2119        plot.setRangeZeroBaselineVisible(true);
2120        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
2121                plot, legend);
2122        currentTheme.apply(chart);
2123        return chart;
2124
2125    }
2126
2127    /**
2128     * Creates and returns a default instance of a box and whisker chart
2129     * based on data from a {@link BoxAndWhiskerCategoryDataset}.
2130     *
2131     * @param title  the chart title (<code>null</code> permitted).
2132     * @param categoryAxisLabel  a label for the category axis
2133     *     (<code>null</code> permitted).
2134     * @param valueAxisLabel  a label for the value axis (<code>null</code>
2135     *     permitted).
2136     * @param dataset  the dataset for the chart (<code>null</code> permitted).
2137     * @param legend  a flag specifying whether or not a legend is required.
2138     *
2139     * @return A box and whisker chart.
2140     *
2141     * @since 1.0.4
2142     */
2143    public static JFreeChart createBoxAndWhiskerChart(String title,
2144            String categoryAxisLabel, String valueAxisLabel,
2145            BoxAndWhiskerCategoryDataset dataset, boolean legend) {
2146
2147        CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
2148        NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
2149        valueAxis.setAutoRangeIncludesZero(false);
2150
2151        BoxAndWhiskerRenderer renderer = new BoxAndWhiskerRenderer();
2152        renderer.setBaseToolTipGenerator(new BoxAndWhiskerToolTipGenerator());
2153
2154        CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis,
2155                renderer);
2156        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
2157                plot, legend);
2158        currentTheme.apply(chart);
2159        return chart;
2160    }
2161
2162    /**
2163     * Creates and returns a default instance of a box and whisker chart.
2164     *
2165     * @param title  the chart title (<code>null</code> permitted).
2166     * @param timeAxisLabel  a label for the time axis (<code>null</code>
2167     *                       permitted).
2168     * @param valueAxisLabel  a label for the value axis (<code>null</code>
2169     *                        permitted).
2170     * @param dataset  the dataset for the chart (<code>null</code> permitted).
2171     * @param legend  a flag specifying whether or not a legend is required.
2172     *
2173     * @return A box and whisker chart.
2174     */
2175    public static JFreeChart createBoxAndWhiskerChart(String title,
2176                                                 String timeAxisLabel,
2177                                                 String valueAxisLabel,
2178                                                 BoxAndWhiskerXYDataset dataset,
2179                                                 boolean legend) {
2180
2181        ValueAxis timeAxis = new DateAxis(timeAxisLabel);
2182        NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
2183        valueAxis.setAutoRangeIncludesZero(false);
2184        XYBoxAndWhiskerRenderer renderer = new XYBoxAndWhiskerRenderer(10.0);
2185        XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, renderer);
2186        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
2187                plot, legend);
2188        currentTheme.apply(chart);
2189        return chart;
2190
2191    }
2192
2193    /**
2194     * Creates a wind plot with default settings.
2195     *
2196     * @param title  the chart title (<code>null</code> permitted).
2197     * @param xAxisLabel  a label for the x-axis (<code>null</code> permitted).
2198     * @param yAxisLabel  a label for the y-axis (<code>null</code> permitted).
2199     * @param dataset  the dataset for the chart (<code>null</code> permitted).
2200     * @param legend  a flag that controls whether or not a legend is created.
2201     * @param tooltips  configure chart to generate tool tips?
2202     * @param urls  configure chart to generate URLs?
2203     *
2204     * @return A wind plot.
2205     *
2206     */
2207    public static JFreeChart createWindPlot(String title,
2208                                            String xAxisLabel,
2209                                            String yAxisLabel,
2210                                            WindDataset dataset,
2211                                            boolean legend,
2212                                            boolean tooltips,
2213                                            boolean urls) {
2214
2215        ValueAxis xAxis = new DateAxis(xAxisLabel);
2216        ValueAxis yAxis = new NumberAxis(yAxisLabel);
2217        yAxis.setRange(-12.0, 12.0);
2218
2219        WindItemRenderer renderer = new WindItemRenderer();
2220        if (tooltips) {
2221            renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
2222        }
2223        if (urls) {
2224            renderer.setURLGenerator(new StandardXYURLGenerator());
2225        }
2226        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);
2227        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
2228                plot, legend);
2229        currentTheme.apply(chart);
2230        return chart;
2231
2232    }
2233
2234    /**
2235     * Creates a wafer map chart.
2236     *
2237     * @param title  the chart title (<code>null</code> permitted).
2238     * @param dataset  the dataset (<code>null</code> permitted).
2239     * @param orientation  the plot orientation (horizontal or vertical)
2240     *                     (<code>null</code> NOT permitted.
2241     * @param legend  display a legend?
2242     * @param tooltips  generate tooltips?
2243     * @param urls  generate URLs?
2244     *
2245     * @return A wafer map chart.
2246     */
2247    public static JFreeChart createWaferMapChart(String title,
2248                                                 WaferMapDataset dataset,
2249                                                 PlotOrientation orientation,
2250                                                 boolean legend,
2251                                                 boolean tooltips,
2252                                                 boolean urls) {
2253
2254        if (orientation == null) {
2255            throw new IllegalArgumentException("Null 'orientation' argument.");
2256        }
2257        WaferMapPlot plot = new WaferMapPlot(dataset);
2258        WaferMapRenderer renderer = new WaferMapRenderer();
2259        plot.setRenderer(renderer);
2260
2261        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT,
2262                plot, legend);
2263        currentTheme.apply(chart);
2264        return chart;
2265    }
2266
2267}

 

posted on 2013-05-31 05:40  Step-BY-Step  阅读(793)  评论(0编辑  收藏  举报

导航