diff --git a/README.md b/README.md index 5baa6a5f462396801c9d331bc1d30152ecfb0443..bd945e26d6c36bae0c54818d0075822b7c9f2fc8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## [](http://www.xeiam.com/xchart) XChart +## [](http://xeiam.com/xchart) XChart A Simple Charting Library for Java ## Description @@ -20,12 +20,12 @@ Usage is very simple: Create a Chart instance, add a series of data to it, and e new SwingWrapper(chart).displayChart(); // Save it - BitmapEncoder.savePNG(chart, "./Sample_Chart.png"); + BitmapEncoder.saveBitmap(chart, "./Sample_Chart", BitmapFormat.PNG); // or save it in high-res - BitmapEncoder.savePNGWithDPI(chart, "./Sample_Chart_300_DPI.png", 300); + BitmapEncoder.saveBitmapWithDPI(chart, "./Sample_Chart_300_DPI", BitmapFormat.PNG, 300); -Now go ahead and [study some more examples](http://www.xeiam.com/xchart_examplecode.jsp), [download the thing](http://www.xeiam.com/xchart_changelog.jsp) and [provide feedback](https://github.com/timmolter/XChart/issues). +Now go ahead and [study some more examples](http://xeiam.com/xchart-example-code/), [download the thing](http://xeiam.com/xchart-change-log) and [provide feedback](https://github.com/timmolter/XChart/issues). ## Features * No additional dependencies @@ -52,7 +52,7 @@ Now go ahead and [study some more examples](http://www.xeiam.com/xchart_examplec ### Non-Maven -Download Jar: http://www.xeiam.com/xchart_changelog.jsp +Download Jar: http://xeiam.com/xchart-change-log ### Maven @@ -63,7 +63,7 @@ Add the XChart library as a dependency to your pom.xml file: <dependency> <groupId>com.xeiam.xchart</groupId> <artifactId>xchart</artifactId> - <version>2.4.0</version> + <version>2.4.1</version> </dependency> For snapshots, add the following to your pom.xml file: @@ -77,7 +77,7 @@ For snapshots, add the following to your pom.xml file: <dependency> <groupId>com.xeiam</groupId> <artifactId>xchart</artifactId> - <version>2.4.1-SNAPSHOT</version> + <version>2.4.2-SNAPSHOT</version> </dependency> ## Building @@ -95,7 +95,7 @@ For snapshots, add the following to your pom.xml file: ## Running Demo cd /path/to/xchart-demo/jar/ - java -cp xchart-demo-2.4.0.jar:xchart-2.4.0.jar com.xeiam.xchart.demo.XChartDemo + java -cp xchart-demo-2.4.1.jar:xchart-2.4.1.jar com.xeiam.xchart.demo.XChartDemo ## Bugs Please report any bugs or submit feature requests to [XChart's Github issue tracker](https://github.com/timmolter/XChart/issues). diff --git a/pom.xml b/pom.xml index fab436d0850495978b0096f09ea61bc438da6d0e..4519217acf4dfe0a9b4194dd7f3d4364dcf44e07 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ <groupId>com.xeiam.xchart</groupId> <artifactId>xchart-parent</artifactId> - <version>2.4.1-SNAPSHOT</version> + <version>2.4.2-SNAPSHOT</version> <packaging>pom</packaging> <name>XChart Parent</name> <description>Basic Charts for Java Applications</description> diff --git a/xchart-demo/pom.xml b/xchart-demo/pom.xml index ad3f5caaf7dd21b82324d5c34f8e36abf4656816..0fe5dd0f84242660ee9db472e83f417f695e9c84 100644 --- a/xchart-demo/pom.xml +++ b/xchart-demo/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>com.xeiam.xchart</groupId> <artifactId>xchart-parent</artifactId> - <version>2.4.1-SNAPSHOT</version> + <version>2.4.2-SNAPSHOT</version> </parent> <artifactId>xchart-demo</artifactId> @@ -17,7 +17,7 @@ <dependency> <groupId>com.xeiam.xchart</groupId> <artifactId>xchart</artifactId> - <version>2.4.1-SNAPSHOT</version> + <version>2.4.2-SNAPSHOT</version> </dependency> </dependencies> diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/demo/XChartDemo.java b/xchart-demo/src/main/java/com/xeiam/xchart/demo/XChartDemo.java index 7232b4b8a264993283957745b64c8d1fc89f4761..25e914d8b4a36c1f2a705c966e41d491e2091e86 100644 --- a/xchart-demo/src/main/java/com/xeiam/xchart/demo/XChartDemo.java +++ b/xchart-demo/src/main/java/com/xeiam/xchart/demo/XChartDemo.java @@ -33,6 +33,7 @@ import javax.swing.tree.TreeSelectionModel; import com.xeiam.xchart.XChartPanel; import com.xeiam.xchart.demo.charts.area.AreaChart01; import com.xeiam.xchart.demo.charts.area.AreaChart02; +import com.xeiam.xchart.demo.charts.area.AreaLineChart03; import com.xeiam.xchart.demo.charts.bar.BarChart01; import com.xeiam.xchart.demo.charts.bar.BarChart02; import com.xeiam.xchart.demo.charts.bar.BarChart03; @@ -65,7 +66,7 @@ import com.xeiam.xchart.demo.charts.theme.ThemeChart03; /** * Class containing all XChart example charts - * + * * @author timmolter */ public class XChartDemo extends JPanel implements TreeSelectionListener { @@ -174,7 +175,7 @@ public class XChartDemo extends JPanel implements TreeSelectionListener { /** * Create the tree - * + * * @param top */ private void createNodes(DefaultMutableTreeNode top) { @@ -194,6 +195,9 @@ public class XChartDemo extends JPanel implements TreeSelectionListener { defaultMutableTreeNode = new DefaultMutableTreeNode(new ChartInfo("AreaChart02 - Null Y-Axis Data Points", new AreaChart02().getChart())); category.add(defaultMutableTreeNode); + defaultMutableTreeNode = new DefaultMutableTreeNode(new ChartInfo("AreaLineChart03 - Combination Are & Line Chart", new AreaLineChart03().getChart())); + category.add(defaultMutableTreeNode); + // Line category category = new DefaultMutableTreeNode("Line Charts"); top.add(category); diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaChart01.java b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaChart01.java index a39f8e2d19ed9b0acb5a26b4101677428edfbf1f..4fb4b5f79b9c6dbe59e1569944f2d380667646dc 100644 --- a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaChart01.java +++ b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaChart01.java @@ -44,7 +44,7 @@ public class AreaChart01 implements ExampleChart { public Chart getChart() { // Create Chart - Chart chart = new ChartBuilder().chartType(ChartType.Area).width(800).height(600).title("AreaChart01").xAxisTitle("X").yAxisTitle("Y").build(); + Chart chart = new ChartBuilder().chartType(ChartType.Area).width(800).height(600).title(getClass().getSimpleName()).xAxisTitle("X").yAxisTitle("Y").build(); chart.addSeries("a", new double[] { 0, 3, 5, 7, 9 }, new double[] { -3, 5, 9, 6, 5 }); chart.addSeries("b", new double[] { 0, 2, 4, 6, 9 }, new double[] { -1, 6, 4, 0, 4 }); chart.addSeries("c", new double[] { 0, 1, 3, 8, 9 }, new double[] { -2, -1, 1, 0, 1 }); diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaChart02.java b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaChart02.java index 262cdc4944a2309e83620173aa5233cf2cd050ea..a5a8274dd00bdf4b9c73b3efc9c4a08c4e8948c8 100644 --- a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaChart02.java +++ b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaChart02.java @@ -47,7 +47,7 @@ public class AreaChart02 implements ExampleChart { public Chart getChart() { // Create Chart - Chart chart = new ChartBuilder().chartType(ChartType.Area).width(800).height(600).title("AreaChart02").xAxisTitle("X").yAxisTitle("Y").build(); + Chart chart = new ChartBuilder().chartType(ChartType.Area).width(800).height(600).title(getClass().getSimpleName()).xAxisTitle("X").yAxisTitle("Y").build(); List<Integer> xData = new ArrayList<Integer>(); List<Integer> yData = new ArrayList<Integer>(); diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaLineChart03.java b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaLineChart03.java new file mode 100644 index 0000000000000000000000000000000000000000..7a020de4552d756213b5ed93318f635d81ae7caa --- /dev/null +++ b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/area/AreaLineChart03.java @@ -0,0 +1,263 @@ +/** + * Copyright 2011 - 2014 Xeiam LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xeiam.xchart.demo.charts.area; + +import com.xeiam.xchart.Chart; +import com.xeiam.xchart.Series; +import com.xeiam.xchart.SeriesMarker; +import com.xeiam.xchart.StyleManager; +import com.xeiam.xchart.StyleManager.ChartType; +import com.xeiam.xchart.StyleManager.LegendPosition; +import com.xeiam.xchart.SwingWrapper; +import com.xeiam.xchart.demo.charts.ExampleChart; + +/** + * Combination Line & Area Chart + * <p/> + * Demonstrates the following: + * <ul> + * <li>Combination of Line and Area series + * <li>Axis Label Alignment + * <li>Ensuring a chart axis on a tick + */ +public class AreaLineChart03 implements ExampleChart { + + public static void main(String[] args) { + + ExampleChart exampleChart = new AreaLineChart03(); + Chart chart = exampleChart.getChart(); + new SwingWrapper(chart).displayChart(); + } + + @Override + public Chart getChart() { + + // Create Chart + Chart chart = new Chart(800, 600); + + // Customize Chart + chart.setChartTitle(getClass().getSimpleName()); + chart.setXAxisTitle("Age"); + chart.setYAxisTitle("Amount"); + chart.getStyleManager().setLegendPosition(LegendPosition.InsideNW); + chart.getStyleManager().setChartType(ChartType.Line); + + // @formatter:off + double[] xAges = new double[]{ + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100}; + + double[] yLiability = new double[]{ + 672234, + 691729, + 711789, + 732431, + 753671, + 775528, + 798018, + 821160, + 844974, + 869478, + 907735, + 887139, + 865486, + 843023, + 819621, + 795398, + 770426, + 744749, + 719011, + 693176, + 667342, + 641609, + 616078, + 590846, + 565385, + 540002, + 514620, + 489380, + 465149, + 441817, + 419513, + 398465, + 377991, + 358784, + 340920, + 323724, + 308114, + 293097, + 279356, + 267008, + 254873 + }; + + double[] yPercentile75th = new double[]{ + 800000, + 878736, + 945583, + 1004209, + 1083964, + 1156332, + 1248041, + 1340801, + 1440138, + 1550005, + 1647728, + 1705046, + 1705032, + 1710672, + 1700847, + 1683418, + 1686522, + 1674901, + 1680456, + 1679164, + 1668514, + 1672860, + 1673988, + 1646597, + 1641842, + 1653758, + 1636317, + 1620725, + 1589985, + 1586451, + 1559507, + 1544234, + 1529700, + 1507496, + 1474907, + 1422169, + 1415079, + 1346929, + 1311689, + 1256114, + 1221034 + }; + + double[] yPercentile50th = new double[]{ + 800000, + 835286, + 873456, + 927048, + 969305, + 1030749, + 1101102, + 1171396, + 1246486, + 1329076, + 1424666, + 1424173, + 1421853, + 1397093, + 1381882, + 1364562, + 1360050, + 1336885, + 1340431, + 1312217, + 1288274, + 1271615, + 1262682, + 1237287, + 1211335, + 1191953, + 1159689, + 1117412, + 1078875, + 1021020, + 974933, + 910189, + 869154, + 798476, + 744934, + 674501, + 609237, + 524516, + 442234, + 343960, + 257025 + }; + + double[] yPercentile25th = new double[]{ + 800000, + 791439, + 809744, + 837020, + 871166, + 914836, + 958257, + 1002955, + 1054094, + 1118934, + 1194071, + 1185041, + 1175401, + 1156578, + 1132121, + 1094879, + 1066202, + 1054411, + 1028619, + 987730, + 944977, + 914929, + 880687, + 809330, + 783318, + 739751, + 696201, + 638242, + 565197, + 496959, + 421280, + 358113, + 276518, + 195571, + 109514, + 13876, + 29, + 0, + 0, + 0, + 0}; + // @formatter:on + + Series seriesLiability = chart.addSeries("Liability", xAges, yLiability); + seriesLiability.setMarker(SeriesMarker.NONE); + seriesLiability.setSeriesType(Series.SeriesType.Area); + + Series seriesPercentile75th = chart.addSeries("75th Percentile", xAges, yPercentile75th); + seriesPercentile75th.setMarker(SeriesMarker.NONE); + + Series seriesPercentile50th = chart.addSeries("50th Percentile", xAges, yPercentile50th); + seriesPercentile50th.setMarker(SeriesMarker.NONE); + + Series seriesPercentile25th = chart.addSeries("25th Percentile", xAges, yPercentile25th); + seriesPercentile25th.setMarker(SeriesMarker.NONE); + + chart.getStyleManager().setYAxisLabelAlignment(StyleManager.TextAlignment.Right); + chart.getStyleManager().setYAxisDecimalPattern("$ #,###.##"); + + chart.getStyleManager().setPlotPadding(0); + chart.getStyleManager().setAxisTickSpacePercentage(.95); + // chart.getStyleManager().setYAxisMax(1620725 * 1.15); // We want to ensure there is a % of padding on the top of the chart + return chart; + } + +} diff --git a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/bar/BarChart02.java b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/bar/BarChart02.java index b9db53f76153a9632368e7de0663d63d2e54a8a7..7774cc2a76b4dc36f211f0ad83a93c10f42dfe84 100644 --- a/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/bar/BarChart02.java +++ b/xchart-demo/src/main/java/com/xeiam/xchart/demo/charts/bar/BarChart02.java @@ -78,6 +78,7 @@ public class BarChart02 implements ExampleChart { Series series = chart.addSeries("Model 77", xData, yData); series.setLineColor(SeriesColor.RED); chart.getStyleManager().setPlotGridLinesVisible(false); + chart.getStyleManager().setBarFilled(false); return chart; } diff --git a/xchart/pom.xml b/xchart/pom.xml index 49c9ae8f008b1482817e973240af124483ab7cbb..8d58c647c28a43850be040d0dee49d0e1657a3e8 100644 --- a/xchart/pom.xml +++ b/xchart/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>com.xeiam.xchart</groupId> <artifactId>xchart-parent</artifactId> - <version>2.4.1-SNAPSHOT</version> + <version>2.4.2-SNAPSHOT</version> </parent> <artifactId>xchart</artifactId> diff --git a/xchart/src/main/java/com/xeiam/xchart/Series.java b/xchart/src/main/java/com/xeiam/xchart/Series.java index 254bcbad413c7cc2dc28439a4de1896ebc1d8fea..47e0b315985951871bb62c8310a76bc967a21a8a 100644 --- a/xchart/src/main/java/com/xeiam/xchart/Series.java +++ b/xchart/src/main/java/com/xeiam/xchart/Series.java @@ -32,6 +32,10 @@ import com.xeiam.xchart.internal.style.SeriesColorMarkerLineStyle; */ public class Series { + public enum SeriesType { + Line, Area + } + private String name = ""; private Collection<?> xData; @@ -40,6 +44,8 @@ public class Series { private Collection<? extends Number> yData; private AxisType yAxisType; + private SeriesType seriesType; + private Collection<? extends Number> errorBars; /** the minimum value of axis range */ @@ -60,6 +66,9 @@ public class Series { /** Line Color */ private Color strokeColor; + /** Fill Colour */ + private Color fillColor; + /** Marker Style */ private Marker marker; @@ -91,6 +100,7 @@ public class Series { this.errorBars = errorBars; strokeColor = seriesColorMarkerLineStyle.getColor(); + fillColor = seriesColorMarkerLineStyle.getColor(); markerColor = seriesColorMarkerLineStyle.getColor(); marker = seriesColorMarkerLineStyle.getMarker(); stroke = seriesColorMarkerLineStyle.getStroke(); @@ -241,6 +251,16 @@ public class Series { return this; } + public SeriesType getSeriesType() { + + return seriesType; + } + + public void setSeriesType(SeriesType seriesType) { + + this.seriesType = seriesType; + } + public Collection<?> getXData() { return xData; @@ -296,6 +316,16 @@ public class Series { return markerColor; } + public Color getFillColor() { + + return fillColor; + } + + public void setFillColor(Color fillColor) { + + this.fillColor = fillColor; + } + public String getName() { return name; diff --git a/xchart/src/main/java/com/xeiam/xchart/StyleManager.java b/xchart/src/main/java/com/xeiam/xchart/StyleManager.java index 0856bb7006d4bdb8392bea39dd17d851a26f2f5c..fb4d87a216127a4db2afee67441546d47c85a67f 100644 --- a/xchart/src/main/java/com/xeiam/xchart/StyleManager.java +++ b/xchart/src/main/java/com/xeiam/xchart/StyleManager.java @@ -28,7 +28,7 @@ import com.xeiam.xchart.internal.style.XChartTheme; /** * The StyleManager is used to manage all things related to styling of the vast number of Chart components - * + * * @author timmolter */ public class StyleManager { @@ -66,6 +66,10 @@ public class StyleManager { } } + public enum TextAlignment { + Left, Centre, Right; + } + /** the default Theme */ private Theme theme = new XChartTheme(); @@ -116,7 +120,9 @@ public class StyleManager { private Double xAxisMax; private Double yAxisMin; private Double yAxisMax; - private double axisTickSpaceRatio; + private double axisTickSpacePercentage; + private TextAlignment xAxisLabelAlignment = TextAlignment.Centre; + private TextAlignment yAxisLabelAlignment = TextAlignment.Left; // Chart Plot Area /////////////////////////////// private boolean isPlotGridLinesVisible; @@ -130,6 +136,7 @@ public class StyleManager { // Bar Charts /////////////////////////////// private double barWidthPercentage; private boolean isBarsOverlapped; + private boolean isBarFilled; // Line, Scatter, Area Charts /////////////////////////////// private int markerSize; @@ -142,6 +149,8 @@ public class StyleManager { private TimeZone timezone; private String datePattern; private String decimalPattern; + private String xAxisDecimalPattern; + private String yAxisDecimalPattern; /** * Constructor @@ -200,7 +209,7 @@ public class StyleManager { xAxisMax = null; yAxisMin = null; yAxisMax = null; - axisTickSpaceRatio = .95; + axisTickSpacePercentage = .95; // Chart Plot Area /////////////////////////////// isPlotGridLinesVisible = theme.isPlotGridLinesVisible(); @@ -214,6 +223,7 @@ public class StyleManager { // Bar Charts /////////////////////////////// barWidthPercentage = theme.getBarWidthPercentage(); isBarsOverlapped = theme.isBarsOverlapped(); + isBarFilled = theme.isBarFilled(); // Line, Scatter, Area Charts /////////////////////////////// @@ -227,11 +237,13 @@ public class StyleManager { timezone = TimeZone.getDefault(); datePattern = null; // if not null, this override pattern will be used decimalPattern = null; + xAxisDecimalPattern = null; + yAxisDecimalPattern = null; } /** * Set the theme the style manager should use - * + * * @param theme */ protected void setTheme(Theme theme) { @@ -249,7 +261,7 @@ public class StyleManager { /** * sets the Chart Type - * + * * @param chartType */ public void setChartType(ChartType chartType) { @@ -264,7 +276,7 @@ public class StyleManager { /** * Set the chart background color - the part around the edge of the chart - * + * * @param color */ public void setChartBackgroundColor(Color color) { @@ -279,7 +291,7 @@ public class StyleManager { /** * Set the chart font color. includes: Chart title, axes label, legend - * + * * @param color */ public void setChartFontColor(Color color) { @@ -294,7 +306,7 @@ public class StyleManager { /** * Set the chart padding - * + * * @param chartPadding */ public void setChartPadding(int chartPadding) { @@ -311,7 +323,7 @@ public class StyleManager { /** * Set the chart title font - * + * * @param font */ public void setChartTitleFont(Font chartTitleFont) { @@ -326,7 +338,7 @@ public class StyleManager { /** * Set the chart title visibility - * + * * @param isChartTitleVisible */ public void setChartTitleVisible(boolean isChartTitleVisible) { @@ -341,7 +353,7 @@ public class StyleManager { /** * Set the chart title box visibility - * + * * @param isChartTitleBoxVisible */ public void setChartTitleBoxVisible(boolean isChartTitleBoxVisible) { @@ -356,7 +368,7 @@ public class StyleManager { /** * set the chart title box background color - * + * * @param chartTitleBoxBackgroundColor */ public void setChartTitleBoxBackgroundColor(Color chartTitleBoxBackgroundColor) { @@ -371,7 +383,7 @@ public class StyleManager { /** * set the chart title box border color - * + * * @param chartTitleBoxBorderColor */ public void setChartTitleBoxBorderColor(Color chartTitleBoxBorderColor) { @@ -386,7 +398,7 @@ public class StyleManager { /** * set the chart title padding; the space between the chart title and the plot area - * + * * @param chartTitlePadding */ public void setChartTitlePadding(int chartTitlePadding) { @@ -403,7 +415,7 @@ public class StyleManager { /** * Set the chart legend background color - * + * * @param color */ public void setLegendBackgroundColor(Color color) { @@ -418,7 +430,7 @@ public class StyleManager { /** * Set the chart legend border color - * + * * @return */ public Color getLegendBorderColor() { @@ -433,7 +445,7 @@ public class StyleManager { /** * Set the chart legend font - * + * * @param font */ public void setLegendFont(Font font) { @@ -448,7 +460,7 @@ public class StyleManager { /** * Set the chart legend visibility - * + * * @param isLegendVisible */ public void setLegendVisible(boolean isLegendVisible) { @@ -463,7 +475,7 @@ public class StyleManager { /** * Set the chart legend padding - * + * * @param legendPadding */ public void setLegendPadding(int legendPadding) { @@ -478,7 +490,7 @@ public class StyleManager { /** * Set the chart legend series line length - * + * * @param legendPadding */ public void setLegendSeriesLineLength(int legendSeriesLineLength) { @@ -498,7 +510,7 @@ public class StyleManager { /** * sets the legend position - * + * * @param legendPosition */ public void setLegendPosition(LegendPosition legendPosition) { @@ -515,7 +527,7 @@ public class StyleManager { /** * Set the x-axis title visibility - * + * * @param isVisible */ public void setXAxisTitleVisible(boolean xAxisTitleVisible) { @@ -530,7 +542,7 @@ public class StyleManager { /** * Set the y-axis title visibility - * + * * @param isVisible */ public void setYAxisTitleVisible(boolean yAxisTitleVisible) { @@ -545,7 +557,7 @@ public class StyleManager { /** * Set the x- and y-axis titles visibility - * + * * @param isVisible */ public void setAxisTitlesVisible(boolean isVisible) { @@ -556,7 +568,7 @@ public class StyleManager { /** * Set the x- and y-axis title font - * + * * @param axisTitleFont */ public void setAxisTitleFont(Font axisTitleFont) { @@ -571,7 +583,7 @@ public class StyleManager { /** * Set the x-axis tick marks and labels visibility - * + * * @param isVisible */ @@ -587,7 +599,7 @@ public class StyleManager { /** * Set the y-axis tick marks and labels visibility - * + * * @param isVisible */ @@ -603,7 +615,7 @@ public class StyleManager { /** * Set the x- and y-axis tick marks and labels visibility - * + * * @param isVisible */ public void setAxisTicksVisible(boolean isVisible) { @@ -614,7 +626,7 @@ public class StyleManager { /** * Set the x- and y-axis tick label font - * + * * @param foxAxisTicksFontnt */ public void setAxisTickLabelsFont(Font axisTicksFont) { @@ -629,7 +641,7 @@ public class StyleManager { /** * set the axis tick mark length - * + * * @param axisTickMarkLength */ public void setAxisTickMarkLength(int axisTickMarkLength) { @@ -644,7 +656,7 @@ public class StyleManager { /** * sets the padding between the tick labels and the tick marks - * + * * @param axisTickPadding */ public void setAxisTickPadding(int axisTickPadding) { @@ -659,7 +671,7 @@ public class StyleManager { /** * sets the axis tick mark color - * + * * @param axisTickColor */ public void setAxisTickMarksColor(Color axisTickColor) { @@ -674,7 +686,7 @@ public class StyleManager { /** * sets the axis tick marks Stroke - * + * * @param axisTickMarksStroke */ public void setAxisTickMarksStroke(Stroke axisTickMarksStroke) { @@ -689,7 +701,7 @@ public class StyleManager { /** * sets the axis tick label color - * + * * @param axisTickLabelsColor */ public void setAxisTickLabelsColor(Color axisTickLabelsColor) { @@ -704,7 +716,7 @@ public class StyleManager { /** * sets the visibility of the line parallel to the plot edges that go along with the tick marks - * + * * @param isAxisTicksLineVisible */ public void setAxisTicksLineVisible(boolean isAxisTicksLineVisible) { @@ -719,7 +731,7 @@ public class StyleManager { /** * sets the visibility of the tick marks - * + * * @param isAxisTicksMarksVisible */ public void setAxisTicksMarksVisible(boolean isAxisTicksMarksVisible) { @@ -734,7 +746,7 @@ public class StyleManager { /** * sets the padding between the tick marks and the plot area - * + * * @param plotPadding */ public void setPlotPadding(int plotPadding) { @@ -749,7 +761,7 @@ public class StyleManager { /** * sets the padding between the axis title and the tick labels - * + * * @param axisTitlePadding */ public void setAxisTitlePadding(int axisTitlePadding) { @@ -764,7 +776,7 @@ public class StyleManager { /** * set the spacing between tick marks for the X-Axis - * + * * @param xAxisTickMarkSpacingHint */ public void setXAxisTickMarkSpacingHint(int xAxisTickMarkSpacingHint) { @@ -779,7 +791,7 @@ public class StyleManager { /** * set the spacing between tick marks for the Y-Axis - * + * * @param xAxisTickMarkSpacingHint */ public void setYAxisTickMarkSpacingHint(int yAxisTickMarkSpacingHint) { @@ -794,7 +806,7 @@ public class StyleManager { /** * sets the X-Axis to be rendered with a logarithmic scale or not - * + * * @param isxAxisLogarithmic */ public void setXAxisLogarithmic(boolean isXAxisLogarithmic) { @@ -809,7 +821,7 @@ public class StyleManager { /** * sets the Y-Axis to be rendered with a logarithmic scale or not - * + * * @param isyAxisLogarithmic */ public void setYAxisLogarithmic(boolean isYAxisLogarithmic) { @@ -862,21 +874,41 @@ public class StyleManager { return yAxisMax; } - public void setAxisTickSpaceRatio(double axisTickSpaceRatio) { + public void setAxisTickSpacePercentage(double axisTickSpacePercentage) { + + this.axisTickSpacePercentage = axisTickSpacePercentage; + } + + public double getAxisTickSpacePercentage() { + + return axisTickSpacePercentage; + } + + public TextAlignment getXAxisLabelAlignment() { + + return xAxisLabelAlignment; + } + + public void setXAxisLabelAlignment(TextAlignment xAxisLabelAlignment) { + + this.xAxisLabelAlignment = xAxisLabelAlignment; + } + + public TextAlignment getYAxisLabelAlignment() { - this.axisTickSpaceRatio = axisTickSpaceRatio; + return yAxisLabelAlignment; } - public double getAxisTickSpaceRatio() { + public void setYAxisLabelAlignment(TextAlignment yAxisLabelAlignment) { - return axisTickSpaceRatio; + this.yAxisLabelAlignment = yAxisLabelAlignment; } // Chart Plot Area /////////////////////////////// /** * sets the visibility of the gridlines on the plot area - * + * * @param isPlotGridLinesVisible */ public void setPlotGridLinesVisible(boolean isPlotGridLinesVisible) { @@ -891,7 +923,7 @@ public class StyleManager { /** * set the plot area's background color - * + * * @param plotBackgroundColor */ public void setPlotBackgroundColor(Color plotBackgroundColor) { @@ -906,7 +938,7 @@ public class StyleManager { /** * set the plot area's border color - * + * * @param plotBorderColor */ public void setPlotBorderColor(Color plotBorderColor) { @@ -921,7 +953,7 @@ public class StyleManager { /** * sets the visibility of the border around the plot area - * + * * @param isPlotBorderVisible */ public void setPlotBorderVisible(boolean isPlotBorderVisible) { @@ -936,7 +968,7 @@ public class StyleManager { /** * sets the visibility of the ticks marks inside the plot area - * + * * @param isPlotTicksMarksVisible */ public void setPlotTicksMarksVisible(boolean isPlotTicksMarksVisible) { @@ -951,7 +983,7 @@ public class StyleManager { /** * set the plot area's grid lines color - * + * * @param plotGridLinesColor */ public void setPlotGridLinesColor(Color plotGridLinesColor) { @@ -966,7 +998,7 @@ public class StyleManager { /** * set the plot area's grid lines Stroke - * + * * @param plotGridLinesStroke */ public void setPlotGridLinesStroke(Stroke plotGridLinesStroke) { @@ -983,7 +1015,7 @@ public class StyleManager { /** * set the width of a single bar in a bar chart. full width is 100%, i.e. 1.0 - * + * * @param barWidthPercentage */ public void setBarWidthPercentage(double barWidthPercentage) { @@ -998,7 +1030,7 @@ public class StyleManager { /** * set whether or no bars are overlapped. Otherwise they are places side-by-side - * + * * @param isBarsOverlapped */ public void setBarsOverlapped(boolean isBarsOverlapped) { @@ -1011,11 +1043,26 @@ public class StyleManager { return isBarsOverlapped; } + /** + * set whether or no bars are filled with a solid color or empty. + * + * @param isBarFilled + */ + public void setBarFilled(boolean isBarFilled) { + + this.isBarFilled = isBarFilled; + } + + public boolean isBarFilled() { + + return isBarFilled; + } + // Line, Scatter, Area Charts /////////////////////////////// /** * Sets the size of the markers in pixels - * + * * @param markerSize */ public void setMarkerSize(int markerSize) { @@ -1032,7 +1079,7 @@ public class StyleManager { /** * Sets the color of the error bars - * + * * @param errorBarsColor */ public void setErrorBarsColor(Color errorBarsColor) { @@ -1049,7 +1096,7 @@ public class StyleManager { /** * Set the locale to use for rendering the chart - * + * * @param locale - the locale to use when formatting Strings and dates for the axis tick labels */ public void setLocale(Locale locale) { @@ -1064,7 +1111,7 @@ public class StyleManager { /** * Set the timezone to use for formatting Date axis tick labels - * + * * @param timezone the timezone to use when formatting date data */ public void setTimezone(TimeZone timezone) { @@ -1079,7 +1126,7 @@ public class StyleManager { /** * Set the String formatter for Data x-axis - * + * * @param pattern - the pattern describing the date and time format */ public void setDatePattern(String datePattern) { @@ -1094,7 +1141,7 @@ public class StyleManager { /** * Set the decimal formatter for all tick labels - * + * * @param pattern - the pattern describing the decimal format */ public void setDecimalPattern(String decimalPattern) { @@ -1107,4 +1154,34 @@ public class StyleManager { return decimalPattern; } + public String getXAxisDecimalPattern() { + + return xAxisDecimalPattern; + } + + /** + * Set the decimal formatting pattern for the X-Axis + * + * @param xAxisDecimalPattern + */ + public void setXAxisDecimalPattern(String xAxisDecimalPattern) { + + this.xAxisDecimalPattern = xAxisDecimalPattern; + } + + public String getYAxisDecimalPattern() { + + return yAxisDecimalPattern; + } + + /** + * Set the decimal formatting pattern for the Y-Axis + * + * @param yAxisDecimalPattern + */ + public void setYAxisDecimalPattern(String yAxisDecimalPattern) { + + this.yAxisDecimalPattern = yAxisDecimalPattern; + } + } diff --git a/xchart/src/main/java/com/xeiam/xchart/XChartPanel.java b/xchart/src/main/java/com/xeiam/xchart/XChartPanel.java index f9795f15c07b2306f1aa07b4d7fe0fbbdf2b53ab..813388da9e6d6c5a01935562bcf4aae6b7237ecf 100644 --- a/xchart/src/main/java/com/xeiam/xchart/XChartPanel.java +++ b/xchart/src/main/java/com/xeiam/xchart/XChartPanel.java @@ -44,23 +44,24 @@ import com.xeiam.xchart.BitmapEncoder.BitmapFormat; * A Swing JPanel that contains a Chart * <p> * Right-click + Save As... or ctrl+S pops up a Save As dialog box for saving the chart as a JPeg or PNG file. - * + * * @author timmolter */ public class XChartPanel extends JPanel { private final Chart chart; - + private final Dimension preferredSize; private String saveAsString = "Save As..."; /** * Constructor - * + * * @param chart */ public XChartPanel(final Chart chart) { this.chart = chart; + preferredSize = new Dimension(chart.getWidth(), chart.getHeight()); // Right-click listener for saving chart this.addMouseListener(new PopUpMenuClickListener()); @@ -73,7 +74,7 @@ public class XChartPanel extends JPanel { /** * Set the "Save As..." String if you want to localize it. - * + * * @param saveAsString */ public void setSaveAsString(String saveAsString) { @@ -92,7 +93,7 @@ public class XChartPanel extends JPanel { @Override public Dimension getPreferredSize() { - return new Dimension(chart.getWidth(), chart.getHeight()); + return this.preferredSize; } private class SaveAction extends AbstractAction { @@ -304,7 +305,7 @@ public class XChartPanel extends JPanel { /** * update a series by only updating the Y-Axis data. The X-Axis data will be automatically generated as a list of increasing Integers starting from 1 and ending at the size of the new Y-Axis data * list. - * + * * @param seriesName * @param newYData * @return @@ -333,7 +334,7 @@ public class XChartPanel extends JPanel { /** * update a series by updating both the X-Axis and Y-Axis data - * + * * @param seriesName * @param newYData * @return @@ -356,7 +357,7 @@ public class XChartPanel extends JPanel { /** * update a series by updating the X-Axis, Y-Axis and error bar data - * + * * @param seriesName * @param newXData * @param newYData @@ -379,4 +380,4 @@ public class XChartPanel extends JPanel { return series; } -} +} \ No newline at end of file diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java index 03eb1fae219f7bac83860f807d9d66951d32896c..aa0531f439f5cd8e90f7ad2a9ca474bfc406973d 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisPair.java @@ -115,6 +115,14 @@ public class AxisPair implements ChartPart { series = new Series(seriesName, generatedXData, xAxis.getAxisType(), yData, yAxis.getAxisType(), errorBars, seriesColorMarkerLineStyleCycler.getNextSeriesColorMarkerLineStyle()); } + switch (chartPainter.getStyleManager().getChartType()) { + case Area: + series.setSeriesType(Series.SeriesType.Area); + break; + case Line: + series.setSeriesType(Series.SeriesType.Line); + } + // Sanity check if (xData != null && xData.size() != yData.size()) { throw new IllegalArgumentException("X and Y-Axis sizes are not the same!!!"); diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java index 422bc51bd6f25ea88c16d49a1c3457f7b470ace8..e70a6e3ca40cd2322482730f90eec21017a0e638 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickBarChartCalculator.java @@ -51,7 +51,7 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { private void calculate(ChartPainter chartPainter) { // tick space - a percentage of the working space available for ticks - int tickSpace = (int) (styleManager.getAxisTickSpaceRatio() * workingSpace); // in plot space + int tickSpace = (int) (styleManager.getAxisTickSpacePercentage() * workingSpace); // in plot space // where the tick should begin in the working space in pixels double margin = Utils.getTickStartOffset(workingSpace, tickSpace); // in plot space double gridStep = getGridStepForDecimal(tickSpace); @@ -119,48 +119,36 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { for (Object category : categories) { if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) { - tickLabels.add(numberFormatter.formatNumber(BigDecimal.valueOf((Double) category), minValue, maxValue)); + tickLabels.add(numberFormatter.formatNumber(new BigDecimal(category.toString()), minValue, maxValue, axisDirection)); } else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Date) { long span = (long) Math.abs(maxValue - minValue); // in data space long gridStepHint = (long) (span / (double) tickSpace * styleManager.getXAxisTickMarkSpacingHint()); long timeUnit = dateFormatter.getTimeUnit(gridStepHint); - tickLabels.add(dateFormatter.formatDate((Double) category, timeUnit)); + tickLabels.add(dateFormatter.formatDate(((Number) category).doubleValue(), timeUnit)); } double tickLabelPosition = (int) (margin + firstPosition + gridStep * counter++); tickLocations.add(tickLabelPosition); } } - else { // Number or Date and more than 12 categories. divide up the axis tick space according to normal number axis layout - - double gridStep = getNumericalGridStep(tickSpace); - double firstPosition = getFirstPosition(gridStep); + else { // Number or Date and more than 12 categories. divide up the axis tick space according to normal date oor number axis layout // generate all tickLabels and tickLocations from the first to last position - NumberFormatter numberFormatter = null; - DateFormatter dateFormatter = null; if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) { - numberFormatter = new NumberFormatter(styleManager); + + AxisTickNumericalCalculator axisTickNumericalCalculator = new AxisTickNumericalCalculator(axisDirection, workingSpace, minValue, maxValue, styleManager); + tickLabels = axisTickNumericalCalculator.getTickLabels(); + tickLocations = axisTickNumericalCalculator.getTickLocations(); + } else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Date) { - dateFormatter = new DateFormatter(chartPainter.getStyleManager()); - } - - for (double tickPosition = firstPosition; tickPosition <= maxValue + 2 * gridStep; tickPosition = tickPosition + gridStep) { - if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) { - tickLabels.add(numberFormatter.formatNumber(BigDecimal.valueOf(tickPosition), minValue, maxValue)); - } - else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Date) { - long span = (long) Math.abs(maxValue - minValue); // in data space - long gridStepHint = (long) (span / (double) tickSpace * styleManager.getXAxisTickMarkSpacingHint()); - long timeUnit = dateFormatter.getTimeUnit(gridStepHint); - tickLabels.add(dateFormatter.formatDate(tickPosition, timeUnit)); - } - double tickLabelPosition = margin + ((tickPosition - minValue) / (maxValue - minValue) * tickSpace); - tickLocations.add(tickLabelPosition); + AxisTickDateCalculator axisTickDateCalculator = new AxisTickDateCalculator(axisDirection, workingSpace, minValue, maxValue, styleManager); + tickLabels = axisTickDateCalculator.getTickLabels(); + tickLocations = axisTickDateCalculator.getTickLocations(); } + } } diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickCalculator.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickCalculator.java index a36884dd4a4458f229383bacbef602fa5fd60f78..edb68709471f3e528e9956d373cb602e6566cb0c 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickCalculator.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickCalculator.java @@ -73,13 +73,13 @@ public abstract class AxisTickCalculator { } // override min and maxValue if specified - if (axisDirection == Direction.X && styleManager.getXAxisMin() != null) { + if (axisDirection == Direction.X && styleManager.getXAxisMin() != null && styleManager.getChartType() != ChartType.Bar) { overrideMinValue = styleManager.getXAxisMin(); } if (axisDirection == Direction.Y && styleManager.getYAxisMin() != null) { overrideMinValue = styleManager.getYAxisMin(); } - if (axisDirection == Direction.X && styleManager.getXAxisMax() != null) { + if (axisDirection == Direction.X && styleManager.getXAxisMax() != null && styleManager.getChartType() != ChartType.Bar) { overrideMaxValue = styleManager.getXAxisMax(); } if (axisDirection == Direction.Y && styleManager.getYAxisMax() != null) { diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickDateCalculator.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickDateCalculator.java index 89963ba2d0546affc216fe29b2756b59a468fa60..b871b94400064c52ef05cbd3d4e49ab446c0f39a 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickDateCalculator.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickDateCalculator.java @@ -47,7 +47,7 @@ public class AxisTickDateCalculator extends AxisTickCalculator { private void calculate() { // tick space - a percentage of the working space available for ticks - double tickSpace = styleManager.getAxisTickSpaceRatio() * workingSpace; // in plot space + double tickSpace = styleManager.getAxisTickSpacePercentage() * workingSpace; // in plot space // where the tick should begin in the working space in pixels double margin = Utils.getTickStartOffset(workingSpace, tickSpace); // in plot space double gridStep = getGridStepForDecimal(tickSpace); diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java index a9d308043bc1601bae75352a57a3bf246bbfc8cf..e25f3bc7e5c0d52039bb1db78153ea0b68a9da82 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLabels.java @@ -21,6 +21,8 @@ import java.awt.font.FontRenderContext; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; +import java.util.HashMap; +import java.util.Map; /** * Axis tick labels @@ -58,38 +60,59 @@ public class AxisTickLabels implements ChartPart { if (axisTick.getAxis().getDirection() == Axis.Direction.Y && getChartPainter().getStyleManager().isYAxisTicksVisible()) { // Y-Axis - double xOffset = axisTick.getAxis().getAxisTitle().getBounds().getX() + axisTick.getAxis().getAxisTitle().getBounds().getWidth(); + double xWidth = axisTick.getAxis().getAxisTitle().getBounds().getWidth(); + double xOffset = axisTick.getAxis().getAxisTitle().getBounds().getX() + xWidth; double yOffset = axisTick.getAxis().getPaintZone().getY(); double height = axisTick.getAxis().getPaintZone().getHeight(); double maxTickLabelWidth = 0; + Map<Double, TextLayout> axisLabelTextLayouts = new HashMap<Double, TextLayout>(); for (int i = 0; i < axisTick.getTickLabels().size(); i++) { - String tickLabel = axisTick.getTickLabels().get(i); - // System.out.println(tickLabel); + // System.out.println("** " + tickLabel); double tickLocation = axisTick.getTickLocations().get(i); double flippedTickLocation = yOffset + height - tickLocation; if (tickLabel != null && flippedTickLocation > yOffset && flippedTickLocation < yOffset + height) { // some are null for logarithmic axes - FontRenderContext frc = g.getFontRenderContext(); - TextLayout layout = new TextLayout(tickLabel, getChartPainter().getStyleManager().getAxisTickLabelsFont(), frc); - Rectangle2D tickLabelBounds = layout.getBounds(); + TextLayout axisLabelTextLayout = new TextLayout(tickLabel, getChartPainter().getStyleManager().getAxisTickLabelsFont(), frc); + Rectangle2D tickLabelBounds = axisLabelTextLayout.getBounds(); + double boundWidth = tickLabelBounds.getWidth(); + if (boundWidth > maxTickLabelWidth) { + maxTickLabelWidth = boundWidth; + } + axisLabelTextLayouts.put(tickLocation, axisLabelTextLayout); + } + } - Shape shape = layout.getOutline(null); + for (Double tickLocation : axisLabelTextLayouts.keySet()) { - AffineTransform orig = g.getTransform(); - AffineTransform at = new AffineTransform(); - at.translate(xOffset, flippedTickLocation + tickLabelBounds.getHeight() / 2.0); - g.transform(at); - g.fill(shape); - g.setTransform(orig); + TextLayout axisLabelTextLayout = axisLabelTextLayouts.get(tickLocation); + Rectangle2D tickLabelBounds = axisLabelTextLayout.getBounds(); + Shape shape = axisLabelTextLayout.getOutline(null); - if (tickLabelBounds.getWidth() > maxTickLabelWidth) { - maxTickLabelWidth = tickLabelBounds.getWidth(); - } + double flippedTickLocation = yOffset + height - tickLocation; + AffineTransform orig = g.getTransform(); + AffineTransform at = new AffineTransform(); + double boundWidth = tickLabelBounds.getWidth(); + double xPos; + switch (getChartPainter().getStyleManager().getYAxisLabelAlignment()) { + case Right: + xPos = xOffset + maxTickLabelWidth - boundWidth; + break; + case Centre: + xPos = xOffset + (maxTickLabelWidth - boundWidth) / 2; + break; + case Left: + default: + xPos = xOffset; } + at.translate(xPos, flippedTickLocation + tickLabelBounds.getHeight() / 2.0); + g.transform(at); + g.fill(shape); + g.setTransform(orig); + } // bounds @@ -124,7 +147,19 @@ public class AxisTickLabels implements ChartPart { AffineTransform orig = g.getTransform(); AffineTransform at = new AffineTransform(); - at.translate(shiftedTickLocation - tickLabelBounds.getWidth() / 2.0, yOffset); + double xPos; + switch (getChartPainter().getStyleManager().getXAxisLabelAlignment()) { + case Left: + xPos = shiftedTickLocation; + break; + case Right: + xPos = shiftedTickLocation - tickLabelBounds.getWidth(); + break; + case Centre: + default: + xPos = shiftedTickLocation - tickLabelBounds.getWidth() / 2.0; + } + at.translate(xPos, yOffset); g.transform(at); g.fill(shape); g.setTransform(orig); diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLogarithmicCalculator.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLogarithmicCalculator.java index 60bb7358802b9a5fedbe43dc794f1a559f4dbfc5..80e627099a34b6af626db7cb677c979aeef35a4a 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLogarithmicCalculator.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickLogarithmicCalculator.java @@ -50,13 +50,13 @@ public class AxisTickLogarithmicCalculator extends AxisTickCalculator { // a check if all axis data are the exact same values if (minValue == maxValue) { - tickLabels.add(numberFormatter.formatNumber(BigDecimal.valueOf(maxValue), minValue, maxValue)); + tickLabels.add(numberFormatter.formatNumber(BigDecimal.valueOf(maxValue), minValue, maxValue, axisDirection)); tickLocations.add(workingSpace / 2.0); return; } // tick space - a percentage of the working space available for ticks - double tickSpace = styleManager.getAxisTickSpaceRatio() * workingSpace; // in plot space + double tickSpace = styleManager.getAxisTickSpacePercentage() * workingSpace; // in plot space // where the tick should begin in the working space in pixels double margin = Utils.getTickStartOffset(workingSpace, tickSpace); // in plot space double gridStep = getGridStepForDecimal(tickSpace); @@ -113,7 +113,7 @@ public class AxisTickLogarithmicCalculator extends AxisTickCalculator { // only add labels for the decades if (Math.abs(Math.log10(j) % 1) < 0.00000001) { - tickLabels.add(numberFormatter.formatLogNumber(j)); + tickLabels.add(numberFormatter.formatLogNumber(j, axisDirection)); } else { tickLabels.add(null); diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickNumericalCalculator.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickNumericalCalculator.java index dffe6f11d5e6f499460ef3e1a555c813983fbee2..fdbad4104d3119180b012cccd0a154bf60e6d8ec 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickNumericalCalculator.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/AxisTickNumericalCalculator.java @@ -51,13 +51,13 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator { // a check if all axis data are the exact same values if (minValue == maxValue) { - tickLabels.add(numberFormatter.formatNumber(BigDecimal.valueOf(maxValue), minValue, maxValue)); + tickLabels.add(numberFormatter.formatNumber(BigDecimal.valueOf(maxValue), minValue, maxValue, axisDirection)); tickLocations.add(workingSpace / 2.0); return; } // tick space - a percentage of the working space available for ticks - double tickSpace = styleManager.getAxisTickSpaceRatio() * workingSpace; // in plot space + double tickSpace = styleManager.getAxisTickSpacePercentage() * workingSpace; // in plot space // where the tick should begin in the working space in pixels double margin = Utils.getTickStartOffset(workingSpace, tickSpace); // in plot space double gridStep = getGridStepForDecimal(tickSpace); @@ -74,7 +74,11 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator { // generate all tickLabels and tickLocations from the first to last position for (BigDecimal tickPosition = cleanedFirstPosition; tickPosition.compareTo(BigDecimal.valueOf(maxValue + 2 * cleanedGridStep.doubleValue())) < 0; tickPosition = tickPosition.add(cleanedGridStep)) { - tickLabels.add(numberFormatter.formatNumber(tickPosition, minValue, maxValue)); + // System.out.println(tickPosition); + String tickLabel = numberFormatter.formatNumber(tickPosition, minValue, maxValue, axisDirection); + // System.out.println(tickLabel); + + tickLabels.add(tickLabel); // here we convert tickPosition finally to plot space, i.e. pixels double tickLabelPosition = margin + ((tickPosition.doubleValue() - minValue) / (maxValue - minValue) * tickSpace); tickLocations.add(tickLabelPosition); diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/NumberFormatter.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/NumberFormatter.java index 5685df93065350addc032e5ccf409050d174ba97..2264d2d051f301800f145a284a5199b3c788c646 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/NumberFormatter.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/NumberFormatter.java @@ -20,6 +20,7 @@ import java.text.DecimalFormat; import java.text.NumberFormat; import com.xeiam.xchart.StyleManager; +import com.xeiam.xchart.internal.chartpart.Axis.Direction; /** * @author timmolter @@ -107,21 +108,32 @@ public class NumberFormatter { * Format a number value, if the override patterns are null, it uses defaults * * @param value + * @param min + * @param max + * @param axisDirection * @return */ - public String formatNumber(BigDecimal value, double min, double max) { + public String formatNumber(BigDecimal value, double min, double max, Direction axisDirection) { NumberFormat numberFormat = NumberFormat.getNumberInstance(styleManager.getLocale()); String decimalPattern; - if (styleManager.getDecimalPattern() == null) { + if (axisDirection == Direction.X && styleManager.getXAxisDecimalPattern() != null) { - decimalPattern = getFormatPattern(value, min, max); + decimalPattern = styleManager.getXAxisDecimalPattern(); } - else { + else if (axisDirection == Direction.Y && styleManager.getYAxisDecimalPattern() != null) { + decimalPattern = styleManager.getYAxisDecimalPattern(); + } + else if (styleManager.getDecimalPattern() != null) { + decimalPattern = styleManager.getDecimalPattern(); } + else { + decimalPattern = getFormatPattern(value, min, max); + } + // System.out.println(decimalPattern); DecimalFormat normalFormat = (DecimalFormat) numberFormat; normalFormat.applyPattern(decimalPattern); @@ -135,19 +147,26 @@ public class NumberFormatter { * @param value * @return */ - public String formatLogNumber(double value) { + public String formatLogNumber(double value, Direction axisDirection) { NumberFormat numberFormat = NumberFormat.getNumberInstance(styleManager.getLocale()); String decimalPattern; - if (styleManager.getDecimalPattern() == null) { + if (axisDirection == Direction.X && styleManager.getXAxisDecimalPattern() != null) { - decimalPattern = "0E0"; + decimalPattern = styleManager.getXAxisDecimalPattern(); } - else { + else if (axisDirection == Direction.Y && styleManager.getYAxisDecimalPattern() != null) { + decimalPattern = styleManager.getYAxisDecimalPattern(); + } + else if (styleManager.getDecimalPattern() != null) { + decimalPattern = styleManager.getDecimalPattern(); } + else { + decimalPattern = "0E0"; + } DecimalFormat normalFormat = (DecimalFormat) numberFormat; normalFormat.applyPattern(decimalPattern); diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentBarChart.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentBarChart.java index a13983f83ee28ee2c00f5f3109eae1503c6fe7d8..197a8002b6f9537a0ba80c64df9f598030e30612 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentBarChart.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentBarChart.java @@ -16,6 +16,7 @@ package com.xeiam.xchart.internal.chartpart; import java.awt.Graphics2D; +import java.awt.Rectangle; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import java.util.Collection; @@ -32,7 +33,7 @@ public class PlotContentBarChart extends PlotContent { /** * Constructor - * + * * @param plot */ protected PlotContentBarChart(Plot plot) { @@ -46,12 +47,16 @@ public class PlotContentBarChart extends PlotContent { Rectangle2D bounds = plot.getBounds(); StyleManager styleManager = plot.getChartPainter().getStyleManager(); + // this is for preventing the series to be drawn outside the plot area if min and max is overridden to fall inside the data range + Rectangle rectangle = new Rectangle(0, 0, getChartPainter().getWidth(), getChartPainter().getHeight()); + g.setClip(bounds.createIntersection(rectangle)); + // X-Axis - double xTickSpace = styleManager.getAxisTickSpaceRatio() * bounds.getWidth(); + double xTickSpace = styleManager.getAxisTickSpacePercentage() * bounds.getWidth(); double xLeftMargin = Utils.getTickStartOffset(bounds.getWidth(), xTickSpace); // Y-Axis - double yTickSpace = styleManager.getAxisTickSpaceRatio() * bounds.getHeight(); + double yTickSpace = styleManager.getAxisTickSpacePercentage() * bounds.getHeight(); double yTopMargin = Utils.getTickStartOffset(bounds.getHeight(), yTickSpace); int numBars = getChartPainter().getAxisPair().getSeriesMap().values().iterator().next().getXData().size(); @@ -190,7 +195,13 @@ public class PlotContentBarChart extends PlotContent { path.lineTo(xOffset + barWidth, zeroOffset); path.lineTo(xOffset, zeroOffset); path.closePath(); - g.fill(path); + g.setStroke(series.getStroke()); + if (getChartPainter().getStyleManager().isBarFilled()) { + g.fill(path); + } + else { + g.draw(path); + } } seriesCounter++; diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentLineChart.java b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentLineChart.java index 27f39f03e0891288555d54924c81ad0678683185..0b2e49aa237ab1064fa17d959702a4406ff02d51 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentLineChart.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/chartpart/PlotContentLineChart.java @@ -16,6 +16,7 @@ package com.xeiam.xchart.internal.chartpart; import java.awt.Graphics2D; +import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.Line2D; import java.awt.geom.Path2D; @@ -49,17 +50,33 @@ public class PlotContentLineChart extends PlotContent { public void paint(Graphics2D g) { Rectangle2D bounds = plot.getBounds(); + // g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + // g.setColor(Color.red); + // g.draw(bounds); + StyleManager styleManager = plot.getChartPainter().getStyleManager(); // this is for preventing the series to be drawn outside the plot area if min and max is overridden to fall inside the data range - g.setClip(bounds); + + // Rectangle rectangle = g.getClipBounds(); + // g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + // g.setColor(Color.green); + // g.draw(rectangle); + + Rectangle rectangle = new Rectangle(0, 0, getChartPainter().getWidth(), getChartPainter().getHeight()); + // g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + // g.setColor(Color.green); + // g.draw(rectangle); + g.setClip(bounds.createIntersection(rectangle)); + + // g.setClip(bounds.createIntersection(g.getClipBounds())); // X-Axis - double xTickSpace = styleManager.getAxisTickSpaceRatio() * bounds.getWidth(); + double xTickSpace = styleManager.getAxisTickSpacePercentage() * bounds.getWidth(); double xLeftMargin = Utils.getTickStartOffset((int) bounds.getWidth(), xTickSpace); // Y-Axis - double yTickSpace = styleManager.getAxisTickSpaceRatio() * bounds.getHeight(); + double yTickSpace = styleManager.getAxisTickSpacePercentage() * bounds.getHeight(); double yTopMargin = Utils.getTickStartOffset((int) bounds.getHeight(), yTickSpace); for (Series series : getChartPainter().getAxisPair().getSeriesMap().values()) { @@ -181,11 +198,11 @@ public class PlotContentLineChart extends PlotContent { } // paint area - if (getChartPainter().getStyleManager().getChartType() == ChartType.Area) { + if (getChartPainter().getStyleManager().getChartType() == ChartType.Area || Series.SeriesType.Area.equals(series.getSeriesType())) { if (previousX != Integer.MIN_VALUE && previousY != Integer.MIN_VALUE) { - g.setColor(series.getStrokeColor()); + g.setColor(series.getFillColor()); double yBottomOfArea = bounds.getY() + bounds.getHeight() - yTopMargin; if (path == null) { @@ -214,7 +231,7 @@ public class PlotContentLineChart extends PlotContent { double eb = 0.0; if (errorBars != null) { - eb = (Double) ebItr.next(); + eb = ebItr.next().doubleValue(); } if (errorBars != null) { diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/style/GGPlot2Theme.java b/xchart/src/main/java/com/xeiam/xchart/internal/style/GGPlot2Theme.java index 3ccbfcbfca171db5abd305c92afb33152cfbba5f..cb95e1a152c682e18a20a878c421f530bba5d3b1 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/style/GGPlot2Theme.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/style/GGPlot2Theme.java @@ -293,6 +293,12 @@ public class GGPlot2Theme implements Theme { return false; } + @Override + public boolean isBarFilled() { + + return true; + } + // Line, Scatter, Area Charts /////////////////////////////// @Override diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/style/MatlabTheme.java b/xchart/src/main/java/com/xeiam/xchart/internal/style/MatlabTheme.java index d329e10e561c5f6353ff8a22017bef405adb2683..5756a29d8c8c1e3a7b762c82aa923be4f6d6ed2f 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/style/MatlabTheme.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/style/MatlabTheme.java @@ -294,6 +294,12 @@ public class MatlabTheme implements Theme { return false; } + @Override + public boolean isBarFilled() { + + return true; + } + // Line, Scatter, Area Charts /////////////////////////////// @Override diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/style/Theme.java b/xchart/src/main/java/com/xeiam/xchart/internal/style/Theme.java index d67e64250ef3859ac47707a9c189809479227cf3..4ca1c5ddeded2e45e890774bfecbe23aaa926f6e 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/style/Theme.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/style/Theme.java @@ -122,6 +122,8 @@ public interface Theme { public boolean isBarsOverlapped(); + public boolean isBarFilled(); + // Line, Scatter, Area Charts /////////////////////////////// public int getMarkerSize(); diff --git a/xchart/src/main/java/com/xeiam/xchart/internal/style/XChartTheme.java b/xchart/src/main/java/com/xeiam/xchart/internal/style/XChartTheme.java index bd292dd16924083a235c7aaa69df0b38c8b9b1bc..1a4cf322ff39347c42aff54fb3c640f39f5c8d05 100644 --- a/xchart/src/main/java/com/xeiam/xchart/internal/style/XChartTheme.java +++ b/xchart/src/main/java/com/xeiam/xchart/internal/style/XChartTheme.java @@ -293,6 +293,12 @@ public class XChartTheme implements Theme { return false; } + @Override + public boolean isBarFilled() { + + return true; + } + // Line, Scatter, Area Charts /////////////////////////////// @Override