first commit

This commit is contained in:
MaddoScientisto 2026-03-14 20:04:39 +01:00
commit 4d332ef662
27586 changed files with 3281783 additions and 0 deletions

View file

@ -0,0 +1,4 @@
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.6.0-b105 (Sun Microsystems Inc.)

View file

@ -0,0 +1,66 @@
package org.jfree.chart;
import java.awt.Color;
import java.awt.Paint;
public class ChartColor extends Color {
public static final Color VERY_DARK_RED = new Color(128, 0, 0);
public static final Color DARK_RED = new Color(192, 0, 0);
public static final Color LIGHT_RED = new Color(255, 64, 64);
public static final Color VERY_LIGHT_RED = new Color(255, 128, 128);
public static final Color VERY_DARK_YELLOW = new Color(128, 128, 0);
public static final Color DARK_YELLOW = new Color(192, 192, 0);
public static final Color LIGHT_YELLOW = new Color(255, 255, 64);
public static final Color VERY_LIGHT_YELLOW = new Color(255, 255, 128);
public static final Color VERY_DARK_GREEN = new Color(0, 128, 0);
public static final Color DARK_GREEN = new Color(0, 192, 0);
public static final Color LIGHT_GREEN = new Color(64, 255, 64);
public static final Color VERY_LIGHT_GREEN = new Color(128, 255, 128);
public static final Color VERY_DARK_CYAN = new Color(0, 128, 128);
public static final Color DARK_CYAN = new Color(0, 192, 192);
public static final Color LIGHT_CYAN = new Color(64, 255, 255);
public static final Color VERY_LIGHT_CYAN = new Color(128, 255, 255);
public static final Color VERY_DARK_BLUE = new Color(0, 0, 128);
public static final Color DARK_BLUE = new Color(0, 0, 192);
public static final Color LIGHT_BLUE = new Color(64, 64, 255);
public static final Color VERY_LIGHT_BLUE = new Color(128, 128, 255);
public static final Color VERY_DARK_MAGENTA = new Color(128, 0, 128);
public static final Color DARK_MAGENTA = new Color(192, 0, 192);
public static final Color LIGHT_MAGENTA = new Color(255, 64, 255);
public static final Color VERY_LIGHT_MAGENTA = new Color(255, 128, 255);
public ChartColor(int r, int g, int b) {
super(r, g, b);
}
public static Paint[] createDefaultPaintArray() {
return new Paint[] {
new Color(255, 85, 85), new Color(85, 85, 255), new Color(85, 255, 85), new Color(255, 255, 85), new Color(255, 85, 255), new Color(85, 255, 255), Color.pink, Color.gray, DARK_RED, DARK_BLUE,
DARK_GREEN, DARK_YELLOW, DARK_MAGENTA, DARK_CYAN, Color.darkGray, LIGHT_RED, LIGHT_BLUE, LIGHT_GREEN, LIGHT_YELLOW, LIGHT_MAGENTA,
LIGHT_CYAN, Color.lightGray, VERY_DARK_RED, VERY_DARK_BLUE, VERY_DARK_GREEN, VERY_DARK_YELLOW, VERY_DARK_MAGENTA, VERY_DARK_CYAN, VERY_LIGHT_RED, VERY_LIGHT_BLUE,
VERY_LIGHT_GREEN, VERY_LIGHT_YELLOW, VERY_LIGHT_MAGENTA, VERY_LIGHT_CYAN };
}
}

View file

@ -0,0 +1,787 @@
package org.jfree.chart;
import java.awt.Color;
import java.awt.Font;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryAxis3D;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberAxis3D;
import org.jfree.chart.axis.Timeline;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.BoxAndWhiskerToolTipGenerator;
import org.jfree.chart.labels.HighLowItemLabelGenerator;
import org.jfree.chart.labels.IntervalCategoryToolTipGenerator;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.PieToolTipGenerator;
import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.labels.StandardPieToolTipGenerator;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.labels.StandardXYZToolTipGenerator;
import org.jfree.chart.labels.XYToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Marker;
import org.jfree.chart.plot.MultiplePiePlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PiePlot3D;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PolarPlot;
import org.jfree.chart.plot.RingPlot;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.WaferMapPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.DefaultPolarItemRenderer;
import org.jfree.chart.renderer.WaferMapRenderer;
import org.jfree.chart.renderer.category.AreaRenderer;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.chart.renderer.category.BoxAndWhiskerRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.renderer.category.GanttRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.renderer.category.LineRenderer3D;
import org.jfree.chart.renderer.category.StackedAreaRenderer;
import org.jfree.chart.renderer.category.StackedBarRenderer;
import org.jfree.chart.renderer.category.StackedBarRenderer3D;
import org.jfree.chart.renderer.category.WaterfallBarRenderer;
import org.jfree.chart.renderer.xy.CandlestickRenderer;
import org.jfree.chart.renderer.xy.HighLowRenderer;
import org.jfree.chart.renderer.xy.StackedXYAreaRenderer2;
import org.jfree.chart.renderer.xy.WindItemRenderer;
import org.jfree.chart.renderer.xy.XYAreaRenderer;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.chart.renderer.xy.XYBoxAndWhiskerRenderer;
import org.jfree.chart.renderer.xy.XYBubbleRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.renderer.xy.XYStepAreaRenderer;
import org.jfree.chart.renderer.xy.XYStepRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.chart.urls.PieURLGenerator;
import org.jfree.chart.urls.StandardCategoryURLGenerator;
import org.jfree.chart.urls.StandardPieURLGenerator;
import org.jfree.chart.urls.StandardXYURLGenerator;
import org.jfree.chart.urls.StandardXYZURLGenerator;
import org.jfree.chart.urls.XYURLGenerator;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.IntervalCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.data.general.WaferMapDataset;
import org.jfree.data.statistics.BoxAndWhiskerCategoryDataset;
import org.jfree.data.statistics.BoxAndWhiskerXYDataset;
import org.jfree.data.xy.IntervalXYDataset;
import org.jfree.data.xy.OHLCDataset;
import org.jfree.data.xy.TableXYDataset;
import org.jfree.data.xy.WindDataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYZDataset;
import org.jfree.ui.Layer;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
import org.jfree.util.SortOrder;
import org.jfree.util.TableOrder;
public abstract class ChartFactory {
public static JFreeChart createPieChart(String title, PieDataset dataset, boolean legend, boolean tooltips, Locale locale) {
PiePlot plot = new PiePlot(dataset);
plot.setLabelGenerator(new StandardPieSectionLabelGenerator(locale));
plot.setInsets(new RectangleInsets(0.0D, 5.0D, 5.0D, 5.0D));
if (tooltips)
plot.setToolTipGenerator(new StandardPieToolTipGenerator(locale));
return new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
}
public static JFreeChart createPieChart(String title, PieDataset dataset, boolean legend, boolean tooltips, boolean urls) {
PiePlot plot = new PiePlot(dataset);
plot.setLabelGenerator(new StandardPieSectionLabelGenerator());
plot.setInsets(new RectangleInsets(0.0D, 5.0D, 5.0D, 5.0D));
if (tooltips)
plot.setToolTipGenerator(new StandardPieToolTipGenerator());
if (urls)
plot.setURLGenerator(new StandardPieURLGenerator());
return new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
}
public static JFreeChart createPieChart(String title, PieDataset dataset, PieDataset previousDataset, int percentDiffForMaxScale, boolean greenForIncrease, boolean legend, boolean tooltips, Locale locale, boolean subTitle, boolean showDifference) {
PiePlot plot = new PiePlot(dataset);
plot.setLabelGenerator(new StandardPieSectionLabelGenerator(locale));
plot.setInsets(new RectangleInsets(0.0D, 5.0D, 5.0D, 5.0D));
if (tooltips)
plot.setToolTipGenerator(new StandardPieToolTipGenerator(locale));
List keys = dataset.getKeys();
DefaultPieDataset series = null;
if (showDifference)
series = new DefaultPieDataset();
double colorPerPercent = 255.0D / (double)percentDiffForMaxScale;
for (Iterator it = keys.iterator(); it.hasNext(); ) {
Comparable key = (Comparable)it.next();
Number newValue = dataset.getValue(key);
Number oldValue = previousDataset.getValue(key);
if (oldValue == null) {
if (greenForIncrease) {
plot.setSectionPaint(key, Color.green);
} else {
plot.setSectionPaint(key, Color.red);
}
if (showDifference)
series.setValue(key + " (+100%)", newValue);
continue;
}
double percentChange = (newValue.doubleValue() / oldValue.doubleValue() - 1.0D) * 100.0D;
double shade = (Math.abs(percentChange) >= (double)percentDiffForMaxScale) ? 255.0D : (Math.abs(percentChange) * colorPerPercent);
if ((greenForIncrease && newValue.doubleValue() > oldValue.doubleValue()) || (!greenForIncrease && newValue.doubleValue() < oldValue.doubleValue())) {
plot.setSectionPaint(key, new Color(0, (int)shade, 0));
} else {
plot.setSectionPaint(key, new Color((int)shade, 0, 0));
}
if (showDifference)
series.setValue(key + " (" + ((percentChange >= 0.0D) ? "+" : "") + NumberFormat.getPercentInstance().format(percentChange / 100.0D) + ")", newValue);
}
if (showDifference)
plot.setDataset(series);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
if (subTitle) {
TextTitle subtitle = null;
subtitle = new TextTitle("Bright " + (greenForIncrease ? "red" : "green") + "=change >=-" + percentDiffForMaxScale + "%, Bright " + (!greenForIncrease ? "red" : "green") + "=change >=+" + percentDiffForMaxScale + "%", new Font("SansSerif", 0, 10));
chart.addSubtitle(subtitle);
}
return chart;
}
public static JFreeChart createPieChart(String title, PieDataset dataset, PieDataset previousDataset, int percentDiffForMaxScale, boolean greenForIncrease, boolean legend, boolean tooltips, boolean urls, boolean subTitle, boolean showDifference) {
PiePlot plot = new PiePlot(dataset);
plot.setLabelGenerator(new StandardPieSectionLabelGenerator());
plot.setInsets(new RectangleInsets(0.0D, 5.0D, 5.0D, 5.0D));
if (tooltips)
plot.setToolTipGenerator(new StandardPieToolTipGenerator());
if (urls)
plot.setURLGenerator(new StandardPieURLGenerator());
List keys = dataset.getKeys();
DefaultPieDataset series = null;
if (showDifference)
series = new DefaultPieDataset();
double colorPerPercent = 255.0D / (double)percentDiffForMaxScale;
for (Iterator it = keys.iterator(); it.hasNext(); ) {
Comparable key = (Comparable)it.next();
Number newValue = dataset.getValue(key);
Number oldValue = previousDataset.getValue(key);
if (oldValue == null) {
if (greenForIncrease) {
plot.setSectionPaint(key, Color.green);
} else {
plot.setSectionPaint(key, Color.red);
}
if (showDifference)
series.setValue(key + " (+100%)", newValue);
continue;
}
double percentChange = (newValue.doubleValue() / oldValue.doubleValue() - 1.0D) * 100.0D;
double shade = (Math.abs(percentChange) >= (double)percentDiffForMaxScale) ? 255.0D : (Math.abs(percentChange) * colorPerPercent);
if ((greenForIncrease && newValue.doubleValue() > oldValue.doubleValue()) || (!greenForIncrease && newValue.doubleValue() < oldValue.doubleValue())) {
plot.setSectionPaint(key, new Color(0, (int)shade, 0));
} else {
plot.setSectionPaint(key, new Color((int)shade, 0, 0));
}
if (showDifference)
series.setValue(key + " (" + ((percentChange >= 0.0D) ? "+" : "") + NumberFormat.getPercentInstance().format(percentChange / 100.0D) + ")", newValue);
}
if (showDifference)
plot.setDataset(series);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
if (subTitle) {
TextTitle subtitle = null;
subtitle = new TextTitle("Bright " + (greenForIncrease ? "red" : "green") + "=change >=-" + percentDiffForMaxScale + "%, Bright " + (!greenForIncrease ? "red" : "green") + "=change >=+" + percentDiffForMaxScale + "%", new Font("SansSerif", 0, 10));
chart.addSubtitle(subtitle);
}
return chart;
}
public static JFreeChart createRingChart(String title, PieDataset dataset, boolean legend, boolean tooltips, Locale locale) {
RingPlot plot = new RingPlot(dataset);
plot.setLabelGenerator(new StandardPieSectionLabelGenerator(locale));
plot.setInsets(new RectangleInsets(0.0D, 5.0D, 5.0D, 5.0D));
if (tooltips)
plot.setToolTipGenerator(new StandardPieToolTipGenerator(locale));
return new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
}
public static JFreeChart createRingChart(String title, PieDataset dataset, boolean legend, boolean tooltips, boolean urls) {
RingPlot plot = new RingPlot(dataset);
plot.setLabelGenerator(new StandardPieSectionLabelGenerator());
plot.setInsets(new RectangleInsets(0.0D, 5.0D, 5.0D, 5.0D));
if (tooltips)
plot.setToolTipGenerator(new StandardPieToolTipGenerator());
if (urls)
plot.setURLGenerator(new StandardPieURLGenerator());
return new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
}
public static JFreeChart createMultiplePieChart(String title, CategoryDataset dataset, TableOrder order, boolean legend, boolean tooltips, boolean urls) {
if (order == null)
throw new IllegalArgumentException("Null 'order' argument.");
MultiplePiePlot plot = new MultiplePiePlot(dataset);
plot.setDataExtractOrder(order);
plot.setBackgroundPaint(null);
plot.setOutlineStroke(null);
if (tooltips) {
PieToolTipGenerator tooltipGenerator = new StandardPieToolTipGenerator();
PiePlot pp = (PiePlot)plot.getPieChart().getPlot();
pp.setToolTipGenerator(tooltipGenerator);
}
if (urls) {
PieURLGenerator urlGenerator = new StandardPieURLGenerator();
PiePlot pp = (PiePlot)plot.getPieChart().getPlot();
pp.setURLGenerator(urlGenerator);
}
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createPieChart3D(String title, PieDataset dataset, boolean legend, boolean tooltips, Locale locale) {
PiePlot3D plot = new PiePlot3D(dataset);
plot.setInsets(new RectangleInsets(0.0D, 5.0D, 5.0D, 5.0D));
if (tooltips)
plot.setToolTipGenerator(new StandardPieToolTipGenerator(locale));
return new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
}
public static JFreeChart createPieChart3D(String title, PieDataset dataset, boolean legend, boolean tooltips, boolean urls) {
PiePlot3D plot = new PiePlot3D(dataset);
plot.setInsets(new RectangleInsets(0.0D, 5.0D, 5.0D, 5.0D));
if (tooltips)
plot.setToolTipGenerator(new StandardPieToolTipGenerator());
if (urls)
plot.setURLGenerator(new StandardPieURLGenerator());
return new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
}
public static JFreeChart createMultiplePieChart3D(String title, CategoryDataset dataset, TableOrder order, boolean legend, boolean tooltips, boolean urls) {
if (order == null)
throw new IllegalArgumentException("Null 'order' argument.");
MultiplePiePlot plot = new MultiplePiePlot(dataset);
plot.setDataExtractOrder(order);
plot.setBackgroundPaint(null);
plot.setOutlineStroke(null);
JFreeChart pieChart = new JFreeChart(new PiePlot3D(null));
TextTitle seriesTitle = new TextTitle("Series Title", new Font("SansSerif", 1, 12));
seriesTitle.setPosition(RectangleEdge.BOTTOM);
pieChart.setTitle(seriesTitle);
pieChart.removeLegend();
pieChart.setBackgroundPaint(null);
plot.setPieChart(pieChart);
if (tooltips) {
PieToolTipGenerator tooltipGenerator = new StandardPieToolTipGenerator();
PiePlot pp = (PiePlot)plot.getPieChart().getPlot();
pp.setToolTipGenerator(tooltipGenerator);
}
if (urls) {
PieURLGenerator urlGenerator = new StandardPieURLGenerator();
PiePlot pp = (PiePlot)plot.getPieChart().getPlot();
pp.setURLGenerator(urlGenerator);
}
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createBarChart(String title, String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
BarRenderer renderer = new BarRenderer();
if (orientation == PlotOrientation.HORIZONTAL) {
ItemLabelPosition position1 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE3, TextAnchor.CENTER_LEFT);
renderer.setBasePositiveItemLabelPosition(position1);
ItemLabelPosition position2 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE9, TextAnchor.CENTER_RIGHT);
renderer.setBaseNegativeItemLabelPosition(position2);
} else if (orientation == PlotOrientation.VERTICAL) {
ItemLabelPosition position1 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BOTTOM_CENTER);
renderer.setBasePositiveItemLabelPosition(position1);
ItemLabelPosition position2 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE6, TextAnchor.TOP_CENTER);
renderer.setBaseNegativeItemLabelPosition(position2);
}
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
if (urls)
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createStackedBarChart(String title, String domainAxisLabel, String rangeAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
CategoryAxis categoryAxis = new CategoryAxis(domainAxisLabel);
ValueAxis valueAxis = new NumberAxis(rangeAxisLabel);
StackedBarRenderer renderer = new StackedBarRenderer();
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
if (urls)
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createBarChart3D(String title, String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
CategoryAxis categoryAxis = new CategoryAxis3D(categoryAxisLabel);
ValueAxis valueAxis = new NumberAxis3D(valueAxisLabel);
BarRenderer3D renderer = new BarRenderer3D();
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
if (urls)
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
plot.setOrientation(orientation);
if (orientation == PlotOrientation.HORIZONTAL) {
plot.setRowRenderingOrder(SortOrder.DESCENDING);
plot.setColumnRenderingOrder(SortOrder.DESCENDING);
}
plot.setForegroundAlpha(0.75F);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createStackedBarChart3D(String title, String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
CategoryAxis categoryAxis = new CategoryAxis3D(categoryAxisLabel);
ValueAxis valueAxis = new NumberAxis3D(valueAxisLabel);
CategoryItemRenderer renderer = new StackedBarRenderer3D();
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
if (urls)
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
plot.setOrientation(orientation);
if (orientation == PlotOrientation.HORIZONTAL)
plot.setColumnRenderingOrder(SortOrder.DESCENDING);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createAreaChart(String title, String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
categoryAxis.setCategoryMargin(0.0D);
ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
AreaRenderer renderer = new AreaRenderer();
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
if (urls)
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createStackedAreaChart(String title, String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
StackedAreaRenderer renderer = new StackedAreaRenderer();
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
if (urls)
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createLineChart(String title, String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
LineAndShapeRenderer renderer = new LineAndShapeRenderer(true, false);
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
if (urls)
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createLineChart3D(String title, String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
CategoryAxis categoryAxis = new CategoryAxis3D(categoryAxisLabel);
ValueAxis valueAxis = new NumberAxis3D(valueAxisLabel);
LineRenderer3D renderer = new LineRenderer3D();
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());
if (urls)
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createGanttChart(String title, String categoryAxisLabel, String dateAxisLabel, IntervalCategoryDataset dataset, boolean legend, boolean tooltips, boolean urls) {
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
DateAxis dateAxis = new DateAxis(dateAxisLabel);
CategoryItemRenderer renderer = new GanttRenderer();
if (tooltips)
renderer.setBaseToolTipGenerator(new IntervalCategoryToolTipGenerator("{3} - {4}", DateFormat.getDateInstance()));
if (urls)
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, dateAxis, renderer);
plot.setOrientation(PlotOrientation.HORIZONTAL);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createWaterfallChart(String title, String categoryAxisLabel, String valueAxisLabel, CategoryDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
categoryAxis.setCategoryMargin(0.0D);
ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
WaterfallBarRenderer renderer = new WaterfallBarRenderer();
if (orientation == PlotOrientation.HORIZONTAL) {
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.CENTER, TextAnchor.CENTER, 1.5707963267948966D);
renderer.setBasePositiveItemLabelPosition(position);
renderer.setBaseNegativeItemLabelPosition(position);
} else if (orientation == PlotOrientation.VERTICAL) {
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.CENTER, TextAnchor.CENTER, 0.0D);
renderer.setBasePositiveItemLabelPosition(position);
renderer.setBaseNegativeItemLabelPosition(position);
}
if (tooltips) {
StandardCategoryToolTipGenerator generator = new StandardCategoryToolTipGenerator();
renderer.setBaseToolTipGenerator(generator);
}
if (urls)
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
plot.clearRangeMarkers();
Marker baseline = new ValueMarker(0.0D);
baseline.setPaint(Color.black);
plot.addRangeMarker(baseline, Layer.FOREGROUND);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createPolarChart(String title, XYDataset dataset, boolean legend, boolean tooltips, boolean urls) {
PolarPlot plot = new PolarPlot();
plot.setDataset(dataset);
NumberAxis rangeAxis = new NumberAxis();
rangeAxis.setAxisLineVisible(false);
rangeAxis.setTickMarksVisible(false);
rangeAxis.setTickLabelInsets(new RectangleInsets(0.0D, 0.0D, 0.0D, 0.0D));
plot.setAxis(rangeAxis);
plot.setRenderer(new DefaultPolarItemRenderer());
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createScatterPlot(String title, String xAxisLabel, String yAxisLabel, XYDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
NumberAxis xAxis = new NumberAxis(xAxisLabel);
xAxis.setAutoRangeIncludesZero(false);
NumberAxis yAxis = new NumberAxis(yAxisLabel);
yAxis.setAutoRangeIncludesZero(false);
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
XYToolTipGenerator toolTipGenerator = null;
if (tooltips)
toolTipGenerator = new StandardXYToolTipGenerator();
XYURLGenerator urlGenerator = null;
if (urls)
urlGenerator = new StandardXYURLGenerator();
XYItemRenderer renderer = new XYLineAndShapeRenderer(false, true);
renderer.setBaseToolTipGenerator(toolTipGenerator);
renderer.setURLGenerator(urlGenerator);
plot.setRenderer(renderer);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createXYBarChart(String title, String xAxisLabel, boolean dateAxis, String yAxisLabel, IntervalXYDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
ValueAxis domainAxis = null;
if (dateAxis) {
domainAxis = new DateAxis(xAxisLabel);
} else {
NumberAxis axis = new NumberAxis(xAxisLabel);
axis.setAutoRangeIncludesZero(false);
domainAxis = axis;
}
ValueAxis valueAxis = new NumberAxis(yAxisLabel);
XYBarRenderer renderer = new XYBarRenderer();
if (tooltips) {
XYToolTipGenerator tt;
if (dateAxis) {
tt = StandardXYToolTipGenerator.getTimeSeriesInstance();
} else {
tt = new StandardXYToolTipGenerator();
}
renderer.setBaseToolTipGenerator(tt);
}
if (urls)
renderer.setURLGenerator(new StandardXYURLGenerator());
XYPlot plot = new XYPlot(dataset, domainAxis, valueAxis, renderer);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createXYAreaChart(String title, String xAxisLabel, String yAxisLabel, XYDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
NumberAxis xAxis = new NumberAxis(xAxisLabel);
xAxis.setAutoRangeIncludesZero(false);
NumberAxis yAxis = new NumberAxis(yAxisLabel);
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
plot.setOrientation(orientation);
plot.setForegroundAlpha(0.5F);
XYToolTipGenerator tipGenerator = null;
if (tooltips)
tipGenerator = new StandardXYToolTipGenerator();
XYURLGenerator urlGenerator = null;
if (urls)
urlGenerator = new StandardXYURLGenerator();
plot.setRenderer(new XYAreaRenderer(4, tipGenerator, urlGenerator));
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createStackedXYAreaChart(String title, String xAxisLabel, String yAxisLabel, TableXYDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
NumberAxis xAxis = new NumberAxis(xAxisLabel);
xAxis.setAutoRangeIncludesZero(false);
xAxis.setLowerMargin(0.0D);
xAxis.setUpperMargin(0.0D);
NumberAxis yAxis = new NumberAxis(yAxisLabel);
XYToolTipGenerator toolTipGenerator = null;
if (tooltips)
toolTipGenerator = new StandardXYToolTipGenerator();
XYURLGenerator urlGenerator = null;
if (urls)
urlGenerator = new StandardXYURLGenerator();
StackedXYAreaRenderer2 renderer = new StackedXYAreaRenderer2(toolTipGenerator, urlGenerator);
renderer.setOutline(true);
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);
plot.setOrientation(orientation);
plot.setRangeAxis(yAxis);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createXYLineChart(String title, String xAxisLabel, String yAxisLabel, XYDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
NumberAxis xAxis = new NumberAxis(xAxisLabel);
xAxis.setAutoRangeIncludesZero(false);
NumberAxis yAxis = new NumberAxis(yAxisLabel);
XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false);
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);
plot.setOrientation(orientation);
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
if (urls)
renderer.setURLGenerator(new StandardXYURLGenerator());
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createXYStepChart(String title, String xAxisLabel, String yAxisLabel, XYDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
DateAxis xAxis = new DateAxis(xAxisLabel);
NumberAxis yAxis = new NumberAxis(yAxisLabel);
yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
XYToolTipGenerator toolTipGenerator = null;
if (tooltips)
toolTipGenerator = new StandardXYToolTipGenerator();
XYURLGenerator urlGenerator = null;
if (urls)
urlGenerator = new StandardXYURLGenerator();
XYItemRenderer renderer = new XYStepRenderer(toolTipGenerator, urlGenerator);
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
plot.setRenderer(renderer);
plot.setOrientation(orientation);
plot.setDomainCrosshairVisible(false);
plot.setRangeCrosshairVisible(false);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createXYStepAreaChart(String title, String xAxisLabel, String yAxisLabel, XYDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
NumberAxis xAxis = new NumberAxis(xAxisLabel);
xAxis.setAutoRangeIncludesZero(false);
NumberAxis yAxis = new NumberAxis(yAxisLabel);
XYToolTipGenerator toolTipGenerator = null;
if (tooltips)
toolTipGenerator = new StandardXYToolTipGenerator();
XYURLGenerator urlGenerator = null;
if (urls)
urlGenerator = new StandardXYURLGenerator();
XYItemRenderer renderer = new XYStepAreaRenderer(3, toolTipGenerator, urlGenerator);
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
plot.setRenderer(renderer);
plot.setOrientation(orientation);
plot.setDomainCrosshairVisible(false);
plot.setRangeCrosshairVisible(false);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createTimeSeriesChart(String title, String timeAxisLabel, String valueAxisLabel, XYDataset dataset, boolean legend, boolean tooltips, boolean urls) {
ValueAxis timeAxis = new DateAxis(timeAxisLabel);
timeAxis.setLowerMargin(0.02D);
timeAxis.setUpperMargin(0.02D);
NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
valueAxis.setAutoRangeIncludesZero(false);
XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, null);
XYToolTipGenerator toolTipGenerator = null;
if (tooltips)
toolTipGenerator = StandardXYToolTipGenerator.getTimeSeriesInstance();
XYURLGenerator urlGenerator = null;
if (urls)
urlGenerator = new StandardXYURLGenerator();
XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, false);
renderer.setBaseToolTipGenerator(toolTipGenerator);
renderer.setURLGenerator(urlGenerator);
plot.setRenderer(renderer);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createCandlestickChart(String title, String timeAxisLabel, String valueAxisLabel, OHLCDataset dataset, boolean legend) {
ValueAxis timeAxis = new DateAxis(timeAxisLabel);
NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, null);
plot.setRenderer(new CandlestickRenderer());
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createHighLowChart(String title, String timeAxisLabel, String valueAxisLabel, OHLCDataset dataset, boolean legend) {
ValueAxis timeAxis = new DateAxis(timeAxisLabel);
NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
HighLowRenderer renderer = new HighLowRenderer();
renderer.setBaseToolTipGenerator(new HighLowItemLabelGenerator());
XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, renderer);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createHighLowChart(String title, String timeAxisLabel, String valueAxisLabel, OHLCDataset dataset, Timeline timeline, boolean legend) {
DateAxis timeAxis = new DateAxis(timeAxisLabel);
timeAxis.setTimeline(timeline);
NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
HighLowRenderer renderer = new HighLowRenderer();
renderer.setBaseToolTipGenerator(new HighLowItemLabelGenerator());
XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, renderer);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createBubbleChart(String title, String xAxisLabel, String yAxisLabel, XYZDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
NumberAxis xAxis = new NumberAxis(xAxisLabel);
xAxis.setAutoRangeIncludesZero(false);
NumberAxis yAxis = new NumberAxis(yAxisLabel);
yAxis.setAutoRangeIncludesZero(false);
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, null);
XYItemRenderer renderer = new XYBubbleRenderer(2);
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardXYZToolTipGenerator());
if (urls)
renderer.setURLGenerator(new StandardXYZURLGenerator());
plot.setRenderer(renderer);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createHistogram(String title, String xAxisLabel, String yAxisLabel, IntervalXYDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
NumberAxis xAxis = new NumberAxis(xAxisLabel);
xAxis.setAutoRangeIncludesZero(false);
ValueAxis yAxis = new NumberAxis(yAxisLabel);
XYItemRenderer renderer = new XYBarRenderer();
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
if (urls)
renderer.setURLGenerator(new StandardXYURLGenerator());
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);
plot.setOrientation(orientation);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createBoxAndWhiskerChart(String title, String categoryAxisLabel, String valueAxisLabel, BoxAndWhiskerCategoryDataset dataset, boolean legend) {
CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
valueAxis.setAutoRangeIncludesZero(false);
BoxAndWhiskerRenderer renderer = new BoxAndWhiskerRenderer();
renderer.setBaseToolTipGenerator(new BoxAndWhiskerToolTipGenerator());
CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
return new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
}
public static JFreeChart createBoxAndWhiskerChart(String title, String timeAxisLabel, String valueAxisLabel, BoxAndWhiskerXYDataset dataset, boolean legend) {
ValueAxis timeAxis = new DateAxis(timeAxisLabel);
NumberAxis valueAxis = new NumberAxis(valueAxisLabel);
valueAxis.setAutoRangeIncludesZero(false);
XYBoxAndWhiskerRenderer renderer = new XYBoxAndWhiskerRenderer(10.0D);
XYPlot plot = new XYPlot(dataset, timeAxis, valueAxis, renderer);
return new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
}
public static JFreeChart createWindPlot(String title, String xAxisLabel, String yAxisLabel, WindDataset dataset, boolean legend, boolean tooltips, boolean urls) {
ValueAxis xAxis = new DateAxis(xAxisLabel);
ValueAxis yAxis = new NumberAxis(yAxisLabel);
yAxis.setRange(-12.0D, 12.0D);
WindItemRenderer renderer = new WindItemRenderer();
if (tooltips)
renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
if (urls)
renderer.setURLGenerator(new StandardXYURLGenerator());
XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
public static JFreeChart createWaferMapChart(String title, WaferMapDataset dataset, PlotOrientation orientation, boolean legend, boolean tooltips, boolean urls) {
if (orientation == null)
throw new IllegalArgumentException("Null 'orientation' argument.");
WaferMapPlot plot = new WaferMapPlot(dataset);
WaferMapRenderer renderer = new WaferMapRenderer();
plot.setRenderer(renderer);
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
return chart;
}
}

View file

@ -0,0 +1,27 @@
package org.jfree.chart;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
public class ChartFrame extends JFrame {
private ChartPanel chartPanel;
public ChartFrame(String title, JFreeChart chart) {
this(title, chart, false);
}
public ChartFrame(String title, JFreeChart chart, boolean scrollPane) {
super(title);
setDefaultCloseOperation(2);
this.chartPanel = new ChartPanel(chart);
if (scrollPane) {
setContentPane(new JScrollPane(this.chartPanel));
} else {
setContentPane(this.chartPanel);
}
}
public ChartPanel getChartPanel() {
return this.chartPanel;
}
}

View file

@ -0,0 +1,35 @@
package org.jfree.chart;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.EventObject;
import org.jfree.chart.entity.ChartEntity;
public class ChartMouseEvent extends EventObject implements Serializable {
private static final long serialVersionUID = -682393837314562149L;
private JFreeChart chart;
private MouseEvent trigger;
private ChartEntity entity;
public ChartMouseEvent(JFreeChart chart, MouseEvent trigger, ChartEntity entity) {
super(chart);
this.chart = chart;
this.trigger = trigger;
this.entity = entity;
}
public JFreeChart getChart() {
return this.chart;
}
public MouseEvent getTrigger() {
return this.trigger;
}
public ChartEntity getEntity() {
return this.entity;
}
}

View file

@ -0,0 +1,9 @@
package org.jfree.chart;
import java.util.EventListener;
public interface ChartMouseListener extends EventListener {
void chartMouseClicked(ChartMouseEvent paramChartMouseEvent);
void chartMouseMoved(ChartMouseEvent paramChartMouseEvent);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,96 @@
package org.jfree.chart;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.io.SerialUtilities;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PublicCloneable;
public class ChartRenderingInfo implements Cloneable, Serializable {
private static final long serialVersionUID = 2751952018173406822L;
private transient Rectangle2D chartArea;
private PlotRenderingInfo plotInfo;
private EntityCollection entities;
public ChartRenderingInfo() {
this(new StandardEntityCollection());
}
public ChartRenderingInfo(EntityCollection entities) {
this.chartArea = new Rectangle2D.Double();
this.plotInfo = new PlotRenderingInfo(this);
this.entities = entities;
}
public Rectangle2D getChartArea() {
return this.chartArea;
}
public void setChartArea(Rectangle2D area) {
this.chartArea.setRect(area);
}
public EntityCollection getEntityCollection() {
return this.entities;
}
public void setEntityCollection(EntityCollection entities) {
this.entities = entities;
}
public void clear() {
this.chartArea.setRect(0.0D, 0.0D, 0.0D, 0.0D);
this.plotInfo = new PlotRenderingInfo(this);
if (this.entities != null)
this.entities.clear();
}
public PlotRenderingInfo getPlotInfo() {
return this.plotInfo;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof ChartRenderingInfo))
return false;
ChartRenderingInfo that = (ChartRenderingInfo)obj;
if (!ObjectUtilities.equal(this.chartArea, that.chartArea))
return false;
if (!ObjectUtilities.equal(this.plotInfo, that.plotInfo))
return false;
if (!ObjectUtilities.equal(this.entities, that.entities))
return false;
return true;
}
public Object clone() throws CloneNotSupportedException {
ChartRenderingInfo clone = (ChartRenderingInfo)super.clone();
if (this.chartArea != null)
clone.chartArea = (Rectangle2D)this.chartArea.clone();
if (this.entities instanceof PublicCloneable) {
PublicCloneable pc = (PublicCloneable)this.entities;
clone.entities = (EntityCollection)pc.clone();
}
return clone;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeShape(this.chartArea, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.chartArea = (Rectangle2D)SerialUtilities.readShape(stream);
}
}

View file

@ -0,0 +1,203 @@
package org.jfree.chart;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import org.jfree.chart.encoders.EncoderUtil;
import org.jfree.chart.imagemap.ImageMapUtilities;
import org.jfree.chart.imagemap.OverLIBToolTipTagFragmentGenerator;
import org.jfree.chart.imagemap.StandardToolTipTagFragmentGenerator;
import org.jfree.chart.imagemap.StandardURLTagFragmentGenerator;
import org.jfree.chart.imagemap.ToolTipTagFragmentGenerator;
import org.jfree.chart.imagemap.URLTagFragmentGenerator;
public abstract class ChartUtilities {
public static void writeChartAsPNG(OutputStream out, JFreeChart chart, int width, int height) throws IOException {
writeChartAsPNG(out, chart, width, height, null);
}
public static void writeChartAsPNG(OutputStream out, JFreeChart chart, int width, int height, boolean encodeAlpha, int compression) throws IOException {
writeChartAsPNG(out, chart, width, height, null, encodeAlpha, compression);
}
public static void writeChartAsPNG(OutputStream out, JFreeChart chart, int width, int height, ChartRenderingInfo info) throws IOException {
if (chart == null)
throw new IllegalArgumentException("Null 'chart' argument.");
BufferedImage bufferedImage = chart.createBufferedImage(width, height, info);
EncoderUtil.writeBufferedImage(bufferedImage, "png", out);
}
public static void writeChartAsPNG(OutputStream out, JFreeChart chart, int width, int height, ChartRenderingInfo info, boolean encodeAlpha, int compression) throws IOException {
if (out == null)
throw new IllegalArgumentException("Null 'out' argument.");
if (chart == null)
throw new IllegalArgumentException("Null 'chart' argument.");
BufferedImage chartImage = chart.createBufferedImage(width, height, 2, info);
writeBufferedImageAsPNG(out, chartImage, encodeAlpha, compression);
}
public static void writeScaledChartAsPNG(OutputStream out, JFreeChart chart, int width, int height, int widthScaleFactor, int heightScaleFactor) throws IOException {
if (out == null)
throw new IllegalArgumentException("Null 'out' argument.");
if (chart == null)
throw new IllegalArgumentException("Null 'chart' argument.");
double desiredWidth = (double)(width * widthScaleFactor);
double desiredHeight = (double)(height * heightScaleFactor);
double defaultWidth = (double)width;
double defaultHeight = (double)height;
boolean scale = false;
if (widthScaleFactor != 1 || heightScaleFactor != 1)
scale = true;
double scaleX = desiredWidth / defaultWidth;
double scaleY = desiredHeight / defaultHeight;
BufferedImage image = new BufferedImage((int)desiredWidth, (int)desiredHeight, 2);
Graphics2D g2 = image.createGraphics();
if (scale) {
AffineTransform saved = g2.getTransform();
g2.transform(AffineTransform.getScaleInstance(scaleX, scaleY));
chart.draw(g2, new Rectangle2D.Double(0.0D, 0.0D, defaultWidth, defaultHeight), null, null);
g2.setTransform(saved);
g2.dispose();
} else {
chart.draw(g2, new Rectangle2D.Double(0.0D, 0.0D, defaultWidth, defaultHeight), null, null);
}
out.write(encodeAsPNG(image));
}
public static void saveChartAsPNG(File file, JFreeChart chart, int width, int height) throws IOException {
saveChartAsPNG(file, chart, width, height, null);
}
public static void saveChartAsPNG(File file, JFreeChart chart, int width, int height, ChartRenderingInfo info) throws IOException {
if (file == null)
throw new IllegalArgumentException("Null 'file' argument.");
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
try {
writeChartAsPNG(out, chart, width, height, info);
} finally {
out.close();
}
}
public static void saveChartAsPNG(File file, JFreeChart chart, int width, int height, ChartRenderingInfo info, boolean encodeAlpha, int compression) throws IOException {
if (file == null)
throw new IllegalArgumentException("Null 'file' argument.");
if (chart == null)
throw new IllegalArgumentException("Null 'chart' argument.");
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
try {
writeChartAsPNG(out, chart, width, height, info, encodeAlpha, compression);
} finally {
out.close();
}
}
public static void writeChartAsJPEG(OutputStream out, JFreeChart chart, int width, int height) throws IOException {
writeChartAsJPEG(out, chart, width, height, null);
}
public static void writeChartAsJPEG(OutputStream out, float quality, JFreeChart chart, int width, int height) throws IOException {
writeChartAsJPEG(out, quality, chart, width, height, null);
}
public static void writeChartAsJPEG(OutputStream out, JFreeChart chart, int width, int height, ChartRenderingInfo info) throws IOException {
if (chart == null)
throw new IllegalArgumentException("Null 'chart' argument.");
BufferedImage image = chart.createBufferedImage(width, height, info);
EncoderUtil.writeBufferedImage(image, "jpeg", out);
}
public static void writeChartAsJPEG(OutputStream out, float quality, JFreeChart chart, int width, int height, ChartRenderingInfo info) throws IOException {
if (chart == null)
throw new IllegalArgumentException("Null 'chart' argument.");
BufferedImage image = chart.createBufferedImage(width, height, info);
EncoderUtil.writeBufferedImage(image, "jpeg", out, quality);
}
public static void saveChartAsJPEG(File file, JFreeChart chart, int width, int height) throws IOException {
saveChartAsJPEG(file, chart, width, height, null);
}
public static void saveChartAsJPEG(File file, float quality, JFreeChart chart, int width, int height) throws IOException {
saveChartAsJPEG(file, quality, chart, width, height, null);
}
public static void saveChartAsJPEG(File file, JFreeChart chart, int width, int height, ChartRenderingInfo info) throws IOException {
if (file == null)
throw new IllegalArgumentException("Null 'file' argument.");
if (chart == null)
throw new IllegalArgumentException("Null 'chart' argument.");
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
try {
writeChartAsJPEG(out, chart, width, height, info);
} finally {
out.close();
}
}
public static void saveChartAsJPEG(File file, float quality, JFreeChart chart, int width, int height, ChartRenderingInfo info) throws IOException {
if (file == null)
throw new IllegalArgumentException("Null 'file' argument.");
if (chart == null)
throw new IllegalArgumentException("Null 'chart' argument.");
OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
try {
writeChartAsJPEG(out, quality, chart, width, height, info);
} finally {
out.close();
}
}
public static void writeBufferedImageAsJPEG(OutputStream out, BufferedImage image) throws IOException {
writeBufferedImageAsJPEG(out, 0.75F, image);
}
public static void writeBufferedImageAsJPEG(OutputStream out, float quality, BufferedImage image) throws IOException {
EncoderUtil.writeBufferedImage(image, "jpeg", out, quality);
}
public static void writeBufferedImageAsPNG(OutputStream out, BufferedImage image) throws IOException {
EncoderUtil.writeBufferedImage(image, "png", out);
}
public static void writeBufferedImageAsPNG(OutputStream out, BufferedImage image, boolean encodeAlpha, int compression) throws IOException {
EncoderUtil.writeBufferedImage(image, "png", out, (float)compression, encodeAlpha);
}
public static byte[] encodeAsPNG(BufferedImage image) throws IOException {
return EncoderUtil.encode(image, "png");
}
public static byte[] encodeAsPNG(BufferedImage image, boolean encodeAlpha, int compression) throws IOException {
return EncoderUtil.encode(image, "png", (float)compression, encodeAlpha);
}
public static void writeImageMap(PrintWriter writer, String name, ChartRenderingInfo info, boolean useOverLibForToolTips) throws IOException {
ToolTipTagFragmentGenerator toolTipTagFragmentGenerator = null;
if (useOverLibForToolTips) {
toolTipTagFragmentGenerator = new OverLIBToolTipTagFragmentGenerator();
} else {
toolTipTagFragmentGenerator = new StandardToolTipTagFragmentGenerator();
}
ImageMapUtilities.writeImageMap(writer, name, info, toolTipTagFragmentGenerator, new StandardURLTagFragmentGenerator());
}
public static void writeImageMap(PrintWriter writer, String name, ChartRenderingInfo info, ToolTipTagFragmentGenerator toolTipTagFragmentGenerator, URLTagFragmentGenerator urlTagFragmentGenerator) throws IOException {
writer.println(ImageMapUtilities.getImageMap(name, info, toolTipTagFragmentGenerator, urlTagFragmentGenerator));
}
public static String getImageMap(String name, ChartRenderingInfo info) {
return ImageMapUtilities.getImageMap(name, info, new StandardToolTipTagFragmentGenerator(), new StandardURLTagFragmentGenerator());
}
public static String getImageMap(String name, ChartRenderingInfo info, ToolTipTagFragmentGenerator toolTipTagFragmentGenerator, URLTagFragmentGenerator urlTagFragmentGenerator) {
return ImageMapUtilities.getImageMap(name, info, toolTipTagFragmentGenerator, urlTagFragmentGenerator);
}
}

View file

@ -0,0 +1,178 @@
package org.jfree.chart;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.ui.RectangleEdge;
public class ClipPath implements Cloneable {
private double[] xValue = null;
private double[] yValue = null;
private boolean clip = true;
private boolean drawPath = false;
private boolean fillPath = false;
private Paint fillPaint = null;
private Paint drawPaint = null;
private Stroke drawStroke = null;
private Composite composite = null;
public ClipPath() {}
public ClipPath(double[] xValue, double[] yValue) {
this(xValue, yValue, true, false, true);
}
public ClipPath(double[] xValue, double[] yValue, boolean clip, boolean fillPath, boolean drawPath) {
this.xValue = xValue;
this.yValue = yValue;
this.clip = clip;
this.fillPath = fillPath;
this.drawPath = drawPath;
this.fillPaint = Color.gray;
this.drawPaint = Color.blue;
this.drawStroke = new BasicStroke(1.0F);
this.composite = AlphaComposite.Src;
}
public ClipPath(double[] xValue, double[] yValue, boolean fillPath, boolean drawPath, Paint fillPaint, Paint drawPaint, Stroke drawStroke, Composite composite) {
this.xValue = xValue;
this.yValue = yValue;
this.fillPath = fillPath;
this.drawPath = drawPath;
this.fillPaint = fillPaint;
this.drawPaint = drawPaint;
this.drawStroke = drawStroke;
this.composite = composite;
}
public GeneralPath draw(Graphics2D g2, Rectangle2D dataArea, ValueAxis horizontalAxis, ValueAxis verticalAxis) {
GeneralPath generalPath = generateClipPath(dataArea, horizontalAxis, verticalAxis);
if (this.fillPath || this.drawPath) {
Composite saveComposite = g2.getComposite();
Paint savePaint = g2.getPaint();
Stroke saveStroke = g2.getStroke();
if (this.fillPaint != null)
g2.setPaint(this.fillPaint);
if (this.composite != null)
g2.setComposite(this.composite);
if (this.fillPath)
g2.fill(generalPath);
if (this.drawStroke != null)
g2.setStroke(this.drawStroke);
if (this.drawPath)
g2.draw(generalPath);
g2.setPaint(savePaint);
g2.setComposite(saveComposite);
g2.setStroke(saveStroke);
}
return generalPath;
}
public GeneralPath generateClipPath(Rectangle2D dataArea, ValueAxis horizontalAxis, ValueAxis verticalAxis) {
GeneralPath generalPath = new GeneralPath();
double transX = horizontalAxis.valueToJava2D(this.xValue[0], dataArea, RectangleEdge.BOTTOM);
double transY = verticalAxis.valueToJava2D(this.yValue[0], dataArea, RectangleEdge.LEFT);
generalPath.moveTo((float)transX, (float)transY);
for (int k = 0; k < this.yValue.length; k++) {
transX = horizontalAxis.valueToJava2D(this.xValue[k], dataArea, RectangleEdge.BOTTOM);
transY = verticalAxis.valueToJava2D(this.yValue[k], dataArea, RectangleEdge.LEFT);
generalPath.lineTo((float)transX, (float)transY);
}
generalPath.closePath();
return generalPath;
}
public Composite getComposite() {
return this.composite;
}
public Paint getDrawPaint() {
return this.drawPaint;
}
public boolean isDrawPath() {
return this.drawPath;
}
public Stroke getDrawStroke() {
return this.drawStroke;
}
public Paint getFillPaint() {
return this.fillPaint;
}
public boolean isFillPath() {
return this.fillPath;
}
public double[] getXValue() {
return this.xValue;
}
public double[] getYValue() {
return this.yValue;
}
public void setComposite(Composite composite) {
this.composite = composite;
}
public void setDrawPaint(Paint drawPaint) {
this.drawPaint = drawPaint;
}
public void setDrawPath(boolean drawPath) {
this.drawPath = drawPath;
}
public void setDrawStroke(Stroke drawStroke) {
this.drawStroke = drawStroke;
}
public void setFillPaint(Paint fillPaint) {
this.fillPaint = fillPaint;
}
public void setFillPath(boolean fillPath) {
this.fillPath = fillPath;
}
public void setXValue(double[] xValue) {
this.xValue = xValue;
}
public void setYValue(double[] yValue) {
this.yValue = yValue;
}
public boolean isClip() {
return this.clip;
}
public void setClip(boolean clip) {
this.clip = clip;
}
public Object clone() throws CloneNotSupportedException {
ClipPath clone = (ClipPath)super.clone();
clone.xValue = (double[])this.xValue.clone();
clone.yValue = (double[])this.yValue.clone();
return clone;
}
}

View file

@ -0,0 +1,94 @@
package org.jfree.chart;
import java.awt.Shape;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
public class DrawableLegendItem {
private LegendItem item;
private double x;
private double y;
private double width;
private double height;
private Shape marker;
private Line2D line;
private Point2D labelPosition;
public DrawableLegendItem(LegendItem item) {
this.item = item;
}
public LegendItem getItem() {
return this.item;
}
public double getX() {
return this.x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return this.y;
}
public void setY(double y) {
this.y = y;
}
public double getWidth() {
return this.width;
}
public double getHeight() {
return this.height;
}
public double getMaxX() {
return getX() + getWidth();
}
public double getMaxY() {
return getY() + getHeight();
}
public Shape getMarker() {
return this.marker;
}
public void setMarker(Shape marker) {
this.marker = marker;
}
public void setLine(Line2D l) {
this.line = l;
}
public Line2D getLine() {
return this.line;
}
public Point2D getLabelPosition() {
return this.labelPosition;
}
public void setLabelPosition(Point2D position) {
this.labelPosition = position;
}
public void setBounds(double x, double y, double width, double height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}

View file

@ -0,0 +1,7 @@
package org.jfree.chart;
public interface Effect3D {
double getXOffset();
double getYOffset();
}

View file

@ -0,0 +1,72 @@
package org.jfree.chart;
import java.awt.GradientPaint;
import java.awt.Paint;
import java.awt.Stroke;
public class HashUtilities {
public static int hashCodeForPaint(Paint p) {
if (p == null)
return 0;
int result = 0;
if (p instanceof GradientPaint) {
GradientPaint gp = (GradientPaint)p;
result = 193;
result = 37 * result + gp.getColor1().hashCode();
result = 37 * result + gp.getPoint1().hashCode();
result = 37 * result + gp.getColor2().hashCode();
result = 37 * result + gp.getPoint2().hashCode();
} else {
result = p.hashCode();
}
return result;
}
public static int hashCodeForDoubleArray(double[] a) {
if (a == null)
return 0;
int result = 193;
for (int i = 0; i < a.length; i++) {
long temp = Double.doubleToLongBits(a[i]);
result = 29 * result + (int)(temp ^ temp >>> 32L);
}
return result;
}
public static int hashCode(int pre, boolean b) {
return 37 * pre + (b ? 0 : 1);
}
public static int hashCode(int pre, int i) {
return 37 * pre + i;
}
public static int hashCode(int pre, double d) {
long l = Double.doubleToLongBits(d);
return 37 * pre + (int)(l ^ l >>> 32L);
}
public static int hashCode(int pre, Paint p) {
return 37 * pre + hashCodeForPaint(p);
}
public static int hashCode(int pre, Stroke s) {
int h = (s != null) ? s.hashCode() : 0;
return 37 * pre + h;
}
public static int hashCode(int pre, String s) {
int h = (s != null) ? s.hashCode() : 0;
return 37 * pre + h;
}
public static int hashCode(int pre, Comparable c) {
int h = (c != null) ? c.hashCode() : 0;
return 37 * pre + h;
}
public static int hashCode(int pre, Object obj) {
int h = (obj != null) ? obj.hashCode() : 0;
return 37 * pre + h;
}
}

View file

@ -0,0 +1,719 @@
package org.jfree.chart;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.UIManager;
import javax.swing.event.EventListenerList;
import org.jfree.chart.block.BlockParams;
import org.jfree.chart.block.EntityBlockResult;
import org.jfree.chart.block.LengthConstraintType;
import org.jfree.chart.block.LineBorder;
import org.jfree.chart.block.RectangleConstraint;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.event.ChartChangeEvent;
import org.jfree.chart.event.ChartChangeListener;
import org.jfree.chart.event.ChartProgressEvent;
import org.jfree.chart.event.ChartProgressListener;
import org.jfree.chart.event.PlotChangeEvent;
import org.jfree.chart.event.PlotChangeListener;
import org.jfree.chart.event.TitleChangeEvent;
import org.jfree.chart.event.TitleChangeListener;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.chart.title.Title;
import org.jfree.data.Range;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.Align;
import org.jfree.ui.Drawable;
import org.jfree.ui.HorizontalAlignment;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.Size2D;
import org.jfree.ui.VerticalAlignment;
import org.jfree.ui.about.ProjectInfo;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
public class JFreeChart implements Drawable, TitleChangeListener, PlotChangeListener, Serializable, Cloneable {
private static final long serialVersionUID = -3470703747817429120L;
public static final ProjectInfo INFO = new JFreeChartInfo();
public static final Font DEFAULT_TITLE_FONT = new Font("SansSerif", 1, 18);
public static final Paint DEFAULT_BACKGROUND_PAINT = UIManager.getColor("Panel.background");
public static final Image DEFAULT_BACKGROUND_IMAGE = null;
public static final int DEFAULT_BACKGROUND_IMAGE_ALIGNMENT = 15;
public static final float DEFAULT_BACKGROUND_IMAGE_ALPHA = 0.5F;
private transient RenderingHints renderingHints;
private boolean borderVisible;
private transient Stroke borderStroke;
private transient Paint borderPaint;
private RectangleInsets padding;
private TextTitle title;
private List subtitles;
private Plot plot;
private transient Paint backgroundPaint;
private transient Image backgroundImage;
private int backgroundImageAlignment = 15;
private float backgroundImageAlpha = 0.5F;
private transient EventListenerList changeListeners;
private transient EventListenerList progressListeners;
private boolean notify;
public JFreeChart(Plot plot) {
this(null, null, plot, true);
}
public JFreeChart(String title, Plot plot) {
this(title, DEFAULT_TITLE_FONT, plot, true);
}
public JFreeChart(String title, Font titleFont, Plot plot, boolean createLegend) {
if (plot == null)
throw new NullPointerException("Null 'plot' argument.");
this.progressListeners = new EventListenerList();
this.changeListeners = new EventListenerList();
this.notify = true;
this.renderingHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
this.borderVisible = false;
this.borderStroke = new BasicStroke(1.0F);
this.borderPaint = Color.black;
this.padding = RectangleInsets.ZERO_INSETS;
this.plot = plot;
plot.addChangeListener(this);
this.subtitles = new ArrayList();
if (createLegend) {
LegendTitle legend = new LegendTitle(this.plot);
legend.setMargin(new RectangleInsets(1.0D, 1.0D, 1.0D, 1.0D));
legend.setFrame(new LineBorder());
legend.setBackgroundPaint(Color.white);
legend.setPosition(RectangleEdge.BOTTOM);
this.subtitles.add(legend);
legend.addChangeListener(this);
}
if (title != null) {
if (titleFont == null)
titleFont = DEFAULT_TITLE_FONT;
this.title = new TextTitle(title, titleFont);
this.title.addChangeListener(this);
}
this.backgroundPaint = DEFAULT_BACKGROUND_PAINT;
this.backgroundImage = DEFAULT_BACKGROUND_IMAGE;
this.backgroundImageAlignment = 15;
this.backgroundImageAlpha = 0.5F;
}
public RenderingHints getRenderingHints() {
return this.renderingHints;
}
public void setRenderingHints(RenderingHints renderingHints) {
if (renderingHints == null)
throw new NullPointerException("RenderingHints given are null");
this.renderingHints = renderingHints;
fireChartChanged();
}
public boolean isBorderVisible() {
return this.borderVisible;
}
public void setBorderVisible(boolean visible) {
this.borderVisible = visible;
fireChartChanged();
}
public Stroke getBorderStroke() {
return this.borderStroke;
}
public void setBorderStroke(Stroke stroke) {
this.borderStroke = stroke;
fireChartChanged();
}
public Paint getBorderPaint() {
return this.borderPaint;
}
public void setBorderPaint(Paint paint) {
this.borderPaint = paint;
fireChartChanged();
}
public RectangleInsets getPadding() {
return this.padding;
}
public void setPadding(RectangleInsets padding) {
if (padding == null)
throw new IllegalArgumentException("Null 'padding' argument.");
this.padding = padding;
notifyListeners(new ChartChangeEvent(this));
}
public TextTitle getTitle() {
return this.title;
}
public void setTitle(TextTitle title) {
this.title = title;
fireChartChanged();
}
public void setTitle(String text) {
if (text != null) {
if (this.title == null) {
setTitle(new TextTitle(text, DEFAULT_TITLE_FONT));
} else {
this.title.setText(text);
}
} else {
setTitle((TextTitle)null);
}
}
public void addLegend(LegendTitle legend) {
addSubtitle(legend);
}
public LegendTitle getLegend() {
return getLegend(0);
}
public LegendTitle getLegend(int index) {
int seen = 0;
Iterator iterator = this.subtitles.iterator();
while (iterator.hasNext()) {
Title subtitle = (Title)iterator.next();
if (subtitle instanceof LegendTitle) {
if (seen == index)
return (LegendTitle)subtitle;
seen++;
}
}
return null;
}
public void removeLegend() {
removeSubtitle(getLegend());
}
public List getSubtitles() {
return new ArrayList(this.subtitles);
}
public void setSubtitles(List subtitles) {
if (subtitles == null)
throw new NullPointerException("Null 'subtitles' argument.");
setNotify(false);
clearSubtitles();
Iterator iterator = subtitles.iterator();
while (iterator.hasNext()) {
Title t = (Title)iterator.next();
if (t != null)
addSubtitle(t);
}
setNotify(true);
}
public int getSubtitleCount() {
return this.subtitles.size();
}
public Title getSubtitle(int index) {
if (index < 0 || index >= getSubtitleCount())
throw new IllegalArgumentException("Index out of range.");
return (Title)this.subtitles.get(index);
}
public void addSubtitle(Title subtitle) {
if (subtitle == null)
throw new IllegalArgumentException("Null 'subtitle' argument.");
this.subtitles.add(subtitle);
subtitle.addChangeListener(this);
fireChartChanged();
}
public void addSubtitle(int index, Title subtitle) {
if (index < 0 || index > getSubtitleCount())
throw new IllegalArgumentException("The 'index' argument is out of range.");
if (subtitle == null)
throw new IllegalArgumentException("Null 'subtitle' argument.");
this.subtitles.add(index, subtitle);
subtitle.addChangeListener(this);
fireChartChanged();
}
public void clearSubtitles() {
Iterator iterator = this.subtitles.iterator();
while (iterator.hasNext()) {
Title t = (Title)iterator.next();
t.removeChangeListener(this);
}
this.subtitles.clear();
fireChartChanged();
}
public void removeSubtitle(Title title) {
this.subtitles.remove(title);
fireChartChanged();
}
public Plot getPlot() {
return this.plot;
}
public CategoryPlot getCategoryPlot() {
return (CategoryPlot)this.plot;
}
public XYPlot getXYPlot() {
return (XYPlot)this.plot;
}
public boolean getAntiAlias() {
Object val = this.renderingHints.get(RenderingHints.KEY_ANTIALIASING);
return RenderingHints.VALUE_ANTIALIAS_ON.equals(val);
}
public void setAntiAlias(boolean flag) {
Object val = this.renderingHints.get(RenderingHints.KEY_ANTIALIASING);
if (val == null)
val = RenderingHints.VALUE_ANTIALIAS_DEFAULT;
if ((!flag && RenderingHints.VALUE_ANTIALIAS_OFF.equals(val)) || (flag && RenderingHints.VALUE_ANTIALIAS_ON.equals(val)))
return;
if (flag) {
this.renderingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
} else {
this.renderingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
}
fireChartChanged();
}
public Object getTextAntiAlias() {
return this.renderingHints.get(RenderingHints.KEY_TEXT_ANTIALIASING);
}
public void setTextAntiAlias(boolean flag) {
if (flag) {
setTextAntiAlias(RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
} else {
setTextAntiAlias(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
}
public void setTextAntiAlias(Object val) {
this.renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, val);
notifyListeners(new ChartChangeEvent(this));
}
public Paint getBackgroundPaint() {
return this.backgroundPaint;
}
public void setBackgroundPaint(Paint paint) {
if (this.backgroundPaint != null) {
if (!this.backgroundPaint.equals(paint)) {
this.backgroundPaint = paint;
fireChartChanged();
}
} else if (paint != null) {
this.backgroundPaint = paint;
fireChartChanged();
}
}
public Image getBackgroundImage() {
return this.backgroundImage;
}
public void setBackgroundImage(Image image) {
if (this.backgroundImage != null) {
if (!this.backgroundImage.equals(image)) {
this.backgroundImage = image;
fireChartChanged();
}
} else if (image != null) {
this.backgroundImage = image;
fireChartChanged();
}
}
public int getBackgroundImageAlignment() {
return this.backgroundImageAlignment;
}
public void setBackgroundImageAlignment(int alignment) {
if (this.backgroundImageAlignment != alignment) {
this.backgroundImageAlignment = alignment;
fireChartChanged();
}
}
public float getBackgroundImageAlpha() {
return this.backgroundImageAlpha;
}
public void setBackgroundImageAlpha(float alpha) {
if (this.backgroundImageAlpha != alpha) {
this.backgroundImageAlpha = alpha;
fireChartChanged();
}
}
public boolean isNotify() {
return this.notify;
}
public void setNotify(boolean notify) {
this.notify = notify;
if (notify)
notifyListeners(new ChartChangeEvent(this));
}
public void draw(Graphics2D g2, Rectangle2D area) {
draw(g2, area, null, null);
}
public void draw(Graphics2D g2, Rectangle2D area, ChartRenderingInfo info) {
draw(g2, area, null, info);
}
public void draw(Graphics2D g2, Rectangle2D chartArea, Point2D anchor, ChartRenderingInfo info) {
notifyListeners(new ChartProgressEvent(this, this, 1, 0));
if (info != null) {
info.clear();
info.setChartArea(chartArea);
}
Shape savedClip = g2.getClip();
g2.clip(chartArea);
g2.addRenderingHints(this.renderingHints);
if (this.backgroundPaint != null) {
g2.setPaint(this.backgroundPaint);
g2.fill(chartArea);
}
if (this.backgroundImage != null) {
Composite originalComposite = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(3, this.backgroundImageAlpha));
Rectangle2D dest = new Rectangle2D.Double(0.0D, 0.0D, (double)this.backgroundImage.getWidth(null), (double)this.backgroundImage.getHeight(null));
Align.align(dest, chartArea, this.backgroundImageAlignment);
g2.drawImage(this.backgroundImage, (int)dest.getX(), (int)dest.getY(), (int)dest.getWidth(), (int)dest.getHeight(), null);
g2.setComposite(originalComposite);
}
if (isBorderVisible()) {
Paint paint = getBorderPaint();
Stroke stroke = getBorderStroke();
if (paint != null && stroke != null) {
Rectangle2D borderArea = new Rectangle2D.Double(chartArea.getX(), chartArea.getY(), chartArea.getWidth() - 1.0D, chartArea.getHeight() - 1.0D);
g2.setPaint(paint);
g2.setStroke(stroke);
g2.draw(borderArea);
}
}
Rectangle2D nonTitleArea = new Rectangle2D.Double();
nonTitleArea.setRect(chartArea);
this.padding.trim(nonTitleArea);
EntityCollection entities = null;
if (info != null)
entities = info.getEntityCollection();
if (this.title != null) {
EntityCollection e = drawTitle(this.title, g2, nonTitleArea, (entities != null));
if (e != null)
entities.addAll(e);
}
Iterator iterator = this.subtitles.iterator();
while (iterator.hasNext()) {
Title currentTitle = (Title)iterator.next();
EntityCollection e = drawTitle(currentTitle, g2, nonTitleArea, (entities != null));
if (e != null)
entities.addAll(e);
}
Rectangle2D plotArea = nonTitleArea;
PlotRenderingInfo plotInfo = null;
if (info != null)
plotInfo = info.getPlotInfo();
this.plot.draw(g2, plotArea, anchor, null, plotInfo);
g2.setClip(savedClip);
notifyListeners(new ChartProgressEvent(this, this, 2, 100));
}
private Rectangle2D createAlignedRectangle2D(Size2D dimensions, Rectangle2D frame, HorizontalAlignment hAlign, VerticalAlignment vAlign) {
double x = Double.NaN;
double y = Double.NaN;
if (hAlign == HorizontalAlignment.LEFT) {
x = frame.getX();
} else if (hAlign == HorizontalAlignment.CENTER) {
x = frame.getCenterX() - dimensions.width / 2.0D;
} else if (hAlign == HorizontalAlignment.RIGHT) {
x = frame.getMaxX() - dimensions.width;
}
if (vAlign == VerticalAlignment.TOP) {
y = frame.getY();
} else if (vAlign == VerticalAlignment.CENTER) {
y = frame.getCenterY() - dimensions.height / 2.0D;
} else if (vAlign == VerticalAlignment.BOTTOM) {
y = frame.getMaxY() - dimensions.height;
}
return new Rectangle2D.Double(x, y, dimensions.width, dimensions.height);
}
protected EntityCollection drawTitle(Title t, Graphics2D g2, Rectangle2D area, boolean entities) {
if (t == null)
throw new IllegalArgumentException("Null 't' argument.");
if (area == null)
throw new IllegalArgumentException("Null 'area' argument.");
Rectangle2D titleArea = new Rectangle2D.Double();
RectangleEdge position = t.getPosition();
double ww = area.getWidth();
if (ww <= 0.0D)
return null;
double hh = area.getHeight();
if (hh <= 0.0D)
return null;
RectangleConstraint constraint = new RectangleConstraint(ww, new Range(0.0D, ww), LengthConstraintType.RANGE, hh, new Range(0.0D, hh), LengthConstraintType.RANGE);
Object retValue = null;
BlockParams p = new BlockParams();
p.setGenerateEntities(entities);
if (position == RectangleEdge.TOP) {
Size2D size = t.arrange(g2, constraint);
titleArea = createAlignedRectangle2D(size, area, t.getHorizontalAlignment(), VerticalAlignment.TOP);
retValue = t.draw(g2, titleArea, p);
area.setRect(area.getX(), Math.min(area.getY() + size.height, area.getMaxY()), area.getWidth(), Math.max(area.getHeight() - size.height, 0.0D));
} else if (position == RectangleEdge.BOTTOM) {
Size2D size = t.arrange(g2, constraint);
titleArea = createAlignedRectangle2D(size, area, t.getHorizontalAlignment(), VerticalAlignment.BOTTOM);
retValue = t.draw(g2, titleArea, p);
area.setRect(area.getX(), area.getY(), area.getWidth(), area.getHeight() - size.height);
} else if (position == RectangleEdge.RIGHT) {
Size2D size = t.arrange(g2, constraint);
titleArea = createAlignedRectangle2D(size, area, HorizontalAlignment.RIGHT, t.getVerticalAlignment());
retValue = t.draw(g2, titleArea, p);
area.setRect(area.getX(), area.getY(), area.getWidth() - size.width, area.getHeight());
} else if (position == RectangleEdge.LEFT) {
Size2D size = t.arrange(g2, constraint);
titleArea = createAlignedRectangle2D(size, area, HorizontalAlignment.LEFT, t.getVerticalAlignment());
retValue = t.draw(g2, titleArea, p);
area.setRect(area.getX() + size.width, area.getY(), area.getWidth() - size.width, area.getHeight());
} else {
throw new RuntimeException("Unrecognised title position.");
}
EntityCollection result = null;
if (retValue instanceof EntityBlockResult) {
EntityBlockResult ebr = (EntityBlockResult)retValue;
result = ebr.getEntityCollection();
}
return result;
}
public BufferedImage createBufferedImage(int width, int height) {
return createBufferedImage(width, height, null);
}
public BufferedImage createBufferedImage(int width, int height, ChartRenderingInfo info) {
return createBufferedImage(width, height, 1, info);
}
public BufferedImage createBufferedImage(int width, int height, int imageType, ChartRenderingInfo info) {
BufferedImage image = new BufferedImage(width, height, imageType);
Graphics2D g2 = image.createGraphics();
draw(g2, new Rectangle2D.Double(0.0D, 0.0D, (double)width, (double)height), null, info);
g2.dispose();
return image;
}
public BufferedImage createBufferedImage(int imageWidth, int imageHeight, double drawWidth, double drawHeight, ChartRenderingInfo info) {
BufferedImage image = new BufferedImage(imageWidth, imageHeight, 1);
Graphics2D g2 = image.createGraphics();
double scaleX = (double)imageWidth / drawWidth;
double scaleY = (double)imageHeight / drawHeight;
AffineTransform st = AffineTransform.getScaleInstance(scaleX, scaleY);
g2.transform(st);
draw(g2, new Rectangle2D.Double(0.0D, 0.0D, drawWidth, drawHeight), null, info);
g2.dispose();
return image;
}
public void handleClick(int x, int y, ChartRenderingInfo info) {
this.plot.handleClick(x, y, info.getPlotInfo());
}
public void addChangeListener(ChartChangeListener listener) {
if (listener == null)
throw new IllegalArgumentException("Null 'listener' argument.");
this.changeListeners.add(ChartChangeListener.class, listener);
}
public void removeChangeListener(ChartChangeListener listener) {
if (listener == null)
throw new IllegalArgumentException("Null 'listener' argument.");
this.changeListeners.remove(ChartChangeListener.class, listener);
}
public void fireChartChanged() {
ChartChangeEvent event = new ChartChangeEvent(this);
notifyListeners(event);
}
protected void notifyListeners(ChartChangeEvent event) {
if (this.notify) {
Object[] listeners = this.changeListeners.getListenerList();
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ChartChangeListener.class)
((ChartChangeListener)listeners[i + 1]).chartChanged(event);
}
}
}
public void addProgressListener(ChartProgressListener listener) {
this.progressListeners.add(ChartProgressListener.class, listener);
}
public void removeProgressListener(ChartProgressListener listener) {
this.progressListeners.remove(ChartProgressListener.class, listener);
}
protected void notifyListeners(ChartProgressEvent event) {
Object[] listeners = this.progressListeners.getListenerList();
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ChartProgressListener.class)
((ChartProgressListener)listeners[i + 1]).chartProgress(event);
}
}
public void titleChanged(TitleChangeEvent event) {
event.setChart(this);
notifyListeners(event);
}
public void plotChanged(PlotChangeEvent event) {
event.setChart(this);
notifyListeners(event);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof JFreeChart))
return false;
JFreeChart that = (JFreeChart)obj;
if (!this.renderingHints.equals(that.renderingHints))
return false;
if (this.borderVisible != that.borderVisible)
return false;
if (!ObjectUtilities.equal(this.borderStroke, that.borderStroke))
return false;
if (!PaintUtilities.equal(this.borderPaint, that.borderPaint))
return false;
if (!this.padding.equals(that.padding))
return false;
if (!ObjectUtilities.equal(this.title, that.title))
return false;
if (!ObjectUtilities.equal(this.subtitles, that.subtitles))
return false;
if (!ObjectUtilities.equal(this.plot, that.plot))
return false;
if (!PaintUtilities.equal(this.backgroundPaint, that.backgroundPaint))
return false;
if (!ObjectUtilities.equal(this.backgroundImage, that.backgroundImage))
return false;
if (this.backgroundImageAlignment != that.backgroundImageAlignment)
return false;
if (this.backgroundImageAlpha != that.backgroundImageAlpha)
return false;
if (this.notify != that.notify)
return false;
return true;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeStroke(this.borderStroke, stream);
SerialUtilities.writePaint(this.borderPaint, stream);
SerialUtilities.writePaint(this.backgroundPaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.borderStroke = SerialUtilities.readStroke(stream);
this.borderPaint = SerialUtilities.readPaint(stream);
this.backgroundPaint = SerialUtilities.readPaint(stream);
this.progressListeners = new EventListenerList();
this.changeListeners = new EventListenerList();
this.renderingHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (this.title != null)
this.title.addChangeListener(this);
for (int i = 0; i < getSubtitleCount(); i++)
getSubtitle(i).addChangeListener(this);
this.plot.addChangeListener(this);
}
public static void main(String[] args) {
System.out.println(INFO.toString());
}
public Object clone() throws CloneNotSupportedException {
JFreeChart chart = (JFreeChart)super.clone();
chart.renderingHints = (RenderingHints)this.renderingHints.clone();
if (this.title != null) {
chart.title = (TextTitle)this.title.clone();
chart.title.addChangeListener(chart);
}
chart.subtitles = new ArrayList();
for (int i = 0; i < getSubtitleCount(); i++) {
Title subtitle = (Title)getSubtitle(i).clone();
chart.subtitles.add(subtitle);
subtitle.addChangeListener(chart);
}
if (this.plot != null) {
chart.plot = (Plot)this.plot.clone();
chart.plot.addChangeListener(chart);
}
chart.progressListeners = new EventListenerList();
chart.changeListeners = new EventListenerList();
return chart;
}
}

View file

@ -0,0 +1,50 @@
package org.jfree.chart;
import java.awt.Image;
import java.net.URL;
import java.util.Arrays;
import java.util.ResourceBundle;
import javax.swing.ImageIcon;
import org.jfree.JCommon;
import org.jfree.base.Library;
import org.jfree.ui.about.Contributor;
import org.jfree.ui.about.Licences;
import org.jfree.ui.about.ProjectInfo;
class JFreeChartInfo extends ProjectInfo {
public JFreeChartInfo() {
String baseResourceClass = "org.jfree.chart.resources.JFreeChartResources";
ResourceBundle resources = ResourceBundle.getBundle(baseResourceClass);
setName(resources.getString("project.name"));
setVersion(resources.getString("project.version"));
setInfo(resources.getString("project.info"));
setCopyright(resources.getString("project.copyright"));
setLogo(null);
setLicenceName("LGPL");
setLicenceText(Licences.getInstance().getLGPL());
setContributors(Arrays.asList(new Contributor[] {
new Contributor("Eric Alexander", "-"), new Contributor("Richard Atkinson", "richard_c_atkinson@ntlworld.com"), new Contributor("David Basten", "-"), new Contributor("David Berry", "-"), new Contributor("Chris Boek", "-"), new Contributor("Zoheb Borbora", "-"), new Contributor("Anthony Boulestreau", "-"), new Contributor("Jeremy Bowman", "-"), new Contributor("Nicolas Brodu", "-"), new Contributor("Jody Brownell", "-"),
new Contributor("David Browning", "-"), new Contributor("Soren Caspersen", "-"), new Contributor("Chuanhao Chiu", "-"), new Contributor("Brian Cole", "-"), new Contributor("Pascal Collet", "-"), new Contributor("Martin Cordova", "-"), new Contributor("Paolo Cova", "-"), new Contributor("Mike Duffy", "-"), new Contributor("Don Elliott", "-"), new Contributor("David Forslund", "-"),
new Contributor("Jonathan Gabbai", "-"), new Contributor("David Gilbert", "david.gilbert@object-refinery.com"), new Contributor("Serge V. Grachov", "-"), new Contributor("Daniel Gredler", "-"), new Contributor("Hans-Jurgen Greiner", "-"), new Contributor("Joao Guilherme Del Valle", "-"), new Contributor("Aiman Han", "-"), new Contributor("Cameron Hayne", "-"), new Contributor("Jon Iles", "-"), new Contributor("Wolfgang Irler", "-"),
new Contributor("Sergei Ivanov", "-"), new Contributor("Adriaan Joubert", "-"), new Contributor("Darren Jung", "-"), new Contributor("Xun Kang", "-"), new Contributor("Bill Kelemen", "-"), new Contributor("Norbert Kiesel", "-"), new Contributor("Gideon Krause", "-"), new Contributor("Pierre-Marie Le Biot", "-"), new Contributor("Arnaud Lelievre", "-"), new Contributor("Wolfgang Lenhard", "-"),
new Contributor("David Li", "-"), new Contributor("Yan Liu", "-"), new Contributor("Tin Luu", "-"), new Contributor("Craig MacFarlane", "-"), new Contributor("Achilleus Mantzios", "-"), new Contributor("Thomas Meier", "-"), new Contributor("Jim Moore", "-"), new Contributor("Jonathan Nash", "-"), new Contributor("Barak Naveh", "-"), new Contributor("David M. O'Donnell", "-"),
new Contributor("Krzysztof Paz", "-"), new Contributor("Tomer Peretz", "-"), new Contributor("Xavier Poinsard", "-"), new Contributor("Andrzej Porebski", "-"), new Contributor("Viktor Rajewski", "-"), new Contributor("Eduardo Ramalho", "-"), new Contributor("Michael Rauch", "-"), new Contributor("Cameron Riley", "-"), new Contributor("Klaus Rheinwald", "-"), new Contributor("Dan Rivett", "d.rivett@ukonline.co.uk"),
new Contributor("Scott Sams", "-"), new Contributor("Michel Santos", "-"), new Contributor("Thierry Saura", "-"), new Contributor("Andreas Schneider", "-"), new Contributor("Jean-Luc SCHWAB", "-"), new Contributor("Bryan Scott", "-"), new Contributor("Tobias Selb", "-"), new Contributor("Mofeed Shahin", "-"), new Contributor("Pady Srinivasan", "-"), new Contributor("Greg Steckman", "-"),
new Contributor("Roger Studner", "-"), new Contributor("Irv Thomae", "-"), new Contributor("Eric Thomas", "-"), new Contributor("Rich Unger", "-"), new Contributor("Daniel van Enckevort", "-"), new Contributor("Laurence Vanhelsuwe", "-"), new Contributor("Sylvain Vieujot", "-"), new Contributor("Jelai Wang", "-"), new Contributor("Mark Watson", "www.markwatson.com"), new Contributor("Alex Weber", "-"),
new Contributor("Matthew Wright", "-"), new Contributor("Benoit Xhenseval", "-"), new Contributor("Christian W. Zuckschwerdt", "Christian.Zuckschwerdt@Informatik.Uni-Oldenburg.de"), new Contributor("Hari", "-"), new Contributor("Sam (oldman)", "-") }));
addLibrary((Library)JCommon.INFO);
}
public Image getLogo() {
Image logo = super.getLogo();
if (logo == null) {
URL imageURL = getClass().getClassLoader().getResource("org/jfree/chart/gorilla.jpg");
if (imageURL != null) {
ImageIcon temp = new ImageIcon(imageURL);
logo = temp.getImage();
setLogo(logo);
}
}
return logo;
}
}

View file

@ -0,0 +1,345 @@
package org.jfree.chart;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.AttributedString;
import java.text.CharacterIterator;
import org.jfree.data.general.Dataset;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.GradientPaintTransformer;
import org.jfree.ui.StandardGradientPaintTransformer;
import org.jfree.util.AttributedStringUtilities;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.ShapeUtilities;
public class LegendItem implements Serializable {
private static final long serialVersionUID = -797214582948827144L;
private Dataset dataset;
private Comparable seriesKey;
private int datasetIndex;
private int series;
private String label;
private transient AttributedString attributedLabel;
private String description;
private String toolTipText;
private String urlText;
private boolean shapeVisible;
private transient Shape shape;
private boolean shapeFilled;
private transient Paint fillPaint;
private GradientPaintTransformer fillPaintTransformer;
private boolean shapeOutlineVisible;
private transient Paint outlinePaint;
private transient Stroke outlineStroke;
private boolean lineVisible;
private transient Shape line;
private transient Stroke lineStroke;
private transient Paint linePaint;
private static final Shape UNUSED_SHAPE = new Line2D.Float();
private static final Stroke UNUSED_STROKE = new BasicStroke(0.0F);
public LegendItem(String label, String description, String toolTipText, String urlText, Shape shape, Paint fillPaint) {
this(label, description, toolTipText, urlText, true, shape, true, fillPaint, false, Color.black, UNUSED_STROKE, false, UNUSED_SHAPE, UNUSED_STROKE, Color.black);
}
public LegendItem(String label, String description, String toolTipText, String urlText, Shape shape, Paint fillPaint, Stroke outlineStroke, Paint outlinePaint) {
this(label, description, toolTipText, urlText, true, shape, true, fillPaint, true, outlinePaint, outlineStroke, false, UNUSED_SHAPE, UNUSED_STROKE, Color.black);
}
public LegendItem(String label, String description, String toolTipText, String urlText, Shape line, Stroke lineStroke, Paint linePaint) {
this(label, description, toolTipText, urlText, false, UNUSED_SHAPE, false, Color.black, false, Color.black, UNUSED_STROKE, true, line, lineStroke, linePaint);
}
public LegendItem(String label, String description, String toolTipText, String urlText, boolean shapeVisible, Shape shape, boolean shapeFilled, Paint fillPaint, boolean shapeOutlineVisible, Paint outlinePaint, Stroke outlineStroke, boolean lineVisible, Shape line, Stroke lineStroke, Paint linePaint) {
if (label == null)
throw new IllegalArgumentException("Null 'label' argument.");
if (fillPaint == null)
throw new IllegalArgumentException("Null 'fillPaint' argument.");
if (lineStroke == null)
throw new IllegalArgumentException("Null 'lineStroke' argument.");
if (outlinePaint == null)
throw new IllegalArgumentException("Null 'outlinePaint' argument.");
if (outlineStroke == null)
throw new IllegalArgumentException("Null 'outlineStroke' argument.");
this.label = label;
this.attributedLabel = null;
this.description = description;
this.shapeVisible = shapeVisible;
this.shape = shape;
this.shapeFilled = shapeFilled;
this.fillPaint = fillPaint;
this.fillPaintTransformer = new StandardGradientPaintTransformer();
this.shapeOutlineVisible = shapeOutlineVisible;
this.outlinePaint = outlinePaint;
this.outlineStroke = outlineStroke;
this.lineVisible = lineVisible;
this.line = line;
this.lineStroke = lineStroke;
this.linePaint = linePaint;
this.toolTipText = toolTipText;
this.urlText = urlText;
}
public LegendItem(AttributedString label, String description, String toolTipText, String urlText, Shape shape, Paint fillPaint) {
this(label, description, toolTipText, urlText, true, shape, true, fillPaint, false, Color.black, UNUSED_STROKE, false, UNUSED_SHAPE, UNUSED_STROKE, Color.black);
}
public LegendItem(AttributedString label, String description, String toolTipText, String urlText, Shape shape, Paint fillPaint, Stroke outlineStroke, Paint outlinePaint) {
this(label, description, toolTipText, urlText, true, shape, true, fillPaint, true, outlinePaint, outlineStroke, false, UNUSED_SHAPE, UNUSED_STROKE, Color.black);
}
public LegendItem(AttributedString label, String description, String toolTipText, String urlText, Shape line, Stroke lineStroke, Paint linePaint) {
this(label, description, toolTipText, urlText, false, UNUSED_SHAPE, false, Color.black, false, Color.black, UNUSED_STROKE, true, line, lineStroke, linePaint);
}
public LegendItem(AttributedString label, String description, String toolTipText, String urlText, boolean shapeVisible, Shape shape, boolean shapeFilled, Paint fillPaint, boolean shapeOutlineVisible, Paint outlinePaint, Stroke outlineStroke, boolean lineVisible, Shape line, Stroke lineStroke, Paint linePaint) {
if (label == null)
throw new IllegalArgumentException("Null 'label' argument.");
if (fillPaint == null)
throw new IllegalArgumentException("Null 'fillPaint' argument.");
if (lineStroke == null)
throw new IllegalArgumentException("Null 'lineStroke' argument.");
if (outlinePaint == null)
throw new IllegalArgumentException("Null 'outlinePaint' argument.");
if (outlineStroke == null)
throw new IllegalArgumentException("Null 'outlineStroke' argument.");
this.label = characterIteratorToString(label.getIterator());
this.attributedLabel = label;
this.description = description;
this.shapeVisible = shapeVisible;
this.shape = shape;
this.shapeFilled = shapeFilled;
this.fillPaint = fillPaint;
this.fillPaintTransformer = new StandardGradientPaintTransformer();
this.shapeOutlineVisible = shapeOutlineVisible;
this.outlinePaint = outlinePaint;
this.outlineStroke = outlineStroke;
this.lineVisible = lineVisible;
this.line = line;
this.lineStroke = lineStroke;
this.linePaint = linePaint;
this.toolTipText = toolTipText;
this.urlText = urlText;
}
private String characterIteratorToString(CharacterIterator iterator) {
int endIndex = iterator.getEndIndex();
int beginIndex = iterator.getBeginIndex();
int count = endIndex - beginIndex;
if (count <= 0)
return "";
char[] chars = new char[count];
int i = 0;
char c = iterator.first();
while (c != Character.MAX_VALUE) {
chars[i] = c;
i++;
c = iterator.next();
}
return new String(chars);
}
public Dataset getDataset() {
return this.dataset;
}
public void setDataset(Dataset dataset) {
this.dataset = dataset;
}
public int getDatasetIndex() {
return this.datasetIndex;
}
public void setDatasetIndex(int index) {
this.datasetIndex = index;
}
public Comparable getSeriesKey() {
return this.seriesKey;
}
public void setSeriesKey(Comparable key) {
this.seriesKey = key;
}
public int getSeriesIndex() {
return this.series;
}
public void setSeriesIndex(int index) {
this.series = index;
}
public String getLabel() {
return this.label;
}
public AttributedString getAttributedLabel() {
return this.attributedLabel;
}
public String getDescription() {
return this.description;
}
public String getToolTipText() {
return this.toolTipText;
}
public String getURLText() {
return this.urlText;
}
public boolean isShapeVisible() {
return this.shapeVisible;
}
public Shape getShape() {
return this.shape;
}
public boolean isShapeFilled() {
return this.shapeFilled;
}
public Paint getFillPaint() {
return this.fillPaint;
}
public boolean isShapeOutlineVisible() {
return this.shapeOutlineVisible;
}
public Stroke getLineStroke() {
return this.lineStroke;
}
public Paint getLinePaint() {
return this.linePaint;
}
public Paint getOutlinePaint() {
return this.outlinePaint;
}
public Stroke getOutlineStroke() {
return this.outlineStroke;
}
public boolean isLineVisible() {
return this.lineVisible;
}
public Shape getLine() {
return this.line;
}
public GradientPaintTransformer getFillPaintTransformer() {
return this.fillPaintTransformer;
}
public void setFillPaintTransformer(GradientPaintTransformer transformer) {
if (transformer == null)
throw new IllegalArgumentException("Null 'transformer' attribute.");
this.fillPaintTransformer = transformer;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof LegendItem))
return false;
LegendItem that = (LegendItem)obj;
if (this.datasetIndex != that.datasetIndex)
return false;
if (this.series != that.series)
return false;
if (!this.label.equals(that.label))
return false;
if (!AttributedStringUtilities.equal(this.attributedLabel, that.attributedLabel))
return false;
if (!ObjectUtilities.equal(this.description, that.description))
return false;
if (this.shapeVisible != that.shapeVisible)
return false;
if (!ShapeUtilities.equal(this.shape, that.shape))
return false;
if (this.shapeFilled != that.shapeFilled)
return false;
if (!this.fillPaint.equals(that.fillPaint))
return false;
if (!ObjectUtilities.equal(this.fillPaintTransformer, that.fillPaintTransformer))
return false;
if (this.shapeOutlineVisible != that.shapeOutlineVisible)
return false;
if (!this.outlineStroke.equals(that.outlineStroke))
return false;
if (!this.outlinePaint.equals(that.outlinePaint))
return false;
if ((!this.lineVisible) == that.lineVisible)
return false;
if (!ShapeUtilities.equal(this.line, that.line))
return false;
if (!this.lineStroke.equals(that.lineStroke))
return false;
if (!this.linePaint.equals(that.linePaint))
return false;
return true;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeAttributedString(this.attributedLabel, stream);
SerialUtilities.writeShape(this.shape, stream);
SerialUtilities.writePaint(this.fillPaint, stream);
SerialUtilities.writeStroke(this.outlineStroke, stream);
SerialUtilities.writePaint(this.outlinePaint, stream);
SerialUtilities.writeShape(this.line, stream);
SerialUtilities.writeStroke(this.lineStroke, stream);
SerialUtilities.writePaint(this.linePaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.attributedLabel = SerialUtilities.readAttributedString(stream);
this.shape = SerialUtilities.readShape(stream);
this.fillPaint = SerialUtilities.readPaint(stream);
this.outlineStroke = SerialUtilities.readStroke(stream);
this.outlinePaint = SerialUtilities.readPaint(stream);
this.line = SerialUtilities.readShape(stream);
this.lineStroke = SerialUtilities.readStroke(stream);
this.linePaint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,47 @@
package org.jfree.chart;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class LegendItemCollection implements Cloneable, Serializable {
private static final long serialVersionUID = 1365215565589815953L;
private List items = new ArrayList();
public void add(LegendItem item) {
this.items.add(item);
}
public void addAll(LegendItemCollection collection) {
this.items.addAll(collection.items);
}
public LegendItem get(int index) {
return (LegendItem)this.items.get(index);
}
public int getItemCount() {
return this.items.size();
}
public Iterator iterator() {
return this.items.iterator();
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof LegendItemCollection))
return false;
LegendItemCollection that = (LegendItemCollection)obj;
if (!this.items.equals(that.items))
return false;
return true;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

View file

@ -0,0 +1,5 @@
package org.jfree.chart;
public interface LegendItemSource {
LegendItemCollection getLegendItems();
}

View file

@ -0,0 +1,41 @@
package org.jfree.chart;
import java.io.ObjectStreamException;
import java.io.Serializable;
public final class LegendRenderingOrder implements Serializable {
private static final long serialVersionUID = -3832486612685808616L;
public static final LegendRenderingOrder STANDARD = new LegendRenderingOrder("LegendRenderingOrder.STANDARD");
public static final LegendRenderingOrder REVERSE = new LegendRenderingOrder("LegendRenderingOrder.REVERSE");
private String name;
private LegendRenderingOrder(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof LegendRenderingOrder))
return false;
LegendRenderingOrder order = (LegendRenderingOrder)obj;
if (!this.name.equals(order.toString()))
return false;
return true;
}
private Object readResolve() throws ObjectStreamException {
if (equals(STANDARD))
return STANDARD;
if (equals(REVERSE))
return REVERSE;
return null;
}
}

View file

@ -0,0 +1,19 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file
#
# Changes (from 31-Aug-2003)
# --------------------------
# 31-Aug-2003 : Initial version (AL);
#
Auto_Range=Auto Range
All_Axes=Both Axes
Chart_Properties=Chart Properties
Copy=Copy
Domain_Axis=Domain Axis
PNG_Image_Files=PNG Image Files
Print...=Print...
Properties...=Properties...
Save_as...=Save as...
Range_Axis=Range Axis
Zoom_In=Zoom In
Zoom_Out=Zoom Out

View file

@ -0,0 +1,20 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file - german version
#
# Changes (from 31-Aug-2003)
# --------------------------
# 31-Aug-2003 : Initial version (AL);
# 15-Mar-2004 : Revised version (Christian W. Zuckschwerdt);
#
Auto_Range=Autojustage
All_Axes=Beide Achsen
Chart_Properties=Diagramm-Eigenschaften
Copy=Kopieren
Domain_Axis=Horizontale Achse
PNG_Image_Files=PNG Datei (Portable Network Graphics) (*.png)
Print...=Drucken...
Properties...=Eigenschaften...
Save_as...=Speichern unter...
Range_Axis=Vertikale Achse
Zoom_In=Hineinzoomen
Zoom_Out=Herauszoomen

View file

@ -0,0 +1,19 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file - spanish version
#
# Changes (from 16-Dec-2003)
# --------------------------
# 16-Dec-2003 : Initial Version: Complejo Hospitalario Universitario Juan Canalejo
#
Auto_Range=Escala autom\u00E1tica
All_Axes=Todos los ejes
Chart_Properties=Propiedades del gr\u00E1fico
Copy=Copiar
Domain_Axis=Eje horizontal
PNG_Image_Files=Formato PNG (Portable Network Graphics) (*.png)
Print...=Imprimir...
Properties...=Propiedades...
Save_as...=Grabar como...
Range_Axis=Eje vertical
Zoom_In=Acercar
Zoom_Out=Alejar

View file

@ -0,0 +1,19 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file - french version
#
# Changes (from 31-Aug-2003)
# --------------------------
# 31-Aug-2003 : Initial version (AL);
#
Auto_Range=Echelle automatique
All_Axes=Les deux axes
Chart_Properties=Propri\u00E9t\u00E9s du graphique
Copy=Copier
Domain_Axis=Axe horizontal
PNG_Image_Files=Format PNG (Portable Network Graphics) (*.png)
Print...=Imprimer...
Properties...=Propri\u00E9t\u00E9s...
Save_as...=Enregistrer sous...
Range_Axis=Axe vertical
Zoom_In=Zoom avant
Zoom_Out=Zoom arri\u00E8re

View file

@ -0,0 +1,13 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file - italian version
Auto_Range=Dimensiona Automaticamente
All_Axes=Entrambi gli Assi
Chart_Properties=Propriet<EFBFBD> del Grafico
Copy=Copia
Domain_Axis=Asse Orizontale
PNG_Image_Files=Immagine PNG
Print...=Stampa...
Properties...=Propriet<EFBFBD>...
Save_as...=Salva Come...
Range_Axis=Asse Verticale
Zoom_In=Ingrandisci
Zoom_Out=Rimpicciolisci

View file

@ -0,0 +1,20 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file
#
# Changes (from 31-Aug-2003)
# --------------------------
# 24-Mar-2003 : Translated into Dutch
# 31-Aug-2003 : Initial version (AL);
#
Auto_Range=Automatisch bereik
All_Axes=Beide assen
Chart_Properties=Eigenschappen
Copy=Kopie\u00EBren
Domain_Axis=Horizontale As
PNG_Image_Files=PNG afbeelding
Print...=Afdrukken...
Properties...=Eigenschappen...
Save_as...=Opslaan als...
Range_Axis=Verticale As
Zoom_In=Inzoomen
Zoom_Out=Uitzoomen

View file

@ -0,0 +1,19 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file
#
# Changes (from 15-Mar-2004)
# --------------------------
# 15-Mar-2004 : Initial version (Kuba Duda);
#
Auto_Range=Automatyczny zakres
All_Axes=Obie osie
Chart_Properties=W\u0142a\u015bciwo\u015bci wykresu
Copy=Kopiuj
Domain_Axis=O\u015b pozioma
PNG_Image_Files=Pliki graficzne PNG
Print...=Drukuj...
Properties...=W\u0142a\u015bciwo\u015bci...
Save_as...=Zapisz jako...
Range_Axis=O\u015b pionowa
Zoom_In=Powi\u0119ksz
Zoom_Out=Pomniejsz

View file

@ -0,0 +1,19 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file - portuguese version
#
# Changes (from 24-May-2007)
# --------------------------
# 24-May-2007 : Initial version (Leonardo Alves Machado);
#
Auto_Range=Escala autom\u00E1tica
All_Axes=Todos os eixos
Chart_Properties=Propriedades do gr\u00E1fico
Copy=Copiar
Domain_Axis=Eixo horizontal
PNG_Image_Files=Formato PNG (Portable Network Graphics) (*.png)
Print...=Imprimir...
Properties...=Propriedades...
Save_as...=Salvar como...
Range_Axis=Eixo vertical
Zoom_In=Ampliar
Zoom_Out=Reduzir

View file

@ -0,0 +1,19 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file - portuguese version
#
# Changes (from 09-Set-2003)
# --------------------------
# 09-Set-2003 : Initial version (ER);
#
Auto_Range=Escala autom\u00E1tica
All_Axes=Todos os eixos
Chart_Properties=Propriedades do gr\u00E1fico
Copy=Copiar
Domain_Axis=Eixo horizontal
PNG_Image_Files=Formato PNG (Portable Network Graphics) (*.png)
Print...=Imprimir...
Properties...=Propriedades...
Save_as...=Gravar como...
Range_Axis=Eixo vertical
Zoom_In=Aproximar
Zoom_Out=Afastar

View file

@ -0,0 +1,19 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file
#
# Changes (from 10-Nov-2003)
# --------------------------
# 10-Nov-2003 : Initial version (AL);
#
Auto_Range=\u0410\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435
All_Axes=\u041f\u043e \u0432\u0441\u0435\u043c \u043e\u0441\u044f\u043c
Chart_Properties=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0433\u0440\u0430\u0444\u0438\u043a\u0430
Copy=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c
Domain_Axis=\u041f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0441\u0438
PNG_Image_Files=PNG \u0444\u0430\u0439\u043b
Print...=\u041f\u0435\u0447\u0430\u0442\u044c...
Properties...=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438...
Save_as...=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u043a...
Range_Axis=\u041f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0441\u0438
Zoom_In=\u041f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u044c
Zoom_Out=\u041e\u0442\u0434\u0430\u043b\u0438\u0442\u044c

View file

@ -0,0 +1,19 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file
#
# Changes
# -------
# 29-Jun-2005 : Initial version, see: http://www.jfree.org/phpBB2/viewtopic.php?t=13495;
#
Auto_Range=\u81ea\u52a8\u8c03\u6574
All_Axes=\u6240\u6709\u8f74
Chart_Properties=\u56fe\u8868\u5c5e\u6027
Copy=\u590d\u5236
Domain_Axis=\u6c34\u5e73\u8f74
PNG_Image_Files=PNG \u683c\u5f0f\u7684\u56fe\u50cf
Print...=\u6253\u5370
Properties...=\u5c5e\u6027
Save_as...=\u53e6\u5b58\u4e3a
Range_Axis=\u5782\u76f4\u8f74
Zoom_In=\u653e\u5927
Zoom_Out=\u7f29\u5c0f

View file

@ -0,0 +1,19 @@
# org.jfree.chart.ChartPanel ResourceBundle properties file
#
# Changes (from 31-Aug-2003)
# --------------------------
# 31-Aug-2003 : Initial version (AL);
#
Auto_Range=\u81ea\u52d5\u8abf\u6574
All_Axes=\u6240\u6709\u8ef8
Chart_Properties=\u5716\u8868\u5167\u5bb9
Copy=\u8907\u88fd
Domain_Axis=\u6a6b\u8ef8
PNG_Image_Files=PNG\u5716\u6a94
Print...=\u5217\u5370
Properties...=\u5167\u5bb9
Save_as...=\u53e6\u5b58\u65b0\u6a94
Range_Axis=\u7e31\u8ef8
Zoom_In=\u653e\u5927
Zoom_Out=\u7e2e\u5c0f

View file

@ -0,0 +1,87 @@
package org.jfree.chart;
import java.awt.Paint;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.jfree.io.SerialUtilities;
import org.jfree.util.PaintUtilities;
public class PaintMap implements Cloneable, Serializable {
static final long serialVersionUID = -4639833772123069274L;
private transient Map store = new HashMap();
public Paint getPaint(Comparable key) {
if (key == null)
throw new IllegalArgumentException("Null 'key' argument.");
return (Paint)this.store.get(key);
}
public boolean containsKey(Comparable key) {
return this.store.containsKey(key);
}
public void put(Comparable key, Paint paint) {
if (key == null)
throw new IllegalArgumentException("Null 'key' argument.");
this.store.put(key, paint);
}
public void clear() {
this.store.clear();
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof PaintMap))
return false;
PaintMap that = (PaintMap)obj;
if (this.store.size() != that.store.size())
return false;
Set keys = this.store.keySet();
Iterator iterator = keys.iterator();
while (iterator.hasNext()) {
Comparable key = (Comparable)iterator.next();
Paint p1 = getPaint(key);
Paint p2 = that.getPaint(key);
if (!PaintUtilities.equal(p1, p2))
return false;
}
return true;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
stream.writeInt(this.store.size());
Set keys = this.store.keySet();
Iterator iterator = keys.iterator();
while (iterator.hasNext()) {
Comparable key = (Comparable)iterator.next();
stream.writeObject(key);
Paint paint = getPaint(key);
SerialUtilities.writePaint(paint, stream);
}
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.store = new HashMap();
int keyCount = stream.readInt();
for (int i = 0; i < keyCount; i++) {
Comparable key = (Comparable)stream.readObject();
Paint paint = SerialUtilities.readPaint(stream);
this.store.put(key, paint);
}
}
}

View file

@ -0,0 +1,106 @@
package org.jfree.chart;
import java.awt.Component;
import java.awt.event.ActionEvent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PolarPlot;
public class PolarChartPanel extends ChartPanel {
private static final String POLAR_ZOOM_IN_ACTION_COMMAND = "Polar Zoom In";
private static final String POLAR_ZOOM_OUT_ACTION_COMMAND = "Polar Zoom Out";
private static final String POLAR_AUTO_RANGE_ACTION_COMMAND = "Polar Auto Range";
public PolarChartPanel(JFreeChart chart) {
this(chart, true);
}
public PolarChartPanel(JFreeChart chart, boolean useBuffer) {
super(chart, useBuffer);
checkChart(chart);
setMinimumDrawWidth(200);
setMinimumDrawHeight(200);
setMaximumDrawWidth(2000);
setMaximumDrawHeight(2000);
}
public void setChart(JFreeChart chart) {
checkChart(chart);
super.setChart(chart);
}
protected JPopupMenu createPopupMenu(boolean properties, boolean save, boolean print, boolean zoom) {
JPopupMenu result = super.createPopupMenu(properties, save, print, zoom);
int zoomInIndex = getPopupMenuItem(result, "Zoom In");
int zoomOutIndex = getPopupMenuItem(result, "Zoom Out");
int autoIndex = getPopupMenuItem(result, "Auto Range");
if (zoom) {
JMenuItem zoomIn = new JMenuItem("Zoom In");
zoomIn.setActionCommand("Polar Zoom In");
zoomIn.addActionListener(this);
JMenuItem zoomOut = new JMenuItem("Zoom Out");
zoomOut.setActionCommand("Polar Zoom Out");
zoomOut.addActionListener(this);
JMenuItem auto = new JMenuItem("Auto Range");
auto.setActionCommand("Polar Auto Range");
auto.addActionListener(this);
if (zoomInIndex != -1) {
result.remove(zoomInIndex);
} else {
zoomInIndex = result.getComponentCount() - 1;
}
result.add((Component)zoomIn, zoomInIndex);
if (zoomOutIndex != -1) {
result.remove(zoomOutIndex);
} else {
zoomOutIndex = zoomInIndex + 1;
}
result.add((Component)zoomOut, zoomOutIndex);
if (autoIndex != -1) {
result.remove(autoIndex);
} else {
autoIndex = zoomOutIndex + 1;
}
result.add((Component)auto, autoIndex);
}
return result;
}
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
if (command.equals("Polar Zoom In")) {
PolarPlot plot = (PolarPlot)getChart().getPlot();
plot.zoom(0.5D);
} else if (command.equals("Polar Zoom Out")) {
PolarPlot plot = (PolarPlot)getChart().getPlot();
plot.zoom(2.0D);
} else if (command.equals("Polar Auto Range")) {
PolarPlot plot = (PolarPlot)getChart().getPlot();
plot.getAxis().setAutoRange(true);
} else {
super.actionPerformed(event);
}
}
private void checkChart(JFreeChart chart) {
Plot plot = chart.getPlot();
if (!(plot instanceof PolarPlot))
throw new IllegalArgumentException("plot is not a PolarPlot");
}
private int getPopupMenuItem(JPopupMenu menu, String text) {
int index = -1;
for (int i = 0; index == -1 && i < menu.getComponentCount(); i++) {
Component comp = menu.getComponent(i);
if (comp instanceof JMenuItem) {
JMenuItem item = (JMenuItem)comp;
if (text.equals(item.getText()))
index = i;
}
}
return index;
}
}

View file

@ -0,0 +1,87 @@
package org.jfree.chart;
import java.awt.Stroke;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.jfree.io.SerialUtilities;
import org.jfree.util.ObjectUtilities;
public class StrokeMap implements Cloneable, Serializable {
static final long serialVersionUID = -8148916785963525169L;
private transient Map store = new TreeMap();
public Stroke getStroke(Comparable key) {
if (key == null)
throw new IllegalArgumentException("Null 'key' argument.");
return (Stroke)this.store.get(key);
}
public boolean containsKey(Comparable key) {
return this.store.containsKey(key);
}
public void put(Comparable key, Stroke stroke) {
if (key == null)
throw new IllegalArgumentException("Null 'key' argument.");
this.store.put(key, stroke);
}
public void clear() {
this.store.clear();
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof StrokeMap))
return false;
StrokeMap that = (StrokeMap)obj;
if (this.store.size() != that.store.size())
return false;
Set keys = this.store.keySet();
Iterator iterator = keys.iterator();
while (iterator.hasNext()) {
Comparable key = (Comparable)iterator.next();
Stroke s1 = getStroke(key);
Stroke s2 = that.getStroke(key);
if (!ObjectUtilities.equal(s1, s2))
return false;
}
return true;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
stream.writeInt(this.store.size());
Set keys = this.store.keySet();
Iterator iterator = keys.iterator();
while (iterator.hasNext()) {
Comparable key = (Comparable)iterator.next();
stream.writeObject(key);
Stroke stroke = getStroke(key);
SerialUtilities.writeStroke(stroke, stream);
}
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.store = new TreeMap();
int keyCount = stream.readInt();
for (int i = 0; i < keyCount; i++) {
Comparable key = (Comparable)stream.readObject();
Stroke stroke = SerialUtilities.readStroke(stream);
this.store.put(key, stroke);
}
}
}

View file

@ -0,0 +1,67 @@
package org.jfree.chart.annotations;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.entity.XYAnnotationEntity;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.util.ObjectUtilities;
public abstract class AbstractXYAnnotation implements XYAnnotation {
private String toolTipText = null;
private String url = null;
public String getToolTipText() {
return this.toolTipText;
}
public void setToolTipText(String text) {
this.toolTipText = text;
}
public String getURL() {
return this.url;
}
public void setURL(String url) {
this.url = url;
}
public abstract void draw(Graphics2D paramGraphics2D, XYPlot paramXYPlot, Rectangle2D paramRectangle2D, ValueAxis paramValueAxis1, ValueAxis paramValueAxis2, int paramInt, PlotRenderingInfo paramPlotRenderingInfo);
protected void addEntity(PlotRenderingInfo info, Shape hotspot, int rendererIndex, String toolTipText, String urlText) {
if (info == null)
return;
EntityCollection entities = info.getOwner().getEntityCollection();
if (entities == null)
return;
XYAnnotationEntity entity = new XYAnnotationEntity(hotspot, rendererIndex, toolTipText, urlText);
entities.add(entity);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof AbstractXYAnnotation))
return false;
AbstractXYAnnotation that = (AbstractXYAnnotation)obj;
if (!ObjectUtilities.equal(this.toolTipText, that.toolTipText))
return false;
if (!ObjectUtilities.equal(this.url, that.url))
return false;
return true;
}
public int hashCode() {
int result = 193;
if (this.toolTipText != null)
result = 37 * result + this.toolTipText.hashCode();
if (this.url != null)
result = 37 * result + this.url.hashCode();
return result;
}
}

View file

@ -0,0 +1,11 @@
package org.jfree.chart.annotations;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
public interface CategoryAnnotation {
void draw(Graphics2D paramGraphics2D, CategoryPlot paramCategoryPlot, Rectangle2D paramRectangle2D, CategoryAxis paramCategoryAxis, ValueAxis paramValueAxis);
}

View file

@ -0,0 +1,191 @@
package org.jfree.chart.annotations;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.HashUtilities;
import org.jfree.chart.axis.CategoryAnchor;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
public class CategoryLineAnnotation implements CategoryAnnotation, Cloneable, Serializable {
static final long serialVersionUID = 3477740483341587984L;
private Comparable category1;
private double value1;
private Comparable category2;
private double value2;
private transient Paint paint = Color.black;
private transient Stroke stroke = new BasicStroke(1.0F);
public CategoryLineAnnotation(Comparable category1, double value1, Comparable category2, double value2, Paint paint, Stroke stroke) {
if (category1 == null)
throw new IllegalArgumentException("Null 'category1' argument.");
if (category2 == null)
throw new IllegalArgumentException("Null 'category2' argument.");
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
if (stroke == null)
throw new IllegalArgumentException("Null 'stroke' argument.");
this.category1 = category1;
this.value1 = value1;
this.category2 = category2;
this.value2 = value2;
this.paint = paint;
this.stroke = stroke;
}
public Comparable getCategory1() {
return this.category1;
}
public void setCategory1(Comparable category) {
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
this.category1 = category;
}
public double getValue1() {
return this.value1;
}
public void setValue1(double value) {
this.value1 = value;
}
public Comparable getCategory2() {
return this.category2;
}
public void setCategory2(Comparable category) {
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
this.category2 = category;
}
public double getValue2() {
return this.value2;
}
public void setValue2(double value) {
this.value2 = value;
}
public Paint getPaint() {
return this.paint;
}
public void setPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.paint = paint;
}
public Stroke getStroke() {
return this.stroke;
}
public void setStroke(Stroke stroke) {
if (stroke == null)
throw new IllegalArgumentException("Null 'stroke' argument.");
this.stroke = stroke;
}
public void draw(Graphics2D g2, CategoryPlot plot, Rectangle2D dataArea, CategoryAxis domainAxis, ValueAxis rangeAxis) {
CategoryDataset dataset = plot.getDataset();
int catIndex1 = dataset.getColumnIndex(this.category1);
int catIndex2 = dataset.getColumnIndex(this.category2);
int catCount = dataset.getColumnCount();
double lineX1 = 0.0D;
double lineY1 = 0.0D;
double lineX2 = 0.0D;
double lineY2 = 0.0D;
PlotOrientation orientation = plot.getOrientation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(plot.getDomainAxisLocation(), orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(plot.getRangeAxisLocation(), orientation);
if (orientation == PlotOrientation.HORIZONTAL) {
lineY1 = domainAxis.getCategoryJava2DCoordinate(CategoryAnchor.MIDDLE, catIndex1, catCount, dataArea, domainEdge);
lineX1 = rangeAxis.valueToJava2D(this.value1, dataArea, rangeEdge);
lineY2 = domainAxis.getCategoryJava2DCoordinate(CategoryAnchor.MIDDLE, catIndex2, catCount, dataArea, domainEdge);
lineX2 = rangeAxis.valueToJava2D(this.value2, dataArea, rangeEdge);
} else if (orientation == PlotOrientation.VERTICAL) {
lineX1 = domainAxis.getCategoryJava2DCoordinate(CategoryAnchor.MIDDLE, catIndex1, catCount, dataArea, domainEdge);
lineY1 = rangeAxis.valueToJava2D(this.value1, dataArea, rangeEdge);
lineX2 = domainAxis.getCategoryJava2DCoordinate(CategoryAnchor.MIDDLE, catIndex2, catCount, dataArea, domainEdge);
lineY2 = rangeAxis.valueToJava2D(this.value2, dataArea, rangeEdge);
}
g2.setPaint(this.paint);
g2.setStroke(this.stroke);
g2.drawLine((int)lineX1, (int)lineY1, (int)lineX2, (int)lineY2);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof CategoryLineAnnotation))
return false;
CategoryLineAnnotation that = (CategoryLineAnnotation)obj;
if (!this.category1.equals(that.getCategory1()))
return false;
if (this.value1 != that.getValue1())
return false;
if (!this.category2.equals(that.getCategory2()))
return false;
if (this.value2 != that.getValue2())
return false;
if (!PaintUtilities.equal(this.paint, that.paint))
return false;
if (!ObjectUtilities.equal(this.stroke, that.stroke))
return false;
return true;
}
public int hashCode() {
int result = 193;
result = 37 * result + this.category1.hashCode();
long temp = Double.doubleToLongBits(this.value1);
result = 37 * result + (int)(temp ^ temp >>> 32L);
result = 37 * result + this.category2.hashCode();
temp = Double.doubleToLongBits(this.value2);
result = 37 * result + (int)(temp ^ temp >>> 32L);
result = 37 * result + HashUtilities.hashCodeForPaint(this.paint);
result = 37 * result + this.stroke.hashCode();
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.paint, stream);
SerialUtilities.writeStroke(this.stroke, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.paint = SerialUtilities.readPaint(stream);
this.stroke = SerialUtilities.readStroke(stream);
}
}

View file

@ -0,0 +1,239 @@
package org.jfree.chart.annotations;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.HashUtilities;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PublicCloneable;
public class CategoryPointerAnnotation extends CategoryTextAnnotation implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = -4031161445009858551L;
public static final double DEFAULT_TIP_RADIUS = 10.0D;
public static final double DEFAULT_BASE_RADIUS = 30.0D;
public static final double DEFAULT_LABEL_OFFSET = 3.0D;
public static final double DEFAULT_ARROW_LENGTH = 5.0D;
public static final double DEFAULT_ARROW_WIDTH = 3.0D;
private double angle;
private double tipRadius;
private double baseRadius;
private double arrowLength;
private double arrowWidth;
private transient Stroke arrowStroke;
private transient Paint arrowPaint;
private double labelOffset;
public CategoryPointerAnnotation(String label, Comparable key, double value, double angle) {
super(label, key, value);
this.angle = angle;
this.tipRadius = 10.0D;
this.baseRadius = 30.0D;
this.arrowLength = 5.0D;
this.arrowWidth = 3.0D;
this.labelOffset = 3.0D;
this.arrowStroke = new BasicStroke(1.0F);
this.arrowPaint = Color.black;
}
public double getAngle() {
return this.angle;
}
public void setAngle(double angle) {
this.angle = angle;
}
public double getTipRadius() {
return this.tipRadius;
}
public void setTipRadius(double radius) {
this.tipRadius = radius;
}
public double getBaseRadius() {
return this.baseRadius;
}
public void setBaseRadius(double radius) {
this.baseRadius = radius;
}
public double getLabelOffset() {
return this.labelOffset;
}
public void setLabelOffset(double offset) {
this.labelOffset = offset;
}
public double getArrowLength() {
return this.arrowLength;
}
public void setArrowLength(double length) {
this.arrowLength = length;
}
public double getArrowWidth() {
return this.arrowWidth;
}
public void setArrowWidth(double width) {
this.arrowWidth = width;
}
public Stroke getArrowStroke() {
return this.arrowStroke;
}
public void setArrowStroke(Stroke stroke) {
if (stroke == null)
throw new IllegalArgumentException("Null 'stroke' not permitted.");
this.arrowStroke = stroke;
}
public Paint getArrowPaint() {
return this.arrowPaint;
}
public void setArrowPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.arrowPaint = paint;
}
public void draw(Graphics2D g2, CategoryPlot plot, Rectangle2D dataArea, CategoryAxis domainAxis, ValueAxis rangeAxis) {
PlotOrientation orientation = plot.getOrientation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(plot.getDomainAxisLocation(), orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(plot.getRangeAxisLocation(), orientation);
CategoryDataset dataset = plot.getDataset();
int catIndex = dataset.getColumnIndex(getCategory());
int catCount = dataset.getColumnCount();
double j2DX = domainAxis.getCategoryMiddle(catIndex, catCount, dataArea, domainEdge);
double j2DY = rangeAxis.valueToJava2D(getValue(), dataArea, rangeEdge);
if (orientation == PlotOrientation.HORIZONTAL) {
double temp = j2DX;
j2DX = j2DY;
j2DY = temp;
}
double startX = j2DX + Math.cos(this.angle) * this.baseRadius;
double startY = j2DY + Math.sin(this.angle) * this.baseRadius;
double endX = j2DX + Math.cos(this.angle) * this.tipRadius;
double endY = j2DY + Math.sin(this.angle) * this.tipRadius;
double arrowBaseX = endX + Math.cos(this.angle) * this.arrowLength;
double arrowBaseY = endY + Math.sin(this.angle) * this.arrowLength;
double arrowLeftX = arrowBaseX + Math.cos(this.angle + 1.5707963267948966D) * this.arrowWidth;
double arrowLeftY = arrowBaseY + Math.sin(this.angle + 1.5707963267948966D) * this.arrowWidth;
double arrowRightX = arrowBaseX - Math.cos(this.angle + 1.5707963267948966D) * this.arrowWidth;
double arrowRightY = arrowBaseY - Math.sin(this.angle + 1.5707963267948966D) * this.arrowWidth;
GeneralPath arrow = new GeneralPath();
arrow.moveTo((float)endX, (float)endY);
arrow.lineTo((float)arrowLeftX, (float)arrowLeftY);
arrow.lineTo((float)arrowRightX, (float)arrowRightY);
arrow.closePath();
g2.setStroke(this.arrowStroke);
g2.setPaint(this.arrowPaint);
Line2D line = new Line2D.Double(startX, startY, endX, endY);
g2.draw(line);
g2.fill(arrow);
g2.setFont(getFont());
g2.setPaint(getPaint());
double labelX = j2DX + Math.cos(this.angle) * (this.baseRadius + this.labelOffset);
double labelY = j2DY + Math.sin(this.angle) * (this.baseRadius + this.labelOffset);
TextUtilities.drawAlignedString(getText(), g2, (float)labelX, (float)labelY, getTextAnchor());
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof CategoryPointerAnnotation))
return false;
if (!super.equals(obj))
return false;
CategoryPointerAnnotation that = (CategoryPointerAnnotation)obj;
if (this.angle != that.angle)
return false;
if (this.tipRadius != that.tipRadius)
return false;
if (this.baseRadius != that.baseRadius)
return false;
if (this.arrowLength != that.arrowLength)
return false;
if (this.arrowWidth != that.arrowWidth)
return false;
if (!this.arrowPaint.equals(that.arrowPaint))
return false;
if (!ObjectUtilities.equal(this.arrowStroke, that.arrowStroke))
return false;
if (this.labelOffset != that.labelOffset)
return false;
return true;
}
public int hashCode() {
int result = 193;
long temp = Double.doubleToLongBits(this.angle);
result = 37 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.tipRadius);
result = 37 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.baseRadius);
result = 37 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.arrowLength);
result = 37 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.arrowWidth);
result = 37 * result + (int)(temp ^ temp >>> 32L);
result = 37 * result + HashUtilities.hashCodeForPaint(this.arrowPaint);
result = 37 * result + this.arrowStroke.hashCode();
temp = Double.doubleToLongBits(this.labelOffset);
result = 37 * result + (int)(temp ^ temp >>> 32L);
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.arrowPaint, stream);
SerialUtilities.writeStroke(this.arrowStroke, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.arrowPaint = SerialUtilities.readPaint(stream);
this.arrowStroke = SerialUtilities.readStroke(stream);
}
}

View file

@ -0,0 +1,112 @@
package org.jfree.chart.annotations;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import org.jfree.chart.axis.CategoryAnchor;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
public class CategoryTextAnnotation extends TextAnnotation implements CategoryAnnotation, Cloneable, Serializable {
private static final long serialVersionUID = 3333360090781320147L;
private Comparable category;
private CategoryAnchor categoryAnchor;
private double value;
public CategoryTextAnnotation(String text, Comparable category, double value) {
super(text);
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
this.category = category;
this.value = value;
this.categoryAnchor = CategoryAnchor.MIDDLE;
}
public Comparable getCategory() {
return this.category;
}
public void setCategory(Comparable category) {
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
this.category = category;
}
public CategoryAnchor getCategoryAnchor() {
return this.categoryAnchor;
}
public void setCategoryAnchor(CategoryAnchor anchor) {
if (anchor == null)
throw new IllegalArgumentException("Null 'anchor' argument.");
this.categoryAnchor = anchor;
}
public double getValue() {
return this.value;
}
public void setValue(double value) {
this.value = value;
}
public void draw(Graphics2D g2, CategoryPlot plot, Rectangle2D dataArea, CategoryAxis domainAxis, ValueAxis rangeAxis) {
CategoryDataset dataset = plot.getDataset();
int catIndex = dataset.getColumnIndex(this.category);
int catCount = dataset.getColumnCount();
float anchorX = 0.0F;
float anchorY = 0.0F;
PlotOrientation orientation = plot.getOrientation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(plot.getDomainAxisLocation(), orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(plot.getRangeAxisLocation(), orientation);
if (orientation == PlotOrientation.HORIZONTAL) {
anchorY = (float)domainAxis.getCategoryJava2DCoordinate(this.categoryAnchor, catIndex, catCount, dataArea, domainEdge);
anchorX = (float)rangeAxis.valueToJava2D(this.value, dataArea, rangeEdge);
} else if (orientation == PlotOrientation.VERTICAL) {
anchorX = (float)domainAxis.getCategoryJava2DCoordinate(this.categoryAnchor, catIndex, catCount, dataArea, domainEdge);
anchorY = (float)rangeAxis.valueToJava2D(this.value, dataArea, rangeEdge);
}
g2.setFont(getFont());
g2.setPaint(getPaint());
TextUtilities.drawRotatedString(getText(), g2, anchorX, anchorY, getTextAnchor(), getRotationAngle(), getRotationAnchor());
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof CategoryTextAnnotation))
return false;
CategoryTextAnnotation that = (CategoryTextAnnotation)obj;
if (!super.equals(obj))
return false;
if (!this.category.equals(that.getCategory()))
return false;
if (!this.categoryAnchor.equals(that.getCategoryAnchor()))
return false;
if (this.value != that.getValue())
return false;
return true;
}
public int hashCode() {
int result = super.hashCode();
result = 37 * result + this.category.hashCode();
result = 37 * result + this.categoryAnchor.hashCode();
long temp = Double.doubleToLongBits(this.value);
result = 37 * result + (int)(temp ^ temp >>> 32L);
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

View file

@ -0,0 +1,150 @@
package org.jfree.chart.annotations;
import java.awt.Color;
import java.awt.Font;
import java.awt.Paint;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.HashUtilities;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.TextAnchor;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
public class TextAnnotation implements Serializable {
private static final long serialVersionUID = 7008912287533127432L;
public static final Font DEFAULT_FONT = new Font("SansSerif", 0, 10);
public static final Paint DEFAULT_PAINT = Color.black;
public static final TextAnchor DEFAULT_TEXT_ANCHOR = TextAnchor.CENTER;
public static final TextAnchor DEFAULT_ROTATION_ANCHOR = TextAnchor.CENTER;
public static final double DEFAULT_ROTATION_ANGLE = 0.0D;
private String text;
private Font font;
private transient Paint paint;
private TextAnchor textAnchor;
private TextAnchor rotationAnchor;
private double rotationAngle;
protected TextAnnotation(String text) {
if (text == null)
throw new IllegalArgumentException("Null 'text' argument.");
this.text = text;
this.font = DEFAULT_FONT;
this.paint = DEFAULT_PAINT;
this.textAnchor = DEFAULT_TEXT_ANCHOR;
this.rotationAnchor = DEFAULT_ROTATION_ANCHOR;
this.rotationAngle = 0.0D;
}
public String getText() {
return this.text;
}
public void setText(String text) {
if (text == null)
throw new IllegalArgumentException("Null 'text' argument.");
this.text = text;
}
public Font getFont() {
return this.font;
}
public void setFont(Font font) {
if (font == null)
throw new IllegalArgumentException("Null 'font' argument.");
this.font = font;
}
public Paint getPaint() {
return this.paint;
}
public void setPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.paint = paint;
}
public TextAnchor getTextAnchor() {
return this.textAnchor;
}
public void setTextAnchor(TextAnchor anchor) {
if (anchor == null)
throw new IllegalArgumentException("Null 'anchor' argument.");
this.textAnchor = anchor;
}
public TextAnchor getRotationAnchor() {
return this.rotationAnchor;
}
public void setRotationAnchor(TextAnchor anchor) {
this.rotationAnchor = anchor;
}
public double getRotationAngle() {
return this.rotationAngle;
}
public void setRotationAngle(double angle) {
this.rotationAngle = angle;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof TextAnnotation))
return false;
TextAnnotation that = (TextAnnotation)obj;
if (!ObjectUtilities.equal(this.text, that.getText()))
return false;
if (!ObjectUtilities.equal(this.font, that.getFont()))
return false;
if (!PaintUtilities.equal(this.paint, that.getPaint()))
return false;
if (!ObjectUtilities.equal(this.textAnchor, that.getTextAnchor()))
return false;
if (!ObjectUtilities.equal(this.rotationAnchor, that.getRotationAnchor()))
return false;
if (this.rotationAngle != that.getRotationAngle())
return false;
return true;
}
public int hashCode() {
int result = 193;
result = 37 * result + this.font.hashCode();
result = 37 * result + HashUtilities.hashCodeForPaint(this.paint);
result = 37 * result + this.rotationAnchor.hashCode();
long temp = Double.doubleToLongBits(this.rotationAngle);
result = 37 * result + (int)(temp ^ temp >>> 32L);
result = 37 * result + this.text.hashCode();
result = 37 * result + this.textAnchor.hashCode();
return result;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.paint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.paint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,11 @@
package org.jfree.chart.annotations;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
public interface XYAnnotation {
void draw(Graphics2D paramGraphics2D, XYPlot paramXYPlot, Rectangle2D paramRectangle2D, ValueAxis paramValueAxis1, ValueAxis paramValueAxis2, int paramInt, PlotRenderingInfo paramPlotRenderingInfo);
}

View file

@ -0,0 +1,139 @@
package org.jfree.chart.annotations;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
import org.jfree.util.PublicCloneable;
public class XYBoxAnnotation extends AbstractXYAnnotation implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = 6764703772526757457L;
private double x0;
private double y0;
private double x1;
private double y1;
private transient Stroke stroke;
private transient Paint outlinePaint;
private transient Paint fillPaint;
public XYBoxAnnotation(double x0, double y0, double x1, double y1) {
this(x0, y0, x1, y1, new BasicStroke(1.0F), Color.black);
}
public XYBoxAnnotation(double x0, double y0, double x1, double y1, Stroke stroke, Paint outlinePaint) {
this(x0, y0, x1, y1, stroke, outlinePaint, null);
}
public XYBoxAnnotation(double x0, double y0, double x1, double y1, Stroke stroke, Paint outlinePaint, Paint fillPaint) {
this.x0 = x0;
this.y0 = y0;
this.x1 = x1;
this.y1 = y1;
this.stroke = stroke;
this.outlinePaint = outlinePaint;
this.fillPaint = fillPaint;
}
public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int rendererIndex, PlotRenderingInfo info) {
PlotOrientation orientation = plot.getOrientation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(plot.getDomainAxisLocation(), orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(plot.getRangeAxisLocation(), orientation);
double transX0 = domainAxis.valueToJava2D(this.x0, dataArea, domainEdge);
double transY0 = rangeAxis.valueToJava2D(this.y0, dataArea, rangeEdge);
double transX1 = domainAxis.valueToJava2D(this.x1, dataArea, domainEdge);
double transY1 = rangeAxis.valueToJava2D(this.y1, dataArea, rangeEdge);
Rectangle2D box = null;
if (orientation == PlotOrientation.HORIZONTAL) {
box = new Rectangle2D.Double(transY0, transX1, transY1 - transY0, transX0 - transX1);
} else if (orientation == PlotOrientation.VERTICAL) {
box = new Rectangle2D.Double(transX0, transY1, transX1 - transX0, transY0 - transY1);
}
if (this.fillPaint != null) {
g2.setPaint(this.fillPaint);
g2.fill(box);
}
if (this.stroke != null && this.outlinePaint != null) {
g2.setPaint(this.outlinePaint);
g2.setStroke(this.stroke);
g2.draw(box);
}
addEntity(info, box, rendererIndex, getToolTipText(), getURL());
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!super.equals(obj))
return false;
if (!(obj instanceof XYBoxAnnotation))
return false;
XYBoxAnnotation that = (XYBoxAnnotation)obj;
if (this.x0 != that.x0)
return false;
if (this.y0 != that.y0)
return false;
if (this.x1 != that.x1)
return false;
if (this.y1 != that.y1)
return false;
if (!ObjectUtilities.equal(this.stroke, that.stroke))
return false;
if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint))
return false;
if (!PaintUtilities.equal(this.fillPaint, that.fillPaint))
return false;
return true;
}
public int hashCode() {
long temp = Double.doubleToLongBits(this.x0);
int result = (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.x1);
result = 29 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.y0);
result = 29 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.y1);
result = 29 * result + (int)(temp ^ temp >>> 32L);
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeStroke(this.stroke, stream);
SerialUtilities.writePaint(this.outlinePaint, stream);
SerialUtilities.writePaint(this.fillPaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.stroke = SerialUtilities.readStroke(stream);
this.outlinePaint = SerialUtilities.readPaint(stream);
this.fillPaint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,89 @@
package org.jfree.chart.annotations;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.ui.Drawable;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PublicCloneable;
public class XYDrawableAnnotation extends AbstractXYAnnotation implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = -6540812859722691020L;
private double x;
private double y;
private double width;
private double height;
private Drawable drawable;
public XYDrawableAnnotation(double x, double y, double width, double height, Drawable drawable) {
if (drawable == null)
throw new IllegalArgumentException("Null 'drawable' argument.");
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.drawable = drawable;
}
public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int rendererIndex, PlotRenderingInfo info) {
PlotOrientation orientation = plot.getOrientation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(plot.getDomainAxisLocation(), orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(plot.getRangeAxisLocation(), orientation);
float j2DX = (float)domainAxis.valueToJava2D(this.x, dataArea, domainEdge);
float j2DY = (float)rangeAxis.valueToJava2D(this.y, dataArea, rangeEdge);
Rectangle2D area = new Rectangle2D.Double((double)j2DX - this.width / 2.0D, (double)j2DY - this.height / 2.0D, this.width, this.height);
this.drawable.draw(g2, area);
String toolTip = getToolTipText();
String url = getURL();
if (toolTip != null || url != null)
addEntity(info, area, rendererIndex, toolTip, url);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!super.equals(obj))
return false;
if (!(obj instanceof XYDrawableAnnotation))
return false;
XYDrawableAnnotation that = (XYDrawableAnnotation)obj;
if (this.x != that.x)
return false;
if (this.y != that.y)
return false;
if (this.width != that.width)
return false;
if (this.height != that.height)
return false;
if (!ObjectUtilities.equal(this.drawable, that.drawable))
return false;
return true;
}
public int hashCode() {
long temp = Double.doubleToLongBits(this.x);
int result = (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.y);
result = 29 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.width);
result = 29 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.height);
result = 29 * result + (int)(temp ^ temp >>> 32L);
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

View file

@ -0,0 +1,128 @@
package org.jfree.chart.annotations;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PublicCloneable;
public class XYImageAnnotation extends AbstractXYAnnotation implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = -4364694501921559958L;
private double x;
private double y;
private transient Image image;
private RectangleAnchor anchor;
public XYImageAnnotation(double x, double y, Image image) {
this(x, y, image, RectangleAnchor.CENTER);
}
public XYImageAnnotation(double x, double y, Image image, RectangleAnchor anchor) {
if (image == null)
throw new IllegalArgumentException("Null 'image' argument.");
if (anchor == null)
throw new IllegalArgumentException("Null 'anchor' argument.");
this.x = x;
this.y = y;
this.image = image;
this.anchor = anchor;
}
public double getX() {
return this.x;
}
public double getY() {
return this.y;
}
public Image getImage() {
return this.image;
}
public RectangleAnchor getImageAnchor() {
return this.anchor;
}
public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int rendererIndex, PlotRenderingInfo info) {
PlotOrientation orientation = plot.getOrientation();
AxisLocation domainAxisLocation = plot.getDomainAxisLocation();
AxisLocation rangeAxisLocation = plot.getRangeAxisLocation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(domainAxisLocation, orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(rangeAxisLocation, orientation);
float j2DX = (float)domainAxis.valueToJava2D(this.x, dataArea, domainEdge);
float j2DY = (float)rangeAxis.valueToJava2D(this.y, dataArea, rangeEdge);
float xx = 0.0F;
float yy = 0.0F;
if (orientation == PlotOrientation.HORIZONTAL) {
xx = j2DY;
yy = j2DX;
} else if (orientation == PlotOrientation.VERTICAL) {
xx = j2DX;
yy = j2DY;
}
int w = this.image.getWidth(null);
int h = this.image.getHeight(null);
Rectangle2D imageRect = new Rectangle2D.Double(0.0D, 0.0D, (double)w, (double)h);
Point2D anchorPoint = RectangleAnchor.coordinates(imageRect, this.anchor);
xx -= (float)anchorPoint.getX();
yy -= (float)anchorPoint.getY();
g2.drawImage(this.image, (int)xx, (int)yy, null);
String toolTip = getToolTipText();
String url = getURL();
if (toolTip != null || url != null)
addEntity(info, new Rectangle2D.Float(xx, yy, (float)w, (float)h), rendererIndex, toolTip, url);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!super.equals(obj))
return false;
if (!(obj instanceof XYImageAnnotation))
return false;
XYImageAnnotation that = (XYImageAnnotation)obj;
if (this.x != that.x)
return false;
if (this.y != that.y)
return false;
if (!ObjectUtilities.equal(this.image, that.image))
return false;
if (!this.anchor.equals(that.anchor))
return false;
return true;
}
public int hashCode() {
return this.image.hashCode();
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
}
}

View file

@ -0,0 +1,137 @@
package org.jfree.chart.annotations;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
import org.jfree.util.PublicCloneable;
import org.jfree.util.ShapeUtilities;
public class XYLineAnnotation extends AbstractXYAnnotation implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = -80535465244091334L;
private double x1;
private double y1;
private double x2;
private double y2;
private transient Stroke stroke;
private transient Paint paint;
public XYLineAnnotation(double x1, double y1, double x2, double y2) {
this(x1, y1, x2, y2, new BasicStroke(1.0F), Color.black);
}
public XYLineAnnotation(double x1, double y1, double x2, double y2, Stroke stroke, Paint paint) {
if (stroke == null)
throw new IllegalArgumentException("Null 'stroke' argument.");
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.stroke = stroke;
this.paint = paint;
}
public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int rendererIndex, PlotRenderingInfo info) {
PlotOrientation orientation = plot.getOrientation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(plot.getDomainAxisLocation(), orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(plot.getRangeAxisLocation(), orientation);
float j2DX1 = 0.0F;
float j2DX2 = 0.0F;
float j2DY1 = 0.0F;
float j2DY2 = 0.0F;
if (orientation == PlotOrientation.VERTICAL) {
j2DX1 = (float)domainAxis.valueToJava2D(this.x1, dataArea, domainEdge);
j2DY1 = (float)rangeAxis.valueToJava2D(this.y1, dataArea, rangeEdge);
j2DX2 = (float)domainAxis.valueToJava2D(this.x2, dataArea, domainEdge);
j2DY2 = (float)rangeAxis.valueToJava2D(this.y2, dataArea, rangeEdge);
} else if (orientation == PlotOrientation.HORIZONTAL) {
j2DY1 = (float)domainAxis.valueToJava2D(this.x1, dataArea, domainEdge);
j2DX1 = (float)rangeAxis.valueToJava2D(this.y1, dataArea, rangeEdge);
j2DY2 = (float)domainAxis.valueToJava2D(this.x2, dataArea, domainEdge);
j2DX2 = (float)rangeAxis.valueToJava2D(this.y2, dataArea, rangeEdge);
}
g2.setPaint(this.paint);
g2.setStroke(this.stroke);
Line2D line = new Line2D.Float(j2DX1, j2DY1, j2DX2, j2DY2);
g2.draw(line);
String toolTip = getToolTipText();
String url = getURL();
if (toolTip != null || url != null)
addEntity(info, ShapeUtilities.createLineRegion(line, 1.0F), rendererIndex, toolTip, url);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!super.equals(obj))
return false;
if (!(obj instanceof XYLineAnnotation))
return false;
XYLineAnnotation that = (XYLineAnnotation)obj;
if (this.x1 != that.x1)
return false;
if (this.y1 != that.y1)
return false;
if (this.x2 != that.x2)
return false;
if (this.y2 != that.y2)
return false;
if (!PaintUtilities.equal(this.paint, that.paint))
return false;
if (!ObjectUtilities.equal(this.stroke, that.stroke))
return false;
return true;
}
public int hashCode() {
long temp = Double.doubleToLongBits(this.x1);
int result = (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.x2);
result = 29 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.y1);
result = 29 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.y2);
result = 29 * result + (int)(temp ^ temp >>> 32L);
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.paint, stream);
SerialUtilities.writeStroke(this.stroke, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.paint = SerialUtilities.readPaint(stream);
this.stroke = SerialUtilities.readStroke(stream);
}
}

View file

@ -0,0 +1,239 @@
package org.jfree.chart.annotations;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.HashUtilities;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PublicCloneable;
public class XYPointerAnnotation extends XYTextAnnotation implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = -4031161445009858551L;
public static final double DEFAULT_TIP_RADIUS = 10.0D;
public static final double DEFAULT_BASE_RADIUS = 30.0D;
public static final double DEFAULT_LABEL_OFFSET = 3.0D;
public static final double DEFAULT_ARROW_LENGTH = 5.0D;
public static final double DEFAULT_ARROW_WIDTH = 3.0D;
private double angle;
private double tipRadius;
private double baseRadius;
private double arrowLength;
private double arrowWidth;
private transient Stroke arrowStroke;
private transient Paint arrowPaint;
private double labelOffset;
public XYPointerAnnotation(String label, double x, double y, double angle) {
super(label, x, y);
this.angle = angle;
this.tipRadius = 10.0D;
this.baseRadius = 30.0D;
this.arrowLength = 5.0D;
this.arrowWidth = 3.0D;
this.labelOffset = 3.0D;
this.arrowStroke = new BasicStroke(1.0F);
this.arrowPaint = Color.black;
}
public double getAngle() {
return this.angle;
}
public void setAngle(double angle) {
this.angle = angle;
}
public double getTipRadius() {
return this.tipRadius;
}
public void setTipRadius(double radius) {
this.tipRadius = radius;
}
public double getBaseRadius() {
return this.baseRadius;
}
public void setBaseRadius(double radius) {
this.baseRadius = radius;
}
public double getLabelOffset() {
return this.labelOffset;
}
public void setLabelOffset(double offset) {
this.labelOffset = offset;
}
public double getArrowLength() {
return this.arrowLength;
}
public void setArrowLength(double length) {
this.arrowLength = length;
}
public double getArrowWidth() {
return this.arrowWidth;
}
public void setArrowWidth(double width) {
this.arrowWidth = width;
}
public Stroke getArrowStroke() {
return this.arrowStroke;
}
public void setArrowStroke(Stroke stroke) {
if (stroke == null)
throw new IllegalArgumentException("Null 'stroke' not permitted.");
this.arrowStroke = stroke;
}
public Paint getArrowPaint() {
return this.arrowPaint;
}
public void setArrowPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.arrowPaint = paint;
}
public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int rendererIndex, PlotRenderingInfo info) {
PlotOrientation orientation = plot.getOrientation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(plot.getDomainAxisLocation(), orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(plot.getRangeAxisLocation(), orientation);
double j2DX = domainAxis.valueToJava2D(getX(), dataArea, domainEdge);
double j2DY = rangeAxis.valueToJava2D(getY(), dataArea, rangeEdge);
if (orientation == PlotOrientation.HORIZONTAL) {
double temp = j2DX;
j2DX = j2DY;
j2DY = temp;
}
double startX = j2DX + Math.cos(this.angle) * this.baseRadius;
double startY = j2DY + Math.sin(this.angle) * this.baseRadius;
double endX = j2DX + Math.cos(this.angle) * this.tipRadius;
double endY = j2DY + Math.sin(this.angle) * this.tipRadius;
double arrowBaseX = endX + Math.cos(this.angle) * this.arrowLength;
double arrowBaseY = endY + Math.sin(this.angle) * this.arrowLength;
double arrowLeftX = arrowBaseX + Math.cos(this.angle + 1.5707963267948966D) * this.arrowWidth;
double arrowLeftY = arrowBaseY + Math.sin(this.angle + 1.5707963267948966D) * this.arrowWidth;
double arrowRightX = arrowBaseX - Math.cos(this.angle + 1.5707963267948966D) * this.arrowWidth;
double arrowRightY = arrowBaseY - Math.sin(this.angle + 1.5707963267948966D) * this.arrowWidth;
GeneralPath arrow = new GeneralPath();
arrow.moveTo((float)endX, (float)endY);
arrow.lineTo((float)arrowLeftX, (float)arrowLeftY);
arrow.lineTo((float)arrowRightX, (float)arrowRightY);
arrow.closePath();
g2.setStroke(this.arrowStroke);
g2.setPaint(this.arrowPaint);
Line2D line = new Line2D.Double(startX, startY, endX, endY);
g2.draw(line);
g2.fill(arrow);
g2.setFont(getFont());
g2.setPaint(getPaint());
double labelX = j2DX + Math.cos(this.angle) * (this.baseRadius + this.labelOffset);
double labelY = j2DY + Math.sin(this.angle) * (this.baseRadius + this.labelOffset);
Rectangle2D hotspot = TextUtilities.drawAlignedString(getText(), g2, (float)labelX, (float)labelY, getTextAnchor());
String toolTip = getToolTipText();
String url = getURL();
if (toolTip != null || url != null)
addEntity(info, hotspot, rendererIndex, toolTip, url);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof XYPointerAnnotation))
return false;
if (!super.equals(obj))
return false;
XYPointerAnnotation that = (XYPointerAnnotation)obj;
if (this.angle != that.angle)
return false;
if (this.tipRadius != that.tipRadius)
return false;
if (this.baseRadius != that.baseRadius)
return false;
if (this.arrowLength != that.arrowLength)
return false;
if (this.arrowWidth != that.arrowWidth)
return false;
if (!this.arrowPaint.equals(that.arrowPaint))
return false;
if (!ObjectUtilities.equal(this.arrowStroke, that.arrowStroke))
return false;
if (this.labelOffset != that.labelOffset)
return false;
return true;
}
public int hashCode() {
int result = super.hashCode();
long temp = Double.doubleToLongBits(this.angle);
result = 37 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.tipRadius);
result = 37 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.baseRadius);
result = 37 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.arrowLength);
result = 37 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.arrowWidth);
result = 37 * result + (int)(temp ^ temp >>> 32L);
result = result * 37 + HashUtilities.hashCodeForPaint(this.arrowPaint);
result = result * 37 + this.arrowStroke.hashCode();
temp = Double.doubleToLongBits(this.labelOffset);
result = 37 * result + (int)(temp ^ temp >>> 32L);
return super.hashCode();
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.arrowPaint, stream);
SerialUtilities.writeStroke(this.arrowStroke, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.arrowPaint = SerialUtilities.readPaint(stream);
this.arrowStroke = SerialUtilities.readStroke(stream);
}
}

View file

@ -0,0 +1,157 @@
package org.jfree.chart.annotations;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import org.jfree.chart.HashUtilities;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
import org.jfree.util.PublicCloneable;
public class XYPolygonAnnotation extends AbstractXYAnnotation implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = -6984203651995900036L;
private double[] polygon;
private transient Stroke stroke;
private transient Paint outlinePaint;
private transient Paint fillPaint;
public XYPolygonAnnotation(double[] polygon) {
this(polygon, new BasicStroke(1.0F), Color.black);
}
public XYPolygonAnnotation(double[] polygon, Stroke stroke, Paint outlinePaint) {
this(polygon, stroke, outlinePaint, null);
}
public XYPolygonAnnotation(double[] polygon, Stroke stroke, Paint outlinePaint, Paint fillPaint) {
if (polygon == null)
throw new IllegalArgumentException("Null 'polygon' argument.");
if (polygon.length % 2 != 0)
throw new IllegalArgumentException("The 'polygon' array must contain an even number of items.");
this.polygon = (double[])polygon.clone();
this.stroke = stroke;
this.outlinePaint = outlinePaint;
this.fillPaint = fillPaint;
}
public double[] getPolygonCoordinates() {
return (double[])this.polygon.clone();
}
public Paint getFillPaint() {
return this.fillPaint;
}
public Stroke getOutlineStroke() {
return this.stroke;
}
public Paint getOutlinePaint() {
return this.outlinePaint;
}
public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int rendererIndex, PlotRenderingInfo info) {
if (this.polygon.length < 4)
return;
PlotOrientation orientation = plot.getOrientation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(plot.getDomainAxisLocation(), orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(plot.getRangeAxisLocation(), orientation);
GeneralPath area = new GeneralPath();
double x = domainAxis.valueToJava2D(this.polygon[0], dataArea, domainEdge);
double y = rangeAxis.valueToJava2D(this.polygon[1], dataArea, rangeEdge);
if (orientation == PlotOrientation.HORIZONTAL) {
area.moveTo((float)y, (float)x);
for (int i = 2; i < this.polygon.length; i += 2) {
x = domainAxis.valueToJava2D(this.polygon[i], dataArea, domainEdge);
y = rangeAxis.valueToJava2D(this.polygon[i + 1], dataArea, rangeEdge);
area.lineTo((float)y, (float)x);
}
area.closePath();
} else if (orientation == PlotOrientation.VERTICAL) {
area.moveTo((float)x, (float)y);
for (int i = 2; i < this.polygon.length; i += 2) {
x = domainAxis.valueToJava2D(this.polygon[i], dataArea, domainEdge);
y = rangeAxis.valueToJava2D(this.polygon[i + 1], dataArea, rangeEdge);
area.lineTo((float)x, (float)y);
}
area.closePath();
}
if (this.fillPaint != null) {
g2.setPaint(this.fillPaint);
g2.fill(area);
}
if (this.stroke != null && this.outlinePaint != null) {
g2.setPaint(this.outlinePaint);
g2.setStroke(this.stroke);
g2.draw(area);
}
addEntity(info, area, rendererIndex, getToolTipText(), getURL());
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!super.equals(obj))
return false;
if (!(obj instanceof XYPolygonAnnotation))
return false;
XYPolygonAnnotation that = (XYPolygonAnnotation)obj;
if (!Arrays.equals(this.polygon, that.polygon))
return false;
if (!ObjectUtilities.equal(this.stroke, that.stroke))
return false;
if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint))
return false;
if (!PaintUtilities.equal(this.fillPaint, that.fillPaint))
return false;
return true;
}
public int hashCode() {
int result = 193;
result = 37 * result + HashUtilities.hashCodeForDoubleArray(this.polygon);
result = 37 * result + HashUtilities.hashCodeForPaint(this.fillPaint);
result = 37 * result + HashUtilities.hashCodeForPaint(this.outlinePaint);
if (this.stroke != null)
result = 37 * result + this.stroke.hashCode();
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeStroke(this.stroke, stream);
SerialUtilities.writePaint(this.outlinePaint, stream);
SerialUtilities.writePaint(this.fillPaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.stroke = SerialUtilities.readStroke(stream);
this.outlinePaint = SerialUtilities.readPaint(stream);
this.fillPaint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,142 @@
package org.jfree.chart.annotations;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.HashUtilities;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
import org.jfree.util.PublicCloneable;
public class XYShapeAnnotation extends AbstractXYAnnotation implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = -8553218317600684041L;
private transient Shape shape;
private transient Stroke stroke;
private transient Paint outlinePaint;
private transient Paint fillPaint;
public XYShapeAnnotation(Shape shape) {
this(shape, new BasicStroke(1.0F), Color.black);
}
public XYShapeAnnotation(Shape shape, Stroke stroke, Paint outlinePaint) {
this(shape, stroke, outlinePaint, null);
}
public XYShapeAnnotation(Shape shape, Stroke stroke, Paint outlinePaint, Paint fillPaint) {
if (shape == null)
throw new IllegalArgumentException("Null 'shape' argument.");
this.shape = shape;
this.stroke = stroke;
this.outlinePaint = outlinePaint;
this.fillPaint = fillPaint;
}
public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int rendererIndex, PlotRenderingInfo info) {
PlotOrientation orientation = plot.getOrientation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(plot.getDomainAxisLocation(), orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(plot.getRangeAxisLocation(), orientation);
Rectangle2D bounds = this.shape.getBounds2D();
double x0 = bounds.getMinX();
double x1 = bounds.getMaxX();
double xx0 = domainAxis.valueToJava2D(x0, dataArea, domainEdge);
double xx1 = domainAxis.valueToJava2D(x1, dataArea, domainEdge);
double m00 = (xx1 - xx0) / (x1 - x0);
double m02 = xx0 - x0 * m00;
double y0 = bounds.getMaxY();
double y1 = bounds.getMinY();
double yy0 = rangeAxis.valueToJava2D(y0, dataArea, rangeEdge);
double yy1 = rangeAxis.valueToJava2D(y1, dataArea, rangeEdge);
double m11 = (yy1 - yy0) / (y1 - y0);
double m12 = yy0 - m11 * y0;
Shape s = null;
if (orientation == PlotOrientation.HORIZONTAL) {
AffineTransform t1 = new AffineTransform(0.0F, 1.0F, 1.0F, 0.0F, 0.0F, 0.0F);
AffineTransform t2 = new AffineTransform(m11, 0.0D, 0.0D, m00, m12, m02);
s = t1.createTransformedShape(this.shape);
s = t2.createTransformedShape(s);
} else if (orientation == PlotOrientation.VERTICAL) {
AffineTransform t = new AffineTransform(m00, 0.0D, 0.0D, m11, m02, m12);
s = t.createTransformedShape(this.shape);
}
if (this.fillPaint != null) {
g2.setPaint(this.fillPaint);
g2.fill(s);
}
if (this.stroke != null && this.outlinePaint != null) {
g2.setPaint(this.outlinePaint);
g2.setStroke(this.stroke);
g2.draw(s);
}
addEntity(info, s, rendererIndex, getToolTipText(), getURL());
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!super.equals(obj))
return false;
if (!(obj instanceof XYShapeAnnotation))
return false;
XYShapeAnnotation that = (XYShapeAnnotation)obj;
if (!this.shape.equals(that.shape))
return false;
if (!ObjectUtilities.equal(this.stroke, that.stroke))
return false;
if (!PaintUtilities.equal(this.outlinePaint, that.outlinePaint))
return false;
if (!PaintUtilities.equal(this.fillPaint, that.fillPaint))
return false;
return true;
}
public int hashCode() {
int result = 193;
result = 37 * result + this.shape.hashCode();
if (this.stroke != null)
result = 37 * result + this.stroke.hashCode();
result = 37 * result + HashUtilities.hashCodeForPaint(this.outlinePaint);
result = 37 * result + HashUtilities.hashCodeForPaint(this.fillPaint);
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeShape(this.shape, stream);
SerialUtilities.writeStroke(this.stroke, stream);
SerialUtilities.writePaint(this.outlinePaint, stream);
SerialUtilities.writePaint(this.fillPaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.shape = SerialUtilities.readShape(stream);
this.stroke = SerialUtilities.readStroke(stream);
this.outlinePaint = SerialUtilities.readPaint(stream);
this.fillPaint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,219 @@
package org.jfree.chart.annotations;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.chart.HashUtilities;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;
import org.jfree.util.PaintUtilities;
import org.jfree.util.PublicCloneable;
public class XYTextAnnotation extends AbstractXYAnnotation implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = -2946063342782506328L;
public static final Font DEFAULT_FONT = new Font("SansSerif", 0, 10);
public static final Paint DEFAULT_PAINT = Color.black;
public static final TextAnchor DEFAULT_TEXT_ANCHOR = TextAnchor.CENTER;
public static final TextAnchor DEFAULT_ROTATION_ANCHOR = TextAnchor.CENTER;
public static final double DEFAULT_ROTATION_ANGLE = 0.0D;
private String text;
private Font font;
private transient Paint paint;
private double x;
private double y;
private TextAnchor textAnchor;
private TextAnchor rotationAnchor;
private double rotationAngle;
public XYTextAnnotation(String text, double x, double y) {
if (text == null)
throw new IllegalArgumentException("Null 'text' argument.");
this.text = text;
this.font = DEFAULT_FONT;
this.paint = DEFAULT_PAINT;
this.x = x;
this.y = y;
this.textAnchor = DEFAULT_TEXT_ANCHOR;
this.rotationAnchor = DEFAULT_ROTATION_ANCHOR;
this.rotationAngle = 0.0D;
}
public String getText() {
return this.text;
}
public void setText(String text) {
if (text == null)
throw new IllegalArgumentException("Null 'text' argument.");
this.text = text;
}
public Font getFont() {
return this.font;
}
public void setFont(Font font) {
if (font == null)
throw new IllegalArgumentException("Null 'font' argument.");
this.font = font;
}
public Paint getPaint() {
return this.paint;
}
public void setPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.paint = paint;
}
public TextAnchor getTextAnchor() {
return this.textAnchor;
}
public void setTextAnchor(TextAnchor anchor) {
if (anchor == null)
throw new IllegalArgumentException("Null 'anchor' argument.");
this.textAnchor = anchor;
}
public TextAnchor getRotationAnchor() {
return this.rotationAnchor;
}
public void setRotationAnchor(TextAnchor anchor) {
if (anchor == null)
throw new IllegalArgumentException("Null 'anchor' argument.");
this.rotationAnchor = anchor;
}
public double getRotationAngle() {
return this.rotationAngle;
}
public void setRotationAngle(double angle) {
this.rotationAngle = angle;
}
public double getX() {
return this.x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return this.y;
}
public void setY(double y) {
this.y = y;
}
public void draw(Graphics2D g2, XYPlot plot, Rectangle2D dataArea, ValueAxis domainAxis, ValueAxis rangeAxis, int rendererIndex, PlotRenderingInfo info) {
PlotOrientation orientation = plot.getOrientation();
RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(plot.getDomainAxisLocation(), orientation);
RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(plot.getRangeAxisLocation(), orientation);
float anchorX = (float)domainAxis.valueToJava2D(this.x, dataArea, domainEdge);
float anchorY = (float)rangeAxis.valueToJava2D(this.y, dataArea, rangeEdge);
if (orientation == PlotOrientation.HORIZONTAL) {
float tempAnchor = anchorX;
anchorX = anchorY;
anchorY = tempAnchor;
}
g2.setFont(getFont());
g2.setPaint(getPaint());
TextUtilities.drawRotatedString(getText(), g2, anchorX, anchorY, getTextAnchor(), getRotationAngle(), getRotationAnchor());
Shape hotspot = TextUtilities.calculateRotatedStringBounds(getText(), g2, anchorX, anchorY, getTextAnchor(), getRotationAngle(), getRotationAnchor());
String toolTip = getToolTipText();
String url = getURL();
if (toolTip != null || url != null)
addEntity(info, hotspot, rendererIndex, toolTip, url);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof XYTextAnnotation))
return false;
if (!super.equals(obj))
return false;
XYTextAnnotation that = (XYTextAnnotation)obj;
if (!this.text.equals(that.text))
return false;
if (this.x != that.x)
return false;
if (this.y != that.y)
return false;
if (!this.font.equals(that.font))
return false;
if (!PaintUtilities.equal(this.paint, that.paint))
return false;
if (!this.rotationAnchor.equals(that.rotationAnchor))
return false;
if (this.rotationAngle != that.rotationAngle)
return false;
if (!this.textAnchor.equals(that.textAnchor))
return false;
return true;
}
public int hashCode() {
int result = 193;
result = 37 * this.text.hashCode();
result = 37 * this.font.hashCode();
result = 37 * result + HashUtilities.hashCodeForPaint(this.paint);
long temp = Double.doubleToLongBits(this.x);
result = 37 * result + (int)(temp ^ temp >>> 32L);
temp = Double.doubleToLongBits(this.y);
result = 37 * result + (int)(temp ^ temp >>> 32L);
result = 37 * result + this.textAnchor.hashCode();
result = 37 * result + this.rotationAnchor.hashCode();
temp = Double.doubleToLongBits(this.rotationAngle);
result = 37 * result + (int)(temp ^ temp >>> 32L);
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.paint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.paint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,541 @@
package org.jfree.chart.axis;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.EventListener;
import java.util.List;
import javax.swing.event.EventListenerList;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.event.AxisChangeListener;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
public abstract class Axis implements Cloneable, Serializable {
private static final long serialVersionUID = 7719289504573298271L;
public static final boolean DEFAULT_AXIS_VISIBLE = true;
public static final Font DEFAULT_AXIS_LABEL_FONT = new Font("SansSerif", 0, 12);
public static final Paint DEFAULT_AXIS_LABEL_PAINT = Color.black;
public static final RectangleInsets DEFAULT_AXIS_LABEL_INSETS = new RectangleInsets(3.0D, 3.0D, 3.0D, 3.0D);
public static final Paint DEFAULT_AXIS_LINE_PAINT = Color.gray;
public static final Stroke DEFAULT_AXIS_LINE_STROKE = new BasicStroke(1.0F);
public static final boolean DEFAULT_TICK_LABELS_VISIBLE = true;
public static final Font DEFAULT_TICK_LABEL_FONT = new Font("SansSerif", 0, 10);
public static final Paint DEFAULT_TICK_LABEL_PAINT = Color.black;
public static final RectangleInsets DEFAULT_TICK_LABEL_INSETS = new RectangleInsets(2.0D, 4.0D, 2.0D, 4.0D);
public static final boolean DEFAULT_TICK_MARKS_VISIBLE = true;
public static final Stroke DEFAULT_TICK_MARK_STROKE = new BasicStroke(1.0F);
public static final Paint DEFAULT_TICK_MARK_PAINT = Color.gray;
public static final float DEFAULT_TICK_MARK_INSIDE_LENGTH = 0.0F;
public static final float DEFAULT_TICK_MARK_OUTSIDE_LENGTH = 2.0F;
private boolean visible;
private String label;
private Font labelFont;
private transient Paint labelPaint;
private RectangleInsets labelInsets;
private double labelAngle;
private boolean axisLineVisible;
private transient Stroke axisLineStroke;
private transient Paint axisLinePaint;
private boolean tickLabelsVisible;
private Font tickLabelFont;
private transient Paint tickLabelPaint;
private RectangleInsets tickLabelInsets;
private boolean tickMarksVisible;
private float tickMarkInsideLength;
private float tickMarkOutsideLength;
private transient Stroke tickMarkStroke;
private transient Paint tickMarkPaint;
private double fixedDimension;
private transient Plot plot;
private transient EventListenerList listenerList;
protected Axis(String label) {
this.label = label;
this.visible = true;
this.labelFont = DEFAULT_AXIS_LABEL_FONT;
this.labelPaint = DEFAULT_AXIS_LABEL_PAINT;
this.labelInsets = DEFAULT_AXIS_LABEL_INSETS;
this.labelAngle = 0.0D;
this.axisLineVisible = true;
this.axisLinePaint = DEFAULT_AXIS_LINE_PAINT;
this.axisLineStroke = DEFAULT_AXIS_LINE_STROKE;
this.tickLabelsVisible = true;
this.tickLabelFont = DEFAULT_TICK_LABEL_FONT;
this.tickLabelPaint = DEFAULT_TICK_LABEL_PAINT;
this.tickLabelInsets = DEFAULT_TICK_LABEL_INSETS;
this.tickMarksVisible = true;
this.tickMarkStroke = DEFAULT_TICK_MARK_STROKE;
this.tickMarkPaint = DEFAULT_TICK_MARK_PAINT;
this.tickMarkInsideLength = 0.0F;
this.tickMarkOutsideLength = 2.0F;
this.plot = null;
this.listenerList = new EventListenerList();
}
public boolean isVisible() {
return this.visible;
}
public void setVisible(boolean flag) {
if (flag != this.visible) {
this.visible = flag;
notifyListeners(new AxisChangeEvent(this));
}
}
public String getLabel() {
return this.label;
}
public void setLabel(String label) {
String existing = this.label;
if (existing != null) {
if (!existing.equals(label)) {
this.label = label;
notifyListeners(new AxisChangeEvent(this));
}
} else if (label != null) {
this.label = label;
notifyListeners(new AxisChangeEvent(this));
}
}
public Font getLabelFont() {
return this.labelFont;
}
public void setLabelFont(Font font) {
if (font == null)
throw new IllegalArgumentException("Null 'font' argument.");
if (!this.labelFont.equals(font)) {
this.labelFont = font;
notifyListeners(new AxisChangeEvent(this));
}
}
public Paint getLabelPaint() {
return this.labelPaint;
}
public void setLabelPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.labelPaint = paint;
notifyListeners(new AxisChangeEvent(this));
}
public RectangleInsets getLabelInsets() {
return this.labelInsets;
}
public void setLabelInsets(RectangleInsets insets) {
if (insets == null)
throw new IllegalArgumentException("Null 'insets' argument.");
if (!insets.equals(this.labelInsets)) {
this.labelInsets = insets;
notifyListeners(new AxisChangeEvent(this));
}
}
public double getLabelAngle() {
return this.labelAngle;
}
public void setLabelAngle(double angle) {
this.labelAngle = angle;
notifyListeners(new AxisChangeEvent(this));
}
public boolean isAxisLineVisible() {
return this.axisLineVisible;
}
public void setAxisLineVisible(boolean visible) {
this.axisLineVisible = visible;
notifyListeners(new AxisChangeEvent(this));
}
public Paint getAxisLinePaint() {
return this.axisLinePaint;
}
public void setAxisLinePaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.axisLinePaint = paint;
notifyListeners(new AxisChangeEvent(this));
}
public Stroke getAxisLineStroke() {
return this.axisLineStroke;
}
public void setAxisLineStroke(Stroke stroke) {
if (stroke == null)
throw new IllegalArgumentException("Null 'stroke' argument.");
this.axisLineStroke = stroke;
notifyListeners(new AxisChangeEvent(this));
}
public boolean isTickLabelsVisible() {
return this.tickLabelsVisible;
}
public void setTickLabelsVisible(boolean flag) {
if (flag != this.tickLabelsVisible) {
this.tickLabelsVisible = flag;
notifyListeners(new AxisChangeEvent(this));
}
}
public Font getTickLabelFont() {
return this.tickLabelFont;
}
public void setTickLabelFont(Font font) {
if (font == null)
throw new IllegalArgumentException("Null 'font' argument.");
if (!this.tickLabelFont.equals(font)) {
this.tickLabelFont = font;
notifyListeners(new AxisChangeEvent(this));
}
}
public Paint getTickLabelPaint() {
return this.tickLabelPaint;
}
public void setTickLabelPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.tickLabelPaint = paint;
notifyListeners(new AxisChangeEvent(this));
}
public RectangleInsets getTickLabelInsets() {
return this.tickLabelInsets;
}
public void setTickLabelInsets(RectangleInsets insets) {
if (insets == null)
throw new IllegalArgumentException("Null 'insets' argument.");
if (!this.tickLabelInsets.equals(insets)) {
this.tickLabelInsets = insets;
notifyListeners(new AxisChangeEvent(this));
}
}
public boolean isTickMarksVisible() {
return this.tickMarksVisible;
}
public void setTickMarksVisible(boolean flag) {
if (flag != this.tickMarksVisible) {
this.tickMarksVisible = flag;
notifyListeners(new AxisChangeEvent(this));
}
}
public float getTickMarkInsideLength() {
return this.tickMarkInsideLength;
}
public void setTickMarkInsideLength(float length) {
this.tickMarkInsideLength = length;
notifyListeners(new AxisChangeEvent(this));
}
public float getTickMarkOutsideLength() {
return this.tickMarkOutsideLength;
}
public void setTickMarkOutsideLength(float length) {
this.tickMarkOutsideLength = length;
notifyListeners(new AxisChangeEvent(this));
}
public Stroke getTickMarkStroke() {
return this.tickMarkStroke;
}
public void setTickMarkStroke(Stroke stroke) {
if (stroke == null)
throw new IllegalArgumentException("Null 'stroke' argument.");
if (!this.tickMarkStroke.equals(stroke)) {
this.tickMarkStroke = stroke;
notifyListeners(new AxisChangeEvent(this));
}
}
public Paint getTickMarkPaint() {
return this.tickMarkPaint;
}
public void setTickMarkPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.tickMarkPaint = paint;
notifyListeners(new AxisChangeEvent(this));
}
public Plot getPlot() {
return this.plot;
}
public void setPlot(Plot plot) {
this.plot = plot;
configure();
}
public double getFixedDimension() {
return this.fixedDimension;
}
public void setFixedDimension(double dimension) {
this.fixedDimension = dimension;
}
public void addChangeListener(AxisChangeListener listener) {
this.listenerList.add(AxisChangeListener.class, listener);
}
public void removeChangeListener(AxisChangeListener listener) {
this.listenerList.remove(AxisChangeListener.class, listener);
}
public boolean hasListener(EventListener listener) {
List list = Arrays.asList(this.listenerList.getListenerList());
return list.contains(listener);
}
protected void notifyListeners(AxisChangeEvent event) {
Object[] listeners = this.listenerList.getListenerList();
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == AxisChangeListener.class)
((AxisChangeListener)listeners[i + 1]).axisChanged(event);
}
}
protected Rectangle2D getLabelEnclosure(Graphics2D g2, RectangleEdge edge) {
Rectangle2D result = new Rectangle2D.Double();
String axisLabel = getLabel();
if (axisLabel != null && !axisLabel.equals("")) {
FontMetrics fm = g2.getFontMetrics(getLabelFont());
Rectangle2D bounds = TextUtilities.getTextBounds(axisLabel, g2, fm);
RectangleInsets insets = getLabelInsets();
bounds = insets.createOutsetRectangle(bounds);
double angle = getLabelAngle();
if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT)
angle -= 1.5707963267948966D;
double x = bounds.getCenterX();
double y = bounds.getCenterY();
AffineTransform transformer = AffineTransform.getRotateInstance(angle, x, y);
Shape labelBounds = transformer.createTransformedShape(bounds);
result = labelBounds.getBounds2D();
}
return result;
}
protected AxisState drawLabel(String label, Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, AxisState state) {
if (state == null)
throw new IllegalArgumentException("Null 'state' argument.");
if (label == null || label.equals(""))
return state;
Font font = getLabelFont();
RectangleInsets insets = getLabelInsets();
g2.setFont(font);
g2.setPaint(getLabelPaint());
FontMetrics fm = g2.getFontMetrics();
Rectangle2D labelBounds = TextUtilities.getTextBounds(label, g2, fm);
if (edge == RectangleEdge.TOP) {
AffineTransform t = AffineTransform.getRotateInstance(getLabelAngle(), labelBounds.getCenterX(), labelBounds.getCenterY());
Shape rotatedLabelBounds = t.createTransformedShape(labelBounds);
labelBounds = rotatedLabelBounds.getBounds2D();
double labelx = dataArea.getCenterX();
double labely = state.getCursor() - insets.getBottom() - labelBounds.getHeight() / 2.0D;
TextUtilities.drawRotatedString(label, g2, (float)labelx, (float)labely, TextAnchor.CENTER, getLabelAngle(), TextAnchor.CENTER);
state.cursorUp(insets.getTop() + labelBounds.getHeight() + insets.getBottom());
} else if (edge == RectangleEdge.BOTTOM) {
AffineTransform t = AffineTransform.getRotateInstance(getLabelAngle(), labelBounds.getCenterX(), labelBounds.getCenterY());
Shape rotatedLabelBounds = t.createTransformedShape(labelBounds);
labelBounds = rotatedLabelBounds.getBounds2D();
double labelx = dataArea.getCenterX();
double labely = state.getCursor() + insets.getTop() + labelBounds.getHeight() / 2.0D;
TextUtilities.drawRotatedString(label, g2, (float)labelx, (float)labely, TextAnchor.CENTER, getLabelAngle(), TextAnchor.CENTER);
state.cursorDown(insets.getTop() + labelBounds.getHeight() + insets.getBottom());
} else if (edge == RectangleEdge.LEFT) {
AffineTransform t = AffineTransform.getRotateInstance(getLabelAngle() - 1.5707963267948966D, labelBounds.getCenterX(), labelBounds.getCenterY());
Shape rotatedLabelBounds = t.createTransformedShape(labelBounds);
labelBounds = rotatedLabelBounds.getBounds2D();
double labelx = state.getCursor() - insets.getRight() - labelBounds.getWidth() / 2.0D;
double labely = dataArea.getCenterY();
TextUtilities.drawRotatedString(label, g2, (float)labelx, (float)labely, TextAnchor.CENTER, getLabelAngle() - 1.5707963267948966D, TextAnchor.CENTER);
state.cursorLeft(insets.getLeft() + labelBounds.getWidth() + insets.getRight());
} else if (edge == RectangleEdge.RIGHT) {
AffineTransform t = AffineTransform.getRotateInstance(getLabelAngle() + 1.5707963267948966D, labelBounds.getCenterX(), labelBounds.getCenterY());
Shape rotatedLabelBounds = t.createTransformedShape(labelBounds);
labelBounds = rotatedLabelBounds.getBounds2D();
double labelx = state.getCursor() + insets.getLeft() + labelBounds.getWidth() / 2.0D;
double labely = dataArea.getY() + dataArea.getHeight() / 2.0D;
TextUtilities.drawRotatedString(label, g2, (float)labelx, (float)labely, TextAnchor.CENTER, getLabelAngle() + 1.5707963267948966D, TextAnchor.CENTER);
state.cursorRight(insets.getLeft() + labelBounds.getWidth() + insets.getRight());
}
return state;
}
protected void drawAxisLine(Graphics2D g2, double cursor, Rectangle2D dataArea, RectangleEdge edge) {
Line2D axisLine = null;
if (edge == RectangleEdge.TOP) {
axisLine = new Line2D.Double(dataArea.getX(), cursor, dataArea.getMaxX(), cursor);
} else if (edge == RectangleEdge.BOTTOM) {
axisLine = new Line2D.Double(dataArea.getX(), cursor, dataArea.getMaxX(), cursor);
} else if (edge == RectangleEdge.LEFT) {
axisLine = new Line2D.Double(cursor, dataArea.getY(), cursor, dataArea.getMaxY());
} else if (edge == RectangleEdge.RIGHT) {
axisLine = new Line2D.Double(cursor, dataArea.getY(), cursor, dataArea.getMaxY());
}
g2.setPaint(this.axisLinePaint);
g2.setStroke(this.axisLineStroke);
g2.draw(axisLine);
}
public Object clone() throws CloneNotSupportedException {
Axis clone = (Axis)super.clone();
clone.plot = null;
clone.listenerList = new EventListenerList();
return clone;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Axis))
return false;
Axis that = (Axis)obj;
if (this.visible != that.visible)
return false;
if (!ObjectUtilities.equal(this.label, that.label))
return false;
if (!ObjectUtilities.equal(this.labelFont, that.labelFont))
return false;
if (!PaintUtilities.equal(this.labelPaint, that.labelPaint))
return false;
if (!ObjectUtilities.equal(this.labelInsets, that.labelInsets))
return false;
if (this.labelAngle != that.labelAngle)
return false;
if (this.axisLineVisible != that.axisLineVisible)
return false;
if (!ObjectUtilities.equal(this.axisLineStroke, that.axisLineStroke))
return false;
if (!PaintUtilities.equal(this.axisLinePaint, that.axisLinePaint))
return false;
if (this.tickLabelsVisible != that.tickLabelsVisible)
return false;
if (!ObjectUtilities.equal(this.tickLabelFont, that.tickLabelFont))
return false;
if (!PaintUtilities.equal(this.tickLabelPaint, that.tickLabelPaint))
return false;
if (!ObjectUtilities.equal(this.tickLabelInsets, that.tickLabelInsets))
return false;
if (this.tickMarksVisible != that.tickMarksVisible)
return false;
if (this.tickMarkInsideLength != that.tickMarkInsideLength)
return false;
if (this.tickMarkOutsideLength != that.tickMarkOutsideLength)
return false;
if (!PaintUtilities.equal(this.tickMarkPaint, that.tickMarkPaint))
return false;
if (!ObjectUtilities.equal(this.tickMarkStroke, that.tickMarkStroke))
return false;
if (this.fixedDimension != that.fixedDimension)
return false;
return true;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.labelPaint, stream);
SerialUtilities.writePaint(this.tickLabelPaint, stream);
SerialUtilities.writeStroke(this.axisLineStroke, stream);
SerialUtilities.writePaint(this.axisLinePaint, stream);
SerialUtilities.writeStroke(this.tickMarkStroke, stream);
SerialUtilities.writePaint(this.tickMarkPaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.labelPaint = SerialUtilities.readPaint(stream);
this.tickLabelPaint = SerialUtilities.readPaint(stream);
this.axisLineStroke = SerialUtilities.readStroke(stream);
this.axisLinePaint = SerialUtilities.readPaint(stream);
this.tickMarkStroke = SerialUtilities.readStroke(stream);
this.tickMarkPaint = SerialUtilities.readPaint(stream);
this.listenerList = new EventListenerList();
}
public abstract void configure();
public abstract AxisSpace reserveSpace(Graphics2D paramGraphics2D, Plot paramPlot, Rectangle2D paramRectangle2D, RectangleEdge paramRectangleEdge, AxisSpace paramAxisSpace);
public abstract AxisState draw(Graphics2D paramGraphics2D, double paramDouble, Rectangle2D paramRectangle2D1, Rectangle2D paramRectangle2D2, RectangleEdge paramRectangleEdge, PlotRenderingInfo paramPlotRenderingInfo);
public abstract List refreshTicks(Graphics2D paramGraphics2D, AxisState paramAxisState, Rectangle2D paramRectangle2D, RectangleEdge paramRectangleEdge);
}

View file

@ -0,0 +1,47 @@
package org.jfree.chart.axis;
import java.util.ArrayList;
import java.util.List;
import org.jfree.ui.RectangleEdge;
public class AxisCollection {
private List axesAtTop = new ArrayList();
private List axesAtBottom = new ArrayList();
private List axesAtLeft = new ArrayList();
private List axesAtRight = new ArrayList();
public List getAxesAtTop() {
return this.axesAtTop;
}
public List getAxesAtBottom() {
return this.axesAtBottom;
}
public List getAxesAtLeft() {
return this.axesAtLeft;
}
public List getAxesAtRight() {
return this.axesAtRight;
}
public void add(Axis axis, RectangleEdge edge) {
if (axis == null)
throw new IllegalArgumentException("Null 'axis' argument.");
if (edge == null)
throw new IllegalArgumentException("Null 'edge' argument.");
if (edge == RectangleEdge.TOP) {
this.axesAtTop.add(axis);
} else if (edge == RectangleEdge.BOTTOM) {
this.axesAtBottom.add(axis);
} else if (edge == RectangleEdge.LEFT) {
this.axesAtLeft.add(axis);
} else if (edge == RectangleEdge.RIGHT) {
this.axesAtRight.add(axis);
}
}
}

View file

@ -0,0 +1,71 @@
package org.jfree.chart.axis;
import java.io.ObjectStreamException;
import java.io.Serializable;
public final class AxisLocation implements Serializable {
private static final long serialVersionUID = -3276922179323563410L;
public static final AxisLocation TOP_OR_LEFT = new AxisLocation("AxisLocation.TOP_OR_LEFT");
public static final AxisLocation TOP_OR_RIGHT = new AxisLocation("AxisLocation.TOP_OR_RIGHT");
public static final AxisLocation BOTTOM_OR_LEFT = new AxisLocation("AxisLocation.BOTTOM_OR_LEFT");
public static final AxisLocation BOTTOM_OR_RIGHT = new AxisLocation("AxisLocation.BOTTOM_OR_RIGHT");
private String name;
private AxisLocation(String name) {
this.name = name;
}
public AxisLocation getOpposite() {
return getOpposite(this);
}
public String toString() {
return this.name;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof AxisLocation))
return false;
AxisLocation location = (AxisLocation)obj;
if (!this.name.equals(location.toString()))
return false;
return true;
}
public static AxisLocation getOpposite(AxisLocation location) {
if (location == null)
throw new IllegalArgumentException("Null 'location' argument.");
AxisLocation result = null;
if (location == TOP_OR_LEFT) {
result = BOTTOM_OR_RIGHT;
} else if (location == TOP_OR_RIGHT) {
result = BOTTOM_OR_LEFT;
} else if (location == BOTTOM_OR_LEFT) {
result = TOP_OR_RIGHT;
} else if (location == BOTTOM_OR_RIGHT) {
result = TOP_OR_LEFT;
} else {
throw new IllegalStateException("AxisLocation not recognised.");
}
return result;
}
private Object readResolve() throws ObjectStreamException {
if (equals(TOP_OR_RIGHT))
return TOP_OR_RIGHT;
if (equals(BOTTOM_OR_RIGHT))
return BOTTOM_OR_RIGHT;
if (equals(TOP_OR_LEFT))
return TOP_OR_LEFT;
if (equals(BOTTOM_OR_LEFT))
return BOTTOM_OR_LEFT;
return null;
}
}

View file

@ -0,0 +1,157 @@
package org.jfree.chart.axis;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.PublicCloneable;
public class AxisSpace implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = -2490732595134766305L;
private double top = 0.0D;
private double bottom = 0.0D;
private double left = 0.0D;
private double right = 0.0D;
public double getTop() {
return this.top;
}
public void setTop(double space) {
this.top = space;
}
public double getBottom() {
return this.bottom;
}
public void setBottom(double space) {
this.bottom = space;
}
public double getLeft() {
return this.left;
}
public void setLeft(double space) {
this.left = space;
}
public double getRight() {
return this.right;
}
public void setRight(double space) {
this.right = space;
}
public void add(double space, RectangleEdge edge) {
if (edge == null)
throw new IllegalArgumentException("Null 'edge' argument.");
if (edge == RectangleEdge.TOP) {
this.top += space;
} else if (edge == RectangleEdge.BOTTOM) {
this.bottom += space;
} else if (edge == RectangleEdge.LEFT) {
this.left += space;
} else if (edge == RectangleEdge.RIGHT) {
this.right += space;
} else {
throw new IllegalStateException("Unrecognised 'edge' argument.");
}
}
public void ensureAtLeast(AxisSpace space) {
this.top = Math.max(this.top, space.top);
this.bottom = Math.max(this.bottom, space.bottom);
this.left = Math.max(this.left, space.left);
this.right = Math.max(this.right, space.right);
}
public void ensureAtLeast(double space, RectangleEdge edge) {
if (edge == RectangleEdge.TOP) {
if (this.top < space)
this.top = space;
} else if (edge == RectangleEdge.BOTTOM) {
if (this.bottom < space)
this.bottom = space;
} else if (edge == RectangleEdge.LEFT) {
if (this.left < space)
this.left = space;
} else if (edge == RectangleEdge.RIGHT) {
if (this.right < space)
this.right = space;
} else {
throw new IllegalStateException("AxisSpace.ensureAtLeast(): unrecognised AxisLocation.");
}
}
public Rectangle2D shrink(Rectangle2D area, Rectangle2D result) {
if (result == null)
result = new Rectangle2D.Double();
result.setRect(area.getX() + this.left, area.getY() + this.top, area.getWidth() - this.left - this.right, area.getHeight() - this.top - this.bottom);
return result;
}
public Rectangle2D expand(Rectangle2D area, Rectangle2D result) {
if (result == null)
result = new Rectangle2D.Double();
result.setRect(area.getX() - this.left, area.getY() - this.top, area.getWidth() + this.left + this.right, area.getHeight() + this.top + this.bottom);
return result;
}
public Rectangle2D reserved(Rectangle2D area, RectangleEdge edge) {
Rectangle2D result = null;
if (edge == RectangleEdge.TOP) {
result = new Rectangle2D.Double(area.getX(), area.getY(), area.getWidth(), this.top);
} else if (edge == RectangleEdge.BOTTOM) {
result = new Rectangle2D.Double(area.getX(), area.getMaxY() - this.top, area.getWidth(), this.bottom);
} else if (edge == RectangleEdge.LEFT) {
result = new Rectangle2D.Double(area.getX(), area.getY(), this.left, area.getHeight());
} else if (edge == RectangleEdge.RIGHT) {
result = new Rectangle2D.Double(area.getMaxX() - this.right, area.getY(), this.right, area.getHeight());
}
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof AxisSpace))
return false;
AxisSpace that = (AxisSpace)obj;
if (this.top != that.top)
return false;
if (this.bottom != that.bottom)
return false;
if (this.left != that.left)
return false;
if (this.right != that.right)
return false;
return true;
}
public int hashCode() {
int result = 23;
long l = Double.doubleToLongBits(this.top);
result = 37 * result + (int)(l ^ l >>> 32L);
l = Double.doubleToLongBits(this.bottom);
result = 37 * result + (int)(l ^ l >>> 32L);
l = Double.doubleToLongBits(this.left);
result = 37 * result + (int)(l ^ l >>> 32L);
l = Double.doubleToLongBits(this.right);
result = 37 * result + (int)(l ^ l >>> 32L);
return result;
}
public String toString() {
return super.toString() + "[left=" + this.left + ",right=" + this.right + ",top=" + this.top + ",bottom=" + this.bottom + "]";
}
}

View file

@ -0,0 +1,74 @@
package org.jfree.chart.axis;
import java.util.ArrayList;
import java.util.List;
import org.jfree.ui.RectangleEdge;
public class AxisState {
private double cursor;
private List ticks;
private double max;
public AxisState() {
this(0.0D);
}
public AxisState(double cursor) {
this.cursor = cursor;
this.ticks = new ArrayList();
}
public double getCursor() {
return this.cursor;
}
public void setCursor(double cursor) {
this.cursor = cursor;
}
public void moveCursor(double units, RectangleEdge edge) {
if (edge == RectangleEdge.TOP) {
cursorUp(units);
} else if (edge == RectangleEdge.BOTTOM) {
cursorDown(units);
} else if (edge == RectangleEdge.LEFT) {
cursorLeft(units);
} else if (edge == RectangleEdge.RIGHT) {
cursorRight(units);
}
}
public void cursorUp(double units) {
this.cursor -= units;
}
public void cursorDown(double units) {
this.cursor += units;
}
public void cursorLeft(double units) {
this.cursor -= units;
}
public void cursorRight(double units) {
this.cursor += units;
}
public List getTicks() {
return this.ticks;
}
public void setTicks(List ticks) {
this.ticks = ticks;
}
public double getMax() {
return this.max;
}
public void setMax(double max) {
this.max = max;
}
}

View file

@ -0,0 +1,45 @@
package org.jfree.chart.axis;
import java.io.ObjectStreamException;
import java.io.Serializable;
public final class CategoryAnchor implements Serializable {
private static final long serialVersionUID = -2604142742210173810L;
public static final CategoryAnchor START = new CategoryAnchor("CategoryAnchor.START");
public static final CategoryAnchor MIDDLE = new CategoryAnchor("CategoryAnchor.MIDDLE");
public static final CategoryAnchor END = new CategoryAnchor("CategoryAnchor.END");
private String name;
private CategoryAnchor(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof CategoryAnchor))
return false;
CategoryAnchor position = (CategoryAnchor)obj;
if (!this.name.equals(position.toString()))
return false;
return true;
}
private Object readResolve() throws ObjectStreamException {
if (equals(START))
return START;
if (equals(MIDDLE))
return MIDDLE;
if (equals(END))
return END;
return null;
}
}

View file

@ -0,0 +1,572 @@
package org.jfree.chart.axis;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jfree.chart.entity.CategoryLabelEntity;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.data.category.CategoryDataset;
import org.jfree.io.SerialUtilities;
import org.jfree.text.G2TextMeasurer;
import org.jfree.text.TextBlock;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.Size2D;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
import org.jfree.util.ShapeUtilities;
public class CategoryAxis extends Axis implements Cloneable, Serializable {
private static final long serialVersionUID = 5886554608114265863L;
public static final double DEFAULT_AXIS_MARGIN = 0.05D;
public static final double DEFAULT_CATEGORY_MARGIN = 0.2D;
private double lowerMargin;
private double upperMargin;
private double categoryMargin;
private int maximumCategoryLabelLines;
private float maximumCategoryLabelWidthRatio;
private int categoryLabelPositionOffset;
private CategoryLabelPositions categoryLabelPositions;
private Map tickLabelFontMap;
private transient Map tickLabelPaintMap;
private Map categoryLabelToolTips;
public CategoryAxis() {
this(null);
}
public CategoryAxis(String label) {
super(label);
this.lowerMargin = 0.05D;
this.upperMargin = 0.05D;
this.categoryMargin = 0.2D;
this.maximumCategoryLabelLines = 1;
this.maximumCategoryLabelWidthRatio = 0.0F;
setTickMarksVisible(false);
this.categoryLabelPositionOffset = 4;
this.categoryLabelPositions = CategoryLabelPositions.STANDARD;
this.tickLabelFontMap = new HashMap();
this.tickLabelPaintMap = new HashMap();
this.categoryLabelToolTips = new HashMap();
}
public double getLowerMargin() {
return this.lowerMargin;
}
public void setLowerMargin(double margin) {
this.lowerMargin = margin;
notifyListeners(new AxisChangeEvent(this));
}
public double getUpperMargin() {
return this.upperMargin;
}
public void setUpperMargin(double margin) {
this.upperMargin = margin;
notifyListeners(new AxisChangeEvent(this));
}
public double getCategoryMargin() {
return this.categoryMargin;
}
public void setCategoryMargin(double margin) {
this.categoryMargin = margin;
notifyListeners(new AxisChangeEvent(this));
}
public int getMaximumCategoryLabelLines() {
return this.maximumCategoryLabelLines;
}
public void setMaximumCategoryLabelLines(int lines) {
this.maximumCategoryLabelLines = lines;
notifyListeners(new AxisChangeEvent(this));
}
public float getMaximumCategoryLabelWidthRatio() {
return this.maximumCategoryLabelWidthRatio;
}
public void setMaximumCategoryLabelWidthRatio(float ratio) {
this.maximumCategoryLabelWidthRatio = ratio;
notifyListeners(new AxisChangeEvent(this));
}
public int getCategoryLabelPositionOffset() {
return this.categoryLabelPositionOffset;
}
public void setCategoryLabelPositionOffset(int offset) {
this.categoryLabelPositionOffset = offset;
notifyListeners(new AxisChangeEvent(this));
}
public CategoryLabelPositions getCategoryLabelPositions() {
return this.categoryLabelPositions;
}
public void setCategoryLabelPositions(CategoryLabelPositions positions) {
if (positions == null)
throw new IllegalArgumentException("Null 'positions' argument.");
this.categoryLabelPositions = positions;
notifyListeners(new AxisChangeEvent(this));
}
public Font getTickLabelFont(Comparable category) {
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
Font result = (Font)this.tickLabelFontMap.get(category);
if (result == null)
result = getTickLabelFont();
return result;
}
public void setTickLabelFont(Comparable category, Font font) {
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
if (font == null) {
this.tickLabelFontMap.remove(category);
} else {
this.tickLabelFontMap.put(category, font);
}
notifyListeners(new AxisChangeEvent(this));
}
public Paint getTickLabelPaint(Comparable category) {
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
Paint result = (Paint)this.tickLabelPaintMap.get(category);
if (result == null)
result = getTickLabelPaint();
return result;
}
public void setTickLabelPaint(Comparable category, Paint paint) {
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
if (paint == null) {
this.tickLabelPaintMap.remove(category);
} else {
this.tickLabelPaintMap.put(category, paint);
}
notifyListeners(new AxisChangeEvent(this));
}
public void addCategoryLabelToolTip(Comparable category, String tooltip) {
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
this.categoryLabelToolTips.put(category, tooltip);
notifyListeners(new AxisChangeEvent(this));
}
public String getCategoryLabelToolTip(Comparable category) {
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
return (String)this.categoryLabelToolTips.get(category);
}
public void removeCategoryLabelToolTip(Comparable category) {
if (category == null)
throw new IllegalArgumentException("Null 'category' argument.");
this.categoryLabelToolTips.remove(category);
notifyListeners(new AxisChangeEvent(this));
}
public void clearCategoryLabelToolTips() {
this.categoryLabelToolTips.clear();
notifyListeners(new AxisChangeEvent(this));
}
public double getCategoryJava2DCoordinate(CategoryAnchor anchor, int category, int categoryCount, Rectangle2D area, RectangleEdge edge) {
double result = 0.0D;
if (anchor == CategoryAnchor.START) {
result = getCategoryStart(category, categoryCount, area, edge);
} else if (anchor == CategoryAnchor.MIDDLE) {
result = getCategoryMiddle(category, categoryCount, area, edge);
} else if (anchor == CategoryAnchor.END) {
result = getCategoryEnd(category, categoryCount, area, edge);
}
return result;
}
public double getCategoryStart(int category, int categoryCount, Rectangle2D area, RectangleEdge edge) {
double result = 0.0D;
if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
result = area.getX() + area.getWidth() * getLowerMargin();
} else if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT) {
result = area.getMinY() + area.getHeight() * getLowerMargin();
}
double categorySize = calculateCategorySize(categoryCount, area, edge);
double categoryGapWidth = calculateCategoryGapSize(categoryCount, area, edge);
result += (double)category * (categorySize + categoryGapWidth);
return result;
}
public double getCategoryMiddle(int category, int categoryCount, Rectangle2D area, RectangleEdge edge) {
return getCategoryStart(category, categoryCount, area, edge) + calculateCategorySize(categoryCount, area, edge) / 2.0D;
}
public double getCategoryEnd(int category, int categoryCount, Rectangle2D area, RectangleEdge edge) {
return getCategoryStart(category, categoryCount, area, edge) + calculateCategorySize(categoryCount, area, edge);
}
public double getCategorySeriesMiddle(Comparable category, Comparable seriesKey, CategoryDataset dataset, double itemMargin, Rectangle2D area, RectangleEdge edge) {
int categoryIndex = dataset.getColumnIndex(category);
int categoryCount = dataset.getColumnCount();
int seriesIndex = dataset.getRowIndex(seriesKey);
int seriesCount = dataset.getRowCount();
double start = getCategoryStart(categoryIndex, categoryCount, area, edge);
double end = getCategoryEnd(categoryIndex, categoryCount, area, edge);
double width = end - start;
if (seriesCount == 1)
return start + width / 2.0D;
double gap = width * itemMargin / (double)(seriesCount - 1);
double ww = width * (1.0D - itemMargin) / (double)seriesCount;
return start + (double)seriesIndex * (ww + gap) + ww / 2.0D;
}
protected double calculateCategorySize(int categoryCount, Rectangle2D area, RectangleEdge edge) {
double result = 0.0D;
double available = 0.0D;
if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
available = area.getWidth();
} else if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT) {
available = area.getHeight();
}
if (categoryCount > 1) {
result = available * (1.0D - getLowerMargin() - getUpperMargin() - getCategoryMargin());
result /= (double)categoryCount;
} else {
result = available * (1.0D - getLowerMargin() - getUpperMargin());
}
return result;
}
protected double calculateCategoryGapSize(int categoryCount, Rectangle2D area, RectangleEdge edge) {
double result = 0.0D;
double available = 0.0D;
if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
available = area.getWidth();
} else if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT) {
available = area.getHeight();
}
if (categoryCount > 1)
result = available * getCategoryMargin() / (double)(categoryCount - 1);
return result;
}
public AxisSpace reserveSpace(Graphics2D g2, Plot plot, Rectangle2D plotArea, RectangleEdge edge, AxisSpace space) {
if (space == null)
space = new AxisSpace();
if (!isVisible())
return space;
double tickLabelHeight = 0.0D;
double tickLabelWidth = 0.0D;
if (isTickLabelsVisible()) {
g2.setFont(getTickLabelFont());
AxisState state = new AxisState();
refreshTicks(g2, state, plotArea, edge);
if (edge == RectangleEdge.TOP) {
tickLabelHeight = state.getMax();
} else if (edge == RectangleEdge.BOTTOM) {
tickLabelHeight = state.getMax();
} else if (edge == RectangleEdge.LEFT) {
tickLabelWidth = state.getMax();
} else if (edge == RectangleEdge.RIGHT) {
tickLabelWidth = state.getMax();
}
}
Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
double labelHeight = 0.0D;
double labelWidth = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
labelHeight = labelEnclosure.getHeight();
space.add(labelHeight + tickLabelHeight + (double)this.categoryLabelPositionOffset, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
labelWidth = labelEnclosure.getWidth();
space.add(labelWidth + tickLabelWidth + (double)this.categoryLabelPositionOffset, edge);
}
return space;
}
public void configure() {}
public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) {
if (!isVisible())
return new AxisState(cursor);
if (isAxisLineVisible())
drawAxisLine(g2, cursor, dataArea, edge);
AxisState state = new AxisState(cursor);
state = drawCategoryLabels(g2, plotArea, dataArea, edge, state, plotState);
state = drawLabel(getLabel(), g2, plotArea, dataArea, edge, state);
return state;
}
protected AxisState drawCategoryLabels(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge, AxisState state, PlotRenderingInfo plotState) {
return drawCategoryLabels(g2, dataArea, dataArea, edge, state, plotState);
}
protected AxisState drawCategoryLabels(Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, AxisState state, PlotRenderingInfo plotState) {
if (state == null)
throw new IllegalArgumentException("Null 'state' argument.");
if (isTickLabelsVisible()) {
List ticks = refreshTicks(g2, state, plotArea, edge);
state.setTicks(ticks);
int categoryIndex = 0;
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
CategoryTick tick = (CategoryTick)iterator.next();
g2.setFont(getTickLabelFont(tick.getCategory()));
g2.setPaint(getTickLabelPaint(tick.getCategory()));
CategoryLabelPosition position = this.categoryLabelPositions.getLabelPosition(edge);
double x0 = 0.0D;
double x1 = 0.0D;
double y0 = 0.0D;
double y1 = 0.0D;
if (edge == RectangleEdge.TOP) {
x0 = getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
x1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
y1 = state.getCursor() - (double)this.categoryLabelPositionOffset;
y0 = y1 - state.getMax();
} else if (edge == RectangleEdge.BOTTOM) {
x0 = getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
x1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
y0 = state.getCursor() + (double)this.categoryLabelPositionOffset;
y1 = y0 + state.getMax();
} else if (edge == RectangleEdge.LEFT) {
y0 = getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
y1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
x1 = state.getCursor() - (double)this.categoryLabelPositionOffset;
x0 = x1 - state.getMax();
} else if (edge == RectangleEdge.RIGHT) {
y0 = getCategoryStart(categoryIndex, ticks.size(), dataArea, edge);
y1 = getCategoryEnd(categoryIndex, ticks.size(), dataArea, edge);
x0 = state.getCursor() + (double)this.categoryLabelPositionOffset;
x1 = x0 - state.getMax();
}
Rectangle2D area = new Rectangle2D.Double(x0, y0, x1 - x0, y1 - y0);
Point2D anchorPoint = RectangleAnchor.coordinates(area, position.getCategoryAnchor());
TextBlock block = tick.getLabel();
block.draw(g2, (float)anchorPoint.getX(), (float)anchorPoint.getY(), position.getLabelAnchor(), (float)anchorPoint.getX(), (float)anchorPoint.getY(), position.getAngle());
Shape bounds = block.calculateBounds(g2, (float)anchorPoint.getX(), (float)anchorPoint.getY(), position.getLabelAnchor(), (float)anchorPoint.getX(), (float)anchorPoint.getY(), position.getAngle());
if (plotState != null && plotState.getOwner() != null) {
EntityCollection entities = plotState.getOwner().getEntityCollection();
if (entities != null) {
String tooltip = getCategoryLabelToolTip(tick.getCategory());
entities.add(new CategoryLabelEntity(tick.getCategory(), bounds, tooltip, null));
}
}
categoryIndex++;
}
if (edge.equals(RectangleEdge.TOP)) {
double h = state.getMax() + (double)this.categoryLabelPositionOffset;
state.cursorUp(h);
} else if (edge.equals(RectangleEdge.BOTTOM)) {
double h = state.getMax() + (double)this.categoryLabelPositionOffset;
state.cursorDown(h);
} else if (edge == RectangleEdge.LEFT) {
double w = state.getMax() + (double)this.categoryLabelPositionOffset;
state.cursorLeft(w);
} else if (edge == RectangleEdge.RIGHT) {
double w = state.getMax() + (double)this.categoryLabelPositionOffset;
state.cursorRight(w);
}
}
return state;
}
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List ticks = new ArrayList();
if (dataArea.getHeight() <= 0.0D || dataArea.getWidth() < 0.0D)
return ticks;
CategoryPlot plot = (CategoryPlot)getPlot();
List categories = plot.getCategoriesForAxis(this);
double max = 0.0D;
if (categories != null) {
CategoryLabelPosition position = this.categoryLabelPositions.getLabelPosition(edge);
float r = this.maximumCategoryLabelWidthRatio;
if ((double)r <= 0.0D)
r = position.getWidthRatio();
float l = 0.0F;
if (position.getWidthType() == CategoryLabelWidthType.CATEGORY) {
l = (float)calculateCategorySize(categories.size(), dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
l = (float)dataArea.getWidth();
} else {
l = (float)dataArea.getHeight();
}
int categoryIndex = 0;
Iterator iterator = categories.iterator();
while (iterator.hasNext()) {
Comparable category = (Comparable)iterator.next();
TextBlock label = createLabel(category, l * r, edge, g2);
if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
max = Math.max(max, calculateTextBlockHeight(label, position, g2));
} else if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT) {
max = Math.max(max, calculateTextBlockWidth(label, position, g2));
}
Tick tick = new CategoryTick(category, label, position.getLabelAnchor(), position.getRotationAnchor(), position.getAngle());
ticks.add(tick);
categoryIndex++;
}
}
state.setMax(max);
return ticks;
}
protected TextBlock createLabel(Comparable category, float width, RectangleEdge edge, Graphics2D g2) {
TextBlock label = TextUtilities.createTextBlock(category.toString(), getTickLabelFont(category), getTickLabelPaint(category), width, this.maximumCategoryLabelLines, new G2TextMeasurer(g2));
return label;
}
protected double calculateTextBlockWidth(TextBlock block, CategoryLabelPosition position, Graphics2D g2) {
RectangleInsets insets = getTickLabelInsets();
Size2D size = block.calculateDimensions(g2);
Rectangle2D box = new Rectangle2D.Double(0.0D, 0.0D, size.getWidth(), size.getHeight());
Shape rotatedBox = ShapeUtilities.rotateShape(box, position.getAngle(), 0.0F, 0.0F);
double w = rotatedBox.getBounds2D().getWidth() + insets.getTop() + insets.getBottom();
return w;
}
protected double calculateTextBlockHeight(TextBlock block, CategoryLabelPosition position, Graphics2D g2) {
RectangleInsets insets = getTickLabelInsets();
Size2D size = block.calculateDimensions(g2);
Rectangle2D box = new Rectangle2D.Double(0.0D, 0.0D, size.getWidth(), size.getHeight());
Shape rotatedBox = ShapeUtilities.rotateShape(box, position.getAngle(), 0.0F, 0.0F);
double h = rotatedBox.getBounds2D().getHeight() + insets.getTop() + insets.getBottom();
return h;
}
public Object clone() throws CloneNotSupportedException {
CategoryAxis clone = (CategoryAxis)super.clone();
clone.tickLabelFontMap = new HashMap(this.tickLabelFontMap);
clone.tickLabelPaintMap = new HashMap(this.tickLabelPaintMap);
clone.categoryLabelToolTips = new HashMap(this.categoryLabelToolTips);
return clone;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof CategoryAxis))
return false;
if (!super.equals(obj))
return false;
CategoryAxis that = (CategoryAxis)obj;
if (that.lowerMargin != this.lowerMargin)
return false;
if (that.upperMargin != this.upperMargin)
return false;
if (that.categoryMargin != this.categoryMargin)
return false;
if (that.maximumCategoryLabelWidthRatio != this.maximumCategoryLabelWidthRatio)
return false;
if (that.categoryLabelPositionOffset != this.categoryLabelPositionOffset)
return false;
if (!ObjectUtilities.equal(that.categoryLabelPositions, this.categoryLabelPositions))
return false;
if (!ObjectUtilities.equal(that.categoryLabelToolTips, this.categoryLabelToolTips))
return false;
if (!ObjectUtilities.equal(this.tickLabelFontMap, that.tickLabelFontMap))
return false;
if (!equalPaintMaps(this.tickLabelPaintMap, that.tickLabelPaintMap))
return false;
return true;
}
public int hashCode() {
if (getLabel() != null)
return getLabel().hashCode();
return 0;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
writePaintMap(this.tickLabelPaintMap, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.tickLabelPaintMap = readPaintMap(stream);
}
private Map readPaintMap(ObjectInputStream in) throws IOException, ClassNotFoundException {
boolean isNull = in.readBoolean();
if (isNull)
return null;
Map result = new HashMap();
int count = in.readInt();
for (int i = 0; i < count; i++) {
Comparable category = (Comparable)in.readObject();
Paint paint = SerialUtilities.readPaint(in);
result.put(category, paint);
}
return result;
}
private void writePaintMap(Map map, ObjectOutputStream out) throws IOException {
if (map == null) {
out.writeBoolean(true);
} else {
out.writeBoolean(false);
Set keys = map.keySet();
int count = keys.size();
out.writeInt(count);
Iterator iterator = keys.iterator();
while (iterator.hasNext()) {
Comparable key = (Comparable)iterator.next();
out.writeObject(key);
SerialUtilities.writePaint((Paint)map.get(key), out);
}
}
}
private boolean equalPaintMaps(Map map1, Map map2) {
if (map1.size() != map2.size())
return false;
Set entries = map1.entrySet();
Iterator iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry)iterator.next();
Paint p1 = (Paint)entry.getValue();
Paint p2 = (Paint)map2.get(entry.getKey());
if (!PaintUtilities.equal(p1, p2))
return false;
}
return true;
}
}

View file

@ -0,0 +1,80 @@
package org.jfree.chart.axis;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import org.jfree.chart.Effect3D;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.ui.RectangleEdge;
public class CategoryAxis3D extends CategoryAxis implements Cloneable, Serializable {
private static final long serialVersionUID = 4114732251353700972L;
public CategoryAxis3D() {
this(null);
}
public CategoryAxis3D(String label) {
super(label);
}
public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) {
if (!isVisible())
return new AxisState(cursor);
CategoryPlot plot = (CategoryPlot)getPlot();
Rectangle2D adjustedDataArea = new Rectangle2D.Double();
if (plot.getRenderer() instanceof Effect3D) {
Effect3D e3D = (Effect3D)plot.getRenderer();
double adjustedX = dataArea.getMinX();
double adjustedY = dataArea.getMinY();
double adjustedW = dataArea.getWidth() - e3D.getXOffset();
double adjustedH = dataArea.getHeight() - e3D.getYOffset();
if (edge == RectangleEdge.LEFT || edge == RectangleEdge.BOTTOM) {
adjustedY += e3D.getYOffset();
} else if (edge == RectangleEdge.RIGHT || edge == RectangleEdge.TOP) {
adjustedX += e3D.getXOffset();
}
adjustedDataArea.setRect(adjustedX, adjustedY, adjustedW, adjustedH);
} else {
adjustedDataArea.setRect(dataArea);
}
AxisState state = new AxisState(cursor);
state = drawCategoryLabels(g2, plotArea, adjustedDataArea, edge, state, plotState);
state = drawLabel(getLabel(), g2, plotArea, dataArea, edge, state);
return state;
}
public double getCategoryJava2DCoordinate(CategoryAnchor anchor, int category, int categoryCount, Rectangle2D area, RectangleEdge edge) {
double result = 0.0D;
Rectangle2D adjustedArea = area;
CategoryPlot plot = (CategoryPlot)getPlot();
CategoryItemRenderer renderer = plot.getRenderer();
if (renderer instanceof Effect3D) {
Effect3D e3D = (Effect3D)renderer;
double adjustedX = area.getMinX();
double adjustedY = area.getMinY();
double adjustedW = area.getWidth() - e3D.getXOffset();
double adjustedH = area.getHeight() - e3D.getYOffset();
if (edge == RectangleEdge.LEFT || edge == RectangleEdge.BOTTOM) {
adjustedY += e3D.getYOffset();
} else if (edge == RectangleEdge.RIGHT || edge == RectangleEdge.TOP) {
adjustedX += e3D.getXOffset();
}
adjustedArea = new Rectangle2D.Double(adjustedX, adjustedY, adjustedW, adjustedH);
}
if (anchor == CategoryAnchor.START) {
result = getCategoryStart(category, categoryCount, adjustedArea, edge);
} else if (anchor == CategoryAnchor.MIDDLE) {
result = getCategoryMiddle(category, categoryCount, adjustedArea, edge);
} else if (anchor == CategoryAnchor.END) {
result = getCategoryEnd(category, categoryCount, adjustedArea, edge);
}
return result;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

View file

@ -0,0 +1,104 @@
package org.jfree.chart.axis;
import java.io.Serializable;
import org.jfree.text.TextBlockAnchor;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.TextAnchor;
public class CategoryLabelPosition implements Serializable {
private static final long serialVersionUID = 5168681143844183864L;
private RectangleAnchor categoryAnchor;
private TextBlockAnchor labelAnchor;
private TextAnchor rotationAnchor;
private double angle;
private CategoryLabelWidthType widthType;
private float widthRatio;
public CategoryLabelPosition() {
this(RectangleAnchor.CENTER, TextBlockAnchor.BOTTOM_CENTER, TextAnchor.CENTER, 0.0D, CategoryLabelWidthType.CATEGORY, 0.95F);
}
public CategoryLabelPosition(RectangleAnchor categoryAnchor, TextBlockAnchor labelAnchor) {
this(categoryAnchor, labelAnchor, TextAnchor.CENTER, 0.0D, CategoryLabelWidthType.CATEGORY, 0.95F);
}
public CategoryLabelPosition(RectangleAnchor categoryAnchor, TextBlockAnchor labelAnchor, CategoryLabelWidthType widthType, float widthRatio) {
this(categoryAnchor, labelAnchor, TextAnchor.CENTER, 0.0D, widthType, widthRatio);
}
public CategoryLabelPosition(RectangleAnchor categoryAnchor, TextBlockAnchor labelAnchor, TextAnchor rotationAnchor, double angle, CategoryLabelWidthType widthType, float widthRatio) {
if (categoryAnchor == null)
throw new IllegalArgumentException("Null 'categoryAnchor' argument.");
if (labelAnchor == null)
throw new IllegalArgumentException("Null 'labelAnchor' argument.");
if (rotationAnchor == null)
throw new IllegalArgumentException("Null 'rotationAnchor' argument.");
if (widthType == null)
throw new IllegalArgumentException("Null 'widthType' argument.");
this.categoryAnchor = categoryAnchor;
this.labelAnchor = labelAnchor;
this.rotationAnchor = rotationAnchor;
this.angle = angle;
this.widthType = widthType;
this.widthRatio = widthRatio;
}
public RectangleAnchor getCategoryAnchor() {
return this.categoryAnchor;
}
public TextBlockAnchor getLabelAnchor() {
return this.labelAnchor;
}
public TextAnchor getRotationAnchor() {
return this.rotationAnchor;
}
public double getAngle() {
return this.angle;
}
public CategoryLabelWidthType getWidthType() {
return this.widthType;
}
public float getWidthRatio() {
return this.widthRatio;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof CategoryLabelPosition))
return false;
CategoryLabelPosition that = (CategoryLabelPosition)obj;
if (!this.categoryAnchor.equals(that.categoryAnchor))
return false;
if (!this.labelAnchor.equals(that.labelAnchor))
return false;
if (!this.rotationAnchor.equals(that.rotationAnchor))
return false;
if (this.angle != that.angle)
return false;
if (this.widthType != that.widthType)
return false;
if (this.widthRatio != that.widthRatio)
return false;
return true;
}
public int hashCode() {
int result = 19;
result = 37 * result + this.categoryAnchor.hashCode();
result = 37 * result + this.labelAnchor.hashCode();
result = 37 * result + this.rotationAnchor.hashCode();
return result;
}
}

View file

@ -0,0 +1,131 @@
package org.jfree.chart.axis;
import java.io.Serializable;
import org.jfree.text.TextBlockAnchor;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;
public class CategoryLabelPositions implements Serializable {
private static final long serialVersionUID = -8999557901920364580L;
public static final CategoryLabelPositions STANDARD = new CategoryLabelPositions(new CategoryLabelPosition(RectangleAnchor.BOTTOM, TextBlockAnchor.BOTTOM_CENTER), new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.TOP_CENTER), new CategoryLabelPosition(RectangleAnchor.RIGHT, TextBlockAnchor.CENTER_RIGHT, CategoryLabelWidthType.RANGE, 0.3F), new CategoryLabelPosition(RectangleAnchor.LEFT, TextBlockAnchor.CENTER_LEFT, CategoryLabelWidthType.RANGE, 0.3F));
public static final CategoryLabelPositions UP_90 = new CategoryLabelPositions(new CategoryLabelPosition(RectangleAnchor.BOTTOM, TextBlockAnchor.CENTER_LEFT, TextAnchor.CENTER_LEFT, -1.5707963267948966D, CategoryLabelWidthType.RANGE, 0.3F), new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER_RIGHT, TextAnchor.CENTER_RIGHT, -1.5707963267948966D, CategoryLabelWidthType.RANGE, 0.3F), new CategoryLabelPosition(RectangleAnchor.RIGHT, TextBlockAnchor.BOTTOM_CENTER, TextAnchor.BOTTOM_CENTER, -1.5707963267948966D, CategoryLabelWidthType.CATEGORY, 0.9F), new CategoryLabelPosition(RectangleAnchor.LEFT, TextBlockAnchor.TOP_CENTER, TextAnchor.TOP_CENTER, -1.5707963267948966D, CategoryLabelWidthType.CATEGORY, 0.9F));
public static final CategoryLabelPositions DOWN_90 = new CategoryLabelPositions(new CategoryLabelPosition(RectangleAnchor.BOTTOM, TextBlockAnchor.CENTER_RIGHT, TextAnchor.CENTER_RIGHT, 1.5707963267948966D, CategoryLabelWidthType.RANGE, 0.3F), new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.CENTER_LEFT, TextAnchor.CENTER_LEFT, 1.5707963267948966D, CategoryLabelWidthType.RANGE, 0.3F), new CategoryLabelPosition(RectangleAnchor.RIGHT, TextBlockAnchor.TOP_CENTER, TextAnchor.TOP_CENTER, 1.5707963267948966D, CategoryLabelWidthType.CATEGORY, 0.9F), new CategoryLabelPosition(RectangleAnchor.LEFT, TextBlockAnchor.BOTTOM_CENTER, TextAnchor.BOTTOM_CENTER, 1.5707963267948966D, CategoryLabelWidthType.CATEGORY, 0.9F));
public static final CategoryLabelPositions UP_45 = createUpRotationLabelPositions(0.7853981633974483D);
public static final CategoryLabelPositions DOWN_45 = createDownRotationLabelPositions(0.7853981633974483D);
private CategoryLabelPosition positionForAxisAtTop;
private CategoryLabelPosition positionForAxisAtBottom;
private CategoryLabelPosition positionForAxisAtLeft;
private CategoryLabelPosition positionForAxisAtRight;
public static CategoryLabelPositions createUpRotationLabelPositions(double angle) {
return new CategoryLabelPositions(new CategoryLabelPosition(RectangleAnchor.BOTTOM, TextBlockAnchor.BOTTOM_LEFT, TextAnchor.BOTTOM_LEFT, -angle, CategoryLabelWidthType.RANGE, 0.5F), new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.TOP_RIGHT, TextAnchor.TOP_RIGHT, -angle, CategoryLabelWidthType.RANGE, 0.5F), new CategoryLabelPosition(RectangleAnchor.RIGHT, TextBlockAnchor.BOTTOM_RIGHT, TextAnchor.BOTTOM_RIGHT, -angle, CategoryLabelWidthType.RANGE, 0.5F), new CategoryLabelPosition(RectangleAnchor.LEFT, TextBlockAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, -angle, CategoryLabelWidthType.RANGE, 0.5F));
}
public static CategoryLabelPositions createDownRotationLabelPositions(double angle) {
return new CategoryLabelPositions(new CategoryLabelPosition(RectangleAnchor.BOTTOM, TextBlockAnchor.BOTTOM_RIGHT, TextAnchor.BOTTOM_RIGHT, angle, CategoryLabelWidthType.RANGE, 0.5F), new CategoryLabelPosition(RectangleAnchor.TOP, TextBlockAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, angle, CategoryLabelWidthType.RANGE, 0.5F), new CategoryLabelPosition(RectangleAnchor.RIGHT, TextBlockAnchor.TOP_RIGHT, TextAnchor.TOP_RIGHT, angle, CategoryLabelWidthType.RANGE, 0.5F), new CategoryLabelPosition(RectangleAnchor.LEFT, TextBlockAnchor.BOTTOM_LEFT, TextAnchor.BOTTOM_LEFT, angle, CategoryLabelWidthType.RANGE, 0.5F));
}
public CategoryLabelPositions() {
this.positionForAxisAtTop = new CategoryLabelPosition();
this.positionForAxisAtBottom = new CategoryLabelPosition();
this.positionForAxisAtLeft = new CategoryLabelPosition();
this.positionForAxisAtRight = new CategoryLabelPosition();
}
public CategoryLabelPositions(CategoryLabelPosition top, CategoryLabelPosition bottom, CategoryLabelPosition left, CategoryLabelPosition right) {
if (top == null)
throw new IllegalArgumentException("Null 'top' argument.");
if (bottom == null)
throw new IllegalArgumentException("Null 'bottom' argument.");
if (left == null)
throw new IllegalArgumentException("Null 'left' argument.");
if (right == null)
throw new IllegalArgumentException("Null 'right' argument.");
this.positionForAxisAtTop = top;
this.positionForAxisAtBottom = bottom;
this.positionForAxisAtLeft = left;
this.positionForAxisAtRight = right;
}
public CategoryLabelPosition getLabelPosition(RectangleEdge edge) {
CategoryLabelPosition result = null;
if (edge == RectangleEdge.TOP) {
result = this.positionForAxisAtTop;
} else if (edge == RectangleEdge.BOTTOM) {
result = this.positionForAxisAtBottom;
} else if (edge == RectangleEdge.LEFT) {
result = this.positionForAxisAtLeft;
} else if (edge == RectangleEdge.RIGHT) {
result = this.positionForAxisAtRight;
}
return result;
}
public static CategoryLabelPositions replaceTopPosition(CategoryLabelPositions base, CategoryLabelPosition top) {
if (base == null)
throw new IllegalArgumentException("Null 'base' argument.");
if (top == null)
throw new IllegalArgumentException("Null 'top' argument.");
return new CategoryLabelPositions(top, base.getLabelPosition(RectangleEdge.BOTTOM), base.getLabelPosition(RectangleEdge.LEFT), base.getLabelPosition(RectangleEdge.RIGHT));
}
public static CategoryLabelPositions replaceBottomPosition(CategoryLabelPositions base, CategoryLabelPosition bottom) {
if (base == null)
throw new IllegalArgumentException("Null 'base' argument.");
if (bottom == null)
throw new IllegalArgumentException("Null 'bottom' argument.");
return new CategoryLabelPositions(base.getLabelPosition(RectangleEdge.TOP), bottom, base.getLabelPosition(RectangleEdge.LEFT), base.getLabelPosition(RectangleEdge.RIGHT));
}
public static CategoryLabelPositions replaceLeftPosition(CategoryLabelPositions base, CategoryLabelPosition left) {
if (base == null)
throw new IllegalArgumentException("Null 'base' argument.");
if (left == null)
throw new IllegalArgumentException("Null 'left' argument.");
return new CategoryLabelPositions(base.getLabelPosition(RectangleEdge.TOP), base.getLabelPosition(RectangleEdge.BOTTOM), left, base.getLabelPosition(RectangleEdge.RIGHT));
}
public static CategoryLabelPositions replaceRightPosition(CategoryLabelPositions base, CategoryLabelPosition right) {
if (base == null)
throw new IllegalArgumentException("Null 'base' argument.");
if (right == null)
throw new IllegalArgumentException("Null 'right' argument.");
return new CategoryLabelPositions(base.getLabelPosition(RectangleEdge.TOP), base.getLabelPosition(RectangleEdge.BOTTOM), base.getLabelPosition(RectangleEdge.LEFT), right);
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof CategoryLabelPositions))
return false;
CategoryLabelPositions that = (CategoryLabelPositions)obj;
if (!this.positionForAxisAtTop.equals(that.positionForAxisAtTop))
return false;
if (!this.positionForAxisAtBottom.equals(that.positionForAxisAtBottom))
return false;
if (!this.positionForAxisAtLeft.equals(that.positionForAxisAtLeft))
return false;
if (!this.positionForAxisAtRight.equals(that.positionForAxisAtRight))
return false;
return true;
}
public int hashCode() {
int result = 19;
result = 37 * result + this.positionForAxisAtTop.hashCode();
result = 37 * result + this.positionForAxisAtBottom.hashCode();
result = 37 * result + this.positionForAxisAtLeft.hashCode();
result = 37 * result + this.positionForAxisAtRight.hashCode();
return result;
}
}

View file

@ -0,0 +1,43 @@
package org.jfree.chart.axis;
import java.io.ObjectStreamException;
import java.io.Serializable;
public final class CategoryLabelWidthType implements Serializable {
private static final long serialVersionUID = -6976024792582949656L;
public static final CategoryLabelWidthType CATEGORY = new CategoryLabelWidthType("CategoryLabelWidthType.CATEGORY");
public static final CategoryLabelWidthType RANGE = new CategoryLabelWidthType("CategoryLabelWidthType.RANGE");
private String name;
private CategoryLabelWidthType(String name) {
if (name == null)
throw new IllegalArgumentException("Null 'name' argument.");
this.name = name;
}
public String toString() {
return this.name;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof CategoryLabelWidthType))
return false;
CategoryLabelWidthType t = (CategoryLabelWidthType)obj;
if (!this.name.equals(t.toString()))
return false;
return true;
}
private Object readResolve() throws ObjectStreamException {
if (equals(CATEGORY))
return CATEGORY;
if (equals(RANGE))
return RANGE;
return null;
}
}

View file

@ -0,0 +1,57 @@
package org.jfree.chart.axis;
import org.jfree.text.TextBlock;
import org.jfree.text.TextBlockAnchor;
import org.jfree.ui.TextAnchor;
import org.jfree.util.ObjectUtilities;
public class CategoryTick extends Tick {
private Comparable category;
private TextBlock label;
private TextBlockAnchor labelAnchor;
public CategoryTick(Comparable category, TextBlock label, TextBlockAnchor labelAnchor, TextAnchor rotationAnchor, double angle) {
super("", TextAnchor.CENTER, rotationAnchor, angle);
this.category = category;
this.label = label;
this.labelAnchor = labelAnchor;
}
public Comparable getCategory() {
return this.category;
}
public TextBlock getLabel() {
return this.label;
}
public TextBlockAnchor getLabelAnchor() {
return this.labelAnchor;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof CategoryTick && super.equals(obj)) {
CategoryTick that = (CategoryTick)obj;
if (!ObjectUtilities.equal(this.category, that.category))
return false;
if (!ObjectUtilities.equal(this.label, that.label))
return false;
if (!ObjectUtilities.equal(this.labelAnchor, that.labelAnchor))
return false;
return true;
}
return false;
}
public int hashCode() {
int result = 41;
result = 37 * result + this.category.hashCode();
result = 37 * result + this.label.hashCode();
result = 37 * result + this.labelAnchor.hashCode();
return result;
}
}

View file

@ -0,0 +1,217 @@
package org.jfree.chart.axis;
import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import org.jfree.chart.plot.ColorPalette;
import org.jfree.chart.plot.ContourPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.RainbowPalette;
import org.jfree.ui.RectangleEdge;
public class ColorBar implements Cloneable, Serializable {
private static final long serialVersionUID = -2101776212647268103L;
public static final int DEFAULT_COLORBAR_THICKNESS = 0;
public static final double DEFAULT_COLORBAR_THICKNESS_PERCENT = 0.1D;
public static final int DEFAULT_OUTERGAP = 2;
private ValueAxis axis;
private int colorBarThickness = 0;
private double colorBarThicknessPercent = 0.1D;
private ColorPalette colorPalette = null;
private int colorBarLength = 0;
private int outerGap;
public ColorBar(String label) {
NumberAxis a = new NumberAxis(label);
a.setAutoRangeIncludesZero(false);
this.axis = a;
this.axis.setLowerMargin(0.0D);
this.axis.setUpperMargin(0.0D);
this.colorPalette = new RainbowPalette();
this.colorBarThickness = 0;
this.colorBarThicknessPercent = 0.1D;
this.outerGap = 2;
this.colorPalette.setMinZ(this.axis.getRange().getLowerBound());
this.colorPalette.setMaxZ(this.axis.getRange().getUpperBound());
}
public void configure(ContourPlot plot) {
double minZ = plot.getDataset().getMinZValue();
double maxZ = plot.getDataset().getMaxZValue();
setMinimumValue(minZ);
setMaximumValue(maxZ);
}
public ValueAxis getAxis() {
return this.axis;
}
public void setAxis(ValueAxis axis) {
this.axis = axis;
}
public void autoAdjustRange() {
this.axis.autoAdjustRange();
this.colorPalette.setMinZ(this.axis.getLowerBound());
this.colorPalette.setMaxZ(this.axis.getUpperBound());
}
public double draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, Rectangle2D reservedArea, RectangleEdge edge) {
Rectangle2D colorBarArea = null;
double thickness = calculateBarThickness(dataArea, edge);
if (this.colorBarThickness > 0)
thickness = (double)this.colorBarThickness;
double length = 0.0D;
if (RectangleEdge.isLeftOrRight(edge)) {
length = dataArea.getHeight();
} else {
length = dataArea.getWidth();
}
if (this.colorBarLength > 0)
length = (double)this.colorBarLength;
if (edge == RectangleEdge.BOTTOM) {
colorBarArea = new Rectangle2D.Double(dataArea.getX(), plotArea.getMaxY() + (double)this.outerGap, length, thickness);
} else if (edge == RectangleEdge.TOP) {
colorBarArea = new Rectangle2D.Double(dataArea.getX(), reservedArea.getMinY() + (double)this.outerGap, length, thickness);
} else if (edge == RectangleEdge.LEFT) {
colorBarArea = new Rectangle2D.Double(plotArea.getX() - thickness - (double)this.outerGap, dataArea.getMinY(), thickness, length);
} else if (edge == RectangleEdge.RIGHT) {
colorBarArea = new Rectangle2D.Double(plotArea.getMaxX() + (double)this.outerGap, dataArea.getMinY(), thickness, length);
}
this.axis.refreshTicks(g2, new AxisState(), colorBarArea, edge);
drawColorBar(g2, colorBarArea, edge);
AxisState state = null;
if (edge == RectangleEdge.TOP) {
cursor = colorBarArea.getMinY();
state = this.axis.draw(g2, cursor, reservedArea, colorBarArea, RectangleEdge.TOP, null);
} else if (edge == RectangleEdge.BOTTOM) {
cursor = colorBarArea.getMaxY();
state = this.axis.draw(g2, cursor, reservedArea, colorBarArea, RectangleEdge.BOTTOM, null);
} else if (edge == RectangleEdge.LEFT) {
cursor = colorBarArea.getMinX();
state = this.axis.draw(g2, cursor, reservedArea, colorBarArea, RectangleEdge.LEFT, null);
} else if (edge == RectangleEdge.RIGHT) {
cursor = colorBarArea.getMaxX();
state = this.axis.draw(g2, cursor, reservedArea, colorBarArea, RectangleEdge.RIGHT, null);
}
return state.getCursor();
}
public void drawColorBar(Graphics2D g2, Rectangle2D colorBarArea, RectangleEdge edge) {
Object antiAlias = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
Stroke strokeSaved = g2.getStroke();
g2.setStroke(new BasicStroke(1.0F));
if (RectangleEdge.isTopOrBottom(edge)) {
double y1 = colorBarArea.getY();
double y2 = colorBarArea.getMaxY();
double xx = colorBarArea.getX();
Line2D line = new Line2D.Double();
while (xx <= colorBarArea.getMaxX()) {
double value = this.axis.java2DToValue(xx, colorBarArea, edge);
line.setLine(xx, y1, xx, y2);
g2.setPaint(getPaint(value));
g2.draw(line);
xx++;
}
} else {
double y1 = colorBarArea.getX();
double y2 = colorBarArea.getMaxX();
double xx = colorBarArea.getY();
Line2D line = new Line2D.Double();
while (xx <= colorBarArea.getMaxY()) {
double value = this.axis.java2DToValue(xx, colorBarArea, edge);
line.setLine(y1, xx, y2, xx);
g2.setPaint(getPaint(value));
g2.draw(line);
xx++;
}
}
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAlias);
g2.setStroke(strokeSaved);
}
public ColorPalette getColorPalette() {
return this.colorPalette;
}
public Paint getPaint(double value) {
return this.colorPalette.getPaint(value);
}
public void setColorPalette(ColorPalette palette) {
this.colorPalette = palette;
}
public void setMaximumValue(double value) {
this.colorPalette.setMaxZ(value);
this.axis.setUpperBound(value);
}
public void setMinimumValue(double value) {
this.colorPalette.setMinZ(value);
this.axis.setLowerBound(value);
}
public AxisSpace reserveSpace(Graphics2D g2, Plot plot, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, AxisSpace space) {
AxisSpace result = this.axis.reserveSpace(g2, plot, plotArea, edge, space);
double thickness = calculateBarThickness(dataArea, edge);
result.add(thickness + (double)(2 * this.outerGap), edge);
return result;
}
private double calculateBarThickness(Rectangle2D plotArea, RectangleEdge edge) {
double result = 0.0D;
if (RectangleEdge.isLeftOrRight(edge)) {
result = plotArea.getWidth() * this.colorBarThicknessPercent;
} else {
result = plotArea.getHeight() * this.colorBarThicknessPercent;
}
return result;
}
public Object clone() throws CloneNotSupportedException {
ColorBar clone = (ColorBar)super.clone();
clone.axis = (ValueAxis)this.axis.clone();
return clone;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof ColorBar))
return false;
ColorBar that = (ColorBar)obj;
if (!this.axis.equals(that.axis))
return false;
if (this.colorBarThickness != that.colorBarThickness)
return false;
if (this.colorBarThicknessPercent != that.colorBarThicknessPercent)
return false;
if (!this.colorPalette.equals(that.colorPalette))
return false;
if (this.colorBarLength != that.colorBarLength)
return false;
if (this.outerGap != that.outerGap)
return false;
return true;
}
public int hashCode() {
return this.axis.hashCode();
}
}

View file

@ -0,0 +1,39 @@
package org.jfree.chart.axis;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
public class CompassFormat extends NumberFormat {
private static final String N = "N";
private static final String E = "E";
private static final String S = "S";
private static final String W = "W";
public static final String[] DIRECTIONS = new String[] {
"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW",
"SW", "WSW", "W", "WNW", "NW", "NNW", "N" };
public String getDirectionCode(double direction) {
direction %= 360.0D;
if (direction < 0.0D)
direction += 360.0D;
int index = ((int)Math.floor(direction / 11.25D) + 1) / 2;
return DIRECTIONS[index];
}
public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
return toAppendTo.append(getDirectionCode(number));
}
public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
return toAppendTo.append(getDirectionCode((double)number));
}
public Number parse(String source, ParsePosition parsePosition) {
return null;
}
}

View file

@ -0,0 +1,539 @@
package org.jfree.chart.axis;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.data.Range;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
public class CyclicNumberAxis extends NumberAxis {
static final long serialVersionUID = -7514160997164582554L;
public static Stroke DEFAULT_ADVANCE_LINE_STROKE = new BasicStroke(1.0F);
public static final Paint DEFAULT_ADVANCE_LINE_PAINT = Color.gray;
protected double offset;
protected double period;
protected boolean boundMappedToLastCycle;
protected boolean advanceLineVisible;
protected transient Stroke advanceLineStroke = DEFAULT_ADVANCE_LINE_STROKE;
protected transient Paint advanceLinePaint;
private transient boolean internalMarkerWhenTicksOverlap;
private transient Tick internalMarkerCycleBoundTick;
public CyclicNumberAxis(double period) {
this(period, 0.0D);
}
public CyclicNumberAxis(double period, double offset) {
this(period, offset, null);
}
public CyclicNumberAxis(double period, String label) {
this(0.0D, period, label);
}
public CyclicNumberAxis(double period, double offset, String label) {
super(label);
this.period = period;
this.offset = offset;
setFixedAutoRange(period);
this.advanceLineVisible = true;
this.advanceLinePaint = DEFAULT_ADVANCE_LINE_PAINT;
}
public boolean isAdvanceLineVisible() {
return this.advanceLineVisible;
}
public void setAdvanceLineVisible(boolean visible) {
this.advanceLineVisible = visible;
}
public Paint getAdvanceLinePaint() {
return this.advanceLinePaint;
}
public void setAdvanceLinePaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.advanceLinePaint = paint;
}
public Stroke getAdvanceLineStroke() {
return this.advanceLineStroke;
}
public void setAdvanceLineStroke(Stroke stroke) {
if (stroke == null)
throw new IllegalArgumentException("Null 'stroke' argument.");
this.advanceLineStroke = stroke;
}
public boolean isBoundMappedToLastCycle() {
return this.boundMappedToLastCycle;
}
public void setBoundMappedToLastCycle(boolean boundMappedToLastCycle) {
this.boundMappedToLastCycle = boundMappedToLastCycle;
}
protected void selectHorizontalAutoTickUnit(Graphics2D g2, Rectangle2D drawArea, Rectangle2D dataArea, RectangleEdge edge) {
double tickLabelWidth = estimateMaximumTickLabelWidth(g2, getTickUnit());
double n = getRange().getLength() * tickLabelWidth / dataArea.getWidth();
setTickUnit((NumberTickUnit)getStandardTickUnits().getCeilingTickUnit(n), false, false);
}
protected void selectVerticalAutoTickUnit(Graphics2D g2, Rectangle2D drawArea, Rectangle2D dataArea, RectangleEdge edge) {
double tickLabelWidth = estimateMaximumTickLabelWidth(g2, getTickUnit());
double n = getRange().getLength() * tickLabelWidth / dataArea.getHeight();
setTickUnit((NumberTickUnit)getStandardTickUnits().getCeilingTickUnit(n), false, false);
}
protected static class CycleBoundTick extends NumberTick {
public boolean mapToLastCycle;
public CycleBoundTick(boolean mapToLastCycle, Number number, String label, TextAnchor textAnchor, TextAnchor rotationAnchor, double angle) {
super(number, label, textAnchor, rotationAnchor, angle);
this.mapToLastCycle = mapToLastCycle;
}
}
protected float[] calculateAnchorPoint(ValueTick tick, double cursor, Rectangle2D dataArea, RectangleEdge edge) {
if (tick instanceof CycleBoundTick) {
boolean mapsav = this.boundMappedToLastCycle;
this.boundMappedToLastCycle = ((CycleBoundTick)tick).mapToLastCycle;
float[] ret = super.calculateAnchorPoint(tick, cursor, dataArea, edge);
this.boundMappedToLastCycle = mapsav;
return ret;
}
return super.calculateAnchorPoint(tick, cursor, dataArea, edge);
}
protected List refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List result = new ArrayList();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection())
selectAutoTickUnit(g2, dataArea, edge);
double unit = getTickUnit().getSize();
double cycleBound = getCycleBound();
double currentTickValue = Math.ceil(cycleBound / unit) * unit;
double upperValue = getRange().getUpperBound();
boolean cycled = false;
boolean boundMapping = this.boundMappedToLastCycle;
this.boundMappedToLastCycle = false;
CycleBoundTick lastTick = null;
float lastX = 0.0F;
if (upperValue == cycleBound) {
currentTickValue = calculateLowestVisibleTickValue();
cycled = true;
this.boundMappedToLastCycle = true;
}
while (currentTickValue <= upperValue) {
String tickLabel;
boolean cyclenow = false;
if (currentTickValue + unit > upperValue && !cycled)
cyclenow = true;
double xx = valueToJava2D(currentTickValue, dataArea, edge);
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
} else {
tickLabel = getTickUnit().valueToString(currentTickValue);
}
float x = (float)xx;
TextAnchor anchor = null;
TextAnchor rotationAnchor = null;
double angle = 0.0D;
if (isVerticalTickLabels()) {
if (edge == RectangleEdge.TOP) {
angle = 1.5707963267948966D;
} else {
angle = -1.5707963267948966D;
}
anchor = TextAnchor.CENTER_RIGHT;
if (lastTick != null && lastX == x && currentTickValue != cycleBound) {
anchor = isInverted() ? TextAnchor.TOP_RIGHT : TextAnchor.BOTTOM_RIGHT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT : TextAnchor.TOP_RIGHT;
}
rotationAnchor = anchor;
} else if (edge == RectangleEdge.TOP) {
anchor = TextAnchor.BOTTOM_CENTER;
if (lastTick != null && lastX == x && currentTickValue != cycleBound) {
anchor = isInverted() ? TextAnchor.BOTTOM_LEFT : TextAnchor.BOTTOM_RIGHT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT : TextAnchor.BOTTOM_LEFT;
}
rotationAnchor = anchor;
} else {
anchor = TextAnchor.TOP_CENTER;
if (lastTick != null && lastX == x && currentTickValue != cycleBound) {
anchor = isInverted() ? TextAnchor.TOP_LEFT : TextAnchor.TOP_RIGHT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.TOP_RIGHT : TextAnchor.TOP_LEFT;
}
rotationAnchor = anchor;
}
CycleBoundTick tick = new CycleBoundTick(this.boundMappedToLastCycle, new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle);
if (currentTickValue == cycleBound)
this.internalMarkerCycleBoundTick = tick;
result.add(tick);
lastTick = tick;
lastX = x;
currentTickValue += unit;
if (cyclenow) {
currentTickValue = calculateLowestVisibleTickValue();
upperValue = cycleBound;
cycled = true;
this.boundMappedToLastCycle = true;
}
}
this.boundMappedToLastCycle = boundMapping;
return result;
}
protected List refreshVerticalTicks(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List result = new ArrayList();
result.clear();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection())
selectAutoTickUnit(g2, dataArea, edge);
double unit = getTickUnit().getSize();
double cycleBound = getCycleBound();
double currentTickValue = Math.ceil(cycleBound / unit) * unit;
double upperValue = getRange().getUpperBound();
boolean cycled = false;
boolean boundMapping = this.boundMappedToLastCycle;
this.boundMappedToLastCycle = true;
NumberTick lastTick = null;
float lastY = 0.0F;
if (upperValue == cycleBound) {
currentTickValue = calculateLowestVisibleTickValue();
cycled = true;
this.boundMappedToLastCycle = true;
}
while (currentTickValue <= upperValue) {
String tickLabel;
boolean cyclenow = false;
if (currentTickValue + unit > upperValue && !cycled)
cyclenow = true;
double yy = valueToJava2D(currentTickValue, dataArea, edge);
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
} else {
tickLabel = getTickUnit().valueToString(currentTickValue);
}
float y = (float)yy;
TextAnchor anchor = null;
TextAnchor rotationAnchor = null;
double angle = 0.0D;
if (isVerticalTickLabels()) {
if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.BOTTOM_CENTER;
if (lastTick != null && lastY == y && currentTickValue != cycleBound) {
anchor = isInverted() ? TextAnchor.BOTTOM_LEFT : TextAnchor.BOTTOM_RIGHT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT : TextAnchor.BOTTOM_LEFT;
}
rotationAnchor = anchor;
angle = -1.5707963267948966D;
} else {
anchor = TextAnchor.BOTTOM_CENTER;
if (lastTick != null && lastY == y && currentTickValue != cycleBound) {
anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT : TextAnchor.BOTTOM_LEFT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.BOTTOM_LEFT : TextAnchor.BOTTOM_RIGHT;
}
rotationAnchor = anchor;
angle = 1.5707963267948966D;
}
} else if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.CENTER_RIGHT;
if (lastTick != null && lastY == y && currentTickValue != cycleBound) {
anchor = isInverted() ? TextAnchor.BOTTOM_RIGHT : TextAnchor.TOP_RIGHT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.TOP_RIGHT : TextAnchor.BOTTOM_RIGHT;
}
rotationAnchor = anchor;
} else {
anchor = TextAnchor.CENTER_LEFT;
if (lastTick != null && lastY == y && currentTickValue != cycleBound) {
anchor = isInverted() ? TextAnchor.BOTTOM_LEFT : TextAnchor.TOP_LEFT;
result.remove(result.size() - 1);
result.add(new CycleBoundTick(this.boundMappedToLastCycle, lastTick.getNumber(), lastTick.getText(), anchor, anchor, lastTick.getAngle()));
this.internalMarkerWhenTicksOverlap = true;
anchor = isInverted() ? TextAnchor.TOP_LEFT : TextAnchor.BOTTOM_LEFT;
}
rotationAnchor = anchor;
}
CycleBoundTick tick = new CycleBoundTick(this.boundMappedToLastCycle, new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle);
if (currentTickValue == cycleBound)
this.internalMarkerCycleBoundTick = tick;
result.add(tick);
lastTick = tick;
lastY = y;
if (currentTickValue == cycleBound)
this.internalMarkerCycleBoundTick = tick;
currentTickValue += unit;
if (cyclenow) {
currentTickValue = calculateLowestVisibleTickValue();
upperValue = cycleBound;
cycled = true;
this.boundMappedToLastCycle = false;
}
}
this.boundMappedToLastCycle = boundMapping;
return result;
}
public double java2DToValue(double java2DValue, Rectangle2D dataArea, RectangleEdge edge) {
Range range = getRange();
double vmax = range.getUpperBound();
double vp = getCycleBound();
double jmin = 0.0D;
double jmax = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
jmin = dataArea.getMinX();
jmax = dataArea.getMaxX();
} else if (RectangleEdge.isLeftOrRight(edge)) {
jmin = dataArea.getMaxY();
jmax = dataArea.getMinY();
}
if (isInverted()) {
double d = jmax - (vmax - vp) * (jmax - jmin) / this.period;
if (java2DValue >= d)
return vp + (jmax - java2DValue) * this.period / (jmax - jmin);
return vp - (java2DValue - jmin) * this.period / (jmax - jmin);
}
double jbreak = (vmax - vp) * (jmax - jmin) / this.period + jmin;
if (java2DValue <= jbreak)
return vp + (java2DValue - jmin) * this.period / (jmax - jmin);
return vp - (jmax - java2DValue) * this.period / (jmax - jmin);
}
public double valueToJava2D(double value, Rectangle2D dataArea, RectangleEdge edge) {
Range range = getRange();
double vmin = range.getLowerBound();
double vmax = range.getUpperBound();
double vp = getCycleBound();
if (value < vmin || value > vmax)
return Double.NaN;
double jmin = 0.0D;
double jmax = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
jmin = dataArea.getMinX();
jmax = dataArea.getMaxX();
} else if (RectangleEdge.isLeftOrRight(edge)) {
jmax = dataArea.getMinY();
jmin = dataArea.getMaxY();
}
if (isInverted()) {
if (value == vp)
return this.boundMappedToLastCycle ? jmin : jmax;
if (value > vp)
return jmax - (value - vp) * (jmax - jmin) / this.period;
return jmin + (vp - value) * (jmax - jmin) / this.period;
}
if (value == vp)
return this.boundMappedToLastCycle ? jmax : jmin;
if (value >= vp)
return jmin + (value - vp) * (jmax - jmin) / this.period;
return jmax - (vp - value) * (jmax - jmin) / this.period;
}
public void centerRange(double value) {
setRange(value - this.period / 2.0D, value + this.period / 2.0D);
}
public void setAutoRangeMinimumSize(double size, boolean notify) {
if (size > this.period)
this.period = size;
super.setAutoRangeMinimumSize(size, notify);
}
public void setFixedAutoRange(double length) {
this.period = length;
super.setFixedAutoRange(length);
}
public void setRange(Range range, boolean turnOffAutoRange, boolean notify) {
double size = range.getUpperBound() - range.getLowerBound();
if (size > this.period)
this.period = size;
super.setRange(range, turnOffAutoRange, notify);
}
public double getCycleBound() {
return Math.floor((getRange().getUpperBound() - this.offset) / this.period) * this.period + this.offset;
}
public double getOffset() {
return this.offset;
}
public void setOffset(double offset) {
this.offset = offset;
}
public double getPeriod() {
return this.period;
}
public void setPeriod(double period) {
this.period = period;
}
protected AxisState drawTickMarksAndLabels(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge) {
this.internalMarkerWhenTicksOverlap = false;
AxisState ret = super.drawTickMarksAndLabels(g2, cursor, plotArea, dataArea, edge);
if (!this.internalMarkerWhenTicksOverlap)
return ret;
double ol = (double)getTickMarkOutsideLength();
FontMetrics fm = g2.getFontMetrics(getTickLabelFont());
if (isVerticalTickLabels()) {
ol = (double)fm.getMaxAdvance();
} else {
ol = (double)fm.getHeight();
}
double il = 0.0D;
if (isTickMarksVisible()) {
float xx = (float)valueToJava2D(getRange().getUpperBound(), dataArea, edge);
Line2D mark = null;
g2.setStroke(getTickMarkStroke());
g2.setPaint(getTickMarkPaint());
if (edge == RectangleEdge.LEFT) {
mark = new Line2D.Double(cursor - ol, (double)xx, cursor + il, (double)xx);
} else if (edge == RectangleEdge.RIGHT) {
mark = new Line2D.Double(cursor + ol, (double)xx, cursor - il, (double)xx);
} else if (edge == RectangleEdge.TOP) {
mark = new Line2D.Double((double)xx, cursor - ol, (double)xx, cursor + il);
} else if (edge == RectangleEdge.BOTTOM) {
mark = new Line2D.Double((double)xx, cursor + ol, (double)xx, cursor - il);
}
g2.draw(mark);
}
return ret;
}
public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) {
AxisState ret = super.draw(g2, cursor, plotArea, dataArea, edge, plotState);
if (isAdvanceLineVisible()) {
double xx = valueToJava2D(getRange().getUpperBound(), dataArea, edge);
Line2D mark = null;
g2.setStroke(getAdvanceLineStroke());
g2.setPaint(getAdvanceLinePaint());
if (edge == RectangleEdge.LEFT) {
mark = new Line2D.Double(cursor, xx, cursor + dataArea.getWidth(), xx);
} else if (edge == RectangleEdge.RIGHT) {
mark = new Line2D.Double(cursor - dataArea.getWidth(), xx, cursor, xx);
} else if (edge == RectangleEdge.TOP) {
mark = new Line2D.Double(xx, cursor + dataArea.getHeight(), xx, cursor);
} else if (edge == RectangleEdge.BOTTOM) {
mark = new Line2D.Double(xx, cursor, xx, cursor - dataArea.getHeight());
}
g2.draw(mark);
}
return ret;
}
public AxisSpace reserveSpace(Graphics2D g2, Plot plot, Rectangle2D plotArea, RectangleEdge edge, AxisSpace space) {
this.internalMarkerCycleBoundTick = null;
AxisSpace ret = super.reserveSpace(g2, plot, plotArea, edge, space);
if (this.internalMarkerCycleBoundTick == null)
return ret;
FontMetrics fm = g2.getFontMetrics(getTickLabelFont());
Rectangle2D r = TextUtilities.getTextBounds(this.internalMarkerCycleBoundTick.getText(), g2, fm);
if (RectangleEdge.isTopOrBottom(edge)) {
if (isVerticalTickLabels()) {
space.add(r.getHeight() / 2.0D, RectangleEdge.RIGHT);
} else {
space.add(r.getWidth() / 2.0D, RectangleEdge.RIGHT);
}
} else if (RectangleEdge.isLeftOrRight(edge)) {
if (isVerticalTickLabels()) {
space.add(r.getWidth() / 2.0D, RectangleEdge.TOP);
} else {
space.add(r.getHeight() / 2.0D, RectangleEdge.TOP);
}
}
return ret;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.advanceLinePaint, stream);
SerialUtilities.writeStroke(this.advanceLineStroke, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.advanceLinePaint = SerialUtilities.readPaint(stream);
this.advanceLineStroke = SerialUtilities.readStroke(stream);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof CyclicNumberAxis))
return false;
if (!super.equals(obj))
return false;
CyclicNumberAxis that = (CyclicNumberAxis)obj;
if (this.period != that.period)
return false;
if (this.offset != that.offset)
return false;
if (!PaintUtilities.equal(this.advanceLinePaint, that.advanceLinePaint))
return false;
if (!ObjectUtilities.equal(this.advanceLineStroke, that.advanceLineStroke))
return false;
if (this.advanceLineVisible != that.advanceLineVisible)
return false;
if (this.boundMappedToLastCycle != that.boundMappedToLastCycle)
return false;
return true;
}
}

View file

@ -0,0 +1,872 @@
package org.jfree.chart.axis;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.ValueAxisPlot;
import org.jfree.data.Range;
import org.jfree.data.time.DateRange;
import org.jfree.data.time.Month;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.Year;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
import org.jfree.util.ObjectUtilities;
public class DateAxis extends ValueAxis implements Cloneable, Serializable {
private static final long serialVersionUID = -1013460999649007604L;
public static final DateRange DEFAULT_DATE_RANGE = new DateRange();
public static final double DEFAULT_AUTO_RANGE_MINIMUM_SIZE_IN_MILLISECONDS = 2.0D;
public static final DateTickUnit DEFAULT_DATE_TICK_UNIT = new DateTickUnit(2, 1, new SimpleDateFormat());
public static final Date DEFAULT_ANCHOR_DATE = new Date();
private DateTickUnit tickUnit;
private DateFormat dateFormatOverride;
private DateTickMarkPosition tickMarkPosition = DateTickMarkPosition.START;
private static class DefaultTimeline implements Timeline, Serializable {
private DefaultTimeline() {}
DefaultTimeline(DateAxis.null x0) {
this();
}
public long toTimelineValue(long millisecond) {
return millisecond;
}
public long toTimelineValue(Date date) {
return date.getTime();
}
public long toMillisecond(long value) {
return value;
}
public boolean containsDomainValue(long millisecond) {
return true;
}
public boolean containsDomainValue(Date date) {
return true;
}
public boolean containsDomainRange(long from, long to) {
return true;
}
public boolean containsDomainRange(Date from, Date to) {
return true;
}
public boolean equals(Object object) {
if (object == null)
return false;
if (object == this)
return true;
if (object instanceof DefaultTimeline)
return true;
return false;
}
}
private static final Timeline DEFAULT_TIMELINE = new DefaultTimeline();
private TimeZone timeZone;
private Timeline timeline;
public DateAxis() {
this(null);
}
public DateAxis(String label) {
this(label, TimeZone.getDefault());
}
public DateAxis(String label, TimeZone zone) {
super(label, createStandardDateTickUnits(zone));
setTickUnit(DEFAULT_DATE_TICK_UNIT, false, false);
setAutoRangeMinimumSize(2.0D);
setRange(DEFAULT_DATE_RANGE, false, false);
this.dateFormatOverride = null;
this.timeZone = zone;
this.timeline = DEFAULT_TIMELINE;
}
public TimeZone getTimeZone() {
return this.timeZone;
}
public void setTimeZone(TimeZone zone) {
if (!this.timeZone.equals(zone)) {
this.timeZone = zone;
setStandardTickUnits(createStandardDateTickUnits(zone));
notifyListeners(new AxisChangeEvent(this));
}
}
public Timeline getTimeline() {
return this.timeline;
}
public void setTimeline(Timeline timeline) {
if (this.timeline != timeline) {
this.timeline = timeline;
notifyListeners(new AxisChangeEvent(this));
}
}
public DateTickUnit getTickUnit() {
return this.tickUnit;
}
public void setTickUnit(DateTickUnit unit) {
setTickUnit(unit, true, true);
}
public void setTickUnit(DateTickUnit unit, boolean notify, boolean turnOffAutoSelection) {
this.tickUnit = unit;
if (turnOffAutoSelection)
setAutoTickUnitSelection(false, false);
if (notify)
notifyListeners(new AxisChangeEvent(this));
}
public DateFormat getDateFormatOverride() {
return this.dateFormatOverride;
}
public void setDateFormatOverride(DateFormat formatter) {
this.dateFormatOverride = formatter;
notifyListeners(new AxisChangeEvent(this));
}
public void setRange(Range range) {
setRange(range, true, true);
}
public void setRange(Range range, boolean turnOffAutoRange, boolean notify) {
if (range == null)
throw new IllegalArgumentException("Null 'range' argument.");
if (!(range instanceof DateRange))
range = new DateRange(range);
super.setRange(range, turnOffAutoRange, notify);
}
public void setRange(Date lower, Date upper) {
if (lower.getTime() >= upper.getTime())
throw new IllegalArgumentException("Requires 'lower' < 'upper'.");
setRange(new DateRange(lower, upper));
}
public void setRange(double lower, double upper) {
if (lower >= upper)
throw new IllegalArgumentException("Requires 'lower' < 'upper'.");
setRange(new DateRange(lower, upper));
}
public Date getMinimumDate() {
Date result = null;
Range range = getRange();
if (range instanceof DateRange) {
DateRange r = (DateRange)range;
result = r.getLowerDate();
} else {
result = new Date((long)range.getLowerBound());
}
return result;
}
public void setMinimumDate(Date date) {
if (date == null)
throw new IllegalArgumentException("Null 'date' argument.");
Date maxDate = getMaximumDate();
long maxMillis = maxDate.getTime();
long newMinMillis = date.getTime();
if (maxMillis <= newMinMillis) {
Date oldMin = getMinimumDate();
long length = maxMillis - oldMin.getTime();
maxDate = new Date(newMinMillis + length);
}
setRange(new DateRange(date, maxDate), true, false);
notifyListeners(new AxisChangeEvent(this));
}
public Date getMaximumDate() {
Date result = null;
Range range = getRange();
if (range instanceof DateRange) {
DateRange r = (DateRange)range;
result = r.getUpperDate();
} else {
result = new Date((long)range.getUpperBound());
}
return result;
}
public void setMaximumDate(Date maximumDate) {
if (maximumDate == null)
throw new IllegalArgumentException("Null 'maximumDate' argument.");
Date minDate = getMinimumDate();
long minMillis = minDate.getTime();
long newMaxMillis = maximumDate.getTime();
if (minMillis >= newMaxMillis) {
Date oldMax = getMaximumDate();
long length = oldMax.getTime() - minMillis;
minDate = new Date(newMaxMillis - length);
}
setRange(new DateRange(minDate, maximumDate), true, false);
notifyListeners(new AxisChangeEvent(this));
}
public DateTickMarkPosition getTickMarkPosition() {
return this.tickMarkPosition;
}
public void setTickMarkPosition(DateTickMarkPosition position) {
if (position == null)
throw new IllegalArgumentException("Null 'position' argument.");
this.tickMarkPosition = position;
notifyListeners(new AxisChangeEvent(this));
}
public void configure() {
if (isAutoRange())
autoAdjustRange();
}
public boolean isHiddenValue(long millis) {
return !this.timeline.containsDomainValue(new Date(millis));
}
public double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge) {
value = (double)this.timeline.toTimelineValue((long)value);
DateRange range = (DateRange)getRange();
double axisMin = (double)this.timeline.toTimelineValue(range.getLowerDate());
double axisMax = (double)this.timeline.toTimelineValue(range.getUpperDate());
double result = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
double minX = area.getX();
double maxX = area.getMaxX();
if (isInverted()) {
result = maxX + (value - axisMin) / (axisMax - axisMin) * (minX - maxX);
} else {
result = minX + (value - axisMin) / (axisMax - axisMin) * (maxX - minX);
}
} else if (RectangleEdge.isLeftOrRight(edge)) {
double minY = area.getMinY();
double maxY = area.getMaxY();
if (isInverted()) {
result = minY + (value - axisMin) / (axisMax - axisMin) * (maxY - minY);
} else {
result = maxY - (value - axisMin) / (axisMax - axisMin) * (maxY - minY);
}
}
return result;
}
public double dateToJava2D(Date date, Rectangle2D area, RectangleEdge edge) {
double value = (double)date.getTime();
return valueToJava2D(value, area, edge);
}
public double java2DToValue(double java2DValue, Rectangle2D area, RectangleEdge edge) {
double result;
DateRange range = (DateRange)getRange();
double axisMin = (double)this.timeline.toTimelineValue(range.getLowerDate());
double axisMax = (double)this.timeline.toTimelineValue(range.getUpperDate());
double min = 0.0D;
double max = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
min = area.getX();
max = area.getMaxX();
} else if (RectangleEdge.isLeftOrRight(edge)) {
min = area.getMaxY();
max = area.getY();
}
if (isInverted()) {
result = axisMax - (java2DValue - min) / (max - min) * (axisMax - axisMin);
} else {
result = axisMin + (java2DValue - min) / (max - min) * (axisMax - axisMin);
}
return (double)this.timeline.toMillisecond((long)result);
}
public Date calculateLowestVisibleTickValue(DateTickUnit unit) {
return nextStandardDate(getMinimumDate(), unit);
}
public Date calculateHighestVisibleTickValue(DateTickUnit unit) {
return previousStandardDate(getMaximumDate(), unit);
}
protected Date previousStandardDate(Date date, DateTickUnit unit) {
int milliseconds, seconds, minutes, hours, days, months, years;
Date mm, dd, d0, d1, d2;
Month month;
Date standardDate;
long millis;
Date d3;
Calendar calendar = Calendar.getInstance(this.timeZone);
calendar.setTime(date);
int count = unit.getCount();
int current = calendar.get(unit.getCalendarField());
int value = count * current / count;
switch (unit.getUnit()) {
case 6:
years = calendar.get(1);
months = calendar.get(2);
days = calendar.get(5);
hours = calendar.get(11);
minutes = calendar.get(12);
seconds = calendar.get(13);
calendar.set(years, months, days, hours, minutes, seconds);
calendar.set(14, value);
mm = calendar.getTime();
if (mm.getTime() >= date.getTime()) {
calendar.set(14, value - 1);
mm = calendar.getTime();
}
return mm;
case 5:
years = calendar.get(1);
months = calendar.get(2);
days = calendar.get(5);
hours = calendar.get(11);
minutes = calendar.get(12);
if (this.tickMarkPosition == DateTickMarkPosition.START) {
milliseconds = 0;
} else if (this.tickMarkPosition == DateTickMarkPosition.MIDDLE) {
milliseconds = 500;
} else {
milliseconds = 999;
}
calendar.set(14, milliseconds);
calendar.set(years, months, days, hours, minutes, value);
dd = calendar.getTime();
if (dd.getTime() >= date.getTime()) {
calendar.set(13, value - 1);
dd = calendar.getTime();
}
return dd;
case 4:
years = calendar.get(1);
months = calendar.get(2);
days = calendar.get(5);
hours = calendar.get(11);
if (this.tickMarkPosition == DateTickMarkPosition.START) {
seconds = 0;
} else if (this.tickMarkPosition == DateTickMarkPosition.MIDDLE) {
seconds = 30;
} else {
seconds = 59;
}
calendar.clear(14);
calendar.set(years, months, days, hours, value, seconds);
d0 = calendar.getTime();
if (d0.getTime() >= date.getTime()) {
calendar.set(12, value - 1);
d0 = calendar.getTime();
}
return d0;
case 3:
years = calendar.get(1);
months = calendar.get(2);
days = calendar.get(5);
if (this.tickMarkPosition == DateTickMarkPosition.START) {
minutes = 0;
seconds = 0;
} else if (this.tickMarkPosition == DateTickMarkPosition.MIDDLE) {
minutes = 30;
seconds = 0;
} else {
minutes = 59;
seconds = 59;
}
calendar.clear(14);
calendar.set(years, months, days, value, minutes, seconds);
d1 = calendar.getTime();
if (d1.getTime() >= date.getTime()) {
calendar.set(11, value - 1);
d1 = calendar.getTime();
}
return d1;
case 2:
years = calendar.get(1);
months = calendar.get(2);
if (this.tickMarkPosition == DateTickMarkPosition.START) {
hours = 0;
minutes = 0;
seconds = 0;
} else if (this.tickMarkPosition == DateTickMarkPosition.MIDDLE) {
hours = 12;
minutes = 0;
seconds = 0;
} else {
hours = 23;
minutes = 59;
seconds = 59;
}
calendar.clear(14);
calendar.set(years, months, value, hours, 0, 0);
d2 = calendar.getTime();
if (d2.getTime() >= date.getTime()) {
calendar.set(5, value - 1);
d2 = calendar.getTime();
}
return d2;
case 1:
years = calendar.get(1);
calendar.clear(14);
calendar.set(years, value, 1, 0, 0, 0);
month = new Month(calendar.getTime(), this.timeZone);
standardDate = calculateDateForPosition(month, this.tickMarkPosition);
millis = standardDate.getTime();
if (millis >= date.getTime()) {
month = (Month)month.previous();
standardDate = calculateDateForPosition(month, this.tickMarkPosition);
}
return standardDate;
case 0:
if (this.tickMarkPosition == DateTickMarkPosition.START) {
months = 0;
days = 1;
} else if (this.tickMarkPosition == DateTickMarkPosition.MIDDLE) {
months = 6;
days = 1;
} else {
months = 11;
days = 31;
}
calendar.clear(14);
calendar.set(value, months, days, 0, 0, 0);
d3 = calendar.getTime();
if (d3.getTime() >= date.getTime()) {
calendar.set(1, value - 1);
d3 = calendar.getTime();
}
return d3;
}
return null;
}
private Date calculateDateForPosition(RegularTimePeriod period, DateTickMarkPosition position) {
if (position == null)
throw new IllegalArgumentException("Null 'position' argument.");
Date result = null;
if (position == DateTickMarkPosition.START) {
result = new Date(period.getFirstMillisecond());
} else if (position == DateTickMarkPosition.MIDDLE) {
result = new Date(period.getMiddleMillisecond());
} else if (position == DateTickMarkPosition.END) {
result = new Date(period.getLastMillisecond());
}
return result;
}
protected Date nextStandardDate(Date date, DateTickUnit unit) {
Date previous = previousStandardDate(date, unit);
Calendar calendar = Calendar.getInstance(this.timeZone);
calendar.setTime(previous);
calendar.add(unit.getCalendarField(), unit.getCount());
return calendar.getTime();
}
public static TickUnitSource createStandardDateTickUnits() {
return createStandardDateTickUnits(TimeZone.getDefault());
}
public static TickUnitSource createStandardDateTickUnits(TimeZone zone) {
if (zone == null)
throw new IllegalArgumentException("Null 'zone' argument.");
TickUnits units = new TickUnits();
DateFormat f1 = new SimpleDateFormat("HH:mm:ss.SSS");
DateFormat f2 = new SimpleDateFormat("HH:mm:ss");
DateFormat f3 = new SimpleDateFormat("HH:mm");
DateFormat f4 = new SimpleDateFormat("d-MMM, HH:mm");
DateFormat f5 = new SimpleDateFormat("d-MMM");
DateFormat f6 = new SimpleDateFormat("MMM-yyyy");
DateFormat f7 = new SimpleDateFormat("yyyy");
f1.setTimeZone(zone);
f2.setTimeZone(zone);
f3.setTimeZone(zone);
f4.setTimeZone(zone);
f5.setTimeZone(zone);
f6.setTimeZone(zone);
f7.setTimeZone(zone);
units.add(new DateTickUnit(6, 1, f1));
units.add(new DateTickUnit(6, 5, 6, 1, f1));
units.add(new DateTickUnit(6, 10, 6, 1, f1));
units.add(new DateTickUnit(6, 25, 6, 5, f1));
units.add(new DateTickUnit(6, 50, 6, 10, f1));
units.add(new DateTickUnit(6, 100, 6, 10, f1));
units.add(new DateTickUnit(6, 250, 6, 10, f1));
units.add(new DateTickUnit(6, 500, 6, 50, f1));
units.add(new DateTickUnit(5, 1, 6, 50, f2));
units.add(new DateTickUnit(5, 5, 5, 1, f2));
units.add(new DateTickUnit(5, 10, 5, 1, f2));
units.add(new DateTickUnit(5, 30, 5, 5, f2));
units.add(new DateTickUnit(4, 1, 5, 5, f3));
units.add(new DateTickUnit(4, 2, 5, 10, f3));
units.add(new DateTickUnit(4, 5, 4, 1, f3));
units.add(new DateTickUnit(4, 10, 4, 1, f3));
units.add(new DateTickUnit(4, 15, 4, 5, f3));
units.add(new DateTickUnit(4, 20, 4, 5, f3));
units.add(new DateTickUnit(4, 30, 4, 5, f3));
units.add(new DateTickUnit(3, 1, 4, 5, f3));
units.add(new DateTickUnit(3, 2, 4, 10, f3));
units.add(new DateTickUnit(3, 4, 4, 30, f3));
units.add(new DateTickUnit(3, 6, 3, 1, f3));
units.add(new DateTickUnit(3, 12, 3, 1, f4));
units.add(new DateTickUnit(2, 1, 3, 1, f5));
units.add(new DateTickUnit(2, 2, 3, 1, f5));
units.add(new DateTickUnit(2, 7, 2, 1, f5));
units.add(new DateTickUnit(2, 15, 2, 1, f5));
units.add(new DateTickUnit(1, 1, 2, 1, f6));
units.add(new DateTickUnit(1, 2, 2, 1, f6));
units.add(new DateTickUnit(1, 3, 1, 1, f6));
units.add(new DateTickUnit(1, 4, 1, 1, f6));
units.add(new DateTickUnit(1, 6, 1, 1, f6));
units.add(new DateTickUnit(0, 1, 1, 1, f7));
units.add(new DateTickUnit(0, 2, 1, 3, f7));
units.add(new DateTickUnit(0, 5, 0, 1, f7));
units.add(new DateTickUnit(0, 10, 0, 1, f7));
units.add(new DateTickUnit(0, 25, 0, 5, f7));
units.add(new DateTickUnit(0, 50, 0, 10, f7));
units.add(new DateTickUnit(0, 100, 0, 20, f7));
return units;
}
protected void autoAdjustRange() {
Plot plot = getPlot();
if (plot == null)
return;
if (plot instanceof ValueAxisPlot) {
ValueAxisPlot vap = (ValueAxisPlot)plot;
Range r = vap.getDataRange(this);
if (r == null)
if (this.timeline instanceof SegmentedTimeline) {
r = new DateRange((double)((SegmentedTimeline)this.timeline).getStartTime(), (double)(((SegmentedTimeline)this.timeline).getStartTime() + 1L));
} else {
r = new DateRange();
}
long upper = this.timeline.toTimelineValue((long)r.getUpperBound());
long fixedAutoRange = (long)getFixedAutoRange();
if ((double)fixedAutoRange > 0.0D) {
lower = upper - fixedAutoRange;
} else {
lower = this.timeline.toTimelineValue((long)r.getLowerBound());
double range = (double)(upper - lower);
long minRange = (long)getAutoRangeMinimumSize();
if (range < (double)minRange) {
long expand = (long)((double)minRange - range) / 2L;
upper += expand;
lower -= expand;
}
upper += (long)(range * getUpperMargin());
lower -= (long)(range * getLowerMargin());
}
upper = this.timeline.toMillisecond(upper);
long lower = this.timeline.toMillisecond(lower);
DateRange dr = new DateRange(new Date(lower), new Date(upper));
setRange(dr, false, false);
}
}
protected void selectAutoTickUnit(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
if (RectangleEdge.isTopOrBottom(edge)) {
selectHorizontalAutoTickUnit(g2, dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
selectVerticalAutoTickUnit(g2, dataArea, edge);
}
}
protected void selectHorizontalAutoTickUnit(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
long shift = 0L;
if (this.timeline instanceof SegmentedTimeline)
shift = ((SegmentedTimeline)this.timeline).getStartTime();
double zero = valueToJava2D((double)shift + 0.0D, dataArea, edge);
double tickLabelWidth = estimateMaximumTickLabelWidth(g2, getTickUnit());
TickUnitSource tickUnits = getStandardTickUnits();
TickUnit unit1 = tickUnits.getCeilingTickUnit(getTickUnit());
double x1 = valueToJava2D((double)shift + unit1.getSize(), dataArea, edge);
double unit1Width = Math.abs(x1 - zero);
double guess = tickLabelWidth / unit1Width * unit1.getSize();
DateTickUnit unit2 = (DateTickUnit)tickUnits.getCeilingTickUnit(guess);
double x2 = valueToJava2D((double)shift + unit2.getSize(), dataArea, edge);
double unit2Width = Math.abs(x2 - zero);
tickLabelWidth = estimateMaximumTickLabelWidth(g2, unit2);
if (tickLabelWidth > unit2Width)
unit2 = (DateTickUnit)tickUnits.getLargerTickUnit(unit2);
setTickUnit(unit2, false, false);
}
protected void selectVerticalAutoTickUnit(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
DateTickUnit finalUnit;
TickUnitSource tickUnits = getStandardTickUnits();
double zero = valueToJava2D(0.0D, dataArea, edge);
double estimate1 = getRange().getLength() / 10.0D;
DateTickUnit candidate1 = (DateTickUnit)tickUnits.getCeilingTickUnit(estimate1);
double labelHeight1 = estimateMaximumTickLabelHeight(g2, candidate1);
double y1 = valueToJava2D(candidate1.getSize(), dataArea, edge);
double candidate1UnitHeight = Math.abs(y1 - zero);
double estimate2 = labelHeight1 / candidate1UnitHeight * candidate1.getSize();
DateTickUnit candidate2 = (DateTickUnit)tickUnits.getCeilingTickUnit(estimate2);
double labelHeight2 = estimateMaximumTickLabelHeight(g2, candidate2);
double y2 = valueToJava2D(candidate2.getSize(), dataArea, edge);
double unit2Height = Math.abs(y2 - zero);
if (labelHeight2 < unit2Height) {
finalUnit = candidate2;
} else {
finalUnit = (DateTickUnit)tickUnits.getLargerTickUnit(candidate2);
}
setTickUnit(finalUnit, false, false);
}
private double estimateMaximumTickLabelWidth(Graphics2D g2, DateTickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);
if (isVerticalTickLabels()) {
result += (double)lm.getHeight();
} else {
DateRange range = (DateRange)getRange();
Date lower = range.getLowerDate();
Date upper = range.getUpperDate();
String lowerStr = null;
String upperStr = null;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
} else {
lowerStr = unit.dateToString(lower);
upperStr = unit.dateToString(upper);
}
FontMetrics fm = g2.getFontMetrics(tickLabelFont);
double w1 = (double)fm.stringWidth(lowerStr);
double w2 = (double)fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
private double estimateMaximumTickLabelHeight(Graphics2D g2, DateTickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getTop() + tickLabelInsets.getBottom();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);
if (!isVerticalTickLabels()) {
result += (double)lm.getHeight();
} else {
DateRange range = (DateRange)getRange();
Date lower = range.getLowerDate();
Date upper = range.getUpperDate();
String lowerStr = null;
String upperStr = null;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
} else {
lowerStr = unit.dateToString(lower);
upperStr = unit.dateToString(upper);
}
FontMetrics fm = g2.getFontMetrics(tickLabelFont);
double w1 = (double)fm.stringWidth(lowerStr);
double w2 = (double)fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List result = null;
if (RectangleEdge.isTopOrBottom(edge)) {
result = refreshTicksHorizontal(g2, dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
result = refreshTicksVertical(g2, dataArea, edge);
}
return result;
}
protected List refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List result = new ArrayList();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection())
selectAutoTickUnit(g2, dataArea, edge);
DateTickUnit unit = getTickUnit();
Date tickDate = calculateLowestVisibleTickValue(unit);
Date upperDate = getMaximumDate();
while (tickDate.before(upperDate)) {
if (!isHiddenValue(tickDate.getTime())) {
String tickLabel;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(tickDate);
} else {
tickLabel = this.tickUnit.dateToString(tickDate);
}
TextAnchor anchor = null;
TextAnchor rotationAnchor = null;
double angle = 0.0D;
if (isVerticalTickLabels()) {
anchor = TextAnchor.CENTER_RIGHT;
rotationAnchor = TextAnchor.CENTER_RIGHT;
if (edge == RectangleEdge.TOP) {
angle = 1.5707963267948966D;
} else {
angle = -1.5707963267948966D;
}
} else if (edge == RectangleEdge.TOP) {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
} else {
anchor = TextAnchor.TOP_CENTER;
rotationAnchor = TextAnchor.TOP_CENTER;
}
Tick tick = new DateTick(tickDate, tickLabel, anchor, rotationAnchor, angle);
result.add(tick);
tickDate = unit.addToDate(tickDate, this.timeZone);
} else {
tickDate = unit.rollDate(tickDate, this.timeZone);
continue;
}
switch (unit.getUnit()) {
case 1:
tickDate = calculateDateForPosition(new Month(tickDate, this.timeZone), this.tickMarkPosition);
case 0:
tickDate = calculateDateForPosition(new Year(tickDate, this.timeZone), this.tickMarkPosition);
}
}
return result;
}
protected List refreshTicksVertical(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List result = new ArrayList();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection())
selectAutoTickUnit(g2, dataArea, edge);
DateTickUnit unit = getTickUnit();
Date tickDate = calculateLowestVisibleTickValue(unit);
Date upperDate = getMaximumDate();
while (tickDate.before(upperDate)) {
if (!isHiddenValue(tickDate.getTime())) {
String tickLabel;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(tickDate);
} else {
tickLabel = this.tickUnit.dateToString(tickDate);
}
TextAnchor anchor = null;
TextAnchor rotationAnchor = null;
double angle = 0.0D;
if (isVerticalTickLabels()) {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
if (edge == RectangleEdge.LEFT) {
angle = -1.5707963267948966D;
} else {
angle = 1.5707963267948966D;
}
} else if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.CENTER_RIGHT;
rotationAnchor = TextAnchor.CENTER_RIGHT;
} else {
anchor = TextAnchor.CENTER_LEFT;
rotationAnchor = TextAnchor.CENTER_LEFT;
}
Tick tick = new DateTick(tickDate, tickLabel, anchor, rotationAnchor, angle);
result.add(tick);
tickDate = unit.addToDate(tickDate, this.timeZone);
continue;
}
tickDate = unit.rollDate(tickDate, this.timeZone);
}
return result;
}
public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) {
if (!isVisible()) {
AxisState axisState = new AxisState(cursor);
List ticks = refreshTicks(g2, axisState, dataArea, edge);
axisState.setTicks(ticks);
return axisState;
}
AxisState state = drawTickMarksAndLabels(g2, cursor, plotArea, dataArea, edge);
state = drawLabel(getLabel(), g2, plotArea, dataArea, edge, state);
return state;
}
public void zoomRange(double lowerPercent, double upperPercent) {
double start = (double)this.timeline.toTimelineValue((long)getRange().getLowerBound());
double length = (double)(this.timeline.toTimelineValue((long)getRange().getUpperBound()) - this.timeline.toTimelineValue((long)getRange().getLowerBound()));
Range adjusted = null;
if (isInverted()) {
adjusted = new DateRange((double)this.timeline.toMillisecond((long)(start + length * (1.0D - upperPercent))), (double)this.timeline.toMillisecond((long)(start + length * (1.0D - lowerPercent))));
} else {
adjusted = new DateRange((double)this.timeline.toMillisecond((long)(start + length * lowerPercent)), (double)this.timeline.toMillisecond((long)(start + length * upperPercent)));
}
setRange(adjusted);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof DateAxis))
return false;
DateAxis that = (DateAxis)obj;
if (!ObjectUtilities.equal(this.tickUnit, that.tickUnit))
return false;
if (!ObjectUtilities.equal(this.dateFormatOverride, that.dateFormatOverride))
return false;
if (!ObjectUtilities.equal(this.tickMarkPosition, that.tickMarkPosition))
return false;
if (!ObjectUtilities.equal(this.timeline, that.timeline))
return false;
if (!super.equals(obj))
return false;
return true;
}
public int hashCode() {
if (getLabel() != null)
return getLabel().hashCode();
return 0;
}
public Object clone() throws CloneNotSupportedException {
DateAxis clone = (DateAxis)super.clone();
if (this.dateFormatOverride != null)
clone.dateFormatOverride = (DateFormat)this.dateFormatOverride.clone();
return clone;
}
}

View file

@ -0,0 +1,34 @@
package org.jfree.chart.axis;
import java.util.Date;
import org.jfree.ui.TextAnchor;
import org.jfree.util.ObjectUtilities;
public class DateTick extends ValueTick {
private Date date;
public DateTick(Date date, String label, TextAnchor textAnchor, TextAnchor rotationAnchor, double angle) {
super((double)date.getTime(), label, textAnchor, rotationAnchor, angle);
this.date = date;
}
public Date getDate() {
return this.date;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof DateTick && super.equals(obj)) {
DateTick dt = (DateTick)obj;
if (!ObjectUtilities.equal(this.date, dt.date))
return false;
return true;
}
return false;
}
public int hashCode() {
return this.date.hashCode();
}
}

View file

@ -0,0 +1,45 @@
package org.jfree.chart.axis;
import java.io.ObjectStreamException;
import java.io.Serializable;
public final class DateTickMarkPosition implements Serializable {
private static final long serialVersionUID = 2540750672764537240L;
public static final DateTickMarkPosition START = new DateTickMarkPosition("DateTickMarkPosition.START");
public static final DateTickMarkPosition MIDDLE = new DateTickMarkPosition("DateTickMarkPosition.MIDDLE");
public static final DateTickMarkPosition END = new DateTickMarkPosition("DateTickMarkPosition.END");
private String name;
private DateTickMarkPosition(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof DateTickMarkPosition))
return false;
DateTickMarkPosition position = (DateTickMarkPosition)obj;
if (!this.name.equals(position.toString()))
return false;
return true;
}
private Object readResolve() throws ObjectStreamException {
if (equals(START))
return START;
if (equals(MIDDLE))
return MIDDLE;
if (equals(END))
return END;
return null;
}
}

View file

@ -0,0 +1,182 @@
package org.jfree.chart.axis;
import java.io.Serializable;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import org.jfree.util.ObjectUtilities;
public class DateTickUnit extends TickUnit implements Serializable {
private static final long serialVersionUID = -7289292157229621901L;
public static final int YEAR = 0;
public static final int MONTH = 1;
public static final int DAY = 2;
public static final int HOUR = 3;
public static final int MINUTE = 4;
public static final int SECOND = 5;
public static final int MILLISECOND = 6;
private int unit;
private int count;
private int rollUnit;
private int rollCount;
private DateFormat formatter;
public DateTickUnit(int unit, int count) {
this(unit, count, null);
}
public DateTickUnit(int unit, int count, DateFormat formatter) {
this(unit, count, unit, count, formatter);
}
public DateTickUnit(int unit, int count, int rollUnit, int rollCount, DateFormat formatter) {
super((double)getMillisecondCount(unit, count));
this.unit = unit;
this.count = count;
this.rollUnit = rollUnit;
this.rollCount = rollCount;
this.formatter = formatter;
if (formatter == null)
this.formatter = DateFormat.getDateInstance(3);
}
public int getUnit() {
return this.unit;
}
public int getCount() {
return this.count;
}
public int getRollUnit() {
return this.rollUnit;
}
public int getRollCount() {
return this.rollCount;
}
public String valueToString(double milliseconds) {
return this.formatter.format(new Date((long)milliseconds));
}
public String dateToString(Date date) {
return this.formatter.format(date);
}
public Date addToDate(Date base) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(base);
calendar.add(getCalendarField(this.unit), this.count);
return calendar.getTime();
}
public Date addToDate(Date base, TimeZone zone) {
Calendar calendar = Calendar.getInstance(zone);
calendar.setTime(base);
calendar.add(getCalendarField(this.unit), this.count);
return calendar.getTime();
}
public Date rollDate(Date base) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(base);
calendar.add(getCalendarField(this.rollUnit), this.rollCount);
return calendar.getTime();
}
public Date rollDate(Date base, TimeZone zone) {
Calendar calendar = Calendar.getInstance(zone);
calendar.setTime(base);
calendar.add(getCalendarField(this.rollUnit), this.rollCount);
return calendar.getTime();
}
public int getCalendarField() {
return getCalendarField(this.unit);
}
private int getCalendarField(int tickUnit) {
switch (tickUnit) {
case 0:
return 1;
case 1:
return 2;
case 2:
return 5;
case 3:
return 11;
case 4:
return 12;
case 5:
return 13;
case 6:
return 14;
}
return 14;
}
private static long getMillisecondCount(int unit, int count) {
switch (unit) {
case 0:
return 31536000000L * (long)count;
case 1:
return 2678400000L * (long)count;
case 2:
return 86400000L * (long)count;
case 3:
return 3600000L * (long)count;
case 4:
return 60000L * (long)count;
case 5:
return 1000L * (long)count;
case 6:
return (long)count;
}
throw new IllegalArgumentException("DateTickUnit.getMillisecondCount() : unit must be one of the constants YEAR, MONTH, DAY, HOUR, MINUTE, SECOND or MILLISECOND defined in the DateTickUnit class. Do *not* use the constants defined in java.util.Calendar.");
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof DateTickUnit))
return false;
if (!super.equals(obj))
return false;
DateTickUnit that = (DateTickUnit)obj;
if (this.unit != that.unit)
return false;
if (this.count != that.count)
return false;
if (!ObjectUtilities.equal(this.formatter, that.formatter))
return false;
return true;
}
public int hashCode() {
int result = 19;
result = 37 * result + this.unit;
result = 37 * result + this.count;
result = 37 * result + this.formatter.hashCode();
return result;
}
private static final String[] units = new String[] { "YEAR", "MONTH", "DAY", "HOUR", "MINUTE", "SECOND", "MILLISECOND" };
public String toString() {
return "DateTickUnit[" + units[this.unit] + ", " + this.count + "]";
}
}

View file

@ -0,0 +1,107 @@
package org.jfree.chart.axis;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextBlock;
import org.jfree.text.TextFragment;
import org.jfree.text.TextLine;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.PaintUtilities;
public class ExtendedCategoryAxis extends CategoryAxis {
static final long serialVersionUID = -3004429093959826567L;
private Map sublabels;
private Font sublabelFont;
private transient Paint sublabelPaint;
public ExtendedCategoryAxis(String label) {
super(label);
this.sublabels = new HashMap();
this.sublabelFont = new Font("SansSerif", 0, 10);
this.sublabelPaint = Color.black;
}
public Font getSubLabelFont() {
return this.sublabelFont;
}
public void setSubLabelFont(Font font) {
if (font == null)
throw new IllegalArgumentException("Null 'font' argument.");
this.sublabelFont = font;
notifyListeners(new AxisChangeEvent(this));
}
public Paint getSubLabelPaint() {
return this.sublabelPaint;
}
public void setSubLabelPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.sublabelPaint = paint;
notifyListeners(new AxisChangeEvent(this));
}
public void addSubLabel(Comparable category, String label) {
this.sublabels.put(category, label);
}
protected TextBlock createLabel(Comparable category, float width, RectangleEdge edge, Graphics2D g2) {
TextBlock label = super.createLabel(category, width, edge, g2);
String s = (String)this.sublabels.get(category);
if (s != null)
if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
TextLine line = new TextLine(s, this.sublabelFont, this.sublabelPaint);
label.addLine(line);
} else if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT) {
TextLine line = label.getLastLine();
if (line != null)
line.addFragment(new TextFragment(" " + s, this.sublabelFont, this.sublabelPaint));
}
return label;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof ExtendedCategoryAxis))
return false;
ExtendedCategoryAxis that = (ExtendedCategoryAxis)obj;
if (!this.sublabelFont.equals(that.sublabelFont))
return false;
if (!PaintUtilities.equal(this.sublabelPaint, that.sublabelPaint))
return false;
if (!this.sublabels.equals(that.sublabels))
return false;
return super.equals(obj);
}
public Object clone() throws CloneNotSupportedException {
ExtendedCategoryAxis clone = (ExtendedCategoryAxis)super.clone();
clone.sublabels = new HashMap(this.sublabels);
return clone;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.sublabelPaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.sublabelPaint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,439 @@
package org.jfree.chart.axis;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.ValueAxisPlot;
import org.jfree.data.Range;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
public class LogAxis extends ValueAxis {
private double base = 10.0D;
private double baseLog = Math.log(10.0D);
private double smallestValue = 1.0E-100D;
private NumberTickUnit tickUnit;
private NumberFormat numberFormatOverride;
private int minorTickCount;
public LogAxis() {
this(null);
}
public LogAxis(String label) {
super(label, createLogTickUnits(Locale.getDefault()));
setDefaultAutoRange(new Range(0.01D, 1.0D));
this.tickUnit = new NumberTickUnit(1.0D, new DecimalFormat("0.#"));
this.minorTickCount = 10;
}
public double getBase() {
return this.base;
}
public void setBase(double base) {
if (base <= 1.0D)
throw new IllegalArgumentException("Requires 'base' > 1.0.");
this.base = base;
this.baseLog = Math.log(base);
notifyListeners(new AxisChangeEvent(this));
}
public double getSmallestValue() {
return this.smallestValue;
}
public void setSmallestValue(double value) {
if (value <= 0.0D)
throw new IllegalArgumentException("Requires 'value' > 0.0.");
this.smallestValue = value;
notifyListeners(new AxisChangeEvent(this));
}
public NumberTickUnit getTickUnit() {
return this.tickUnit;
}
public void setTickUnit(NumberTickUnit unit) {
setTickUnit(unit, true, true);
}
public void setTickUnit(NumberTickUnit unit, boolean notify, boolean turnOffAutoSelect) {
if (unit == null)
throw new IllegalArgumentException("Null 'unit' argument.");
this.tickUnit = unit;
if (turnOffAutoSelect)
setAutoTickUnitSelection(false, false);
if (notify)
notifyListeners(new AxisChangeEvent(this));
}
public NumberFormat getNumberFormatOverride() {
return this.numberFormatOverride;
}
public void setNumberFormatOverride(NumberFormat formatter) {
this.numberFormatOverride = formatter;
notifyListeners(new AxisChangeEvent(this));
}
public int getMinorTickCount() {
return this.minorTickCount;
}
public void setMinorTickCount(int count) {
if (count <= 0)
throw new IllegalArgumentException("Requires 'count' > 0.");
this.minorTickCount = count;
notifyListeners(new AxisChangeEvent(this));
}
public double calculateLog(double value) {
return Math.log(value) / this.baseLog;
}
public double calculateValue(double log) {
return Math.pow(this.base, log);
}
public double java2DToValue(double java2DValue, Rectangle2D area, RectangleEdge edge) {
Range range = getRange();
double axisMin = calculateLog(range.getLowerBound());
double axisMax = calculateLog(range.getUpperBound());
double min = 0.0D;
double max = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
min = area.getX();
max = area.getMaxX();
} else if (RectangleEdge.isLeftOrRight(edge)) {
min = area.getMaxY();
max = area.getY();
}
double log = 0.0D;
if (isInverted()) {
log = axisMax - (java2DValue - min) / (max - min) * (axisMax - axisMin);
} else {
log = axisMin + (java2DValue - min) / (max - min) * (axisMax - axisMin);
}
return calculateValue(log);
}
public double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge) {
Range range = getRange();
double axisMin = calculateLog(range.getLowerBound());
double axisMax = calculateLog(range.getUpperBound());
value = calculateLog(value);
double min = 0.0D;
double max = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
min = area.getX();
max = area.getMaxX();
} else if (RectangleEdge.isLeftOrRight(edge)) {
max = area.getMinY();
min = area.getMaxY();
}
if (isInverted())
return max - (value - axisMin) / (axisMax - axisMin) * (max - min);
return min + (value - axisMin) / (axisMax - axisMin) * (max - min);
}
public void configure() {
if (isAutoRange())
autoAdjustRange();
}
protected void autoAdjustRange() {
Plot plot = getPlot();
if (plot == null)
return;
if (plot instanceof ValueAxisPlot) {
ValueAxisPlot vap = (ValueAxisPlot)plot;
Range r = vap.getDataRange(this);
if (r == null)
r = getDefaultAutoRange();
double upper = r.getUpperBound();
double lower = Math.max(r.getLowerBound(), this.smallestValue);
double range = upper - lower;
double fixedAutoRange = getFixedAutoRange();
if (fixedAutoRange > 0.0D) {
lower = Math.max(upper - fixedAutoRange, this.smallestValue);
} else {
double minRange = getAutoRangeMinimumSize();
if (range < minRange) {
double expand = (minRange - range) / 2.0D;
upper += expand;
lower -= expand;
}
double logUpper = calculateLog(upper);
double logLower = calculateLog(lower);
double logRange = logUpper - logLower;
logUpper += getUpperMargin() * logRange;
logLower -= getLowerMargin() * logRange;
upper = calculateValue(logUpper);
lower = calculateValue(logLower);
}
setRange(new Range(lower, upper), false, false);
}
}
public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) {
AxisState state = null;
if (!isVisible()) {
state = new AxisState(cursor);
List ticks = refreshTicks(g2, state, dataArea, edge);
state.setTicks(ticks);
return state;
}
state = drawTickMarksAndLabels(g2, cursor, plotArea, dataArea, edge);
state = drawLabel(getLabel(), g2, plotArea, dataArea, edge, state);
return state;
}
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List result = new ArrayList();
if (RectangleEdge.isTopOrBottom(edge)) {
result = refreshTicksHorizontal(g2, dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
result = refreshTicksVertical(g2, dataArea, edge);
}
return result;
}
protected List refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
Range range = getRange();
List ticks = new ArrayList();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection())
selectAutoTickUnit(g2, dataArea, edge);
double start = Math.floor(calculateLog(getLowerBound()));
double end = Math.ceil(calculateLog(getUpperBound()));
double current = start;
while (current <= end) {
double v = calculateValue(current);
if (range.contains(v))
ticks.add(new NumberTick(TickType.MAJOR, v, createTickLabel(v), TextAnchor.TOP_CENTER, TextAnchor.CENTER, 0.0D));
double next = Math.pow(this.base, current + this.tickUnit.getSize());
for (int i = 1; i < this.minorTickCount; i++) {
double minorV = v + (double)i * (next - v) / (double)this.minorTickCount;
if (range.contains(minorV))
ticks.add(new NumberTick(TickType.MINOR, minorV, "", TextAnchor.TOP_CENTER, TextAnchor.CENTER, 0.0D));
}
current += this.tickUnit.getSize();
}
return ticks;
}
protected List refreshTicksVertical(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
Range range = getRange();
List ticks = new ArrayList();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection())
selectAutoTickUnit(g2, dataArea, edge);
double start = Math.floor(calculateLog(getLowerBound()));
double end = Math.ceil(calculateLog(getUpperBound()));
double current = start;
while (current <= end) {
double v = calculateValue(current);
if (range.contains(v))
ticks.add(new NumberTick(TickType.MINOR, v, createTickLabel(v), TextAnchor.CENTER_RIGHT, TextAnchor.CENTER, 0.0D));
double next = Math.pow(this.base, current + this.tickUnit.getSize());
for (int i = 1; i < this.minorTickCount; i++) {
double minorV = v + (double)i * (next - v) / (double)this.minorTickCount;
if (range.contains(minorV))
ticks.add(new NumberTick(TickType.MINOR, minorV, "", TextAnchor.CENTER_RIGHT, TextAnchor.CENTER, 0.0D));
}
current += this.tickUnit.getSize();
}
return ticks;
}
protected void selectAutoTickUnit(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
if (RectangleEdge.isTopOrBottom(edge)) {
selectHorizontalAutoTickUnit(g2, dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
selectVerticalAutoTickUnit(g2, dataArea, edge);
}
}
protected void selectHorizontalAutoTickUnit(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
double tickLabelWidth = estimateMaximumTickLabelWidth(g2, getTickUnit());
TickUnitSource tickUnits = getStandardTickUnits();
TickUnit unit1 = tickUnits.getCeilingTickUnit(getTickUnit());
double unit1Width = exponentLengthToJava2D(unit1.getSize(), dataArea, edge);
double guess = tickLabelWidth / unit1Width * unit1.getSize();
NumberTickUnit unit2 = (NumberTickUnit)tickUnits.getCeilingTickUnit(guess);
double unit2Width = exponentLengthToJava2D(unit2.getSize(), dataArea, edge);
tickLabelWidth = estimateMaximumTickLabelWidth(g2, unit2);
if (tickLabelWidth > unit2Width)
unit2 = (NumberTickUnit)tickUnits.getLargerTickUnit(unit2);
setTickUnit(unit2, false, false);
}
public double exponentLengthToJava2D(double length, Rectangle2D area, RectangleEdge edge) {
double one = valueToJava2D(calculateValue(1.0D), area, edge);
double l = valueToJava2D(calculateValue(length + 1.0D), area, edge);
return Math.abs(l - one);
}
protected void selectVerticalAutoTickUnit(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
double tickLabelHeight = estimateMaximumTickLabelHeight(g2);
TickUnitSource tickUnits = getStandardTickUnits();
TickUnit unit1 = tickUnits.getCeilingTickUnit(getTickUnit());
double unitHeight = exponentLengthToJava2D(unit1.getSize(), dataArea, edge);
double guess = tickLabelHeight / unitHeight * unit1.getSize();
NumberTickUnit unit2 = (NumberTickUnit)tickUnits.getCeilingTickUnit(guess);
double unit2Height = exponentLengthToJava2D(unit2.getSize(), dataArea, edge);
tickLabelHeight = estimateMaximumTickLabelHeight(g2);
if (tickLabelHeight > unit2Height)
unit2 = (NumberTickUnit)tickUnits.getLargerTickUnit(unit2);
setTickUnit(unit2, false, false);
}
protected double estimateMaximumTickLabelHeight(Graphics2D g2) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getTop() + tickLabelInsets.getBottom();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
result += (double)tickLabelFont.getLineMetrics("123", frc).getHeight();
return result;
}
protected double estimateMaximumTickLabelWidth(Graphics2D g2, TickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
if (isVerticalTickLabels()) {
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = getTickLabelFont().getLineMetrics("0", frc);
result += (double)lm.getHeight();
} else {
FontMetrics fm = g2.getFontMetrics(getTickLabelFont());
Range range = getRange();
double lower = range.getLowerBound();
double upper = range.getUpperBound();
String lowerStr = "";
String upperStr = "";
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
} else {
lowerStr = unit.valueToString(lower);
upperStr = unit.valueToString(upper);
}
double w1 = (double)fm.stringWidth(lowerStr);
double w2 = (double)fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
public void zoomRange(double lowerPercent, double upperPercent) {
Range range = getRange();
double start = range.getLowerBound();
double end = range.getUpperBound();
double log1 = calculateLog(start);
double log2 = calculateLog(end);
double length = log2 - log1;
Range adjusted = null;
if (isInverted()) {
double logA = log1 + length * (1.0D - upperPercent);
double logB = log1 + length * (1.0D - lowerPercent);
adjusted = new Range(calculateValue(logA), calculateValue(logB));
} else {
double logA = log1 + length * lowerPercent;
double logB = log1 + length * upperPercent;
adjusted = new Range(calculateValue(logA), calculateValue(logB));
}
setRange(adjusted);
}
private String createTickLabel(double value) {
if (this.numberFormatOverride != null)
return this.numberFormatOverride.format(value);
return this.tickUnit.valueToString(value);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof LogAxis))
return false;
LogAxis that = (LogAxis)obj;
if (this.base != that.base)
return false;
if (this.smallestValue != that.smallestValue)
return false;
if (this.minorTickCount != that.minorTickCount)
return false;
return super.equals(obj);
}
public int hashCode() {
int result = 193;
long temp = Double.doubleToLongBits(this.base);
result = 37 * result + (int)(temp ^ temp >>> 32L);
result = 37 * result + this.minorTickCount;
temp = Double.doubleToLongBits(this.smallestValue);
result = 37 * result + (int)(temp ^ temp >>> 32L);
if (this.numberFormatOverride != null)
result = 37 * result + this.numberFormatOverride.hashCode();
result = 37 * result + this.tickUnit.hashCode();
return result;
}
public static TickUnitSource createLogTickUnits(Locale locale) {
TickUnits units = new TickUnits();
NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
units.add(new NumberTickUnit(1.0D, numberFormat));
units.add(new NumberTickUnit(2.0D, numberFormat));
units.add(new NumberTickUnit(5.0D, numberFormat));
units.add(new NumberTickUnit(10.0D, numberFormat));
units.add(new NumberTickUnit(20.0D, numberFormat));
units.add(new NumberTickUnit(50.0D, numberFormat));
units.add(new NumberTickUnit(100.0D, numberFormat));
units.add(new NumberTickUnit(200.0D, numberFormat));
units.add(new NumberTickUnit(500.0D, numberFormat));
units.add(new NumberTickUnit(1000.0D, numberFormat));
units.add(new NumberTickUnit(2000.0D, numberFormat));
units.add(new NumberTickUnit(5000.0D, numberFormat));
units.add(new NumberTickUnit(10000.0D, numberFormat));
units.add(new NumberTickUnit(20000.0D, numberFormat));
units.add(new NumberTickUnit(50000.0D, numberFormat));
units.add(new NumberTickUnit(100000.0D, numberFormat));
units.add(new NumberTickUnit(200000.0D, numberFormat));
units.add(new NumberTickUnit(500000.0D, numberFormat));
units.add(new NumberTickUnit(1000000.0D, numberFormat));
units.add(new NumberTickUnit(2000000.0D, numberFormat));
units.add(new NumberTickUnit(5000000.0D, numberFormat));
units.add(new NumberTickUnit(1.0E7D, numberFormat));
units.add(new NumberTickUnit(2.0E7D, numberFormat));
units.add(new NumberTickUnit(5.0E7D, numberFormat));
units.add(new NumberTickUnit(1.0E8D, numberFormat));
units.add(new NumberTickUnit(2.0E8D, numberFormat));
units.add(new NumberTickUnit(5.0E8D, numberFormat));
units.add(new NumberTickUnit(1.0E9D, numberFormat));
units.add(new NumberTickUnit(2.0E9D, numberFormat));
units.add(new NumberTickUnit(5.0E9D, numberFormat));
units.add(new NumberTickUnit(1.0E10D, numberFormat));
return units;
}
}

View file

@ -0,0 +1,466 @@
package org.jfree.chart.axis;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.ValueAxisPlot;
import org.jfree.data.Range;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;
public class LogarithmicAxis extends NumberAxis {
private static final long serialVersionUID = 2502918599004103054L;
public static final double LOG10_VALUE = Math.log(10.0D);
public static final double SMALL_LOG_VALUE = 1.0E-100D;
protected boolean allowNegativesFlag = false;
protected boolean strictValuesFlag = true;
protected final NumberFormat numberFormatterObj = NumberFormat.getInstance();
protected boolean expTickLabelsFlag = false;
protected boolean log10TickLabelsFlag = false;
protected boolean autoRangeNextLogFlag = false;
protected boolean smallLogFlag = false;
public LogarithmicAxis(String label) {
super(label);
setupNumberFmtObj();
}
public void setAllowNegativesFlag(boolean flgVal) {
this.allowNegativesFlag = flgVal;
}
public boolean getAllowNegativesFlag() {
return this.allowNegativesFlag;
}
public void setStrictValuesFlag(boolean flgVal) {
this.strictValuesFlag = flgVal;
}
public boolean getStrictValuesFlag() {
return this.strictValuesFlag;
}
public void setExpTickLabelsFlag(boolean flgVal) {
this.expTickLabelsFlag = flgVal;
setupNumberFmtObj();
}
public boolean getExpTickLabelsFlag() {
return this.expTickLabelsFlag;
}
public void setLog10TickLabelsFlag(boolean flag) {
this.log10TickLabelsFlag = flag;
}
public boolean getLog10TickLabelsFlag() {
return this.log10TickLabelsFlag;
}
public void setAutoRangeNextLogFlag(boolean flag) {
this.autoRangeNextLogFlag = flag;
}
public boolean getAutoRangeNextLogFlag() {
return this.autoRangeNextLogFlag;
}
public void setRange(Range range) {
super.setRange(range);
setupSmallLogFlag();
}
protected void setupSmallLogFlag() {
double lowerVal = getRange().getLowerBound();
this.smallLogFlag = (!this.allowNegativesFlag && lowerVal < 10.0D && lowerVal > 0.0D);
}
protected void setupNumberFmtObj() {
if (this.numberFormatterObj instanceof DecimalFormat)
((DecimalFormat)this.numberFormatterObj).applyPattern(this.expTickLabelsFlag ? "0E0" : "0.###");
}
protected double switchedLog10(double val) {
return this.smallLogFlag ? (Math.log(val) / LOG10_VALUE) : adjustedLog10(val);
}
public double switchedPow10(double val) {
return this.smallLogFlag ? Math.pow(10.0D, val) : adjustedPow10(val);
}
public double adjustedLog10(double val) {
boolean negFlag = (val < 0.0D);
if (negFlag)
val = -val;
if (val < 10.0D)
val += (10.0D - val) / 10.0D;
double res = Math.log(val) / LOG10_VALUE;
return negFlag ? -res : res;
}
public double adjustedPow10(double val) {
double res;
boolean negFlag = (val < 0.0D);
if (negFlag)
val = -val;
if (val < 1.0D) {
res = (Math.pow(10.0D, val + 1.0D) - 10.0D) / 9.0D;
} else {
res = Math.pow(10.0D, val);
}
return negFlag ? -res : res;
}
protected double computeLogFloor(double lower) {
double logFloor;
if (this.allowNegativesFlag) {
if (lower > 10.0D) {
logFloor = Math.log(lower) / LOG10_VALUE;
logFloor = Math.floor(logFloor);
logFloor = Math.pow(10.0D, logFloor);
} else if (lower < -10.0D) {
logFloor = Math.log(-lower) / LOG10_VALUE;
logFloor = Math.floor(-logFloor);
logFloor = -Math.pow(10.0D, -logFloor);
} else {
logFloor = Math.floor(lower);
}
} else if (lower > 0.0D) {
logFloor = Math.log(lower) / LOG10_VALUE;
logFloor = Math.floor(logFloor);
logFloor = Math.pow(10.0D, logFloor);
} else {
logFloor = Math.floor(lower);
}
return logFloor;
}
protected double computeLogCeil(double upper) {
double logCeil;
if (this.allowNegativesFlag) {
if (upper > 10.0D) {
logCeil = Math.log(upper) / LOG10_VALUE;
logCeil = Math.ceil(logCeil);
logCeil = Math.pow(10.0D, logCeil);
} else if (upper < -10.0D) {
logCeil = Math.log(-upper) / LOG10_VALUE;
logCeil = Math.ceil(-logCeil);
logCeil = -Math.pow(10.0D, -logCeil);
} else {
logCeil = Math.ceil(upper);
}
} else if (upper > 0.0D) {
logCeil = Math.log(upper) / LOG10_VALUE;
logCeil = Math.ceil(logCeil);
logCeil = Math.pow(10.0D, logCeil);
} else {
logCeil = Math.ceil(upper);
}
return logCeil;
}
public void autoAdjustRange() {
Plot plot = getPlot();
if (plot == null)
return;
if (plot instanceof ValueAxisPlot) {
double lower;
ValueAxisPlot vap = (ValueAxisPlot)plot;
Range r = vap.getDataRange(this);
if (r == null) {
r = getDefaultAutoRange();
lower = r.getLowerBound();
} else {
lower = r.getLowerBound();
if (this.strictValuesFlag && !this.allowNegativesFlag && lower <= 0.0D)
throw new RuntimeException("Values less than or equal to zero not allowed with logarithmic axis");
}
double lowerMargin;
if (lower > 0.0D && (lowerMargin = getLowerMargin()) > 0.0D) {
double logLower = Math.log(lower) / LOG10_VALUE;
double logAbs;
if ((logAbs = Math.abs(logLower)) < 1.0D)
logAbs = 1.0D;
lower = Math.pow(10.0D, logLower - logAbs * lowerMargin);
}
if (this.autoRangeNextLogFlag)
lower = computeLogFloor(lower);
if (!this.allowNegativesFlag && lower >= 0.0D && lower < 1.0E-100D)
lower = r.getLowerBound();
double upper = r.getUpperBound();
double upperMargin;
if (upper > 0.0D && (upperMargin = getUpperMargin()) > 0.0D) {
double logUpper = Math.log(upper) / LOG10_VALUE;
double logAbs;
if ((logAbs = Math.abs(logUpper)) < 1.0D)
logAbs = 1.0D;
upper = Math.pow(10.0D, logUpper + logAbs * upperMargin);
}
if (!this.allowNegativesFlag && upper < 1.0D && upper > 0.0D && lower > 0.0D) {
double expVal = Math.log(upper) / LOG10_VALUE;
expVal = Math.ceil(-expVal + 0.001D);
expVal = Math.pow(10.0D, expVal);
upper = (expVal > 0.0D) ? (Math.ceil(upper * expVal) / expVal) : Math.ceil(upper);
} else {
upper = this.autoRangeNextLogFlag ? computeLogCeil(upper) : Math.ceil(upper);
}
double minRange = getAutoRangeMinimumSize();
if (upper - lower < minRange) {
upper = (upper + lower + minRange) / 2.0D;
lower = (upper + lower - minRange) / 2.0D;
if (upper - lower < minRange) {
double absUpper = Math.abs(upper);
double adjVal = (absUpper > 1.0E-100D) ? (absUpper / 100.0D) : 0.01D;
upper = (upper + lower + adjVal) / 2.0D;
lower = (upper + lower - adjVal) / 2.0D;
}
}
setRange(new Range(lower, upper), false, false);
setupSmallLogFlag();
}
}
public double valueToJava2D(double value, Rectangle2D plotArea, RectangleEdge edge) {
Range range = getRange();
double axisMin = switchedLog10(range.getLowerBound());
double axisMax = switchedLog10(range.getUpperBound());
double min = 0.0D;
double max = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
min = plotArea.getMinX();
max = plotArea.getMaxX();
} else if (RectangleEdge.isLeftOrRight(edge)) {
min = plotArea.getMaxY();
max = plotArea.getMinY();
}
value = switchedLog10(value);
if (isInverted())
return max - (value - axisMin) / (axisMax - axisMin) * (max - min);
return min + (value - axisMin) / (axisMax - axisMin) * (max - min);
}
public double java2DToValue(double java2DValue, Rectangle2D plotArea, RectangleEdge edge) {
Range range = getRange();
double axisMin = switchedLog10(range.getLowerBound());
double axisMax = switchedLog10(range.getUpperBound());
double plotMin = 0.0D;
double plotMax = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
plotMin = plotArea.getX();
plotMax = plotArea.getMaxX();
} else if (RectangleEdge.isLeftOrRight(edge)) {
plotMin = plotArea.getMaxY();
plotMax = plotArea.getMinY();
}
if (isInverted())
return switchedPow10(axisMax - (java2DValue - plotMin) / (plotMax - plotMin) * (axisMax - axisMin));
return switchedPow10(axisMin + (java2DValue - plotMin) / (plotMax - plotMin) * (axisMax - axisMin));
}
public void zoomRange(double lowerPercent, double upperPercent) {
Range adjusted;
double startLog = switchedLog10(getRange().getLowerBound());
double lengthLog = switchedLog10(getRange().getUpperBound()) - startLog;
if (isInverted()) {
adjusted = new Range(switchedPow10(startLog + lengthLog * (1.0D - upperPercent)), switchedPow10(startLog + lengthLog * (1.0D - lowerPercent)));
} else {
adjusted = new Range(switchedPow10(startLog + lengthLog * lowerPercent), switchedPow10(startLog + lengthLog * upperPercent));
}
setRange(adjusted);
}
protected List refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List ticks = new ArrayList();
Range range = getRange();
double lowerBoundVal = range.getLowerBound();
if (this.smallLogFlag && lowerBoundVal < 1.0E-100D)
lowerBoundVal = 1.0E-100D;
double upperBoundVal = range.getUpperBound();
int iBegCount = (int)Math.rint(switchedLog10(lowerBoundVal));
int iEndCount = (int)Math.rint(switchedLog10(upperBoundVal));
if (iBegCount == iEndCount && iBegCount > 0 && Math.pow(10.0D, (double)iBegCount) > lowerBoundVal)
iBegCount--;
boolean zeroTickFlag = false;
for (int i = iBegCount; i <= iEndCount; i++) {
for (int j = 0; j < 10; j++) {
double currentTickValue;
String tickLabel;
if (this.smallLogFlag) {
currentTickValue = Math.pow(10.0D, (double)i) + Math.pow(10.0D, (double)i) * (double)j;
if (this.expTickLabelsFlag || (i < 0 && currentTickValue > 0.0D && currentTickValue < 1.0D)) {
if (j == 0 || (i > -4 && j < 2) || currentTickValue >= upperBoundVal) {
this.numberFormatterObj.setMaximumFractionDigits(-i);
tickLabel = makeTickLabel(currentTickValue, true);
} else {
tickLabel = "";
}
} else {
tickLabel = (j < 1 || (i < 1 && j < 5) || j < 4 - i || currentTickValue >= upperBoundVal) ? makeTickLabel(currentTickValue) : "";
}
} else {
if (zeroTickFlag)
j--;
currentTickValue = (i >= 0) ? (Math.pow(10.0D, (double)i) + Math.pow(10.0D, (double)i) * (double)j) : -(Math.pow(10.0D, (double)-i) - Math.pow(10.0D, (double)(-i - 1)) * (double)j);
if (!zeroTickFlag) {
if (Math.abs(currentTickValue - 1.0D) < 1.0E-4D && lowerBoundVal <= 0.0D && upperBoundVal >= 0.0D) {
currentTickValue = 0.0D;
zeroTickFlag = true;
}
} else {
zeroTickFlag = false;
}
tickLabel = ((this.expTickLabelsFlag && j < 2) || j < 1 || (i < 1 && j < 5) || j < 4 - i || currentTickValue >= upperBoundVal) ? makeTickLabel(currentTickValue) : "";
}
if (currentTickValue > upperBoundVal)
return ticks;
if (currentTickValue >= lowerBoundVal - 1.0E-100D) {
TextAnchor anchor = null;
TextAnchor rotationAnchor = null;
double angle = 0.0D;
if (isVerticalTickLabels()) {
anchor = TextAnchor.CENTER_RIGHT;
rotationAnchor = TextAnchor.CENTER_RIGHT;
if (edge == RectangleEdge.TOP) {
angle = 1.5707963267948966D;
} else {
angle = -1.5707963267948966D;
}
} else if (edge == RectangleEdge.TOP) {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
} else {
anchor = TextAnchor.TOP_CENTER;
rotationAnchor = TextAnchor.TOP_CENTER;
}
Tick tick = new NumberTick(new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle);
ticks.add(tick);
}
}
}
return ticks;
}
protected List refreshTicksVertical(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List ticks = new ArrayList();
double lowerBoundVal = getRange().getLowerBound();
if (this.smallLogFlag && lowerBoundVal < 1.0E-100D)
lowerBoundVal = 1.0E-100D;
double upperBoundVal = getRange().getUpperBound();
int iBegCount = (int)Math.rint(switchedLog10(lowerBoundVal));
int iEndCount = (int)Math.rint(switchedLog10(upperBoundVal));
if (iBegCount == iEndCount && iBegCount > 0 && Math.pow(10.0D, (double)iBegCount) > lowerBoundVal)
iBegCount--;
boolean zeroTickFlag = false;
for (int i = iBegCount; i <= iEndCount; i++) {
int jEndCount = 10;
if (i == iEndCount)
jEndCount = 1;
for (int j = 0; j < jEndCount; j++) {
double tickVal;
String tickLabel;
if (this.smallLogFlag) {
tickVal = Math.pow(10.0D, (double)i) + Math.pow(10.0D, (double)i) * (double)j;
if (j == 0) {
if (this.log10TickLabelsFlag) {
tickLabel = "10^" + i;
} else if (this.expTickLabelsFlag) {
tickLabel = "1e" + i;
} else if (i >= 0) {
NumberFormat format = getNumberFormatOverride();
if (format != null) {
tickLabel = format.format(tickVal);
} else {
tickLabel = Long.toString((long)Math.rint(tickVal));
}
} else {
this.numberFormatterObj.setMaximumFractionDigits(-i);
tickLabel = this.numberFormatterObj.format(tickVal);
}
} else {
tickLabel = "";
}
} else {
if (zeroTickFlag)
j--;
tickVal = (i >= 0) ? (Math.pow(10.0D, (double)i) + Math.pow(10.0D, (double)i) * (double)j) : -(Math.pow(10.0D, (double)-i) - Math.pow(10.0D, (double)(-i - 1)) * (double)j);
if (j == 0) {
if (!zeroTickFlag) {
if (i > iBegCount && i < iEndCount && Math.abs(tickVal - 1.0D) < 1.0E-4D) {
tickVal = 0.0D;
zeroTickFlag = true;
tickLabel = "0";
} else if (this.log10TickLabelsFlag) {
tickLabel = ((i < 0) ? "-" : "") + "10^" + Math.abs(i);
} else if (this.expTickLabelsFlag) {
tickLabel = ((i < 0) ? "-" : "") + "1e" + Math.abs(i);
} else {
NumberFormat format = getNumberFormatOverride();
if (format != null) {
tickLabel = format.format(tickVal);
} else {
tickLabel = Long.toString((long)Math.rint(tickVal));
}
}
} else {
tickLabel = "";
zeroTickFlag = false;
}
} else {
tickLabel = "";
zeroTickFlag = false;
}
}
if (tickVal > upperBoundVal)
return ticks;
if (tickVal >= lowerBoundVal - 1.0E-100D) {
TextAnchor anchor = null;
TextAnchor rotationAnchor = null;
double angle = 0.0D;
if (isVerticalTickLabels()) {
if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
angle = -1.5707963267948966D;
} else {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
angle = 1.5707963267948966D;
}
} else if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.CENTER_RIGHT;
rotationAnchor = TextAnchor.CENTER_RIGHT;
} else {
anchor = TextAnchor.CENTER_LEFT;
rotationAnchor = TextAnchor.CENTER_LEFT;
}
ticks.add(new NumberTick(new Double(tickVal), tickLabel, anchor, rotationAnchor, angle));
}
}
}
return ticks;
}
protected String makeTickLabel(double val, boolean forceFmtFlag) {
if (this.expTickLabelsFlag || forceFmtFlag)
return this.numberFormatterObj.format(val).toLowerCase();
return getTickUnit().valueToString(val);
}
protected String makeTickLabel(double val) {
return makeTickLabel(val, false);
}
}

View file

@ -0,0 +1,120 @@
package org.jfree.chart.axis;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.jfree.chart.plot.IntervalMarker;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.ObjectUtilities;
public class MarkerAxisBand implements Serializable {
private static final long serialVersionUID = -1729482413886398919L;
private NumberAxis axis;
private double topOuterGap;
private double topInnerGap;
private double bottomOuterGap;
private double bottomInnerGap;
private Font font;
private List markers;
public MarkerAxisBand(NumberAxis axis, double topOuterGap, double topInnerGap, double bottomOuterGap, double bottomInnerGap, Font font) {
this.axis = axis;
this.topOuterGap = topOuterGap;
this.topInnerGap = topInnerGap;
this.bottomOuterGap = bottomOuterGap;
this.bottomInnerGap = bottomInnerGap;
this.font = font;
this.markers = new ArrayList();
}
public void addMarker(IntervalMarker marker) {
this.markers.add(marker);
}
public double getHeight(Graphics2D g2) {
double result = 0.0D;
if (this.markers.size() > 0) {
LineMetrics metrics = this.font.getLineMetrics("123g", g2.getFontRenderContext());
result = this.topOuterGap + this.topInnerGap + (double)metrics.getHeight() + this.bottomInnerGap + this.bottomOuterGap;
}
return result;
}
private void drawStringInRect(Graphics2D g2, Rectangle2D bounds, Font font, String text) {
g2.setFont(font);
FontMetrics fm = g2.getFontMetrics(font);
Rectangle2D r = TextUtilities.getTextBounds(text, g2, fm);
double x = bounds.getX();
if (r.getWidth() < bounds.getWidth())
x += (bounds.getWidth() - r.getWidth()) / 2.0D;
LineMetrics metrics = font.getLineMetrics(text, g2.getFontRenderContext());
g2.drawString(text, (float)x, (float)(bounds.getMaxY() - this.bottomInnerGap - (double)metrics.getDescent()));
}
public void draw(Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, double x, double y) {
double h = getHeight(g2);
Iterator iterator = this.markers.iterator();
while (iterator.hasNext()) {
IntervalMarker marker = (IntervalMarker)iterator.next();
double start = Math.max(marker.getStartValue(), this.axis.getRange().getLowerBound());
double end = Math.min(marker.getEndValue(), this.axis.getRange().getUpperBound());
double s = this.axis.valueToJava2D(start, dataArea, RectangleEdge.BOTTOM);
double e = this.axis.valueToJava2D(end, dataArea, RectangleEdge.BOTTOM);
Rectangle2D r = new Rectangle2D.Double(s, y + this.topOuterGap, e - s, h - this.topOuterGap - this.bottomOuterGap);
Composite originalComposite = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(3, marker.getAlpha()));
g2.setPaint(marker.getPaint());
g2.fill(r);
g2.setPaint(marker.getOutlinePaint());
g2.draw(r);
g2.setComposite(originalComposite);
g2.setPaint(Color.black);
drawStringInRect(g2, r, this.font, marker.getLabel());
}
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof MarkerAxisBand))
return false;
MarkerAxisBand that = (MarkerAxisBand)obj;
if (this.topOuterGap != that.topOuterGap)
return false;
if (this.topInnerGap != that.topInnerGap)
return false;
if (this.bottomInnerGap != that.bottomInnerGap)
return false;
if (this.bottomOuterGap != that.bottomOuterGap)
return false;
if (!ObjectUtilities.equal(this.font, that.font))
return false;
if (!ObjectUtilities.equal(this.markers, that.markers))
return false;
return true;
}
public int hashCode() {
int result = 37;
result = 19 * result + this.font.hashCode();
result = 19 * result + this.markers.hashCode();
return result;
}
}

View file

@ -0,0 +1,176 @@
package org.jfree.chart.axis;
import java.awt.geom.Rectangle2D;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.data.Range;
import org.jfree.ui.RectangleEdge;
public class ModuloAxis extends NumberAxis {
private Range fixedRange;
private double displayStart;
private double displayEnd;
public ModuloAxis(String label, Range fixedRange) {
super(label);
this.fixedRange = fixedRange;
this.displayStart = 270.0D;
this.displayEnd = 90.0D;
}
public double getDisplayStart() {
return this.displayStart;
}
public double getDisplayEnd() {
return this.displayEnd;
}
public void setDisplayRange(double start, double end) {
this.displayStart = mapValueToFixedRange(start);
this.displayEnd = mapValueToFixedRange(end);
if (this.displayStart < this.displayEnd) {
setRange(this.displayStart, this.displayEnd);
} else {
setRange(this.displayStart, this.fixedRange.getUpperBound() + this.displayEnd - this.fixedRange.getLowerBound());
}
notifyListeners(new AxisChangeEvent(this));
}
protected void autoAdjustRange() {
setRange(this.fixedRange, false, false);
}
public double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge) {
double result = 0.0D;
double v = mapValueToFixedRange(value);
if (this.displayStart < this.displayEnd) {
result = trans(v, area, edge);
} else {
double cutoff = (this.displayStart + this.displayEnd) / 2.0D;
double length1 = this.fixedRange.getUpperBound() - this.displayStart;
double length2 = this.displayEnd - this.fixedRange.getLowerBound();
if (v > cutoff) {
result = transStart(v, area, edge, length1, length2);
} else {
result = transEnd(v, area, edge, length1, length2);
}
}
return result;
}
private double trans(double value, Rectangle2D area, RectangleEdge edge) {
double min = 0.0D;
double max = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
min = area.getX();
max = area.getX() + area.getWidth();
} else if (RectangleEdge.isLeftOrRight(edge)) {
min = area.getMaxY();
max = area.getMaxY() - area.getHeight();
}
if (isInverted())
return max - (value - this.displayStart) / (this.displayEnd - this.displayStart) * (max - min);
return min + (value - this.displayStart) / (this.displayEnd - this.displayStart) * (max - min);
}
private double transStart(double value, Rectangle2D area, RectangleEdge edge, double length1, double length2) {
double min = 0.0D;
double max = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
min = area.getX();
max = area.getX() + area.getWidth() * length1 / (length1 + length2);
} else if (RectangleEdge.isLeftOrRight(edge)) {
min = area.getMaxY();
max = area.getMaxY() - area.getHeight() * length1 / (length1 + length2);
}
if (isInverted())
return max - (value - this.displayStart) / (this.fixedRange.getUpperBound() - this.displayStart) * (max - min);
return min + (value - this.displayStart) / (this.fixedRange.getUpperBound() - this.displayStart) * (max - min);
}
private double transEnd(double value, Rectangle2D area, RectangleEdge edge, double length1, double length2) {
double min = 0.0D;
double max = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
max = area.getMaxX();
min = area.getMaxX() - area.getWidth() * length2 / (length1 + length2);
} else if (RectangleEdge.isLeftOrRight(edge)) {
max = area.getMinY();
min = area.getMinY() + area.getHeight() * length2 / (length1 + length2);
}
if (isInverted())
return max - (value - this.fixedRange.getLowerBound()) / (this.displayEnd - this.fixedRange.getLowerBound()) * (max - min);
return min + (value - this.fixedRange.getLowerBound()) / (this.displayEnd - this.fixedRange.getLowerBound()) * (max - min);
}
private double mapValueToFixedRange(double value) {
double lower = this.fixedRange.getLowerBound();
double length = this.fixedRange.getLength();
if (value < lower)
return lower + length + (value - lower) % length;
return lower + (value - lower) % length;
}
public double java2DToValue(double java2DValue, Rectangle2D area, RectangleEdge edge) {
double result = 0.0D;
if (this.displayStart < this.displayEnd)
result = super.java2DToValue(java2DValue, area, edge);
return result;
}
private double getDisplayLength() {
if (this.displayStart < this.displayEnd)
return this.displayEnd - this.displayStart;
return this.fixedRange.getUpperBound() - this.displayStart + this.displayEnd - this.fixedRange.getLowerBound();
}
private double getDisplayCentralValue() {
return mapValueToFixedRange(this.displayStart + getDisplayLength() / 2.0D);
}
public void resizeRange(double percent) {
resizeRange(percent, getDisplayCentralValue());
}
public void resizeRange(double percent, double anchorValue) {
if (percent > 0.0D) {
double halfLength = getDisplayLength() * percent / 2.0D;
setDisplayRange(anchorValue - halfLength, anchorValue + halfLength);
} else {
setAutoRange(true);
}
}
public double lengthToJava2D(double length, Rectangle2D area, RectangleEdge edge) {
double axisLength = 0.0D;
if (this.displayEnd > this.displayStart) {
axisLength = this.displayEnd - this.displayStart;
} else {
axisLength = this.fixedRange.getUpperBound() - this.displayStart + this.displayEnd - this.fixedRange.getLowerBound();
}
double areaLength = 0.0D;
if (RectangleEdge.isLeftOrRight(edge)) {
areaLength = area.getHeight();
} else {
areaLength = area.getWidth();
}
return length / axisLength * areaLength;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof ModuloAxis))
return false;
ModuloAxis that = (ModuloAxis)obj;
if (this.displayStart != that.displayStart)
return false;
if (this.displayEnd != that.displayEnd)
return false;
if (!this.fixedRange.equals(that.fixedRange))
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,147 @@
package org.jfree.chart.axis;
import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import org.jfree.data.time.Month;
public class MonthDateFormat extends DateFormat {
private String[] months;
private boolean[] showYear;
private DateFormat yearFormatter;
public MonthDateFormat() {
this(TimeZone.getDefault());
}
public MonthDateFormat(TimeZone zone) {
this(zone, Locale.getDefault(), 1, true, false);
}
public MonthDateFormat(Locale locale) {
this(TimeZone.getDefault(), locale, 1, true, false);
}
public MonthDateFormat(TimeZone zone, int chars) {
this(zone, Locale.getDefault(), chars, true, false);
}
public MonthDateFormat(Locale locale, int chars) {
this(TimeZone.getDefault(), locale, chars, true, false);
}
public MonthDateFormat(TimeZone zone, Locale locale, int chars, boolean showYearForJan, boolean showYearForDec) {
this(zone, locale, chars, new boolean[] {
showYearForJan, false, false, false, false, false, false, false, false, false,
false, false, showYearForDec }, new SimpleDateFormat("yy"));
}
public MonthDateFormat(TimeZone zone, Locale locale, int chars, boolean[] showYear, DateFormat yearFormatter) {
if (locale == null)
throw new IllegalArgumentException("Null 'locale' argument.");
DateFormatSymbols dfs = new DateFormatSymbols(locale);
String[] monthsFromLocale = dfs.getMonths();
this.months = new String[12];
for (int i = 0; i < 12; i++) {
if (chars > 0) {
this.months[i] = monthsFromLocale[i].substring(0, Math.min(chars, monthsFromLocale[i].length()));
} else {
this.months[i] = monthsFromLocale[i];
}
}
this.calendar = new GregorianCalendar(zone);
this.showYear = showYear;
this.yearFormatter = yearFormatter;
this.numberFormat = NumberFormat.getNumberInstance();
}
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
this.calendar.setTime(date);
int month = this.calendar.get(2);
toAppendTo.append(this.months[month]);
if (this.showYear[month])
toAppendTo.append(this.yearFormatter.format(date));
return toAppendTo;
}
public Date parse(String source, ParsePosition pos) {
return null;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof MonthDateFormat))
return false;
if (!super.equals(obj))
return false;
MonthDateFormat that = (MonthDateFormat)obj;
if (!Arrays.equals(this.months, that.months))
return false;
if (!Arrays.equals(this.showYear, that.showYear))
return false;
if (!this.yearFormatter.equals(that.yearFormatter))
return false;
return true;
}
public static void main(String[] args) {
MonthDateFormat mdf = new MonthDateFormat(Locale.UK, 2);
System.out.println("UK:");
System.out.println(mdf.format(new Month(1, 2005).getStart()));
System.out.println(mdf.format(new Month(2, 2005).getStart()));
System.out.println(mdf.format(new Month(3, 2005).getStart()));
System.out.println(mdf.format(new Month(4, 2005).getStart()));
System.out.println(mdf.format(new Month(5, 2005).getStart()));
System.out.println(mdf.format(new Month(6, 2005).getStart()));
System.out.println(mdf.format(new Month(7, 2005).getStart()));
System.out.println(mdf.format(new Month(8, 2005).getStart()));
System.out.println(mdf.format(new Month(9, 2005).getStart()));
System.out.println(mdf.format(new Month(10, 2005).getStart()));
System.out.println(mdf.format(new Month(11, 2005).getStart()));
System.out.println(mdf.format(new Month(12, 2005).getStart()));
System.out.println();
mdf = new MonthDateFormat(Locale.GERMANY, 2);
System.out.println("GERMANY:");
System.out.println(mdf.format(new Month(1, 2005).getStart()));
System.out.println(mdf.format(new Month(2, 2005).getStart()));
System.out.println(mdf.format(new Month(3, 2005).getStart()));
System.out.println(mdf.format(new Month(4, 2005).getStart()));
System.out.println(mdf.format(new Month(5, 2005).getStart()));
System.out.println(mdf.format(new Month(6, 2005).getStart()));
System.out.println(mdf.format(new Month(7, 2005).getStart()));
System.out.println(mdf.format(new Month(8, 2005).getStart()));
System.out.println(mdf.format(new Month(9, 2005).getStart()));
System.out.println(mdf.format(new Month(10, 2005).getStart()));
System.out.println(mdf.format(new Month(11, 2005).getStart()));
System.out.println(mdf.format(new Month(12, 2005).getStart()));
System.out.println();
mdf = new MonthDateFormat(Locale.FRANCE, 2);
System.out.println("FRANCE:");
System.out.println(mdf.format(new Month(1, 2005).getStart()));
System.out.println(mdf.format(new Month(2, 2005).getStart()));
System.out.println(mdf.format(new Month(3, 2005).getStart()));
System.out.println(mdf.format(new Month(4, 2005).getStart()));
System.out.println(mdf.format(new Month(5, 2005).getStart()));
System.out.println(mdf.format(new Month(6, 2005).getStart()));
System.out.println(mdf.format(new Month(7, 2005).getStart()));
System.out.println(mdf.format(new Month(8, 2005).getStart()));
System.out.println(mdf.format(new Month(9, 2005).getStart()));
System.out.println(mdf.format(new Month(10, 2005).getStart()));
System.out.println(mdf.format(new Month(11, 2005).getStart()));
System.out.println(mdf.format(new Month(12, 2005).getStart()));
System.out.println();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
sdf.setNumberFormat(null);
}
}

View file

@ -0,0 +1,690 @@
package org.jfree.chart.axis;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.ValueAxisPlot;
import org.jfree.data.Range;
import org.jfree.data.RangeType;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
import org.jfree.util.ObjectUtilities;
public class NumberAxis extends ValueAxis implements Cloneable, Serializable {
private static final long serialVersionUID = 2805933088476185789L;
public static final boolean DEFAULT_AUTO_RANGE_INCLUDES_ZERO = true;
public static final boolean DEFAULT_AUTO_RANGE_STICKY_ZERO = true;
public static final NumberTickUnit DEFAULT_TICK_UNIT = new NumberTickUnit(1.0D, new DecimalFormat("0"));
public static final boolean DEFAULT_VERTICAL_TICK_LABELS = false;
private RangeType rangeType;
private boolean autoRangeIncludesZero;
private boolean autoRangeStickyZero;
private NumberTickUnit tickUnit;
private NumberFormat numberFormatOverride;
private MarkerAxisBand markerBand;
public NumberAxis() {
this(null);
}
public NumberAxis(String label) {
super(label, createStandardTickUnits());
this.rangeType = RangeType.FULL;
this.autoRangeIncludesZero = true;
this.autoRangeStickyZero = true;
this.tickUnit = DEFAULT_TICK_UNIT;
this.numberFormatOverride = null;
this.markerBand = null;
}
public RangeType getRangeType() {
return this.rangeType;
}
public void setRangeType(RangeType rangeType) {
if (rangeType == null)
throw new IllegalArgumentException("Null 'rangeType' argument.");
this.rangeType = rangeType;
notifyListeners(new AxisChangeEvent(this));
}
public boolean getAutoRangeIncludesZero() {
return this.autoRangeIncludesZero;
}
public void setAutoRangeIncludesZero(boolean flag) {
if (this.autoRangeIncludesZero != flag) {
this.autoRangeIncludesZero = flag;
if (isAutoRange())
autoAdjustRange();
notifyListeners(new AxisChangeEvent(this));
}
}
public boolean getAutoRangeStickyZero() {
return this.autoRangeStickyZero;
}
public void setAutoRangeStickyZero(boolean flag) {
if (this.autoRangeStickyZero != flag) {
this.autoRangeStickyZero = flag;
if (isAutoRange())
autoAdjustRange();
notifyListeners(new AxisChangeEvent(this));
}
}
public NumberTickUnit getTickUnit() {
return this.tickUnit;
}
public void setTickUnit(NumberTickUnit unit) {
setTickUnit(unit, true, true);
}
public void setTickUnit(NumberTickUnit unit, boolean notify, boolean turnOffAutoSelect) {
if (unit == null)
throw new IllegalArgumentException("Null 'unit' argument.");
this.tickUnit = unit;
if (turnOffAutoSelect)
setAutoTickUnitSelection(false, false);
if (notify)
notifyListeners(new AxisChangeEvent(this));
}
public NumberFormat getNumberFormatOverride() {
return this.numberFormatOverride;
}
public void setNumberFormatOverride(NumberFormat formatter) {
this.numberFormatOverride = formatter;
notifyListeners(new AxisChangeEvent(this));
}
public MarkerAxisBand getMarkerBand() {
return this.markerBand;
}
public void setMarkerBand(MarkerAxisBand band) {
this.markerBand = band;
notifyListeners(new AxisChangeEvent(this));
}
public void configure() {
if (isAutoRange())
autoAdjustRange();
}
protected void autoAdjustRange() {
Plot plot = getPlot();
if (plot == null)
return;
if (plot instanceof ValueAxisPlot) {
ValueAxisPlot vap = (ValueAxisPlot)plot;
Range r = vap.getDataRange(this);
if (r == null)
r = getDefaultAutoRange();
double upper = r.getUpperBound();
double lower = r.getLowerBound();
if (this.rangeType == RangeType.POSITIVE) {
lower = Math.max(0.0D, lower);
upper = Math.max(0.0D, upper);
} else if (this.rangeType == RangeType.NEGATIVE) {
lower = Math.min(0.0D, lower);
upper = Math.min(0.0D, upper);
}
if (getAutoRangeIncludesZero()) {
lower = Math.min(lower, 0.0D);
upper = Math.max(upper, 0.0D);
}
double range = upper - lower;
double fixedAutoRange = getFixedAutoRange();
if (fixedAutoRange > 0.0D) {
lower = upper - fixedAutoRange;
} else {
double minRange = getAutoRangeMinimumSize();
if (range < minRange) {
double expand = (minRange - range) / 2.0D;
upper += expand;
lower -= expand;
if (lower == upper) {
double adjust = Math.abs(lower) / 10.0D;
lower -= adjust;
upper += adjust;
}
if (this.rangeType == RangeType.POSITIVE) {
if (lower < 0.0D) {
upper -= lower;
lower = 0.0D;
}
} else if (this.rangeType == RangeType.NEGATIVE &&
upper > 0.0D) {
lower -= upper;
upper = 0.0D;
}
}
if (getAutoRangeStickyZero()) {
if (upper <= 0.0D) {
upper = Math.min(0.0D, upper + getUpperMargin() * range);
} else {
upper += getUpperMargin() * range;
}
if (lower >= 0.0D) {
lower = Math.max(0.0D, lower - getLowerMargin() * range);
} else {
lower -= getLowerMargin() * range;
}
} else {
upper += getUpperMargin() * range;
lower -= getLowerMargin() * range;
}
}
setRange(new Range(lower, upper), false, false);
}
}
public double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge) {
Range range = getRange();
double axisMin = range.getLowerBound();
double axisMax = range.getUpperBound();
double min = 0.0D;
double max = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
min = area.getX();
max = area.getMaxX();
} else if (RectangleEdge.isLeftOrRight(edge)) {
max = area.getMinY();
min = area.getMaxY();
}
if (isInverted())
return max - (value - axisMin) / (axisMax - axisMin) * (max - min);
return min + (value - axisMin) / (axisMax - axisMin) * (max - min);
}
public double java2DToValue(double java2DValue, Rectangle2D area, RectangleEdge edge) {
Range range = getRange();
double axisMin = range.getLowerBound();
double axisMax = range.getUpperBound();
double min = 0.0D;
double max = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
min = area.getX();
max = area.getMaxX();
} else if (RectangleEdge.isLeftOrRight(edge)) {
min = area.getMaxY();
max = area.getY();
}
if (isInverted())
return axisMax - (java2DValue - min) / (max - min) * (axisMax - axisMin);
return axisMin + (java2DValue - min) / (max - min) * (axisMax - axisMin);
}
protected double calculateLowestVisibleTickValue() {
double unit = getTickUnit().getSize();
double index = Math.ceil(getRange().getLowerBound() / unit);
return index * unit;
}
protected double calculateHighestVisibleTickValue() {
double unit = getTickUnit().getSize();
double index = Math.floor(getRange().getUpperBound() / unit);
return index * unit;
}
protected int calculateVisibleTickCount() {
double unit = getTickUnit().getSize();
Range range = getRange();
return (int)(Math.floor(range.getUpperBound() / unit) - Math.ceil(range.getLowerBound() / unit) + 1.0D);
}
public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) {
AxisState state = null;
if (!isVisible()) {
state = new AxisState(cursor);
List ticks = refreshTicks(g2, state, dataArea, edge);
state.setTicks(ticks);
return state;
}
state = drawTickMarksAndLabels(g2, cursor, plotArea, dataArea, edge);
state = drawLabel(getLabel(), g2, plotArea, dataArea, edge, state);
return state;
}
public static TickUnitSource createStandardTickUnits() {
TickUnits units = new TickUnits();
DecimalFormat df0 = new DecimalFormat("0.00000000");
DecimalFormat df1 = new DecimalFormat("0.0000000");
DecimalFormat df2 = new DecimalFormat("0.000000");
DecimalFormat df3 = new DecimalFormat("0.00000");
DecimalFormat df4 = new DecimalFormat("0.0000");
DecimalFormat df5 = new DecimalFormat("0.000");
DecimalFormat df6 = new DecimalFormat("0.00");
DecimalFormat df7 = new DecimalFormat("0.0");
DecimalFormat df8 = new DecimalFormat("#,##0");
DecimalFormat df9 = new DecimalFormat("#,###,##0");
DecimalFormat df10 = new DecimalFormat("#,###,###,##0");
units.add(new NumberTickUnit(1.0E-7D, df1));
units.add(new NumberTickUnit(1.0E-6D, df2));
units.add(new NumberTickUnit(1.0E-5D, df3));
units.add(new NumberTickUnit(1.0E-4D, df4));
units.add(new NumberTickUnit(0.001D, df5));
units.add(new NumberTickUnit(0.01D, df6));
units.add(new NumberTickUnit(0.1D, df7));
units.add(new NumberTickUnit(1.0D, df8));
units.add(new NumberTickUnit(10.0D, df8));
units.add(new NumberTickUnit(100.0D, df8));
units.add(new NumberTickUnit(1000.0D, df8));
units.add(new NumberTickUnit(10000.0D, df8));
units.add(new NumberTickUnit(100000.0D, df8));
units.add(new NumberTickUnit(1000000.0D, df9));
units.add(new NumberTickUnit(1.0E7D, df9));
units.add(new NumberTickUnit(1.0E8D, df9));
units.add(new NumberTickUnit(1.0E9D, df10));
units.add(new NumberTickUnit(1.0E10D, df10));
units.add(new NumberTickUnit(1.0E11D, df10));
units.add(new NumberTickUnit(2.5E-7D, df0));
units.add(new NumberTickUnit(2.5E-6D, df1));
units.add(new NumberTickUnit(2.5E-5D, df2));
units.add(new NumberTickUnit(2.5E-4D, df3));
units.add(new NumberTickUnit(0.0025D, df4));
units.add(new NumberTickUnit(0.025D, df5));
units.add(new NumberTickUnit(0.25D, df6));
units.add(new NumberTickUnit(2.5D, df7));
units.add(new NumberTickUnit(25.0D, df8));
units.add(new NumberTickUnit(250.0D, df8));
units.add(new NumberTickUnit(2500.0D, df8));
units.add(new NumberTickUnit(25000.0D, df8));
units.add(new NumberTickUnit(250000.0D, df8));
units.add(new NumberTickUnit(2500000.0D, df9));
units.add(new NumberTickUnit(2.5E7D, df9));
units.add(new NumberTickUnit(2.5E8D, df9));
units.add(new NumberTickUnit(2.5E9D, df10));
units.add(new NumberTickUnit(2.5E10D, df10));
units.add(new NumberTickUnit(2.5E11D, df10));
units.add(new NumberTickUnit(5.0E-7D, df1));
units.add(new NumberTickUnit(5.0E-6D, df2));
units.add(new NumberTickUnit(5.0E-5D, df3));
units.add(new NumberTickUnit(5.0E-4D, df4));
units.add(new NumberTickUnit(0.005D, df5));
units.add(new NumberTickUnit(0.05D, df6));
units.add(new NumberTickUnit(0.5D, df7));
units.add(new NumberTickUnit(5.0D, df8));
units.add(new NumberTickUnit(50.0D, df8));
units.add(new NumberTickUnit(500.0D, df8));
units.add(new NumberTickUnit(5000.0D, df8));
units.add(new NumberTickUnit(50000.0D, df8));
units.add(new NumberTickUnit(500000.0D, df8));
units.add(new NumberTickUnit(5000000.0D, df9));
units.add(new NumberTickUnit(5.0E7D, df9));
units.add(new NumberTickUnit(5.0E8D, df9));
units.add(new NumberTickUnit(5.0E9D, df10));
units.add(new NumberTickUnit(5.0E10D, df10));
units.add(new NumberTickUnit(5.0E11D, df10));
return units;
}
public static TickUnitSource createIntegerTickUnits() {
TickUnits units = new TickUnits();
DecimalFormat df0 = new DecimalFormat("0");
DecimalFormat df1 = new DecimalFormat("#,##0");
units.add(new NumberTickUnit(1.0D, df0));
units.add(new NumberTickUnit(2.0D, df0));
units.add(new NumberTickUnit(5.0D, df0));
units.add(new NumberTickUnit(10.0D, df0));
units.add(new NumberTickUnit(20.0D, df0));
units.add(new NumberTickUnit(50.0D, df0));
units.add(new NumberTickUnit(100.0D, df0));
units.add(new NumberTickUnit(200.0D, df0));
units.add(new NumberTickUnit(500.0D, df0));
units.add(new NumberTickUnit(1000.0D, df1));
units.add(new NumberTickUnit(2000.0D, df1));
units.add(new NumberTickUnit(5000.0D, df1));
units.add(new NumberTickUnit(10000.0D, df1));
units.add(new NumberTickUnit(20000.0D, df1));
units.add(new NumberTickUnit(50000.0D, df1));
units.add(new NumberTickUnit(100000.0D, df1));
units.add(new NumberTickUnit(200000.0D, df1));
units.add(new NumberTickUnit(500000.0D, df1));
units.add(new NumberTickUnit(1000000.0D, df1));
units.add(new NumberTickUnit(2000000.0D, df1));
units.add(new NumberTickUnit(5000000.0D, df1));
units.add(new NumberTickUnit(1.0E7D, df1));
units.add(new NumberTickUnit(2.0E7D, df1));
units.add(new NumberTickUnit(5.0E7D, df1));
units.add(new NumberTickUnit(1.0E8D, df1));
units.add(new NumberTickUnit(2.0E8D, df1));
units.add(new NumberTickUnit(5.0E8D, df1));
units.add(new NumberTickUnit(1.0E9D, df1));
units.add(new NumberTickUnit(2.0E9D, df1));
units.add(new NumberTickUnit(5.0E9D, df1));
units.add(new NumberTickUnit(1.0E10D, df1));
return units;
}
public static TickUnitSource createStandardTickUnits(Locale locale) {
TickUnits units = new TickUnits();
NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
units.add(new NumberTickUnit(1.0E-7D, numberFormat));
units.add(new NumberTickUnit(1.0E-6D, numberFormat));
units.add(new NumberTickUnit(1.0E-5D, numberFormat));
units.add(new NumberTickUnit(1.0E-4D, numberFormat));
units.add(new NumberTickUnit(0.001D, numberFormat));
units.add(new NumberTickUnit(0.01D, numberFormat));
units.add(new NumberTickUnit(0.1D, numberFormat));
units.add(new NumberTickUnit(1.0D, numberFormat));
units.add(new NumberTickUnit(10.0D, numberFormat));
units.add(new NumberTickUnit(100.0D, numberFormat));
units.add(new NumberTickUnit(1000.0D, numberFormat));
units.add(new NumberTickUnit(10000.0D, numberFormat));
units.add(new NumberTickUnit(100000.0D, numberFormat));
units.add(new NumberTickUnit(1000000.0D, numberFormat));
units.add(new NumberTickUnit(1.0E7D, numberFormat));
units.add(new NumberTickUnit(1.0E8D, numberFormat));
units.add(new NumberTickUnit(1.0E9D, numberFormat));
units.add(new NumberTickUnit(1.0E10D, numberFormat));
units.add(new NumberTickUnit(2.5E-7D, numberFormat));
units.add(new NumberTickUnit(2.5E-6D, numberFormat));
units.add(new NumberTickUnit(2.5E-5D, numberFormat));
units.add(new NumberTickUnit(2.5E-4D, numberFormat));
units.add(new NumberTickUnit(0.0025D, numberFormat));
units.add(new NumberTickUnit(0.025D, numberFormat));
units.add(new NumberTickUnit(0.25D, numberFormat));
units.add(new NumberTickUnit(2.5D, numberFormat));
units.add(new NumberTickUnit(25.0D, numberFormat));
units.add(new NumberTickUnit(250.0D, numberFormat));
units.add(new NumberTickUnit(2500.0D, numberFormat));
units.add(new NumberTickUnit(25000.0D, numberFormat));
units.add(new NumberTickUnit(250000.0D, numberFormat));
units.add(new NumberTickUnit(2500000.0D, numberFormat));
units.add(new NumberTickUnit(2.5E7D, numberFormat));
units.add(new NumberTickUnit(2.5E8D, numberFormat));
units.add(new NumberTickUnit(2.5E9D, numberFormat));
units.add(new NumberTickUnit(2.5E10D, numberFormat));
units.add(new NumberTickUnit(5.0E-7D, numberFormat));
units.add(new NumberTickUnit(5.0E-6D, numberFormat));
units.add(new NumberTickUnit(5.0E-5D, numberFormat));
units.add(new NumberTickUnit(5.0E-4D, numberFormat));
units.add(new NumberTickUnit(0.005D, numberFormat));
units.add(new NumberTickUnit(0.05D, numberFormat));
units.add(new NumberTickUnit(0.5D, numberFormat));
units.add(new NumberTickUnit(5.0D, numberFormat));
units.add(new NumberTickUnit(50.0D, numberFormat));
units.add(new NumberTickUnit(500.0D, numberFormat));
units.add(new NumberTickUnit(5000.0D, numberFormat));
units.add(new NumberTickUnit(50000.0D, numberFormat));
units.add(new NumberTickUnit(500000.0D, numberFormat));
units.add(new NumberTickUnit(5000000.0D, numberFormat));
units.add(new NumberTickUnit(5.0E7D, numberFormat));
units.add(new NumberTickUnit(5.0E8D, numberFormat));
units.add(new NumberTickUnit(5.0E9D, numberFormat));
units.add(new NumberTickUnit(5.0E10D, numberFormat));
return units;
}
public static TickUnitSource createIntegerTickUnits(Locale locale) {
TickUnits units = new TickUnits();
NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
units.add(new NumberTickUnit(1.0D, numberFormat));
units.add(new NumberTickUnit(2.0D, numberFormat));
units.add(new NumberTickUnit(5.0D, numberFormat));
units.add(new NumberTickUnit(10.0D, numberFormat));
units.add(new NumberTickUnit(20.0D, numberFormat));
units.add(new NumberTickUnit(50.0D, numberFormat));
units.add(new NumberTickUnit(100.0D, numberFormat));
units.add(new NumberTickUnit(200.0D, numberFormat));
units.add(new NumberTickUnit(500.0D, numberFormat));
units.add(new NumberTickUnit(1000.0D, numberFormat));
units.add(new NumberTickUnit(2000.0D, numberFormat));
units.add(new NumberTickUnit(5000.0D, numberFormat));
units.add(new NumberTickUnit(10000.0D, numberFormat));
units.add(new NumberTickUnit(20000.0D, numberFormat));
units.add(new NumberTickUnit(50000.0D, numberFormat));
units.add(new NumberTickUnit(100000.0D, numberFormat));
units.add(new NumberTickUnit(200000.0D, numberFormat));
units.add(new NumberTickUnit(500000.0D, numberFormat));
units.add(new NumberTickUnit(1000000.0D, numberFormat));
units.add(new NumberTickUnit(2000000.0D, numberFormat));
units.add(new NumberTickUnit(5000000.0D, numberFormat));
units.add(new NumberTickUnit(1.0E7D, numberFormat));
units.add(new NumberTickUnit(2.0E7D, numberFormat));
units.add(new NumberTickUnit(5.0E7D, numberFormat));
units.add(new NumberTickUnit(1.0E8D, numberFormat));
units.add(new NumberTickUnit(2.0E8D, numberFormat));
units.add(new NumberTickUnit(5.0E8D, numberFormat));
units.add(new NumberTickUnit(1.0E9D, numberFormat));
units.add(new NumberTickUnit(2.0E9D, numberFormat));
units.add(new NumberTickUnit(5.0E9D, numberFormat));
units.add(new NumberTickUnit(1.0E10D, numberFormat));
return units;
}
protected double estimateMaximumTickLabelHeight(Graphics2D g2) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getTop() + tickLabelInsets.getBottom();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
result += (double)tickLabelFont.getLineMetrics("123", frc).getHeight();
return result;
}
protected double estimateMaximumTickLabelWidth(Graphics2D g2, TickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
if (isVerticalTickLabels()) {
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = getTickLabelFont().getLineMetrics("0", frc);
result += (double)lm.getHeight();
} else {
FontMetrics fm = g2.getFontMetrics(getTickLabelFont());
Range range = getRange();
double lower = range.getLowerBound();
double upper = range.getUpperBound();
String lowerStr = "";
String upperStr = "";
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
} else {
lowerStr = unit.valueToString(lower);
upperStr = unit.valueToString(upper);
}
double w1 = (double)fm.stringWidth(lowerStr);
double w2 = (double)fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
protected void selectAutoTickUnit(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
if (RectangleEdge.isTopOrBottom(edge)) {
selectHorizontalAutoTickUnit(g2, dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
selectVerticalAutoTickUnit(g2, dataArea, edge);
}
}
protected void selectHorizontalAutoTickUnit(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
double tickLabelWidth = estimateMaximumTickLabelWidth(g2, getTickUnit());
TickUnitSource tickUnits = getStandardTickUnits();
TickUnit unit1 = tickUnits.getCeilingTickUnit(getTickUnit());
double unit1Width = lengthToJava2D(unit1.getSize(), dataArea, edge);
double guess = tickLabelWidth / unit1Width * unit1.getSize();
NumberTickUnit unit2 = (NumberTickUnit)tickUnits.getCeilingTickUnit(guess);
double unit2Width = lengthToJava2D(unit2.getSize(), dataArea, edge);
tickLabelWidth = estimateMaximumTickLabelWidth(g2, unit2);
if (tickLabelWidth > unit2Width)
unit2 = (NumberTickUnit)tickUnits.getLargerTickUnit(unit2);
setTickUnit(unit2, false, false);
}
protected void selectVerticalAutoTickUnit(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
double tickLabelHeight = estimateMaximumTickLabelHeight(g2);
TickUnitSource tickUnits = getStandardTickUnits();
TickUnit unit1 = tickUnits.getCeilingTickUnit(getTickUnit());
double unitHeight = lengthToJava2D(unit1.getSize(), dataArea, edge);
double guess = tickLabelHeight / unitHeight * unit1.getSize();
NumberTickUnit unit2 = (NumberTickUnit)tickUnits.getCeilingTickUnit(guess);
double unit2Height = lengthToJava2D(unit2.getSize(), dataArea, edge);
tickLabelHeight = estimateMaximumTickLabelHeight(g2);
if (tickLabelHeight > unit2Height)
unit2 = (NumberTickUnit)tickUnits.getLargerTickUnit(unit2);
setTickUnit(unit2, false, false);
}
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List result = new ArrayList();
if (RectangleEdge.isTopOrBottom(edge)) {
result = refreshTicksHorizontal(g2, dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
result = refreshTicksVertical(g2, dataArea, edge);
}
return result;
}
protected List refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List result = new ArrayList();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection())
selectAutoTickUnit(g2, dataArea, edge);
double size = getTickUnit().getSize();
int count = calculateVisibleTickCount();
double lowestTickValue = calculateLowestVisibleTickValue();
if (count <= 500)
for (int i = 0; i < count; i++) {
String tickLabel;
double currentTickValue = lowestTickValue + (double)i * size;
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
} else {
tickLabel = getTickUnit().valueToString(currentTickValue);
}
TextAnchor anchor = null;
TextAnchor rotationAnchor = null;
double angle = 0.0D;
if (isVerticalTickLabels()) {
anchor = TextAnchor.CENTER_RIGHT;
rotationAnchor = TextAnchor.CENTER_RIGHT;
if (edge == RectangleEdge.TOP) {
angle = 1.5707963267948966D;
} else {
angle = -1.5707963267948966D;
}
} else if (edge == RectangleEdge.TOP) {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
} else {
anchor = TextAnchor.TOP_CENTER;
rotationAnchor = TextAnchor.TOP_CENTER;
}
Tick tick = new NumberTick(new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle);
result.add(tick);
}
return result;
}
protected List refreshTicksVertical(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List result = new ArrayList();
result.clear();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
if (isAutoTickUnitSelection())
selectAutoTickUnit(g2, dataArea, edge);
double size = getTickUnit().getSize();
int count = calculateVisibleTickCount();
double lowestTickValue = calculateLowestVisibleTickValue();
if (count <= 500)
for (int i = 0; i < count; i++) {
String tickLabel;
double currentTickValue = lowestTickValue + (double)i * size;
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
} else {
tickLabel = getTickUnit().valueToString(currentTickValue);
}
TextAnchor anchor = null;
TextAnchor rotationAnchor = null;
double angle = 0.0D;
if (isVerticalTickLabels()) {
if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
angle = -1.5707963267948966D;
} else {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
angle = 1.5707963267948966D;
}
} else if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.CENTER_RIGHT;
rotationAnchor = TextAnchor.CENTER_RIGHT;
} else {
anchor = TextAnchor.CENTER_LEFT;
rotationAnchor = TextAnchor.CENTER_LEFT;
}
Tick tick = new NumberTick(new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle);
result.add(tick);
}
return result;
}
public Object clone() throws CloneNotSupportedException {
NumberAxis clone = (NumberAxis)super.clone();
if (this.numberFormatOverride != null)
clone.numberFormatOverride = (NumberFormat)this.numberFormatOverride.clone();
return clone;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof NumberAxis))
return false;
if (!super.equals(obj))
return false;
NumberAxis that = (NumberAxis)obj;
if (this.autoRangeIncludesZero != that.autoRangeIncludesZero)
return false;
if (this.autoRangeStickyZero != that.autoRangeStickyZero)
return false;
if (!ObjectUtilities.equal(this.tickUnit, that.tickUnit))
return false;
if (!ObjectUtilities.equal(this.numberFormatOverride, that.numberFormatOverride))
return false;
if (!this.rangeType.equals(that.rangeType))
return false;
return true;
}
public int hashCode() {
if (getLabel() != null)
return getLabel().hashCode();
return 0;
}
}

View file

@ -0,0 +1,59 @@
package org.jfree.chart.axis;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.List;
import org.jfree.chart.Effect3D;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.ui.RectangleEdge;
public class NumberAxis3D extends NumberAxis implements Serializable {
private static final long serialVersionUID = -1790205852569123512L;
public NumberAxis3D() {
this(null);
}
public NumberAxis3D(String label) {
super(label);
setAxisLineVisible(false);
}
public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) {
if (!isVisible()) {
AxisState state = new AxisState(cursor);
List ticks = refreshTicks(g2, state, dataArea, edge);
state.setTicks(ticks);
return state;
}
double xOffset = 0.0D;
double yOffset = 0.0D;
Plot plot = getPlot();
if (plot instanceof CategoryPlot) {
CategoryPlot cp = (CategoryPlot)plot;
CategoryItemRenderer r = cp.getRenderer();
if (r instanceof Effect3D) {
Effect3D e3D = (Effect3D)r;
xOffset = e3D.getXOffset();
yOffset = e3D.getYOffset();
}
}
double adjustedX = dataArea.getMinX();
double adjustedY = dataArea.getMinY();
double adjustedW = dataArea.getWidth() - xOffset;
double adjustedH = dataArea.getHeight() - yOffset;
if (edge == RectangleEdge.LEFT || edge == RectangleEdge.BOTTOM) {
adjustedY += yOffset;
} else if (edge == RectangleEdge.RIGHT || edge == RectangleEdge.TOP) {
adjustedX += xOffset;
}
Rectangle2D adjustedDataArea = new Rectangle2D.Double(adjustedX, adjustedY, adjustedW, adjustedH);
AxisState info = drawTickMarksAndLabels(g2, cursor, plotArea, adjustedDataArea, edge);
info = drawLabel(getLabel(), g2, plotArea, dataArea, edge, info);
return info;
}
}

View file

@ -0,0 +1,21 @@
package org.jfree.chart.axis;
import org.jfree.ui.TextAnchor;
public class NumberTick extends ValueTick {
private Number number;
public NumberTick(Number number, String label, TextAnchor textAnchor, TextAnchor rotationAnchor, double angle) {
super(number.doubleValue(), label, textAnchor, rotationAnchor, angle);
this.number = number;
}
public NumberTick(TickType tickType, double value, String label, TextAnchor textAnchor, TextAnchor rotationAnchor, double angle) {
super(tickType, value, label, textAnchor, rotationAnchor, angle);
this.number = new Double(value);
}
public Number getNumber() {
return this.number;
}
}

View file

@ -0,0 +1,55 @@
package org.jfree.chart.axis;
import java.io.Serializable;
import java.text.NumberFormat;
public class NumberTickUnit extends TickUnit implements Serializable {
private static final long serialVersionUID = 3849459506627654442L;
private NumberFormat formatter;
public NumberTickUnit(double size) {
this(size, NumberFormat.getNumberInstance());
}
public NumberTickUnit(double size, NumberFormat formatter) {
super(size);
if (formatter == null)
throw new IllegalArgumentException("Null 'formatter' argument.");
this.formatter = formatter;
}
public NumberTickUnit(double size, NumberFormat formatter, int minorTickCount) {
super(size, minorTickCount);
if (formatter == null)
throw new IllegalArgumentException("Null 'formatter' argument.");
this.formatter = formatter;
}
public String valueToString(double value) {
return this.formatter.format(value);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof NumberTickUnit))
return false;
if (!super.equals(obj))
return false;
NumberTickUnit that = (NumberTickUnit)obj;
if (!this.formatter.equals(that.formatter))
return false;
return true;
}
public String toString() {
return "[size=" + valueToString(getSize()) + "]";
}
public int hashCode() {
int result = super.hashCode();
result = 29 * result + ((this.formatter != null) ? this.formatter.hashCode() : 0);
return result;
}
}

View file

@ -0,0 +1,576 @@
package org.jfree.chart.axis;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.ValueAxisPlot;
import org.jfree.data.Range;
import org.jfree.data.time.Day;
import org.jfree.data.time.Month;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.data.time.Year;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;
import org.jfree.util.PublicCloneable;
public class PeriodAxis extends ValueAxis implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = 8353295532075872069L;
private RegularTimePeriod first;
private RegularTimePeriod last;
private TimeZone timeZone;
private Calendar calendar;
private Class autoRangeTimePeriodClass;
private Class majorTickTimePeriodClass;
private boolean minorTickMarksVisible;
private Class minorTickTimePeriodClass;
private float minorTickMarkInsideLength = 0.0F;
private float minorTickMarkOutsideLength = 2.0F;
private transient Stroke minorTickMarkStroke = new BasicStroke(0.5F);
private transient Paint minorTickMarkPaint = Color.black;
private PeriodAxisLabelInfo[] labelInfo;
public PeriodAxis(String label) {
this(label, new Day(), new Day());
}
public PeriodAxis(String label, RegularTimePeriod first, RegularTimePeriod last) {
this(label, first, last, TimeZone.getDefault());
}
public PeriodAxis(String label, RegularTimePeriod first, RegularTimePeriod last, TimeZone timeZone) {
super(label, null);
this.first = first;
this.last = last;
this.timeZone = timeZone;
this.calendar = Calendar.getInstance(timeZone);
this.autoRangeTimePeriodClass = first.getClass();
this.majorTickTimePeriodClass = first.getClass();
this.minorTickMarksVisible = false;
this.minorTickTimePeriodClass = RegularTimePeriod.downsize(this.majorTickTimePeriodClass);
setAutoRange(true);
this.labelInfo = new PeriodAxisLabelInfo[2];
this.labelInfo[0] = new PeriodAxisLabelInfo(Month.class, new SimpleDateFormat("MMM"));
this.labelInfo[1] = new PeriodAxisLabelInfo(Year.class, new SimpleDateFormat("yyyy"));
}
public RegularTimePeriod getFirst() {
return this.first;
}
public void setFirst(RegularTimePeriod first) {
if (first == null)
throw new IllegalArgumentException("Null 'first' argument.");
this.first = first;
notifyListeners(new AxisChangeEvent(this));
}
public RegularTimePeriod getLast() {
return this.last;
}
public void setLast(RegularTimePeriod last) {
if (last == null)
throw new IllegalArgumentException("Null 'last' argument.");
this.last = last;
notifyListeners(new AxisChangeEvent(this));
}
public TimeZone getTimeZone() {
return this.timeZone;
}
public void setTimeZone(TimeZone zone) {
if (zone == null)
throw new IllegalArgumentException("Null 'zone' argument.");
this.timeZone = zone;
this.calendar = Calendar.getInstance(zone);
notifyListeners(new AxisChangeEvent(this));
}
public Class getAutoRangeTimePeriodClass() {
return this.autoRangeTimePeriodClass;
}
public void setAutoRangeTimePeriodClass(Class c) {
if (c == null)
throw new IllegalArgumentException("Null 'c' argument.");
this.autoRangeTimePeriodClass = c;
notifyListeners(new AxisChangeEvent(this));
}
public Class getMajorTickTimePeriodClass() {
return this.majorTickTimePeriodClass;
}
public void setMajorTickTimePeriodClass(Class c) {
if (c == null)
throw new IllegalArgumentException("Null 'c' argument.");
this.majorTickTimePeriodClass = c;
notifyListeners(new AxisChangeEvent(this));
}
public boolean isMinorTickMarksVisible() {
return this.minorTickMarksVisible;
}
public void setMinorTickMarksVisible(boolean visible) {
this.minorTickMarksVisible = visible;
notifyListeners(new AxisChangeEvent(this));
}
public Class getMinorTickTimePeriodClass() {
return this.minorTickTimePeriodClass;
}
public void setMinorTickTimePeriodClass(Class c) {
if (c == null)
throw new IllegalArgumentException("Null 'c' argument.");
this.minorTickTimePeriodClass = c;
notifyListeners(new AxisChangeEvent(this));
}
public Stroke getMinorTickMarkStroke() {
return this.minorTickMarkStroke;
}
public void setMinorTickMarkStroke(Stroke stroke) {
if (stroke == null)
throw new IllegalArgumentException("Null 'stroke' argument.");
this.minorTickMarkStroke = stroke;
notifyListeners(new AxisChangeEvent(this));
}
public Paint getMinorTickMarkPaint() {
return this.minorTickMarkPaint;
}
public void setMinorTickMarkPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.minorTickMarkPaint = paint;
notifyListeners(new AxisChangeEvent(this));
}
public float getMinorTickMarkInsideLength() {
return this.minorTickMarkInsideLength;
}
public void setMinorTickMarkInsideLength(float length) {
this.minorTickMarkInsideLength = length;
notifyListeners(new AxisChangeEvent(this));
}
public float getMinorTickMarkOutsideLength() {
return this.minorTickMarkOutsideLength;
}
public void setMinorTickMarkOutsideLength(float length) {
this.minorTickMarkOutsideLength = length;
notifyListeners(new AxisChangeEvent(this));
}
public PeriodAxisLabelInfo[] getLabelInfo() {
return this.labelInfo;
}
public void setLabelInfo(PeriodAxisLabelInfo[] info) {
this.labelInfo = info;
}
public Range getRange() {
return new Range((double)this.first.getFirstMillisecond(this.calendar), (double)this.last.getLastMillisecond(this.calendar));
}
public void setRange(Range range, boolean turnOffAutoRange, boolean notify) {
super.setRange(range, turnOffAutoRange, false);
long upper = Math.round(range.getUpperBound());
long lower = Math.round(range.getLowerBound());
this.first = createInstance(this.autoRangeTimePeriodClass, new Date(lower), this.timeZone);
this.last = createInstance(this.autoRangeTimePeriodClass, new Date(upper), this.timeZone);
}
public void configure() {
if (isAutoRange())
autoAdjustRange();
}
public AxisSpace reserveSpace(Graphics2D g2, Plot plot, Rectangle2D plotArea, RectangleEdge edge, AxisSpace space) {
if (space == null)
space = new AxisSpace();
if (!isVisible())
return space;
double dimension = getFixedDimension();
if (dimension > 0.0D)
space.ensureAtLeast(dimension, edge);
Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
double labelHeight = 0.0D;
double labelWidth = 0.0D;
double tickLabelBandsDimension = 0.0D;
for (int i = 0; i < this.labelInfo.length; i++) {
PeriodAxisLabelInfo info = this.labelInfo[i];
FontMetrics fm = g2.getFontMetrics(info.getLabelFont());
tickLabelBandsDimension += info.getPadding().extendHeight((double)fm.getHeight());
}
if (RectangleEdge.isTopOrBottom(edge)) {
labelHeight = labelEnclosure.getHeight();
space.add(labelHeight + tickLabelBandsDimension, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
labelWidth = labelEnclosure.getWidth();
space.add(labelWidth + tickLabelBandsDimension, edge);
}
double tickMarkSpace = 0.0D;
if (isTickMarksVisible())
tickMarkSpace = (double)getTickMarkOutsideLength();
if (this.minorTickMarksVisible)
tickMarkSpace = Math.max(tickMarkSpace, (double)this.minorTickMarkOutsideLength);
space.add(tickMarkSpace, edge);
return space;
}
public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) {
AxisState axisState = new AxisState(cursor);
if (isAxisLineVisible())
drawAxisLine(g2, cursor, dataArea, edge);
drawTickMarks(g2, axisState, dataArea, edge);
for (int band = 0; band < this.labelInfo.length; band++)
axisState = drawTickLabels(band, g2, axisState, dataArea, edge);
axisState = drawLabel(getLabel(), g2, plotArea, dataArea, edge, axisState);
return axisState;
}
protected void drawTickMarks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
if (RectangleEdge.isTopOrBottom(edge)) {
drawTickMarksHorizontal(g2, state, dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
drawTickMarksVertical(g2, state, dataArea, edge);
}
}
protected void drawTickMarksHorizontal(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List ticks = new ArrayList();
double x0 = dataArea.getX();
double y0 = state.getCursor();
double insideLength = (double)getTickMarkInsideLength();
double outsideLength = (double)getTickMarkOutsideLength();
RegularTimePeriod t = RegularTimePeriod.createInstance(this.majorTickTimePeriodClass, this.first.getStart(), getTimeZone());
long t0 = t.getFirstMillisecond(this.calendar);
Line2D inside = null;
Line2D outside = null;
long firstOnAxis = getFirst().getFirstMillisecond(this.calendar);
long lastOnAxis = getLast().getLastMillisecond(this.calendar);
while (t0 <= lastOnAxis) {
ticks.add(new NumberTick(new Double((double)t0), "", TextAnchor.CENTER, TextAnchor.CENTER, 0.0D));
x0 = valueToJava2D((double)t0, dataArea, edge);
if (edge == RectangleEdge.TOP) {
inside = new Line2D.Double(x0, y0, x0, y0 + insideLength);
outside = new Line2D.Double(x0, y0, x0, y0 - outsideLength);
} else if (edge == RectangleEdge.BOTTOM) {
inside = new Line2D.Double(x0, y0, x0, y0 - insideLength);
outside = new Line2D.Double(x0, y0, x0, y0 + outsideLength);
}
if (t0 > firstOnAxis) {
g2.setPaint(getTickMarkPaint());
g2.setStroke(getTickMarkStroke());
g2.draw(inside);
g2.draw(outside);
}
if (this.minorTickMarksVisible) {
RegularTimePeriod tminor = RegularTimePeriod.createInstance(this.minorTickTimePeriodClass, new Date(t0), getTimeZone());
long tt0 = tminor.getFirstMillisecond(this.calendar);
while (tt0 < t.getLastMillisecond(this.calendar) && tt0 < lastOnAxis) {
double xx0 = valueToJava2D((double)tt0, dataArea, edge);
if (edge == RectangleEdge.TOP) {
inside = new Line2D.Double(xx0, y0, xx0, y0 + (double)this.minorTickMarkInsideLength);
outside = new Line2D.Double(xx0, y0, xx0, y0 - (double)this.minorTickMarkOutsideLength);
} else if (edge == RectangleEdge.BOTTOM) {
inside = new Line2D.Double(xx0, y0, xx0, y0 - (double)this.minorTickMarkInsideLength);
outside = new Line2D.Double(xx0, y0, xx0, y0 + (double)this.minorTickMarkOutsideLength);
}
if (tt0 >= firstOnAxis) {
g2.setPaint(this.minorTickMarkPaint);
g2.setStroke(this.minorTickMarkStroke);
g2.draw(inside);
g2.draw(outside);
}
tminor = tminor.next();
tt0 = tminor.getFirstMillisecond(this.calendar);
}
}
t = t.next();
t0 = t.getFirstMillisecond(this.calendar);
}
if (edge == RectangleEdge.TOP) {
state.cursorUp(Math.max(outsideLength, (double)this.minorTickMarkOutsideLength));
} else if (edge == RectangleEdge.BOTTOM) {
state.cursorDown(Math.max(outsideLength, (double)this.minorTickMarkOutsideLength));
}
state.setTicks(ticks);
}
protected void drawTickMarksVertical(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {}
protected AxisState drawTickLabels(int band, Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
double delta1 = 0.0D;
FontMetrics fm = g2.getFontMetrics(this.labelInfo[band].getLabelFont());
if (edge == RectangleEdge.BOTTOM) {
delta1 = this.labelInfo[band].getPadding().calculateTopOutset((double)fm.getHeight());
} else if (edge == RectangleEdge.TOP) {
delta1 = this.labelInfo[band].getPadding().calculateBottomOutset((double)fm.getHeight());
}
state.moveCursor(delta1, edge);
long axisMin = this.first.getFirstMillisecond(this.calendar);
long axisMax = this.last.getLastMillisecond(this.calendar);
g2.setFont(this.labelInfo[band].getLabelFont());
g2.setPaint(this.labelInfo[band].getLabelPaint());
RegularTimePeriod p1 = this.labelInfo[band].createInstance(new Date(axisMin), this.timeZone);
RegularTimePeriod p2 = this.labelInfo[band].createInstance(new Date(axisMax), this.timeZone);
String label1 = this.labelInfo[band].getDateFormat().format(new Date(p1.getMiddleMillisecond(this.calendar)));
String label2 = this.labelInfo[band].getDateFormat().format(new Date(p2.getMiddleMillisecond(this.calendar)));
Rectangle2D b1 = TextUtilities.getTextBounds(label1, g2, g2.getFontMetrics());
Rectangle2D b2 = TextUtilities.getTextBounds(label2, g2, g2.getFontMetrics());
double w = Math.max(b1.getWidth(), b2.getWidth());
long ww = Math.round(java2DToValue(dataArea.getX() + w + 5.0D, dataArea, edge));
if (isInverted()) {
ww = axisMax - ww;
} else {
ww -= axisMin;
}
long length = p1.getLastMillisecond(this.calendar) - p1.getFirstMillisecond(this.calendar);
int periods = (int)(ww / length) + 1;
RegularTimePeriod p = this.labelInfo[band].createInstance(new Date(axisMin), this.timeZone);
Rectangle2D b = null;
long lastXX = 0L;
float y = (float)state.getCursor();
TextAnchor anchor = TextAnchor.TOP_CENTER;
float yDelta = (float)b1.getHeight();
if (edge == RectangleEdge.TOP) {
anchor = TextAnchor.BOTTOM_CENTER;
yDelta = -yDelta;
}
while (p.getFirstMillisecond(this.calendar) <= axisMax) {
float x = (float)valueToJava2D((double)p.getMiddleMillisecond(this.calendar), dataArea, edge);
DateFormat df = this.labelInfo[band].getDateFormat();
String label = df.format(new Date(p.getMiddleMillisecond(this.calendar)));
long first = p.getFirstMillisecond(this.calendar);
long last = p.getLastMillisecond(this.calendar);
if (last > axisMax) {
Rectangle2D bb = TextUtilities.getTextBounds(label, g2, g2.getFontMetrics());
if ((double)x + bb.getWidth() / 2.0D > dataArea.getMaxX()) {
float xstart = (float)valueToJava2D((double)Math.max(first, axisMin), dataArea, edge);
if (bb.getWidth() < dataArea.getMaxX() - (double)xstart) {
x = ((float)dataArea.getMaxX() + xstart) / 2.0F;
} else {
label = null;
}
}
}
if (first < axisMin) {
Rectangle2D bb = TextUtilities.getTextBounds(label, g2, g2.getFontMetrics());
if ((double)x - bb.getWidth() / 2.0D < dataArea.getX()) {
float xlast = (float)valueToJava2D((double)Math.min(last, axisMax), dataArea, edge);
if (bb.getWidth() < (double)xlast - dataArea.getX()) {
x = (xlast + (float)dataArea.getX()) / 2.0F;
} else {
label = null;
}
}
}
if (label != null) {
g2.setPaint(this.labelInfo[band].getLabelPaint());
b = TextUtilities.drawAlignedString(label, g2, x, y, anchor);
}
if (lastXX > 0L &&
this.labelInfo[band].getDrawDividers()) {
long nextXX = p.getFirstMillisecond(this.calendar);
long mid = (lastXX + nextXX) / 2L;
float mid2d = (float)valueToJava2D((double)mid, dataArea, edge);
g2.setStroke(this.labelInfo[band].getDividerStroke());
g2.setPaint(this.labelInfo[band].getDividerPaint());
g2.draw(new Line2D.Float(mid2d, y, mid2d, y + yDelta));
}
lastXX = last;
for (int i = 0; i < periods; i++)
p = p.next();
}
double used = 0.0D;
if (b != null) {
used = b.getHeight();
if (edge == RectangleEdge.BOTTOM) {
used += this.labelInfo[band].getPadding().calculateBottomOutset((double)fm.getHeight());
} else if (edge == RectangleEdge.TOP) {
used += this.labelInfo[band].getPadding().calculateTopOutset((double)fm.getHeight());
}
}
state.moveCursor(used, edge);
return state;
}
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
return Collections.EMPTY_LIST;
}
public double valueToJava2D(double value, Rectangle2D area, RectangleEdge edge) {
double result = Double.NaN;
double axisMin = (double)this.first.getFirstMillisecond(this.calendar);
double axisMax = (double)this.last.getLastMillisecond(this.calendar);
if (RectangleEdge.isTopOrBottom(edge)) {
double minX = area.getX();
double maxX = area.getMaxX();
if (isInverted()) {
result = maxX + (value - axisMin) / (axisMax - axisMin) * (minX - maxX);
} else {
result = minX + (value - axisMin) / (axisMax - axisMin) * (maxX - minX);
}
} else if (RectangleEdge.isLeftOrRight(edge)) {
double minY = area.getMinY();
double maxY = area.getMaxY();
if (isInverted()) {
result = minY + (value - axisMin) / (axisMax - axisMin) * (maxY - minY);
} else {
result = maxY - (value - axisMin) / (axisMax - axisMin) * (maxY - minY);
}
}
return result;
}
public double java2DToValue(double java2DValue, Rectangle2D area, RectangleEdge edge) {
double result = Double.NaN;
double min = 0.0D;
double max = 0.0D;
double axisMin = (double)this.first.getFirstMillisecond(this.calendar);
double axisMax = (double)this.last.getLastMillisecond(this.calendar);
if (RectangleEdge.isTopOrBottom(edge)) {
min = area.getX();
max = area.getMaxX();
} else if (RectangleEdge.isLeftOrRight(edge)) {
min = area.getMaxY();
max = area.getY();
}
if (isInverted()) {
result = axisMax - (java2DValue - min) / (max - min) * (axisMax - axisMin);
} else {
result = axisMin + (java2DValue - min) / (max - min) * (axisMax - axisMin);
}
return result;
}
protected void autoAdjustRange() {
Plot plot = getPlot();
if (plot == null)
return;
if (plot instanceof ValueAxisPlot) {
ValueAxisPlot vap = (ValueAxisPlot)plot;
Range r = vap.getDataRange(this);
if (r == null)
r = getDefaultAutoRange();
long upper = Math.round(r.getUpperBound());
long lower = Math.round(r.getLowerBound());
this.first = createInstance(this.autoRangeTimePeriodClass, new Date(lower), this.timeZone);
this.last = createInstance(this.autoRangeTimePeriodClass, new Date(upper), this.timeZone);
setRange(r, false, false);
}
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof PeriodAxis && super.equals(obj)) {
PeriodAxis that = (PeriodAxis)obj;
if (!this.first.equals(that.first))
return false;
if (!this.last.equals(that.last))
return false;
if (!this.timeZone.equals(that.timeZone))
return false;
if (!this.autoRangeTimePeriodClass.equals(that.autoRangeTimePeriodClass))
return false;
if (isMinorTickMarksVisible() != that.isMinorTickMarksVisible())
return false;
if (!this.majorTickTimePeriodClass.equals(that.majorTickTimePeriodClass))
return false;
if (!this.minorTickTimePeriodClass.equals(that.minorTickTimePeriodClass))
return false;
if (!this.minorTickMarkPaint.equals(that.minorTickMarkPaint))
return false;
if (!this.minorTickMarkStroke.equals(that.minorTickMarkStroke))
return false;
if (!Arrays.equals(this.labelInfo, that.labelInfo))
return false;
return true;
}
return false;
}
public int hashCode() {
if (getLabel() != null)
return getLabel().hashCode();
return 0;
}
public Object clone() throws CloneNotSupportedException {
PeriodAxis clone = (PeriodAxis)super.clone();
clone.timeZone = (TimeZone)this.timeZone.clone();
clone.labelInfo = new PeriodAxisLabelInfo[this.labelInfo.length];
for (int i = 0; i < this.labelInfo.length; i++)
clone.labelInfo[i] = this.labelInfo[i];
return clone;
}
private RegularTimePeriod createInstance(Class periodClass, Date millisecond, TimeZone zone) {
RegularTimePeriod result = null;
try {
Constructor c = periodClass.getDeclaredConstructor(new Class[] { Date.class, TimeZone.class });
result = (RegularTimePeriod)c.newInstance(new Object[] { millisecond, zone });
} catch (Exception e) {}
return result;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeStroke(this.minorTickMarkStroke, stream);
SerialUtilities.writePaint(this.minorTickMarkPaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.minorTickMarkStroke = SerialUtilities.readStroke(stream);
this.minorTickMarkPaint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,170 @@
package org.jfree.chart.axis;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Paint;
import java.awt.Stroke;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.text.DateFormat;
import java.util.Date;
import java.util.TimeZone;
import org.jfree.data.time.RegularTimePeriod;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.RectangleInsets;
public class PeriodAxisLabelInfo implements Cloneable, Serializable {
private static final long serialVersionUID = 5710451740920277357L;
public static final RectangleInsets DEFAULT_INSETS = new RectangleInsets(2.0D, 2.0D, 2.0D, 2.0D);
public static final Font DEFAULT_FONT = new Font("SansSerif", 0, 10);
public static final Paint DEFAULT_LABEL_PAINT = Color.black;
public static final Stroke DEFAULT_DIVIDER_STROKE = new BasicStroke(0.5F);
public static final Paint DEFAULT_DIVIDER_PAINT = Color.gray;
private Class periodClass;
private RectangleInsets padding;
private DateFormat dateFormat;
private Font labelFont;
private transient Paint labelPaint;
private boolean drawDividers;
private transient Stroke dividerStroke;
private transient Paint dividerPaint;
public PeriodAxisLabelInfo(Class periodClass, DateFormat dateFormat) {
this(periodClass, dateFormat, DEFAULT_INSETS, DEFAULT_FONT, DEFAULT_LABEL_PAINT, true, DEFAULT_DIVIDER_STROKE, DEFAULT_DIVIDER_PAINT);
}
public PeriodAxisLabelInfo(Class periodClass, DateFormat dateFormat, RectangleInsets padding, Font labelFont, Paint labelPaint, boolean drawDividers, Stroke dividerStroke, Paint dividerPaint) {
if (periodClass == null)
throw new IllegalArgumentException("Null 'periodClass' argument.");
if (dateFormat == null)
throw new IllegalArgumentException("Null 'dateFormat' argument.");
if (padding == null)
throw new IllegalArgumentException("Null 'padding' argument.");
if (labelFont == null)
throw new IllegalArgumentException("Null 'labelFont' argument.");
if (labelPaint == null)
throw new IllegalArgumentException("Null 'labelPaint' argument.");
if (dividerStroke == null)
throw new IllegalArgumentException("Null 'dividerStroke' argument.");
if (dividerPaint == null)
throw new IllegalArgumentException("Null 'dividerPaint' argument.");
this.periodClass = periodClass;
this.dateFormat = dateFormat;
this.padding = padding;
this.labelFont = labelFont;
this.labelPaint = labelPaint;
this.drawDividers = drawDividers;
this.dividerStroke = dividerStroke;
this.dividerPaint = dividerPaint;
}
public Class getPeriodClass() {
return this.periodClass;
}
public DateFormat getDateFormat() {
return this.dateFormat;
}
public RectangleInsets getPadding() {
return this.padding;
}
public Font getLabelFont() {
return this.labelFont;
}
public Paint getLabelPaint() {
return this.labelPaint;
}
public boolean getDrawDividers() {
return this.drawDividers;
}
public Stroke getDividerStroke() {
return this.dividerStroke;
}
public Paint getDividerPaint() {
return this.dividerPaint;
}
public RegularTimePeriod createInstance(Date millisecond, TimeZone zone) {
RegularTimePeriod result = null;
try {
Constructor c = this.periodClass.getDeclaredConstructor(new Class[] { Date.class, TimeZone.class });
result = (RegularTimePeriod)c.newInstance(new Object[] { millisecond, zone });
} catch (Exception e) {}
return result;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof PeriodAxisLabelInfo) {
PeriodAxisLabelInfo info = (PeriodAxisLabelInfo)obj;
if (!info.periodClass.equals(this.periodClass))
return false;
if (!info.dateFormat.equals(this.dateFormat))
return false;
if (!info.padding.equals(this.padding))
return false;
if (!info.labelFont.equals(this.labelFont))
return false;
if (!info.labelPaint.equals(this.labelPaint))
return false;
if (info.drawDividers != this.drawDividers)
return false;
if (!info.dividerStroke.equals(this.dividerStroke))
return false;
if (!info.dividerPaint.equals(this.dividerPaint))
return false;
return true;
}
return false;
}
public int hashCode() {
int result = 41;
result = 37 * this.periodClass.hashCode();
result = 37 * this.dateFormat.hashCode();
return result;
}
public Object clone() throws CloneNotSupportedException {
PeriodAxisLabelInfo clone = (PeriodAxisLabelInfo)super.clone();
return clone;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.labelPaint, stream);
SerialUtilities.writeStroke(this.dividerStroke, stream);
SerialUtilities.writePaint(this.dividerPaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.labelPaint = SerialUtilities.readPaint(stream);
this.dividerStroke = SerialUtilities.readStroke(stream);
this.dividerPaint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,80 @@
package org.jfree.chart.axis;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class QuarterDateFormat extends DateFormat implements Cloneable, Serializable {
private static final long serialVersionUID = -6738465248529797176L;
public static final String[] REGULAR_QUARTERS = new String[] { "1", "2", "3", "4" };
public static final String[] ROMAN_QUARTERS = new String[] { "I", "II", "III", "IV" };
public static final String[] GREEK_QUARTERS = new String[] { "Α", "Β", "Γ", "Δ" };
private String[] quarters = REGULAR_QUARTERS;
private boolean quarterFirst;
public QuarterDateFormat() {
this(TimeZone.getDefault());
}
public QuarterDateFormat(TimeZone zone) {
this(zone, REGULAR_QUARTERS);
}
public QuarterDateFormat(TimeZone zone, String[] quarterSymbols) {
this(zone, quarterSymbols, false);
}
public QuarterDateFormat(TimeZone zone, String[] quarterSymbols, boolean quarterFirst) {
if (zone == null)
throw new IllegalArgumentException("Null 'zone' argument.");
this.calendar = new GregorianCalendar(zone);
this.quarters = quarterSymbols;
this.quarterFirst = quarterFirst;
this.numberFormat = NumberFormat.getNumberInstance();
}
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
this.calendar.setTime(date);
int year = this.calendar.get(1);
int month = this.calendar.get(2);
int quarter = month / 3;
if (this.quarterFirst) {
toAppendTo.append(this.quarters[quarter]);
toAppendTo.append(" ");
toAppendTo.append(year);
} else {
toAppendTo.append(year);
toAppendTo.append(" ");
toAppendTo.append(this.quarters[quarter]);
}
return toAppendTo;
}
public Date parse(String source, ParsePosition pos) {
return null;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof QuarterDateFormat))
return false;
QuarterDateFormat that = (QuarterDateFormat)obj;
if (!Arrays.equals(this.quarters, that.quarters))
return false;
if (this.quarterFirst != that.quarterFirst)
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,657 @@
package org.jfree.chart.axis;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
public class SegmentedTimeline implements Timeline, Cloneable, Serializable {
private static final long serialVersionUID = 1093779862539903110L;
public static final long DAY_SEGMENT_SIZE = 86400000L;
public static final long HOUR_SEGMENT_SIZE = 3600000L;
public static final long FIFTEEN_MINUTE_SEGMENT_SIZE = 900000L;
public static final long MINUTE_SEGMENT_SIZE = 60000L;
public static long FIRST_MONDAY_AFTER_1900;
public static TimeZone NO_DST_TIME_ZONE;
public static TimeZone DEFAULT_TIME_ZONE = TimeZone.getDefault();
private Calendar workingCalendarNoDST;
private Calendar workingCalendar = Calendar.getInstance();
private long segmentSize;
private int segmentsIncluded;
private int segmentsExcluded;
private int groupSegmentCount;
private long startTime;
private long segmentsIncludedSize;
private long segmentsExcludedSize;
private long segmentsGroupSize;
private List exceptionSegments = new ArrayList();
private SegmentedTimeline baseTimeline;
private boolean adjustForDaylightSaving = false;
static {
int offset = TimeZone.getDefault().getRawOffset();
NO_DST_TIME_ZONE = new SimpleTimeZone(offset, "UTC-" + offset);
Calendar cal = new GregorianCalendar(NO_DST_TIME_ZONE);
cal.set(1900, 0, 1, 0, 0, 0);
cal.set(14, 0);
while (cal.get(7) != 2)
cal.add(5, 1);
FIRST_MONDAY_AFTER_1900 = cal.getTime().getTime();
}
public SegmentedTimeline(long segmentSize, int segmentsIncluded, int segmentsExcluded) {
this.segmentSize = segmentSize;
this.segmentsIncluded = segmentsIncluded;
this.segmentsExcluded = segmentsExcluded;
this.groupSegmentCount = this.segmentsIncluded + this.segmentsExcluded;
this.segmentsIncludedSize = (long)this.segmentsIncluded * this.segmentSize;
this.segmentsExcludedSize = (long)this.segmentsExcluded * this.segmentSize;
this.segmentsGroupSize = this.segmentsIncludedSize + this.segmentsExcludedSize;
int offset = TimeZone.getDefault().getRawOffset();
TimeZone z = new SimpleTimeZone(offset, "UTC-" + offset);
this.workingCalendarNoDST = new GregorianCalendar(z, Locale.getDefault());
}
public static long firstMondayAfter1900() {
int offset = TimeZone.getDefault().getRawOffset();
TimeZone z = new SimpleTimeZone(offset, "UTC-" + offset);
Calendar cal = new GregorianCalendar(z);
cal.set(1900, 0, 1, 0, 0, 0);
cal.set(14, 0);
while (cal.get(7) != 2)
cal.add(5, 1);
return cal.getTime().getTime();
}
public static SegmentedTimeline newMondayThroughFridayTimeline() {
SegmentedTimeline timeline = new SegmentedTimeline(86400000L, 5, 2);
timeline.setStartTime(firstMondayAfter1900());
return timeline;
}
public static SegmentedTimeline newFifteenMinuteTimeline() {
SegmentedTimeline timeline = new SegmentedTimeline(900000L, 28, 68);
timeline.setStartTime(firstMondayAfter1900() + 36L * timeline.getSegmentSize());
timeline.setBaseTimeline(newMondayThroughFridayTimeline());
return timeline;
}
public boolean getAdjustForDaylightSaving() {
return this.adjustForDaylightSaving;
}
public void setAdjustForDaylightSaving(boolean adjust) {
this.adjustForDaylightSaving = adjust;
}
public void setStartTime(long millisecond) {
this.startTime = millisecond;
}
public long getStartTime() {
return this.startTime;
}
public int getSegmentsExcluded() {
return this.segmentsExcluded;
}
public long getSegmentsExcludedSize() {
return this.segmentsExcludedSize;
}
public int getGroupSegmentCount() {
return this.groupSegmentCount;
}
public long getSegmentsGroupSize() {
return this.segmentsGroupSize;
}
public int getSegmentsIncluded() {
return this.segmentsIncluded;
}
public long getSegmentsIncludedSize() {
return this.segmentsIncludedSize;
}
public long getSegmentSize() {
return this.segmentSize;
}
public List getExceptionSegments() {
return Collections.unmodifiableList(this.exceptionSegments);
}
public void setExceptionSegments(List exceptionSegments) {
this.exceptionSegments = exceptionSegments;
}
public SegmentedTimeline getBaseTimeline() {
return this.baseTimeline;
}
public void setBaseTimeline(SegmentedTimeline baseTimeline) {
if (baseTimeline != null) {
if (baseTimeline.getSegmentSize() < this.segmentSize)
throw new IllegalArgumentException("baseTimeline.getSegmentSize() is smaller than segmentSize");
if (baseTimeline.getStartTime() > this.startTime)
throw new IllegalArgumentException("baseTimeline.getStartTime() is after startTime");
if (baseTimeline.getSegmentSize() % this.segmentSize != 0L)
throw new IllegalArgumentException("baseTimeline.getSegmentSize() is not multiple of segmentSize");
if ((this.startTime - baseTimeline.getStartTime()) % this.segmentSize != 0L)
throw new IllegalArgumentException("baseTimeline is not aligned");
}
this.baseTimeline = baseTimeline;
}
public long toTimelineValue(long millisecond) {
long result;
long rawMilliseconds = millisecond - this.startTime;
long groupMilliseconds = rawMilliseconds % this.segmentsGroupSize;
long groupIndex = rawMilliseconds / this.segmentsGroupSize;
if (groupMilliseconds >= this.segmentsIncludedSize) {
result = toTimelineValue(this.startTime + this.segmentsGroupSize * (groupIndex + 1L));
} else {
Segment segment = getSegment(millisecond);
if (segment.inExceptionSegments()) {
do {
segment = getSegment(millisecond = segment.getSegmentEnd() + 1L);
} while (segment.inExceptionSegments());
result = toTimelineValue(millisecond);
} else {
long shiftedSegmentedValue = millisecond - this.startTime;
long x = shiftedSegmentedValue % this.segmentsGroupSize;
long y = shiftedSegmentedValue / this.segmentsGroupSize;
long wholeExceptionsBeforeDomainValue = getExceptionSegmentCount(this.startTime, millisecond - 1L);
if (x < this.segmentsIncludedSize) {
result = this.segmentsIncludedSize * y + x - wholeExceptionsBeforeDomainValue * this.segmentSize;
} else {
result = this.segmentsIncludedSize * (y + 1L) - wholeExceptionsBeforeDomainValue * this.segmentSize;
}
}
}
return result;
}
public long toTimelineValue(Date date) {
return toTimelineValue(getTime(date));
}
public long toMillisecond(long timelineValue) {
Segment result = new Segment(this, this.startTime + timelineValue + timelineValue / this.segmentsIncludedSize * this.segmentsExcludedSize);
long lastIndex = this.startTime;
while (lastIndex <= result.segmentStart) {
long exceptionSegmentCount;
while ((exceptionSegmentCount = getExceptionSegmentCount(lastIndex, result.millisecond / this.segmentSize * this.segmentSize - 1L)) > 0L) {
lastIndex = result.segmentStart;
for (int i = 0; (long)i < exceptionSegmentCount;) {
while (true) {
result.inc();
if (!result.inExcludeSegments())
i++;
}
}
}
lastIndex = result.segmentStart;
while (result.inExceptionSegments() || result.inExcludeSegments()) {
result.inc();
lastIndex += this.segmentSize;
}
lastIndex++;
}
return getTimeFromLong(result.millisecond);
}
public long getTimeFromLong(long date) {
long result = date;
if (this.adjustForDaylightSaving) {
this.workingCalendarNoDST.setTime(new Date(date));
this.workingCalendar.set(this.workingCalendarNoDST.get(1), this.workingCalendarNoDST.get(2), this.workingCalendarNoDST.get(5), this.workingCalendarNoDST.get(11), this.workingCalendarNoDST.get(12), this.workingCalendarNoDST.get(13));
this.workingCalendar.set(14, this.workingCalendarNoDST.get(14));
result = this.workingCalendar.getTime().getTime();
}
return result;
}
public boolean containsDomainValue(long millisecond) {
Segment segment = getSegment(millisecond);
return segment.inIncludeSegments();
}
public boolean containsDomainValue(Date date) {
return containsDomainValue(getTime(date));
}
public boolean containsDomainRange(long domainValueStart, long domainValueEnd) {
if (domainValueEnd < domainValueStart)
throw new IllegalArgumentException("domainValueEnd (" + domainValueEnd + ") < domainValueStart (" + domainValueStart + ")");
Segment segment = getSegment(domainValueStart);
boolean contains = true;
do {
contains = segment.inIncludeSegments();
if (segment.contains(domainValueEnd))
break;
segment.inc();
} while (contains);
return contains;
}
public boolean containsDomainRange(Date dateDomainValueStart, Date dateDomainValueEnd) {
return containsDomainRange(getTime(dateDomainValueStart), getTime(dateDomainValueEnd));
}
public void addException(long millisecond) {
addException(new Segment(this, millisecond));
}
public void addException(long fromDomainValue, long toDomainValue) {
addException(new SegmentRange(this, fromDomainValue, toDomainValue));
}
public void addException(Date exceptionDate) {
addException(getTime(exceptionDate));
}
public void addExceptions(List exceptionList) {
for (Iterator iter = exceptionList.iterator(); iter.hasNext();)
addException((Date)iter.next());
}
private void addException(Segment segment) {
if (segment.inIncludeSegments()) {
int p = binarySearchExceptionSegments(segment);
this.exceptionSegments.add(-(p + 1), segment);
}
}
public void addBaseTimelineException(long domainValue) {
Segment baseSegment = this.baseTimeline.getSegment(domainValue);
if (baseSegment.inIncludeSegments()) {
Segment segment = getSegment(baseSegment.getSegmentStart());
while (segment.getSegmentStart() <= baseSegment.getSegmentEnd()) {
if (segment.inIncludeSegments()) {
long toDomainValue;
long fromDomainValue = segment.getSegmentStart();
do {
toDomainValue = segment.getSegmentEnd();
segment.inc();
} while (segment.inIncludeSegments());
addException(fromDomainValue, toDomainValue);
continue;
}
segment.inc();
}
}
}
public void addBaseTimelineException(Date date) {
addBaseTimelineException(getTime(date));
}
public void addBaseTimelineExclusions(long fromBaseDomainValue, long toBaseDomainValue) {
Segment baseSegment = this.baseTimeline.getSegment(fromBaseDomainValue);
while (baseSegment.getSegmentStart() <= toBaseDomainValue && !baseSegment.inExcludeSegments())
baseSegment.inc();
while (baseSegment.getSegmentStart() <= toBaseDomainValue) {
long baseExclusionRangeEnd = baseSegment.getSegmentStart() + (long)this.baseTimeline.getSegmentsExcluded() * this.baseTimeline.getSegmentSize() - 1L;
Segment segment = getSegment(baseSegment.getSegmentStart());
while (segment.getSegmentStart() <= baseExclusionRangeEnd) {
if (segment.inIncludeSegments()) {
long toDomainValue;
long fromDomainValue = segment.getSegmentStart();
do {
toDomainValue = segment.getSegmentEnd();
segment.inc();
} while (segment.inIncludeSegments());
addException(new BaseTimelineSegmentRange(this, fromDomainValue, toDomainValue));
continue;
}
segment.inc();
}
baseSegment.inc((long)this.baseTimeline.getGroupSegmentCount());
}
}
public long getExceptionSegmentCount(long fromMillisecond, long toMillisecond) {
if (toMillisecond < fromMillisecond)
return 0L;
int n = 0;
Iterator iter = this.exceptionSegments.iterator();
while (iter.hasNext()) {
Segment segment = (Segment)iter.next();
Segment intersection = segment.intersect(fromMillisecond, toMillisecond);
if (intersection != null)
n = (int)((long)n + intersection.getSegmentCount());
}
return (long)n;
}
public Segment getSegment(long millisecond) {
return new Segment(this, millisecond);
}
public Segment getSegment(Date date) {
return getSegment(getTime(date));
}
private boolean equals(Object o, Object p) {
return (o == p || (o != null && o.equals(p)));
}
public boolean equals(Object o) {
if (o instanceof SegmentedTimeline) {
SegmentedTimeline other = (SegmentedTimeline)o;
boolean b0 = (this.segmentSize == other.getSegmentSize());
boolean b1 = (this.segmentsIncluded == other.getSegmentsIncluded());
boolean b2 = (this.segmentsExcluded == other.getSegmentsExcluded());
boolean b3 = (this.startTime == other.getStartTime());
boolean b4 = equals(this.exceptionSegments, other.getExceptionSegments());
return (b0 && b1 && b2 && b3 && b4);
}
return false;
}
public int hashCode() {
int result = 19;
result = 37 * result + (int)(this.segmentSize ^ this.segmentSize >>> 32L);
result = 37 * result + (int)(this.startTime ^ this.startTime >>> 32L);
return result;
}
private int binarySearchExceptionSegments(Segment segment) {
int low = 0;
int high = this.exceptionSegments.size() - 1;
while (low <= high) {
int mid = (low + high) / 2;
Segment midSegment = (Segment)this.exceptionSegments.get(mid);
if (segment.contains(midSegment) || midSegment.contains(segment))
return mid;
if (midSegment.before(segment)) {
low = mid + 1;
continue;
}
if (midSegment.after(segment)) {
high = mid - 1;
continue;
}
throw new IllegalStateException("Invalid condition.");
}
return -(low + 1);
}
public long getTime(Date date) {
long result = date.getTime();
if (this.adjustForDaylightSaving) {
this.workingCalendar.setTime(date);
this.workingCalendarNoDST.set(this.workingCalendar.get(1), this.workingCalendar.get(2), this.workingCalendar.get(5), this.workingCalendar.get(11), this.workingCalendar.get(12), this.workingCalendar.get(13));
this.workingCalendarNoDST.set(14, this.workingCalendar.get(14));
Date revisedDate = this.workingCalendarNoDST.getTime();
result = revisedDate.getTime();
}
return result;
}
public Date getDate(long value) {
this.workingCalendarNoDST.setTime(new Date(value));
return this.workingCalendarNoDST.getTime();
}
public Object clone() throws CloneNotSupportedException {
SegmentedTimeline clone = (SegmentedTimeline)super.clone();
return clone;
}
public class Segment implements Comparable, Cloneable, Serializable {
protected long segmentNumber;
protected long segmentStart;
protected long segmentEnd;
protected long millisecond;
private final SegmentedTimeline this$0;
protected Segment(SegmentedTimeline this$0) {
this.this$0 = this$0;
}
protected Segment(SegmentedTimeline this$0, long millisecond) {
this.this$0 = this$0;
this.segmentNumber = calculateSegmentNumber(millisecond);
this.segmentStart = this$0.startTime + this.segmentNumber * this$0.segmentSize;
this.segmentEnd = this.segmentStart + this$0.segmentSize - 1L;
this.millisecond = millisecond;
}
public long calculateSegmentNumber(long millis) {
if (millis >= this.this$0.startTime)
return (millis - this.this$0.startTime) / this.this$0.segmentSize;
return (millis - this.this$0.startTime) / this.this$0.segmentSize - 1L;
}
public long getSegmentNumber() {
return this.segmentNumber;
}
public long getSegmentCount() {
return 1L;
}
public long getSegmentStart() {
return this.segmentStart;
}
public long getSegmentEnd() {
return this.segmentEnd;
}
public long getMillisecond() {
return this.millisecond;
}
public Date getDate() {
return this.this$0.getDate(this.millisecond);
}
public boolean contains(long millis) {
return (this.segmentStart <= millis && millis <= this.segmentEnd);
}
public boolean contains(long from, long to) {
return (this.segmentStart <= from && to <= this.segmentEnd);
}
public boolean contains(Segment segment) {
return contains(segment.getSegmentStart(), segment.getSegmentEnd());
}
public boolean contained(long from, long to) {
return (from <= this.segmentStart && this.segmentEnd <= to);
}
public Segment intersect(long from, long to) {
if (from <= this.segmentStart && this.segmentEnd <= to)
return this;
return null;
}
public boolean before(Segment other) {
return (this.segmentEnd < other.getSegmentStart());
}
public boolean after(Segment other) {
return (this.segmentStart > other.getSegmentEnd());
}
public boolean equals(Object object) {
if (object instanceof Segment) {
Segment other = (Segment)object;
return (this.segmentNumber == other.getSegmentNumber() && this.segmentStart == other.getSegmentStart() && this.segmentEnd == other.getSegmentEnd() && this.millisecond == other.getMillisecond());
}
return false;
}
public Segment copy() {
try {
return (Segment)clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
public int compareTo(Object object) {
Segment other = (Segment)object;
if (before(other))
return -1;
if (after(other))
return 1;
return 0;
}
public boolean inIncludeSegments() {
if (getSegmentNumberRelativeToGroup() < (long)this.this$0.segmentsIncluded)
return !inExceptionSegments();
return false;
}
public boolean inExcludeSegments() {
return (getSegmentNumberRelativeToGroup() >= (long)this.this$0.segmentsIncluded);
}
private long getSegmentNumberRelativeToGroup() {
long p = this.segmentNumber % (long)this.this$0.groupSegmentCount;
if (p < 0L)
p += (long)this.this$0.groupSegmentCount;
return p;
}
public boolean inExceptionSegments() {
return (this.this$0.binarySearchExceptionSegments(this) >= 0);
}
public void inc(long n) {
this.segmentNumber += n;
long m = n * this.this$0.segmentSize;
this.segmentStart += m;
this.segmentEnd += m;
this.millisecond += m;
}
public void inc() {
inc(1L);
}
public void dec(long n) {
this.segmentNumber -= n;
long m = n * this.this$0.segmentSize;
this.segmentStart -= m;
this.segmentEnd -= m;
this.millisecond -= m;
}
public void dec() {
dec(1L);
}
public void moveIndexToStart() {
this.millisecond = this.segmentStart;
}
public void moveIndexToEnd() {
this.millisecond = this.segmentEnd;
}
}
protected class SegmentRange extends Segment {
private long segmentCount;
private final SegmentedTimeline this$0;
public SegmentRange(SegmentedTimeline this$0, long fromMillisecond, long toMillisecond) {
super(this$0);
this.this$0 = this$0;
SegmentedTimeline.Segment start = this$0.getSegment(fromMillisecond);
SegmentedTimeline.Segment end = this$0.getSegment(toMillisecond);
this.millisecond = fromMillisecond;
this.segmentNumber = calculateSegmentNumber(fromMillisecond);
this.segmentStart = start.segmentStart;
this.segmentEnd = end.segmentEnd;
this.segmentCount = end.getSegmentNumber() - start.getSegmentNumber() + 1L;
}
public long getSegmentCount() {
return this.segmentCount;
}
public SegmentedTimeline.Segment intersect(long from, long to) {
long start = Math.max(from, this.segmentStart);
long end = Math.min(to, this.segmentEnd);
if (start <= end)
return new SegmentRange(this.this$0, start, end);
return null;
}
public boolean inIncludeSegments() {
SegmentedTimeline.Segment segment = this.this$0.getSegment(this.segmentStart);
for (; segment.getSegmentStart() < this.segmentEnd;
segment.inc()) {
if (!segment.inIncludeSegments())
return false;
}
return true;
}
public boolean inExcludeSegments() {
SegmentedTimeline.Segment segment = this.this$0.getSegment(this.segmentStart);
for (; segment.getSegmentStart() < this.segmentEnd;
segment.inc()) {
if (!segment.inExceptionSegments())
return false;
}
return true;
}
public void inc(long n) {
throw new IllegalArgumentException("Not implemented in SegmentRange");
}
}
protected class BaseTimelineSegmentRange extends SegmentRange {
private final SegmentedTimeline this$0;
public BaseTimelineSegmentRange(SegmentedTimeline this$0, long fromDomainValue, long toDomainValue) {
super(this$0, fromDomainValue, toDomainValue);
this.this$0 = this$0;
}
}
}

View file

@ -0,0 +1,35 @@
package org.jfree.chart.axis;
import java.io.Serializable;
import java.text.DecimalFormat;
public class StandardTickUnitSource implements TickUnitSource, Serializable {
private static final double LOG_10_VALUE = Math.log(10.0D);
public TickUnit getLargerTickUnit(TickUnit unit) {
double x = unit.getSize();
double log = Math.log(x) / LOG_10_VALUE;
double higher = Math.ceil(log);
return new NumberTickUnit(Math.pow(10.0D, higher), new DecimalFormat("0.0E0"));
}
public TickUnit getCeilingTickUnit(TickUnit unit) {
return getLargerTickUnit(unit);
}
public TickUnit getCeilingTickUnit(double size) {
double log = Math.log(size) / LOG_10_VALUE;
double higher = Math.ceil(log);
return new NumberTickUnit(Math.pow(10.0D, higher), new DecimalFormat("0.0E0"));
}
public boolean equals(Object obj) {
if (obj == this)
return true;
return obj instanceof StandardTickUnitSource;
}
public int hashCode() {
return 0;
}
}

View file

@ -0,0 +1,211 @@
package org.jfree.chart.axis;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.data.category.CategoryDataset;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;
public class SubCategoryAxis extends CategoryAxis implements Cloneable, Serializable {
private static final long serialVersionUID = -1279463299793228344L;
private List subCategories;
private Font subLabelFont = new Font("SansSerif", 0, 10);
private transient Paint subLabelPaint = Color.black;
public SubCategoryAxis(String label) {
super(label);
this.subCategories = new ArrayList();
}
public void addSubCategory(Comparable subCategory) {
if (subCategory == null)
throw new IllegalArgumentException("Null 'subcategory' axis.");
this.subCategories.add(subCategory);
notifyListeners(new AxisChangeEvent(this));
}
public Font getSubLabelFont() {
return this.subLabelFont;
}
public void setSubLabelFont(Font font) {
if (font == null)
throw new IllegalArgumentException("Null 'font' argument.");
this.subLabelFont = font;
notifyListeners(new AxisChangeEvent(this));
}
public Paint getSubLabelPaint() {
return this.subLabelPaint;
}
public void setSubLabelPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.subLabelPaint = paint;
notifyListeners(new AxisChangeEvent(this));
}
public AxisSpace reserveSpace(Graphics2D g2, Plot plot, Rectangle2D plotArea, RectangleEdge edge, AxisSpace space) {
if (space == null)
space = new AxisSpace();
if (!isVisible())
return space;
space = super.reserveSpace(g2, plot, plotArea, edge, space);
double maxdim = getMaxDim(g2, edge);
if (RectangleEdge.isTopOrBottom(edge)) {
space.add(maxdim, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
space.add(maxdim, edge);
}
return space;
}
private double getMaxDim(Graphics2D g2, RectangleEdge edge) {
double result = 0.0D;
g2.setFont(this.subLabelFont);
FontMetrics fm = g2.getFontMetrics();
Iterator iterator = this.subCategories.iterator();
while (iterator.hasNext()) {
Comparable subcategory = (Comparable)iterator.next();
String label = subcategory.toString();
Rectangle2D bounds = TextUtilities.getTextBounds(label, g2, fm);
double dim = 0.0D;
if (RectangleEdge.isLeftOrRight(edge)) {
dim = bounds.getWidth();
} else {
dim = bounds.getHeight();
}
result = Math.max(result, dim);
}
return result;
}
public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) {
if (!isVisible())
return new AxisState(cursor);
if (isAxisLineVisible())
drawAxisLine(g2, cursor, dataArea, edge);
AxisState state = new AxisState(cursor);
state = drawSubCategoryLabels(g2, plotArea, dataArea, edge, state, plotState);
state = drawCategoryLabels(g2, plotArea, dataArea, edge, state, plotState);
state = drawLabel(getLabel(), g2, plotArea, dataArea, edge, state);
return state;
}
protected AxisState drawSubCategoryLabels(Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, AxisState state, PlotRenderingInfo plotState) {
if (state == null)
throw new IllegalArgumentException("Null 'state' argument.");
g2.setFont(this.subLabelFont);
g2.setPaint(this.subLabelPaint);
CategoryPlot plot = (CategoryPlot)getPlot();
CategoryDataset dataset = plot.getDataset();
int categoryCount = dataset.getColumnCount();
double maxdim = getMaxDim(g2, edge);
for (int categoryIndex = 0; categoryIndex < categoryCount;
categoryIndex++) {
double x0 = 0.0D;
double x1 = 0.0D;
double y0 = 0.0D;
double y1 = 0.0D;
if (edge == RectangleEdge.TOP) {
x0 = getCategoryStart(categoryIndex, categoryCount, dataArea, edge);
x1 = getCategoryEnd(categoryIndex, categoryCount, dataArea, edge);
y1 = state.getCursor();
y0 = y1 - maxdim;
} else if (edge == RectangleEdge.BOTTOM) {
x0 = getCategoryStart(categoryIndex, categoryCount, dataArea, edge);
x1 = getCategoryEnd(categoryIndex, categoryCount, dataArea, edge);
y0 = state.getCursor();
y1 = y0 + maxdim;
} else if (edge == RectangleEdge.LEFT) {
y0 = getCategoryStart(categoryIndex, categoryCount, dataArea, edge);
y1 = getCategoryEnd(categoryIndex, categoryCount, dataArea, edge);
x1 = state.getCursor();
x0 = x1 - maxdim;
} else if (edge == RectangleEdge.RIGHT) {
y0 = getCategoryStart(categoryIndex, categoryCount, dataArea, edge);
y1 = getCategoryEnd(categoryIndex, categoryCount, dataArea, edge);
x0 = state.getCursor();
x1 = x0 + maxdim;
}
Rectangle2D area = new Rectangle2D.Double(x0, y0, x1 - x0, y1 - y0);
int subCategoryCount = this.subCategories.size();
float width = (float)((x1 - x0) / (double)subCategoryCount);
float height = (float)((y1 - y0) / (double)subCategoryCount);
float xx = 0.0F;
float yy = 0.0F;
for (int i = 0; i < subCategoryCount; i++) {
if (RectangleEdge.isTopOrBottom(edge)) {
xx = (float)(x0 + ((double)i + 0.5D) * (double)width);
yy = (float)area.getCenterY();
} else {
xx = (float)area.getCenterX();
yy = (float)(y0 + ((double)i + 0.5D) * (double)height);
}
String label = this.subCategories.get(i).toString();
TextUtilities.drawRotatedString(label, g2, xx, yy, TextAnchor.CENTER, 0.0D, TextAnchor.CENTER);
}
}
if (edge.equals(RectangleEdge.TOP)) {
double h = maxdim;
state.cursorUp(h);
} else if (edge.equals(RectangleEdge.BOTTOM)) {
double h = maxdim;
state.cursorDown(h);
} else if (edge == RectangleEdge.LEFT) {
double w = maxdim;
state.cursorLeft(w);
} else if (edge == RectangleEdge.RIGHT) {
double w = maxdim;
state.cursorRight(w);
}
return state;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof SubCategoryAxis && super.equals(obj)) {
SubCategoryAxis axis = (SubCategoryAxis)obj;
if (!this.subCategories.equals(axis.subCategories))
return false;
if (!this.subLabelFont.equals(axis.subLabelFont))
return false;
if (!this.subLabelPaint.equals(axis.subLabelPaint))
return false;
return true;
}
return false;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.subLabelPaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.subLabelPaint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,385 @@
package org.jfree.chart.axis;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.data.Range;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.TextAnchor;
import org.jfree.util.PaintUtilities;
public class SymbolAxis extends NumberAxis implements Serializable {
private static final long serialVersionUID = 7216330468770619716L;
public static final Paint DEFAULT_GRID_BAND_PAINT = new Color(232, 234, 232, 128);
public static final Paint DEFAULT_GRID_BAND_ALTERNATE_PAINT = new Color(0, 0, 0, 0);
private List symbols;
private boolean gridBandsVisible;
private transient Paint gridBandPaint;
private transient Paint gridBandAlternatePaint;
public SymbolAxis(String label, String[] sv) {
super(label);
this.symbols = Arrays.asList(sv);
this.gridBandsVisible = true;
this.gridBandPaint = DEFAULT_GRID_BAND_PAINT;
this.gridBandAlternatePaint = DEFAULT_GRID_BAND_ALTERNATE_PAINT;
setAutoTickUnitSelection(false, false);
setAutoRangeStickyZero(false);
}
public String[] getSymbols() {
String[] result = new String[this.symbols.size()];
result = (String[])this.symbols.toArray(result);
return result;
}
public boolean isGridBandsVisible() {
return this.gridBandsVisible;
}
public void setGridBandsVisible(boolean flag) {
if (this.gridBandsVisible != flag) {
this.gridBandsVisible = flag;
notifyListeners(new AxisChangeEvent(this));
}
}
public Paint getGridBandPaint() {
return this.gridBandPaint;
}
public void setGridBandPaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.gridBandPaint = paint;
notifyListeners(new AxisChangeEvent(this));
}
public Paint getGridBandAlternatePaint() {
return this.gridBandAlternatePaint;
}
public void setGridBandAlternatePaint(Paint paint) {
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.gridBandAlternatePaint = paint;
notifyListeners(new AxisChangeEvent(this));
}
protected void selectAutoTickUnit(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
throw new UnsupportedOperationException();
}
public AxisState draw(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, PlotRenderingInfo plotState) {
AxisState info = new AxisState(cursor);
if (isVisible())
info = super.draw(g2, cursor, plotArea, dataArea, edge, plotState);
if (this.gridBandsVisible)
drawGridBands(g2, plotArea, dataArea, edge, info.getTicks());
return info;
}
protected void drawGridBands(Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge, List ticks) {
Shape savedClip = g2.getClip();
g2.clip(dataArea);
if (RectangleEdge.isTopOrBottom(edge)) {
drawGridBandsHorizontal(g2, plotArea, dataArea, true, ticks);
} else if (RectangleEdge.isLeftOrRight(edge)) {
drawGridBandsVertical(g2, plotArea, dataArea, true, ticks);
}
g2.setClip(savedClip);
}
protected void drawGridBandsHorizontal(Graphics2D g2, Rectangle2D plotArea, Rectangle2D dataArea, boolean firstGridBandIsDark, List ticks) {
double outlineStrokeWidth;
boolean currentGridBandIsDark = firstGridBandIsDark;
double yy = dataArea.getY();
if (getPlot().getOutlineStroke() != null) {
outlineStrokeWidth = (double)((BasicStroke)getPlot().getOutlineStroke()).getLineWidth();
} else {
outlineStrokeWidth = 1.0D;
}
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
ValueTick tick = (ValueTick)iterator.next();
double xx1 = valueToJava2D(tick.getValue() - 0.5D, dataArea, RectangleEdge.BOTTOM);
double xx2 = valueToJava2D(tick.getValue() + 0.5D, dataArea, RectangleEdge.BOTTOM);
if (currentGridBandIsDark) {
g2.setPaint(this.gridBandPaint);
} else {
g2.setPaint(Color.white);
}
Rectangle2D band = new Rectangle2D.Double(xx1, yy + outlineStrokeWidth, xx2 - xx1, dataArea.getMaxY() - yy - outlineStrokeWidth);
g2.fill(band);
currentGridBandIsDark = !currentGridBandIsDark;
}
g2.setPaintMode();
}
protected void drawGridBandsVertical(Graphics2D g2, Rectangle2D drawArea, Rectangle2D plotArea, boolean firstGridBandIsDark, List ticks) {
double outlineStrokeWidth;
boolean currentGridBandIsDark = firstGridBandIsDark;
double xx = plotArea.getX();
Stroke outlineStroke = getPlot().getOutlineStroke();
if (outlineStroke != null && outlineStroke instanceof BasicStroke) {
outlineStrokeWidth = (double)((BasicStroke)outlineStroke).getLineWidth();
} else {
outlineStrokeWidth = 1.0D;
}
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
ValueTick tick = (ValueTick)iterator.next();
double yy1 = valueToJava2D(tick.getValue() + 0.5D, plotArea, RectangleEdge.LEFT);
double yy2 = valueToJava2D(tick.getValue() - 0.5D, plotArea, RectangleEdge.LEFT);
if (currentGridBandIsDark) {
g2.setPaint(this.gridBandPaint);
} else {
g2.setPaint(Color.white);
}
Rectangle2D band = new Rectangle2D.Double(xx + outlineStrokeWidth, yy1, plotArea.getMaxX() - xx - outlineStrokeWidth, yy2 - yy1);
g2.fill(band);
currentGridBandIsDark = !currentGridBandIsDark;
}
g2.setPaintMode();
}
protected void autoAdjustRange() {
Plot plot = getPlot();
if (plot == null)
return;
if (plot instanceof org.jfree.chart.plot.ValueAxisPlot) {
double upper = (double)(this.symbols.size() - 1);
double lower = 0.0D;
double range = upper - lower;
double minRange = getAutoRangeMinimumSize();
if (range < minRange) {
upper = (upper + lower + minRange) / 2.0D;
lower = (upper + lower - minRange) / 2.0D;
}
double upperMargin = 0.5D;
double lowerMargin = 0.5D;
if (getAutoRangeIncludesZero()) {
if (getAutoRangeStickyZero()) {
if (upper <= 0.0D) {
upper = 0.0D;
} else {
upper += upperMargin;
}
if (lower >= 0.0D) {
lower = 0.0D;
} else {
lower -= lowerMargin;
}
} else {
upper = Math.max(0.0D, upper + upperMargin);
lower = Math.min(0.0D, lower - lowerMargin);
}
} else if (getAutoRangeStickyZero()) {
if (upper <= 0.0D) {
upper = Math.min(0.0D, upper + upperMargin);
} else {
upper += upperMargin * range;
}
if (lower >= 0.0D) {
lower = Math.max(0.0D, lower - lowerMargin);
} else {
lower -= lowerMargin;
}
} else {
upper += upperMargin;
lower -= lowerMargin;
}
setRange(new Range(lower, upper), false, false);
}
}
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List ticks = null;
if (RectangleEdge.isTopOrBottom(edge)) {
ticks = refreshTicksHorizontal(g2, dataArea, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
ticks = refreshTicksVertical(g2, dataArea, edge);
}
return ticks;
}
protected List refreshTicksHorizontal(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List ticks = new ArrayList();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
double size = getTickUnit().getSize();
int count = calculateVisibleTickCount();
double lowestTickValue = calculateLowestVisibleTickValue();
double previousDrawnTickLabelPos = 0.0D;
double previousDrawnTickLabelLength = 0.0D;
if (count <= 500)
for (int i = 0; i < count; i++) {
String tickLabel;
double currentTickValue = lowestTickValue + (double)i * size;
double xx = valueToJava2D(currentTickValue, dataArea, edge);
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
} else {
tickLabel = valueToString(currentTickValue);
}
Rectangle2D bounds = TextUtilities.getTextBounds(tickLabel, g2, g2.getFontMetrics());
double tickLabelLength = isVerticalTickLabels() ? bounds.getHeight() : bounds.getWidth();
boolean tickLabelsOverlapping = false;
if (i > 0) {
double avgTickLabelLength = (previousDrawnTickLabelLength + tickLabelLength) / 2.0D;
if (Math.abs(xx - previousDrawnTickLabelPos) < avgTickLabelLength)
tickLabelsOverlapping = true;
}
if (tickLabelsOverlapping) {
tickLabel = "";
} else {
previousDrawnTickLabelPos = xx;
previousDrawnTickLabelLength = tickLabelLength;
}
TextAnchor anchor = null;
TextAnchor rotationAnchor = null;
double angle = 0.0D;
if (isVerticalTickLabels()) {
anchor = TextAnchor.CENTER_RIGHT;
rotationAnchor = TextAnchor.CENTER_RIGHT;
if (edge == RectangleEdge.TOP) {
angle = 1.5707963267948966D;
} else {
angle = -1.5707963267948966D;
}
} else if (edge == RectangleEdge.TOP) {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
} else {
anchor = TextAnchor.TOP_CENTER;
rotationAnchor = TextAnchor.TOP_CENTER;
}
Tick tick = new NumberTick(new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle);
ticks.add(tick);
}
return ticks;
}
protected List refreshTicksVertical(Graphics2D g2, Rectangle2D dataArea, RectangleEdge edge) {
List ticks = new ArrayList();
Font tickLabelFont = getTickLabelFont();
g2.setFont(tickLabelFont);
double size = getTickUnit().getSize();
int count = calculateVisibleTickCount();
double lowestTickValue = calculateLowestVisibleTickValue();
double previousDrawnTickLabelPos = 0.0D;
double previousDrawnTickLabelLength = 0.0D;
if (count <= 500)
for (int i = 0; i < count; i++) {
String tickLabel;
double currentTickValue = lowestTickValue + (double)i * size;
double yy = valueToJava2D(currentTickValue, dataArea, edge);
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
tickLabel = formatter.format(currentTickValue);
} else {
tickLabel = valueToString(currentTickValue);
}
Rectangle2D bounds = TextUtilities.getTextBounds(tickLabel, g2, g2.getFontMetrics());
double tickLabelLength = isVerticalTickLabels() ? bounds.getWidth() : bounds.getHeight();
boolean tickLabelsOverlapping = false;
if (i > 0) {
double avgTickLabelLength = (previousDrawnTickLabelLength + tickLabelLength) / 2.0D;
if (Math.abs(yy - previousDrawnTickLabelPos) < avgTickLabelLength)
tickLabelsOverlapping = true;
}
if (tickLabelsOverlapping) {
tickLabel = "";
} else {
previousDrawnTickLabelPos = yy;
previousDrawnTickLabelLength = tickLabelLength;
}
TextAnchor anchor = null;
TextAnchor rotationAnchor = null;
double angle = 0.0D;
if (isVerticalTickLabels()) {
anchor = TextAnchor.BOTTOM_CENTER;
rotationAnchor = TextAnchor.BOTTOM_CENTER;
if (edge == RectangleEdge.LEFT) {
angle = -1.5707963267948966D;
} else {
angle = 1.5707963267948966D;
}
} else if (edge == RectangleEdge.LEFT) {
anchor = TextAnchor.CENTER_RIGHT;
rotationAnchor = TextAnchor.CENTER_RIGHT;
} else {
anchor = TextAnchor.CENTER_LEFT;
rotationAnchor = TextAnchor.CENTER_LEFT;
}
Tick tick = new NumberTick(new Double(currentTickValue), tickLabel, anchor, rotationAnchor, angle);
ticks.add(tick);
}
return ticks;
}
public String valueToString(double value) {
String str;
try {
str = (String)this.symbols.get((int)value);
} catch (IndexOutOfBoundsException ex) {
str = "";
}
return str;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof SymbolAxis))
return false;
SymbolAxis that = (SymbolAxis)obj;
if (!this.symbols.equals(that.symbols))
return false;
if (this.gridBandsVisible != that.gridBandsVisible)
return false;
if (!PaintUtilities.equal(this.gridBandPaint, that.gridBandPaint))
return false;
if (!PaintUtilities.equal(this.gridBandAlternatePaint, that.gridBandAlternatePaint))
return false;
return super.equals(obj);
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.gridBandPaint, stream);
SerialUtilities.writePaint(this.gridBandAlternatePaint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.gridBandPaint = SerialUtilities.readPaint(stream);
this.gridBandAlternatePaint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,71 @@
package org.jfree.chart.axis;
import java.io.Serializable;
import org.jfree.ui.TextAnchor;
import org.jfree.util.ObjectUtilities;
public abstract class Tick implements Serializable, Cloneable {
private static final long serialVersionUID = 6668230383875149773L;
private String text;
private TextAnchor textAnchor;
private TextAnchor rotationAnchor;
private double angle;
public Tick(String text, TextAnchor textAnchor, TextAnchor rotationAnchor, double angle) {
if (textAnchor == null)
throw new IllegalArgumentException("Null 'textAnchor' argument.");
if (rotationAnchor == null)
throw new IllegalArgumentException("Null 'rotationAnchor' argument.");
this.text = text;
this.textAnchor = textAnchor;
this.rotationAnchor = rotationAnchor;
this.angle = angle;
}
public String getText() {
return this.text;
}
public TextAnchor getTextAnchor() {
return this.textAnchor;
}
public TextAnchor getRotationAnchor() {
return this.rotationAnchor;
}
public double getAngle() {
return this.angle;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof Tick) {
Tick t = (Tick)obj;
if (!ObjectUtilities.equal(this.text, t.text))
return false;
if (!ObjectUtilities.equal(this.textAnchor, t.textAnchor))
return false;
if (!ObjectUtilities.equal(this.rotationAnchor, t.rotationAnchor))
return false;
if (this.angle != t.angle)
return false;
return true;
}
return false;
}
public Object clone() throws CloneNotSupportedException {
Tick clone = (Tick)super.clone();
return clone;
}
public String toString() {
return this.text;
}
}

View file

@ -0,0 +1,41 @@
package org.jfree.chart.axis;
import java.io.ObjectStreamException;
import java.io.Serializable;
public final class TickType implements Serializable {
public static final TickType MAJOR = new TickType("MAJOR");
public static final TickType MINOR = new TickType("MINOR");
private String name;
private TickType(String name) {
this.name = name;
}
public String toString() {
return this.name;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof TickType))
return false;
TickType that = (TickType)obj;
if (!this.name.equals(that.name))
return false;
return true;
}
private Object readResolve() throws ObjectStreamException {
Object result = null;
if (equals(MAJOR)) {
result = MAJOR;
} else if (equals(MINOR)) {
result = MINOR;
}
return result;
}
}

View file

@ -0,0 +1,62 @@
package org.jfree.chart.axis;
import java.io.Serializable;
public abstract class TickUnit implements Comparable, Serializable {
private static final long serialVersionUID = 510179855057013974L;
private double size;
private int minorTickCount;
public TickUnit(double size) {
this.size = size;
}
public TickUnit(double size, int minorTickCount) {
this.size = size;
this.minorTickCount = minorTickCount;
}
public double getSize() {
return this.size;
}
public int getMinorTickCount() {
return this.minorTickCount;
}
public String valueToString(double value) {
return String.valueOf(value);
}
public int compareTo(Object object) {
if (object instanceof TickUnit) {
TickUnit other = (TickUnit)object;
if (this.size > other.getSize())
return 1;
if (this.size < other.getSize())
return -1;
return 0;
}
return -1;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof TickUnit))
return false;
TickUnit that = (TickUnit)obj;
if (this.size != that.size)
return false;
if (this.minorTickCount != that.minorTickCount)
return false;
return true;
}
public int hashCode() {
long temp = (this.size != 0.0D) ? Double.doubleToLongBits(this.size) : 0L;
return (int)(temp ^ temp >>> 32L);
}
}

View file

@ -0,0 +1,9 @@
package org.jfree.chart.axis;
public interface TickUnitSource {
TickUnit getLargerTickUnit(TickUnit paramTickUnit);
TickUnit getCeilingTickUnit(TickUnit paramTickUnit);
TickUnit getCeilingTickUnit(double paramDouble);
}

View file

@ -0,0 +1,65 @@
package org.jfree.chart.axis;
import java.io.Serializable;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TickUnits implements TickUnitSource, Cloneable, Serializable {
private static final long serialVersionUID = 1134174035901467545L;
private List tickUnits = new ArrayList();
public void add(TickUnit unit) {
if (unit == null)
throw new NullPointerException("Null 'unit' argument.");
this.tickUnits.add(unit);
Collections.sort(this.tickUnits);
}
public int size() {
return this.tickUnits.size();
}
public TickUnit get(int pos) {
return (TickUnit)this.tickUnits.get(pos);
}
public TickUnit getLargerTickUnit(TickUnit unit) {
int index = Collections.binarySearch(this.tickUnits, unit);
if (index >= 0) {
index++;
} else {
index = -index;
}
return (TickUnit)this.tickUnits.get(Math.min(index, this.tickUnits.size() - 1));
}
public TickUnit getCeilingTickUnit(TickUnit unit) {
int index = Collections.binarySearch(this.tickUnits, unit);
if (index >= 0)
return (TickUnit)this.tickUnits.get(index);
index = -(index + 1);
return (TickUnit)this.tickUnits.get(Math.min(index, this.tickUnits.size() - 1));
}
public TickUnit getCeilingTickUnit(double size) {
return getCeilingTickUnit(new NumberTickUnit(size, NumberFormat.getInstance()));
}
public Object clone() throws CloneNotSupportedException {
TickUnits clone = (TickUnits)super.clone();
clone.tickUnits = new ArrayList(this.tickUnits);
return clone;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof TickUnits))
return false;
TickUnits that = (TickUnits)obj;
return that.tickUnits.equals(this.tickUnits);
}
}

View file

@ -0,0 +1,19 @@
package org.jfree.chart.axis;
import java.util.Date;
public interface Timeline {
long toTimelineValue(long paramLong);
long toTimelineValue(Date paramDate);
long toMillisecond(long paramLong);
boolean containsDomainValue(long paramLong);
boolean containsDomainValue(Date paramDate);
boolean containsDomainRange(long paramLong1, long paramLong2);
boolean containsDomainRange(Date paramDate1, Date paramDate2);
}

View file

@ -0,0 +1,697 @@
package org.jfree.chart.axis;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.font.LineMetrics;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import org.jfree.chart.event.AxisChangeEvent;
import org.jfree.chart.plot.Plot;
import org.jfree.data.Range;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PublicCloneable;
public abstract class ValueAxis extends Axis implements Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = 3698345477322391456L;
public static final Range DEFAULT_RANGE = new Range(0.0D, 1.0D);
public static final boolean DEFAULT_AUTO_RANGE = true;
public static final boolean DEFAULT_INVERTED = false;
public static final double DEFAULT_AUTO_RANGE_MINIMUM_SIZE = 1.0E-8D;
public static final double DEFAULT_LOWER_MARGIN = 0.05D;
public static final double DEFAULT_UPPER_MARGIN = 0.05D;
public static final double DEFAULT_LOWER_BOUND = 0.0D;
public static final double DEFAULT_UPPER_BOUND = 1.0D;
public static final boolean DEFAULT_AUTO_TICK_UNIT_SELECTION = true;
public static final int MAXIMUM_TICK_COUNT = 500;
private boolean positiveArrowVisible;
private boolean negativeArrowVisible;
private transient Shape upArrow;
private transient Shape downArrow;
private transient Shape leftArrow;
private transient Shape rightArrow;
private boolean inverted;
private Range range;
private boolean autoRange;
private double autoRangeMinimumSize;
private Range defaultAutoRange;
private double upperMargin;
private double lowerMargin;
private double fixedAutoRange;
private boolean autoTickUnitSelection;
private TickUnitSource standardTickUnits;
private int autoTickIndex;
private boolean verticalTickLabels;
protected ValueAxis(String label, TickUnitSource standardTickUnits) {
super(label);
this.positiveArrowVisible = false;
this.negativeArrowVisible = false;
this.range = DEFAULT_RANGE;
this.autoRange = true;
this.defaultAutoRange = DEFAULT_RANGE;
this.inverted = false;
this.autoRangeMinimumSize = 1.0E-8D;
this.lowerMargin = 0.05D;
this.upperMargin = 0.05D;
this.fixedAutoRange = 0.0D;
this.autoTickUnitSelection = true;
this.standardTickUnits = standardTickUnits;
Polygon p1 = new Polygon();
p1.addPoint(0, 0);
p1.addPoint(-2, 2);
p1.addPoint(2, 2);
this.upArrow = p1;
Polygon p2 = new Polygon();
p2.addPoint(0, 0);
p2.addPoint(-2, -2);
p2.addPoint(2, -2);
this.downArrow = p2;
Polygon p3 = new Polygon();
p3.addPoint(0, 0);
p3.addPoint(-2, -2);
p3.addPoint(-2, 2);
this.rightArrow = p3;
Polygon p4 = new Polygon();
p4.addPoint(0, 0);
p4.addPoint(2, -2);
p4.addPoint(2, 2);
this.leftArrow = p4;
this.verticalTickLabels = false;
}
public boolean isVerticalTickLabels() {
return this.verticalTickLabels;
}
public void setVerticalTickLabels(boolean flag) {
if (this.verticalTickLabels != flag) {
this.verticalTickLabels = flag;
notifyListeners(new AxisChangeEvent(this));
}
}
public boolean isPositiveArrowVisible() {
return this.positiveArrowVisible;
}
public void setPositiveArrowVisible(boolean visible) {
this.positiveArrowVisible = visible;
notifyListeners(new AxisChangeEvent(this));
}
public boolean isNegativeArrowVisible() {
return this.negativeArrowVisible;
}
public void setNegativeArrowVisible(boolean visible) {
this.negativeArrowVisible = visible;
notifyListeners(new AxisChangeEvent(this));
}
public Shape getUpArrow() {
return this.upArrow;
}
public void setUpArrow(Shape arrow) {
if (arrow == null)
throw new IllegalArgumentException("Null 'arrow' argument.");
this.upArrow = arrow;
notifyListeners(new AxisChangeEvent(this));
}
public Shape getDownArrow() {
return this.downArrow;
}
public void setDownArrow(Shape arrow) {
if (arrow == null)
throw new IllegalArgumentException("Null 'arrow' argument.");
this.downArrow = arrow;
notifyListeners(new AxisChangeEvent(this));
}
public Shape getLeftArrow() {
return this.leftArrow;
}
public void setLeftArrow(Shape arrow) {
if (arrow == null)
throw new IllegalArgumentException("Null 'arrow' argument.");
this.leftArrow = arrow;
notifyListeners(new AxisChangeEvent(this));
}
public Shape getRightArrow() {
return this.rightArrow;
}
public void setRightArrow(Shape arrow) {
if (arrow == null)
throw new IllegalArgumentException("Null 'arrow' argument.");
this.rightArrow = arrow;
notifyListeners(new AxisChangeEvent(this));
}
protected void drawAxisLine(Graphics2D g2, double cursor, Rectangle2D dataArea, RectangleEdge edge) {
Line2D axisLine = null;
if (edge == RectangleEdge.TOP) {
axisLine = new Line2D.Double(dataArea.getX(), cursor, dataArea.getMaxX(), cursor);
} else if (edge == RectangleEdge.BOTTOM) {
axisLine = new Line2D.Double(dataArea.getX(), cursor, dataArea.getMaxX(), cursor);
} else if (edge == RectangleEdge.LEFT) {
axisLine = new Line2D.Double(cursor, dataArea.getY(), cursor, dataArea.getMaxY());
} else if (edge == RectangleEdge.RIGHT) {
axisLine = new Line2D.Double(cursor, dataArea.getY(), cursor, dataArea.getMaxY());
}
g2.setPaint(getAxisLinePaint());
g2.setStroke(getAxisLineStroke());
g2.draw(axisLine);
boolean drawUpOrRight = false;
boolean drawDownOrLeft = false;
if (this.positiveArrowVisible)
if (this.inverted) {
drawDownOrLeft = true;
} else {
drawUpOrRight = true;
}
if (this.negativeArrowVisible)
if (this.inverted) {
drawUpOrRight = true;
} else {
drawDownOrLeft = true;
}
if (drawUpOrRight) {
double x = 0.0D;
double y = 0.0D;
Shape arrow = null;
if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
x = dataArea.getMaxX();
y = cursor;
arrow = this.rightArrow;
} else if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT) {
x = cursor;
y = dataArea.getMinY();
arrow = this.upArrow;
}
AffineTransform transformer = new AffineTransform();
transformer.setToTranslation(x, y);
Shape shape = transformer.createTransformedShape(arrow);
g2.fill(shape);
g2.draw(shape);
}
if (drawDownOrLeft) {
double x = 0.0D;
double y = 0.0D;
Shape arrow = null;
if (edge == RectangleEdge.TOP || edge == RectangleEdge.BOTTOM) {
x = dataArea.getMinX();
y = cursor;
arrow = this.leftArrow;
} else if (edge == RectangleEdge.LEFT || edge == RectangleEdge.RIGHT) {
x = cursor;
y = dataArea.getMaxY();
arrow = this.downArrow;
}
AffineTransform transformer = new AffineTransform();
transformer.setToTranslation(x, y);
Shape shape = transformer.createTransformedShape(arrow);
g2.fill(shape);
g2.draw(shape);
}
}
protected float[] calculateAnchorPoint(ValueTick tick, double cursor, Rectangle2D dataArea, RectangleEdge edge) {
RectangleInsets insets = getTickLabelInsets();
float[] result = new float[2];
if (edge == RectangleEdge.TOP) {
result[0] = (float)valueToJava2D(tick.getValue(), dataArea, edge);
result[1] = (float)(cursor - insets.getBottom() - 2.0D);
} else if (edge == RectangleEdge.BOTTOM) {
result[0] = (float)valueToJava2D(tick.getValue(), dataArea, edge);
result[1] = (float)(cursor + insets.getTop() + 2.0D);
} else if (edge == RectangleEdge.LEFT) {
result[0] = (float)(cursor - insets.getLeft() - 2.0D);
result[1] = (float)valueToJava2D(tick.getValue(), dataArea, edge);
} else if (edge == RectangleEdge.RIGHT) {
result[0] = (float)(cursor + insets.getRight() + 2.0D);
result[1] = (float)valueToJava2D(tick.getValue(), dataArea, edge);
}
return result;
}
protected AxisState drawTickMarksAndLabels(Graphics2D g2, double cursor, Rectangle2D plotArea, Rectangle2D dataArea, RectangleEdge edge) {
AxisState state = new AxisState(cursor);
if (isAxisLineVisible())
drawAxisLine(g2, cursor, dataArea, edge);
double ol = (double)getTickMarkOutsideLength();
double il = (double)getTickMarkInsideLength();
List ticks = refreshTicks(g2, state, dataArea, edge);
state.setTicks(ticks);
g2.setFont(getTickLabelFont());
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
ValueTick tick = (ValueTick)iterator.next();
if (isTickLabelsVisible()) {
g2.setPaint(getTickLabelPaint());
float[] anchorPoint = calculateAnchorPoint(tick, cursor, dataArea, edge);
TextUtilities.drawRotatedString(tick.getText(), g2, anchorPoint[0], anchorPoint[1], tick.getTextAnchor(), tick.getAngle(), tick.getRotationAnchor());
}
if (isTickMarksVisible() && tick.getTickType().equals(TickType.MAJOR)) {
float xx = (float)valueToJava2D(tick.getValue(), dataArea, edge);
Line2D mark = null;
g2.setStroke(getTickMarkStroke());
g2.setPaint(getTickMarkPaint());
if (edge == RectangleEdge.LEFT) {
mark = new Line2D.Double(cursor - ol, (double)xx, cursor + il, (double)xx);
} else if (edge == RectangleEdge.RIGHT) {
mark = new Line2D.Double(cursor + ol, (double)xx, cursor - il, (double)xx);
} else if (edge == RectangleEdge.TOP) {
mark = new Line2D.Double((double)xx, cursor - ol, (double)xx, cursor + il);
} else if (edge == RectangleEdge.BOTTOM) {
mark = new Line2D.Double((double)xx, cursor + ol, (double)xx, cursor - il);
}
g2.draw(mark);
}
}
double used = 0.0D;
if (isTickLabelsVisible())
if (edge == RectangleEdge.LEFT) {
used += findMaximumTickLabelWidth(ticks, g2, plotArea, isVerticalTickLabels());
state.cursorLeft(used);
} else if (edge == RectangleEdge.RIGHT) {
used = findMaximumTickLabelWidth(ticks, g2, plotArea, isVerticalTickLabels());
state.cursorRight(used);
} else if (edge == RectangleEdge.TOP) {
used = findMaximumTickLabelHeight(ticks, g2, plotArea, isVerticalTickLabels());
state.cursorUp(used);
} else if (edge == RectangleEdge.BOTTOM) {
used = findMaximumTickLabelHeight(ticks, g2, plotArea, isVerticalTickLabels());
state.cursorDown(used);
}
return state;
}
public AxisSpace reserveSpace(Graphics2D g2, Plot plot, Rectangle2D plotArea, RectangleEdge edge, AxisSpace space) {
if (space == null)
space = new AxisSpace();
if (!isVisible())
return space;
double dimension = getFixedDimension();
if (dimension > 0.0D)
space.ensureAtLeast(dimension, edge);
double tickLabelHeight = 0.0D;
double tickLabelWidth = 0.0D;
if (isTickLabelsVisible()) {
g2.setFont(getTickLabelFont());
List ticks = refreshTicks(g2, new AxisState(), plotArea, edge);
if (RectangleEdge.isTopOrBottom(edge)) {
tickLabelHeight = findMaximumTickLabelHeight(ticks, g2, plotArea, isVerticalTickLabels());
} else if (RectangleEdge.isLeftOrRight(edge)) {
tickLabelWidth = findMaximumTickLabelWidth(ticks, g2, plotArea, isVerticalTickLabels());
}
}
Rectangle2D labelEnclosure = getLabelEnclosure(g2, edge);
double labelHeight = 0.0D;
double labelWidth = 0.0D;
if (RectangleEdge.isTopOrBottom(edge)) {
labelHeight = labelEnclosure.getHeight();
space.add(labelHeight + tickLabelHeight, edge);
} else if (RectangleEdge.isLeftOrRight(edge)) {
labelWidth = labelEnclosure.getWidth();
space.add(labelWidth + tickLabelWidth, edge);
}
return space;
}
protected double findMaximumTickLabelHeight(List ticks, Graphics2D g2, Rectangle2D drawArea, boolean vertical) {
RectangleInsets insets = getTickLabelInsets();
Font font = getTickLabelFont();
double maxHeight = 0.0D;
if (vertical) {
FontMetrics fm = g2.getFontMetrics(font);
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
Tick tick = (Tick)iterator.next();
Rectangle2D labelBounds = TextUtilities.getTextBounds(tick.getText(), g2, fm);
if (labelBounds.getWidth() + insets.getTop() + insets.getBottom() > maxHeight)
maxHeight = labelBounds.getWidth() + insets.getTop() + insets.getBottom();
}
} else {
LineMetrics metrics = font.getLineMetrics("ABCxyz", g2.getFontRenderContext());
maxHeight = (double)metrics.getHeight() + insets.getTop() + insets.getBottom();
}
return maxHeight;
}
protected double findMaximumTickLabelWidth(List ticks, Graphics2D g2, Rectangle2D drawArea, boolean vertical) {
RectangleInsets insets = getTickLabelInsets();
Font font = getTickLabelFont();
double maxWidth = 0.0D;
if (!vertical) {
FontMetrics fm = g2.getFontMetrics(font);
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
Tick tick = (Tick)iterator.next();
Rectangle2D labelBounds = TextUtilities.getTextBounds(tick.getText(), g2, fm);
if (labelBounds.getWidth() + insets.getLeft() + insets.getRight() > maxWidth)
maxWidth = labelBounds.getWidth() + insets.getLeft() + insets.getRight();
}
} else {
LineMetrics metrics = font.getLineMetrics("ABCxyz", g2.getFontRenderContext());
maxWidth = (double)metrics.getHeight() + insets.getTop() + insets.getBottom();
}
return maxWidth;
}
public boolean isInverted() {
return this.inverted;
}
public void setInverted(boolean flag) {
if (this.inverted != flag) {
this.inverted = flag;
notifyListeners(new AxisChangeEvent(this));
}
}
public boolean isAutoRange() {
return this.autoRange;
}
public void setAutoRange(boolean auto) {
setAutoRange(auto, true);
}
protected void setAutoRange(boolean auto, boolean notify) {
if (this.autoRange != auto) {
this.autoRange = auto;
if (this.autoRange)
autoAdjustRange();
if (notify)
notifyListeners(new AxisChangeEvent(this));
}
}
public double getAutoRangeMinimumSize() {
return this.autoRangeMinimumSize;
}
public void setAutoRangeMinimumSize(double size) {
setAutoRangeMinimumSize(size, true);
}
public void setAutoRangeMinimumSize(double size, boolean notify) {
if (size <= 0.0D)
throw new IllegalArgumentException("NumberAxis.setAutoRangeMinimumSize(double): must be > 0.0.");
if (this.autoRangeMinimumSize != size) {
this.autoRangeMinimumSize = size;
if (this.autoRange)
autoAdjustRange();
if (notify)
notifyListeners(new AxisChangeEvent(this));
}
}
public Range getDefaultAutoRange() {
return this.defaultAutoRange;
}
public void setDefaultAutoRange(Range range) {
if (range == null)
throw new IllegalArgumentException("Null 'range' argument.");
this.defaultAutoRange = range;
notifyListeners(new AxisChangeEvent(this));
}
public double getLowerMargin() {
return this.lowerMargin;
}
public void setLowerMargin(double margin) {
this.lowerMargin = margin;
if (isAutoRange())
autoAdjustRange();
notifyListeners(new AxisChangeEvent(this));
}
public double getUpperMargin() {
return this.upperMargin;
}
public void setUpperMargin(double margin) {
this.upperMargin = margin;
if (isAutoRange())
autoAdjustRange();
notifyListeners(new AxisChangeEvent(this));
}
public double getFixedAutoRange() {
return this.fixedAutoRange;
}
public void setFixedAutoRange(double length) {
this.fixedAutoRange = length;
if (isAutoRange())
autoAdjustRange();
notifyListeners(new AxisChangeEvent(this));
}
public double getLowerBound() {
return this.range.getLowerBound();
}
public void setLowerBound(double min) {
if (this.range.getUpperBound() > min) {
setRange(new Range(min, this.range.getUpperBound()));
} else {
setRange(new Range(min, min + 1.0D));
}
}
public double getUpperBound() {
return this.range.getUpperBound();
}
public void setUpperBound(double max) {
if (this.range.getLowerBound() < max) {
setRange(new Range(this.range.getLowerBound(), max));
} else {
setRange(max - 1.0D, max);
}
}
public Range getRange() {
return this.range;
}
public void setRange(Range range) {
setRange(range, true, true);
}
public void setRange(Range range, boolean turnOffAutoRange, boolean notify) {
if (range == null)
throw new IllegalArgumentException("Null 'range' argument.");
if (turnOffAutoRange)
this.autoRange = false;
this.range = range;
if (notify)
notifyListeners(new AxisChangeEvent(this));
}
public void setRange(double lower, double upper) {
setRange(new Range(lower, upper));
}
public void setRangeWithMargins(Range range) {
setRangeWithMargins(range, true, true);
}
public void setRangeWithMargins(Range range, boolean turnOffAutoRange, boolean notify) {
if (range == null)
throw new IllegalArgumentException("Null 'range' argument.");
setRange(Range.expand(range, getLowerMargin(), getUpperMargin()), turnOffAutoRange, notify);
}
public void setRangeWithMargins(double lower, double upper) {
setRangeWithMargins(new Range(lower, upper));
}
public void setRangeAboutValue(double value, double length) {
setRange(new Range(value - length / 2.0D, value + length / 2.0D));
}
public boolean isAutoTickUnitSelection() {
return this.autoTickUnitSelection;
}
public void setAutoTickUnitSelection(boolean flag) {
setAutoTickUnitSelection(flag, true);
}
public void setAutoTickUnitSelection(boolean flag, boolean notify) {
if (this.autoTickUnitSelection != flag) {
this.autoTickUnitSelection = flag;
if (notify)
notifyListeners(new AxisChangeEvent(this));
}
}
public TickUnitSource getStandardTickUnits() {
return this.standardTickUnits;
}
public void setStandardTickUnits(TickUnitSource source) {
this.standardTickUnits = source;
notifyListeners(new AxisChangeEvent(this));
}
public abstract double valueToJava2D(double paramDouble, Rectangle2D paramRectangle2D, RectangleEdge paramRectangleEdge);
public double lengthToJava2D(double length, Rectangle2D area, RectangleEdge edge) {
double zero = valueToJava2D(0.0D, area, edge);
double l = valueToJava2D(length, area, edge);
return Math.abs(l - zero);
}
public abstract double java2DToValue(double paramDouble, Rectangle2D paramRectangle2D, RectangleEdge paramRectangleEdge);
protected abstract void autoAdjustRange();
public void centerRange(double value) {
double central = this.range.getCentralValue();
Range adjusted = new Range(this.range.getLowerBound() + value - central, this.range.getUpperBound() + value - central);
setRange(adjusted);
}
public void resizeRange(double percent) {
resizeRange(percent, this.range.getCentralValue());
}
public void resizeRange(double percent, double anchorValue) {
if (percent > 0.0D) {
double halfLength = this.range.getLength() * percent / 2.0D;
Range adjusted = new Range(anchorValue - halfLength, anchorValue + halfLength);
setRange(adjusted);
} else {
setAutoRange(true);
}
}
public void zoomRange(double lowerPercent, double upperPercent) {
double start = this.range.getLowerBound();
double length = this.range.getLength();
Range adjusted = null;
if (isInverted()) {
adjusted = new Range(start + length * (1.0D - upperPercent), start + length * (1.0D - lowerPercent));
} else {
adjusted = new Range(start + length * lowerPercent, start + length * upperPercent);
}
setRange(adjusted);
}
protected int getAutoTickIndex() {
return this.autoTickIndex;
}
protected void setAutoTickIndex(int index) {
this.autoTickIndex = index;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof ValueAxis))
return false;
ValueAxis that = (ValueAxis)obj;
if (this.positiveArrowVisible != that.positiveArrowVisible)
return false;
if (this.negativeArrowVisible != that.negativeArrowVisible)
return false;
if (this.inverted != that.inverted)
return false;
if (!ObjectUtilities.equal(this.range, that.range))
return false;
if (this.autoRange != that.autoRange)
return false;
if (this.autoRangeMinimumSize != that.autoRangeMinimumSize)
return false;
if (!this.defaultAutoRange.equals(that.defaultAutoRange))
return false;
if (this.upperMargin != that.upperMargin)
return false;
if (this.lowerMargin != that.lowerMargin)
return false;
if (this.fixedAutoRange != that.fixedAutoRange)
return false;
if (this.autoTickUnitSelection != that.autoTickUnitSelection)
return false;
if (!ObjectUtilities.equal(this.standardTickUnits, that.standardTickUnits))
return false;
if (this.verticalTickLabels != that.verticalTickLabels)
return false;
return super.equals(obj);
}
public Object clone() throws CloneNotSupportedException {
ValueAxis clone = (ValueAxis)super.clone();
return clone;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeShape(this.upArrow, stream);
SerialUtilities.writeShape(this.downArrow, stream);
SerialUtilities.writeShape(this.leftArrow, stream);
SerialUtilities.writeShape(this.rightArrow, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.upArrow = SerialUtilities.readShape(stream);
this.downArrow = SerialUtilities.readShape(stream);
this.leftArrow = SerialUtilities.readShape(stream);
this.rightArrow = SerialUtilities.readShape(stream);
}
}

View file

@ -0,0 +1,41 @@
package org.jfree.chart.axis;
import org.jfree.ui.TextAnchor;
public abstract class ValueTick extends Tick {
private double value;
private TickType tickType;
public ValueTick(double value, String label, TextAnchor textAnchor, TextAnchor rotationAnchor, double angle) {
this(TickType.MAJOR, value, label, textAnchor, rotationAnchor, angle);
this.value = value;
}
public ValueTick(TickType tickType, double value, String label, TextAnchor textAnchor, TextAnchor rotationAnchor, double angle) {
super(label, textAnchor, rotationAnchor, angle);
this.value = value;
this.tickType = tickType;
}
public double getValue() {
return this.value;
}
public TickType getTickType() {
return this.tickType;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof ValueTick))
return false;
ValueTick that = (ValueTick)obj;
if (this.value != that.value)
return false;
if (!this.tickType.equals(that.tickType))
return false;
return super.equals(obj);
}
}

View file

@ -0,0 +1,268 @@
package org.jfree.chart.block;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.data.Range;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.Size2D;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PublicCloneable;
import org.jfree.util.ShapeUtilities;
public class AbstractBlock implements Cloneable, Serializable {
private String id = null;
private double width = 0.0D;
private double height = 0.0D;
private transient Rectangle2D bounds = new Rectangle2D.Float();
private RectangleInsets margin = RectangleInsets.ZERO_INSETS;
private BlockFrame frame = BlockBorder.NONE;
private RectangleInsets padding = RectangleInsets.ZERO_INSETS;
private static final long serialVersionUID = 7689852412141274563L;
public String getID() {
return this.id;
}
public void setID(String id) {
this.id = id;
}
public double getWidth() {
return this.width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return this.height;
}
public void setHeight(double height) {
this.height = height;
}
public RectangleInsets getMargin() {
return this.margin;
}
public void setMargin(RectangleInsets margin) {
if (margin == null)
throw new IllegalArgumentException("Null 'margin' argument.");
this.margin = margin;
}
public void setMargin(double top, double left, double bottom, double right) {
setMargin(new RectangleInsets(top, left, bottom, right));
}
public BlockBorder getBorder() {
if (this.frame instanceof BlockBorder)
return (BlockBorder)this.frame;
return null;
}
public void setBorder(BlockBorder border) {
setFrame(border);
}
public void setBorder(double top, double left, double bottom, double right) {
setFrame(new BlockBorder(top, left, bottom, right));
}
public BlockFrame getFrame() {
return this.frame;
}
public void setFrame(BlockFrame frame) {
if (frame == null)
throw new IllegalArgumentException("Null 'frame' argument.");
this.frame = frame;
}
public RectangleInsets getPadding() {
return this.padding;
}
public void setPadding(RectangleInsets padding) {
if (padding == null)
throw new IllegalArgumentException("Null 'padding' argument.");
this.padding = padding;
}
public void setPadding(double top, double left, double bottom, double right) {
setPadding(new RectangleInsets(top, left, bottom, right));
}
public double getContentXOffset() {
return this.margin.getLeft() + this.frame.getInsets().getLeft() + this.padding.getLeft();
}
public double getContentYOffset() {
return this.margin.getTop() + this.frame.getInsets().getTop() + this.padding.getTop();
}
public Size2D arrange(Graphics2D g2) {
return arrange(g2, RectangleConstraint.NONE);
}
public Size2D arrange(Graphics2D g2, RectangleConstraint constraint) {
Size2D base = new Size2D(getWidth(), getHeight());
return constraint.calculateConstrainedSize(base);
}
public Rectangle2D getBounds() {
return this.bounds;
}
public void setBounds(Rectangle2D bounds) {
if (bounds == null)
throw new IllegalArgumentException("Null 'bounds' argument.");
this.bounds = bounds;
}
protected double trimToContentWidth(double fixedWidth) {
double result = this.margin.trimWidth(fixedWidth);
result = this.frame.getInsets().trimWidth(result);
result = this.padding.trimWidth(result);
return Math.max(result, 0.0D);
}
protected double trimToContentHeight(double fixedHeight) {
double result = this.margin.trimHeight(fixedHeight);
result = this.frame.getInsets().trimHeight(result);
result = this.padding.trimHeight(result);
return Math.max(result, 0.0D);
}
protected RectangleConstraint toContentConstraint(RectangleConstraint c) {
if (c == null)
throw new IllegalArgumentException("Null 'c' argument.");
if (c.equals(RectangleConstraint.NONE))
return c;
double w = c.getWidth();
Range wr = c.getWidthRange();
double h = c.getHeight();
Range hr = c.getHeightRange();
double ww = trimToContentWidth(w);
double hh = trimToContentHeight(h);
Range wwr = trimToContentWidth(wr);
Range hhr = trimToContentHeight(hr);
return new RectangleConstraint(ww, wwr, c.getWidthConstraintType(), hh, hhr, c.getHeightConstraintType());
}
private Range trimToContentWidth(Range r) {
if (r == null)
return null;
double lowerBound = 0.0D;
double upperBound = Double.POSITIVE_INFINITY;
if (r.getLowerBound() > 0.0D)
lowerBound = trimToContentWidth(r.getLowerBound());
if (r.getUpperBound() < Double.POSITIVE_INFINITY)
upperBound = trimToContentWidth(r.getUpperBound());
return new Range(lowerBound, upperBound);
}
private Range trimToContentHeight(Range r) {
if (r == null)
return null;
double lowerBound = 0.0D;
double upperBound = Double.POSITIVE_INFINITY;
if (r.getLowerBound() > 0.0D)
lowerBound = trimToContentHeight(r.getLowerBound());
if (r.getUpperBound() < Double.POSITIVE_INFINITY)
upperBound = trimToContentHeight(r.getUpperBound());
return new Range(lowerBound, upperBound);
}
protected double calculateTotalWidth(double contentWidth) {
double result = contentWidth;
result = this.padding.extendWidth(result);
result = this.frame.getInsets().extendWidth(result);
result = this.margin.extendWidth(result);
return result;
}
protected double calculateTotalHeight(double contentHeight) {
double result = contentHeight;
result = this.padding.extendHeight(result);
result = this.frame.getInsets().extendHeight(result);
result = this.margin.extendHeight(result);
return result;
}
protected Rectangle2D trimMargin(Rectangle2D area) {
this.margin.trim(area);
return area;
}
protected Rectangle2D trimBorder(Rectangle2D area) {
this.frame.getInsets().trim(area);
return area;
}
protected Rectangle2D trimPadding(Rectangle2D area) {
this.padding.trim(area);
return area;
}
protected void drawBorder(Graphics2D g2, Rectangle2D area) {
this.frame.draw(g2, area);
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof AbstractBlock))
return false;
AbstractBlock that = (AbstractBlock)obj;
if (!ObjectUtilities.equal(this.id, that.id))
return false;
if (!this.frame.equals(that.frame))
return false;
if (!this.bounds.equals(that.bounds))
return false;
if (!this.margin.equals(that.margin))
return false;
if (!this.padding.equals(that.padding))
return false;
if (this.height != that.height)
return false;
if (this.width != that.width)
return false;
return true;
}
public Object clone() throws CloneNotSupportedException {
AbstractBlock clone = (AbstractBlock)super.clone();
clone.bounds = (Rectangle2D)ShapeUtilities.clone(this.bounds);
if (this.frame instanceof PublicCloneable) {
PublicCloneable pc = (PublicCloneable)this.frame;
clone.frame = (BlockFrame)pc.clone();
}
return clone;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeShape(this.bounds, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.bounds = (Rectangle2D)SerialUtilities.readShape(stream);
}
}

View file

@ -0,0 +1,12 @@
package org.jfree.chart.block;
import java.awt.Graphics2D;
import org.jfree.ui.Size2D;
public interface Arrangement {
void add(Block paramBlock, Object paramObject);
Size2D arrange(BlockContainer paramBlockContainer, Graphics2D paramGraphics2D, RectangleConstraint paramRectangleConstraint);
void clear();
}

View file

@ -0,0 +1,22 @@
package org.jfree.chart.block;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import org.jfree.ui.Drawable;
import org.jfree.ui.Size2D;
public interface Block extends Drawable {
String getID();
void setID(String paramString);
Size2D arrange(Graphics2D paramGraphics2D);
Size2D arrange(Graphics2D paramGraphics2D, RectangleConstraint paramRectangleConstraint);
Rectangle2D getBounds();
void setBounds(Rectangle2D paramRectangle2D);
Object draw(Graphics2D paramGraphics2D, Rectangle2D paramRectangle2D, Object paramObject);
}

View file

@ -0,0 +1,108 @@
package org.jfree.chart.block;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.jfree.io.SerialUtilities;
import org.jfree.ui.RectangleInsets;
import org.jfree.util.PaintUtilities;
public class BlockBorder implements BlockFrame, Serializable {
private static final long serialVersionUID = 4961579220410228283L;
public static final BlockBorder NONE = new BlockBorder(RectangleInsets.ZERO_INSETS, Color.white);
private RectangleInsets insets;
private transient Paint paint;
public BlockBorder() {
this(Color.black);
}
public BlockBorder(Paint paint) {
this(new RectangleInsets(1.0D, 1.0D, 1.0D, 1.0D), paint);
}
public BlockBorder(double top, double left, double bottom, double right) {
this(new RectangleInsets(top, left, bottom, right), Color.black);
}
public BlockBorder(double top, double left, double bottom, double right, Paint paint) {
this(new RectangleInsets(top, left, bottom, right), paint);
}
public BlockBorder(RectangleInsets insets, Paint paint) {
if (insets == null)
throw new IllegalArgumentException("Null 'insets' argument.");
if (paint == null)
throw new IllegalArgumentException("Null 'paint' argument.");
this.insets = insets;
this.paint = paint;
}
public RectangleInsets getInsets() {
return this.insets;
}
public Paint getPaint() {
return this.paint;
}
public void draw(Graphics2D g2, Rectangle2D area) {
double t = this.insets.calculateTopInset(area.getHeight());
double b = this.insets.calculateBottomInset(area.getHeight());
double l = this.insets.calculateLeftInset(area.getWidth());
double r = this.insets.calculateRightInset(area.getWidth());
double x = area.getX();
double y = area.getY();
double w = area.getWidth();
double h = area.getHeight();
g2.setPaint(this.paint);
Rectangle2D rect = new Rectangle2D.Double();
if (t > 0.0D) {
rect.setRect(x, y, w, t);
g2.fill(rect);
}
if (b > 0.0D) {
rect.setRect(x, y + h - b, w, b);
g2.fill(rect);
}
if (l > 0.0D) {
rect.setRect(x, y, l, h);
g2.fill(rect);
}
if (r > 0.0D) {
rect.setRect(x + w - r, y, r, h);
g2.fill(rect);
}
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof BlockBorder))
return false;
BlockBorder that = (BlockBorder)obj;
if (!this.insets.equals(that.insets))
return false;
if (!PaintUtilities.equal(this.paint, that.paint))
return false;
return true;
}
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writePaint(this.paint, stream);
}
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.paint = SerialUtilities.readPaint(stream);
}
}

View file

@ -0,0 +1,126 @@
package org.jfree.chart.block;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.ui.Size2D;
import org.jfree.util.PublicCloneable;
public class BlockContainer extends AbstractBlock implements Block, Cloneable, PublicCloneable, Serializable {
private static final long serialVersionUID = 8199508075695195293L;
private List blocks;
private Arrangement arrangement;
public BlockContainer() {
this(new BorderArrangement());
}
public BlockContainer(Arrangement arrangement) {
if (arrangement == null)
throw new IllegalArgumentException("Null 'arrangement' argument.");
this.arrangement = arrangement;
this.blocks = new ArrayList();
}
public Arrangement getArrangement() {
return this.arrangement;
}
public void setArrangement(Arrangement arrangement) {
if (arrangement == null)
throw new IllegalArgumentException("Null 'arrangement' argument.");
this.arrangement = arrangement;
}
public boolean isEmpty() {
return this.blocks.isEmpty();
}
public List getBlocks() {
return Collections.unmodifiableList(this.blocks);
}
public void add(Block block) {
add(block, null);
}
public void add(Block block, Object key) {
this.blocks.add(block);
this.arrangement.add(block, key);
}
public void clear() {
this.blocks.clear();
this.arrangement.clear();
}
public Size2D arrange(Graphics2D g2, RectangleConstraint constraint) {
return this.arrangement.arrange(this, g2, constraint);
}
public void draw(Graphics2D g2, Rectangle2D area) {
draw(g2, area, null);
}
public Object draw(Graphics2D g2, Rectangle2D area, Object params) {
EntityBlockParams ebp = null;
StandardEntityCollection sec = null;
if (params instanceof EntityBlockParams) {
ebp = (EntityBlockParams)params;
if (ebp.getGenerateEntities())
sec = new StandardEntityCollection();
}
Rectangle2D contentArea = (Rectangle2D)area.clone();
contentArea = trimMargin(contentArea);
drawBorder(g2, contentArea);
contentArea = trimBorder(contentArea);
contentArea = trimPadding(contentArea);
Iterator iterator = this.blocks.iterator();
while (iterator.hasNext()) {
Block block = (Block)iterator.next();
Rectangle2D bounds = block.getBounds();
Rectangle2D drawArea = new Rectangle2D.Double(bounds.getX() + area.getX(), bounds.getY() + area.getY(), bounds.getWidth(), bounds.getHeight());
Object r = block.draw(g2, drawArea, params);
if (sec != null &&
r instanceof EntityBlockResult) {
EntityBlockResult ebr = (EntityBlockResult)r;
EntityCollection ec = ebr.getEntityCollection();
sec.addAll(ec);
}
}
BlockResult result = null;
if (sec != null) {
result = new BlockResult();
result.setEntityCollection(sec);
}
return result;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (!(obj instanceof BlockContainer))
return false;
if (!super.equals(obj))
return false;
BlockContainer that = (BlockContainer)obj;
if (!this.arrangement.equals(that.arrangement))
return false;
if (!this.blocks.equals(that.blocks))
return false;
return true;
}
public Object clone() throws CloneNotSupportedException {
BlockContainer clone = (BlockContainer)super.clone();
return clone;
}
}

View file

@ -0,0 +1,11 @@
package org.jfree.chart.block;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import org.jfree.ui.RectangleInsets;
public interface BlockFrame {
RectangleInsets getInsets();
void draw(Graphics2D paramGraphics2D, Rectangle2D paramRectangle2D);
}

View file

@ -0,0 +1,33 @@
package org.jfree.chart.block;
public class BlockParams implements EntityBlockParams {
private double translateX = 0.0D;
private double translateY = 0.0D;
private boolean generateEntities = false;
public boolean getGenerateEntities() {
return this.generateEntities;
}
public void setGenerateEntities(boolean generate) {
this.generateEntities = generate;
}
public double getTranslateX() {
return this.translateX;
}
public void setTranslateX(double x) {
this.translateX = x;
}
public double getTranslateY() {
return this.translateY;
}
public void setTranslateY(double y) {
this.translateY = y;
}
}

Some files were not shown because too many files have changed in this diff Show more