diff --git a/README.md b/README.md index 445adb656fff357452e5c5e0b23bced19db8cc7b..87ba9b686967184ed630fde74a89db3832794a0c 100644 --- a/README.md +++ b/README.md @@ -109,11 +109,11 @@ For snapshots, add the following to your pom.xml file: <dependency> <groupId>org.knowm.xchart</groupId> <artifactId>xchart</artifactId> - <version>2.6.2-SNAPSHOT</version> + <version>2.7.0-SNAPSHOT</version> </dependency> ``` -Snapshots can be manually downloaded from Sonatyope: [https://oss.sonatype.org/content/groups/public/com/xeiam/xchart/xchart/](https://oss.sonatype.org/content/groups/public/com/xeiam/xchart/xchart/) +Snapshots can be manually downloaded from Sonatyope: [https://oss.sonatype.org/content/groups/public/org/knowm/xchart/xchart/](https://oss.sonatype.org/content/groups/public/org/knowm/xchart/xchart/) ### SBT @@ -140,7 +140,7 @@ libraryDependencies += "org.knowm.xchart" % "xchart" % "2.6.0" exclude("de.erich ## Running Demo cd /path/to/xchart-demo/jar/ - java -cp xchart-demo-2.6.0.jar:xchart-2.6.0.jar org.knowm.xchart.demo.XChartDemo + java -cp xchart-demo-2.6.1.jar:xchart-2.6.1.jar org.knowm.xchart.demo.XChartDemo  diff --git a/pom.xml b/pom.xml index bc3b120704c13dce159f2862a61dc50e648e7026..ccb912a0c64f35d695e6c8e33242eef6e48073fe 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>org.knowm.xchart</groupId> <artifactId>xchart-parent</artifactId> - <version>2.6.2-SNAPSHOT</version> + <version>2.7.0-SNAPSHOT</version> <packaging>pom</packaging> <name>XChart Parent</name> <description>XChart is a light weight Java library for plotting data.</description> diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/XChartDemo.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/XChartDemo.java index 7cacab7e56fda0b88e962b473bbe94d830ccfb61..37ac297c328454b040458b3a26a2192483cea641 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/XChartDemo.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/XChartDemo.java @@ -43,6 +43,7 @@ import org.knowm.xchart.demo.charts.bar.BarChart05; import org.knowm.xchart.demo.charts.bar.BarChart06; import org.knowm.xchart.demo.charts.bar.BarChart07; import org.knowm.xchart.demo.charts.bar.BarChart08; +import org.knowm.xchart.demo.charts.bar.BarChart09; import org.knowm.xchart.demo.charts.date.DateChart01; import org.knowm.xchart.demo.charts.date.DateChart02; import org.knowm.xchart.demo.charts.date.DateChart03; @@ -57,6 +58,8 @@ import org.knowm.xchart.demo.charts.line.LineChart03; import org.knowm.xchart.demo.charts.line.LineChart04; import org.knowm.xchart.demo.charts.line.LineChart05; import org.knowm.xchart.demo.charts.line.LineChart06; +import org.knowm.xchart.demo.charts.line.LineChart07; +import org.knowm.xchart.demo.charts.pie.PieChart01; import org.knowm.xchart.demo.charts.realtime.RealtimeChart01; import org.knowm.xchart.demo.charts.realtime.RealtimeChart02; import org.knowm.xchart.demo.charts.realtime.RealtimeChart03; @@ -217,6 +220,13 @@ public class XChartDemo extends JPanel implements TreeSelectionListener { defaultMutableTreeNode = new DefaultMutableTreeNode(new ChartInfo("AreaLineChart03 - Combination Area & Line Chart", new AreaLineChart03().getChart())); category.add(defaultMutableTreeNode); + // Pie category + category = new DefaultMutableTreeNode("Pie Charts"); + top.add(category); + + defaultMutableTreeNode = new DefaultMutableTreeNode(new ChartInfo("PieChart01 - Pie Chart with 4 Slices", new PieChart01().getChart())); + category.add(defaultMutableTreeNode); + // Line category category = new DefaultMutableTreeNode("Line Charts"); top.add(category); @@ -239,6 +249,9 @@ public class XChartDemo extends JPanel implements TreeSelectionListener { defaultMutableTreeNode = new DefaultMutableTreeNode(new ChartInfo("LineChart06 - Logarithmic Y-Axis with Error Bars", new LineChart06().getChart())); category.add(defaultMutableTreeNode); + defaultMutableTreeNode = new DefaultMutableTreeNode(new ChartInfo("LineChart07 - Line Chart with Multiple Category Series", new LineChart07().getChart())); + category.add(defaultMutableTreeNode); + // Scatter category category = new DefaultMutableTreeNode("Scatter Charts"); top.add(category); @@ -283,6 +296,9 @@ public class XChartDemo extends JPanel implements TreeSelectionListener { defaultMutableTreeNode = new DefaultMutableTreeNode(new ChartInfo("BarChart08 - Histogram with Error Bars", new BarChart08().getChart())); category.add(defaultMutableTreeNode); + defaultMutableTreeNode = new DefaultMutableTreeNode(new ChartInfo("BarChart09 - Category chart with Bar, Line and Scatter Series", new BarChart09().getChart())); + category.add(defaultMutableTreeNode); + // Theme category category = new DefaultMutableTreeNode("Chart Themes"); top.add(category); diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart01.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart01.java index bac75519031598f38263c464565723f9942a38b3..bedf64209ee39f025f828613907ce5c753520512 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart01.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart01.java @@ -16,6 +16,8 @@ */ package org.knowm.xchart.demo.charts.bar; +import java.util.Arrays; + import org.knowm.xchart.Chart; import org.knowm.xchart.ChartBuilder; import org.knowm.xchart.StyleManager.ChartType; @@ -47,7 +49,7 @@ public class BarChart01 implements ExampleChart { // Create Chart Chart chart = new ChartBuilder().chartType(ChartType.Bar).width(800).height(600).title("Score Histogram").xAxisTitle("Score").yAxisTitle("Number").build(); - chart.addSeries("test 1", new double[] { 0, 1, 2, 3, 4 }, new double[] { 4, 5, 9, 6, 5 }); + chart.addCategorySeries("test 1", Arrays.asList(new Integer[] { 0, 1, 2, 3, 4 }), Arrays.asList(new Integer[] { 4, 5, 9, 6, 5 })); // Customize Chart chart.getStyleManager().setLegendPosition(LegendPosition.InsideNW); diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart02.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart02.java index a20557c4e7588a78bc0269b6559345b846e4b69a..780a81a9c4b6968fb2ed18936c7380b7fb4f1230 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart02.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart02.java @@ -27,11 +27,11 @@ import java.util.Random; import org.knowm.xchart.Chart; import org.knowm.xchart.ChartBuilder; import org.knowm.xchart.Series; -import org.knowm.xchart.SeriesColor; import org.knowm.xchart.StyleManager.ChartTheme; import org.knowm.xchart.StyleManager.ChartType; import org.knowm.xchart.SwingWrapper; import org.knowm.xchart.demo.charts.ExampleChart; +import org.knowm.xchart.internal.style.MatlabTheme; /** * Date Categories @@ -75,8 +75,8 @@ public class BarChart02 implements ExampleChart { xData.add(date); yData.add(-1 * 0.00000001 * ((random.nextInt(i) + 1))); } - Series series = chart.addSeries("Model 77", xData, yData); - series.setLineColor(SeriesColor.RED); + Series series = chart.addCategorySeries("Model 77", xData, yData); + series.setLineColor(MatlabTheme.RED); chart.getStyleManager().setPlotGridLinesVisible(false); chart.getStyleManager().setBarFilled(false); chart.getStyleManager().setDatePattern("YYYY"); diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart03.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart03.java index 361b96377bc4f32ef27cb0255ea732e368437d6a..fb57944c46007bdd55b0376423ee4a4990a11cb0 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart03.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart03.java @@ -16,6 +16,8 @@ */ package org.knowm.xchart.demo.charts.bar; +import java.util.Arrays; + import org.knowm.xchart.Chart; import org.knowm.xchart.ChartBuilder; import org.knowm.xchart.StyleManager.ChartType; @@ -45,7 +47,7 @@ public class BarChart03 implements ExampleChart { // Create Chart Chart chart = new ChartBuilder().chartType(ChartType.Bar).width(800).height(600).title("Score vs. Age").xAxisTitle("Age").yAxisTitle("Score").build(); - chart.addSeries("males", new double[] { 10, 20, 30, 40 }, new double[] { 40, -30, -20, -60 }); + chart.addCategorySeries("males", Arrays.asList(new Integer[] { 10, 20, 30, 40 }), Arrays.asList(new Integer[] { 40, -30, -20, -60 })); return chart; } diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart04.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart04.java index 2089a7764c6b528f18868aa8e86c59c6769e61cb..ed79870882a3e5da2ef48b956fd9309737929ad9 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart04.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart04.java @@ -16,6 +16,8 @@ */ package org.knowm.xchart.demo.charts.bar; +import java.util.Arrays; + import org.knowm.xchart.Chart; import org.knowm.xchart.ChartBuilder; import org.knowm.xchart.StyleManager.ChartType; @@ -47,8 +49,8 @@ public class BarChart04 implements ExampleChart { // Create Chart Chart chart = new ChartBuilder().chartType(ChartType.Bar).width(800).height(600).title("XFactor vs. Age").xAxisTitle("Age").yAxisTitle("XFactor").build(); - chart.addSeries("female", new double[] { 10, 20, 30, 40, 50 }, new double[] { 50, 10, 20, 40, 35 }); - chart.addSeries("male", new double[] { 10, 20, 30, 40, 50 }, new double[] { 40, 30, 20, 0, 60 }); + chart.addCategorySeries("female", Arrays.asList(new Integer[] { 10, 20, 30, 40, 50 }), Arrays.asList(new Integer[] { 50, 10, 20, 40, 35 })); + chart.addCategorySeries("male", Arrays.asList(new Integer[] { 10, 20, 30, 40, 50 }), Arrays.asList(new Integer[] { 40, 30, 20, null, 60 })); chart.getStyleManager().setYAxisMin(5); chart.getStyleManager().setYAxisMax(70); diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart05.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart05.java index f6a2150a35acc6dc5274f89df2a24c4c470ed713..7250c4cfff407f4b1d6e0411fe7de8cf1fd67c59 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart05.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart05.java @@ -49,10 +49,16 @@ public class BarChart05 implements ExampleChart { // Create Chart Chart chart = new ChartBuilder().chartType(ChartType.Bar).width(800).height(600).title("Temperature vs. Color").xAxisTitle("Color").yAxisTitle("Temperature").theme(ChartTheme.GGPlot2).build(); - chart.addSeries("fish", new ArrayList<String>(Arrays.asList(new String[] { "Blue", "Red", "Green", "Yellow", "Yellow" })), new ArrayList<Number>(Arrays.asList(new Number[] { -40, 30, 20, 60, - 60 }))); - chart.addSeries("worms", new ArrayList<String>(Arrays.asList(new String[] { "Blue", "Red", "Green", "Yellow", "Yellow" })), new ArrayList<Number>(Arrays.asList(new Number[] { 50, 10, -20, 40, - 60 }))); + chart.addCategorySeries("fish", new ArrayList<String>(Arrays.asList(new String[] { "Blue", "Red", "Green", "Yellow", "Orange" })), new ArrayList<Number>(Arrays.asList(new Number[] { -40, 30, 20, + 60, 60 }))); + chart.addCategorySeries("worms", new ArrayList<String>(Arrays.asList(new String[] { "Blue", "Red", "Green", "Yellow", "Orange" })), new ArrayList<Number>(Arrays.asList(new Number[] { 50, 10, -20, + 40, 60 }))); + chart.addCategorySeries("birds", new ArrayList<String>(Arrays.asList(new String[] { "Blue", "Red", "Green", "Yellow", "Orange" })), new ArrayList<Number>(Arrays.asList(new Number[] { 13, 22, -23, + -34, 37 }))); + chart.addCategorySeries("ants", new ArrayList<String>(Arrays.asList(new String[] { "Blue", "Red", "Green", "Yellow", "Orange" })), new ArrayList<Number>(Arrays.asList(new Number[] { 50, 57, -14, + -20, 31 }))); + chart.addCategorySeries("slugs", new ArrayList<String>(Arrays.asList(new String[] { "Blue", "Red", "Green", "Yellow", "Orange" })), new ArrayList<Number>(Arrays.asList(new Number[] { -2, 29, 49, + -16, -43 }))); return chart; } diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart06.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart06.java index b7650a48979cf6743461910ba0033071e3b6fd36..64c088feae9d808d14700bd4f654ffd48f21b7ed 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart06.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart06.java @@ -53,8 +53,8 @@ public class BarChart06 implements ExampleChart { Histogram histogram1 = new Histogram(getGaussianData(10000), 30, -30, 30); Histogram histogram2 = new Histogram(getGaussianData(5000), 30, -30, 30); - chart.addSeries("histogram 1", histogram1.getxAxisData(), histogram1.getyAxisData()); - chart.addSeries("histogram 2", histogram2.getxAxisData(), histogram2.getyAxisData()); + chart.addCategorySeries("histogram 1", histogram1.getxAxisData(), histogram1.getyAxisData()); + chart.addCategorySeries("histogram 2", histogram2.getxAxisData(), histogram2.getyAxisData()); // Customize Chart chart.getStyleManager().setLegendPosition(LegendPosition.InsideNW); diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart07.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart07.java index 1980e7ca270d8dc5ecd008174b812be268534336..5711df06ea911780d589e059a0a27bed7cc404ce 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart07.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart07.java @@ -53,9 +53,9 @@ public class BarChart07 implements ExampleChart { Chart chart = new ChartBuilder().chartType(ChartType.Bar).width(800).height(600).title("Score Histogram").xAxisTitle("Mean").yAxisTitle("Count").build(); Histogram histogram1 = new Histogram(getGaussianData(1000), 10, -30, 30); - chart.addSeries("histogram 1", histogram1.getxAxisData(), histogram1.getyAxisData()); + chart.addCategorySeries("histogram 1", histogram1.getxAxisData(), histogram1.getyAxisData()); Histogram histogram2 = new Histogram(getGaussianData(1000), 10, -30, 30); - chart.addSeries("histogram 2", histogram2.getxAxisData(), histogram2.getyAxisData()); + chart.addCategorySeries("histogram 2", histogram2.getxAxisData(), histogram2.getyAxisData()); // Customize Chart chart.getStyleManager().setLegendPosition(LegendPosition.InsideNW); diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart08.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart08.java index 28d2d05bd21ddeeb796dda8e5570863d801c90bb..17725bba4b03bf3f5a1734b31b1ad9976920e1ff 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart08.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart08.java @@ -52,7 +52,7 @@ public class BarChart08 implements ExampleChart { Chart chart = new ChartBuilder().chartType(ChartType.Bar).width(800).height(600).title("Histogram").xAxisTitle("Mean").yAxisTitle("Count").build(); Histogram histogram1 = new Histogram(getGaussianData(10000), 10, -10, 10); - chart.addSeries("histogram", histogram1.getxAxisData(), histogram1.getyAxisData(), getFakeErrorData(histogram1.getxAxisData().size())); + chart.addCategorySeries("histogram", histogram1.getxAxisData(), histogram1.getyAxisData(), getFakeErrorData(histogram1.getxAxisData().size())); // Customize Chart chart.getStyleManager().setLegendPosition(LegendPosition.InsideNW); diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart09.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart09.java new file mode 100644 index 0000000000000000000000000000000000000000..0920bc39a60f7315e179a9487c85ce261a375c54 --- /dev/null +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart09.java @@ -0,0 +1,70 @@ +/** + * Copyright 2015 Knowm Inc. (http://knowm.org) and contributors. + * Copyright 2011-2015 Xeiam LLC (http://xeiam.com) and contributors. + * + * 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 org.knowm.xchart.demo.charts.bar; + +import java.util.ArrayList; +import java.util.Arrays; + +import org.knowm.xchart.Chart; +import org.knowm.xchart.ChartBuilder; +import org.knowm.xchart.Series; +import org.knowm.xchart.Series.SeriesType; +import org.knowm.xchart.StyleManager.ChartTheme; +import org.knowm.xchart.StyleManager.ChartType; +import org.knowm.xchart.StyleManager.LegendPosition; +import org.knowm.xchart.SwingWrapper; +import org.knowm.xchart.demo.charts.ExampleChart; + +/** + * Category chart with Bar, Line and Scatter Series + * <p> + * Demonstrates the following: + * <ul> + * <li>Mixed series types - Bar, Line and Scatter + * <li>Bar Chart styles - overlapped, bar width + */ +public class BarChart09 implements ExampleChart { + + public static void main(String[] args) { + + ExampleChart exampleChart = new BarChart09(); + Chart chart = exampleChart.getChart(); + new SwingWrapper(chart).displayChart(); + } + + @Override + public Chart getChart() { + + // Create Chart + Chart chart = new ChartBuilder().chartType(ChartType.Bar).width(800).height(600).title("Value vs. Letter").xAxisTitle("Letter").yAxisTitle("Value").theme(ChartTheme.GGPlot2).build(); + chart.addCategorySeries("China", new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "C", "D", "E" })), new ArrayList<Number>(Arrays.asList(new Number[] { 11, 23, 20, 36, 5 }))); + Series series2 = chart.addCategorySeries("Korea", new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "C", "D", "E" })), new ArrayList<Number>(Arrays.asList(new Number[] { 13, 25, 22, 38, + 7 })), new ArrayList<Number>(Arrays.asList(new Number[] { 1, 3, 2, 1, 2 }))); + series2.setSeriesType(SeriesType.Line); + Series series3 = chart.addCategorySeries("World Ave.", new ArrayList<String>(Arrays.asList(new String[] { "A", "B", "C", "D", "E" })), new ArrayList<Number>(Arrays.asList(new Number[] { 20, 22, + 18, 36, 32 }))); + series3.setSeriesType(SeriesType.Scatter); + + // Customize Chart + chart.getStyleManager().setLegendPosition(LegendPosition.InsideNW); + chart.getStyleManager().setBarWidthPercentage(.55); + chart.getStyleManager().setBarsOverlapped(true); + + return chart; + } + +} diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart02.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart02.java index 7813658aa83cd9a793ac9fa37b858c6468721515..e4333adacdebb3aba4fc78c541250a26cefbc5c5 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart02.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart02.java @@ -21,11 +21,11 @@ import java.util.List; import org.knowm.xchart.Chart; import org.knowm.xchart.Series; -import org.knowm.xchart.SeriesColor; import org.knowm.xchart.SeriesLineStyle; import org.knowm.xchart.SeriesMarker; import org.knowm.xchart.SwingWrapper; import org.knowm.xchart.demo.charts.ExampleChart; +import org.knowm.xchart.internal.style.XChartTheme; /** * Sine wave with customized series style @@ -65,9 +65,9 @@ public class LineChart02 implements ExampleChart { // Series 1 Series series1 = chart.addSeries("y=sin(x)", xData, yData); - series1.setLineColor(SeriesColor.PURPLE); + series1.setLineColor(XChartTheme.PURPLE); series1.setLineStyle(SeriesLineStyle.DASH_DASH); - series1.setMarkerColor(SeriesColor.GREEN); + series1.setMarkerColor(XChartTheme.GREEN); series1.setMarker(SeriesMarker.SQUARE); return chart; diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart03.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart03.java index 55d8778149c98b656954f581a4444da14c454526..6a919496d08953361ac741e24f6e9614935eb011 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart03.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart03.java @@ -29,12 +29,12 @@ import java.util.Locale; import org.knowm.xchart.Chart; import org.knowm.xchart.ChartColor; import org.knowm.xchart.Series; -import org.knowm.xchart.SeriesColor; import org.knowm.xchart.SeriesLineStyle; import org.knowm.xchart.SeriesMarker; import org.knowm.xchart.StyleManager.LegendPosition; import org.knowm.xchart.SwingWrapper; import org.knowm.xchart.demo.charts.ExampleChart; +import org.knowm.xchart.internal.style.XChartTheme; /** * Extensive Chart Customization @@ -102,7 +102,7 @@ public class LineChart03 implements ExampleChart { chart.getStyleManager().setLocale(Locale.GERMAN); Series series = chart.addSeries("Fake Data", xData, yData); - series.setLineColor(SeriesColor.BLUE); + series.setLineColor(XChartTheme.BLUE); series.setMarkerColor(Color.ORANGE); series.setMarker(SeriesMarker.CIRCLE); series.setLineStyle(SeriesLineStyle.SOLID); diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart04.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart04.java index 3f251761da72944055ccfaedd46a01eb72e91bbb..4925c568a8b76093800d7ee3a3b0d87ba9d1673e 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart04.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart04.java @@ -18,11 +18,11 @@ package org.knowm.xchart.demo.charts.line; import org.knowm.xchart.Chart; import org.knowm.xchart.Series; -import org.knowm.xchart.SeriesColor; import org.knowm.xchart.SeriesLineStyle; import org.knowm.xchart.SeriesMarker; import org.knowm.xchart.SwingWrapper; import org.knowm.xchart.demo.charts.ExampleChart; +import org.knowm.xchart.internal.style.XChartTheme; /** * Hundreds of Series on One Plot @@ -50,10 +50,10 @@ public class LineChart04 implements ExampleChart { for (int i = 0; i < 200; i++) { Series series = chart.addSeries("A" + i, new double[] { Math.random() / 1000, Math.random() / 1000 }, new double[] { Math.random() / -1000, Math.random() / -1000 }); - series.setLineColor(SeriesColor.BLUE); + series.setLineColor(XChartTheme.BLUE); series.setLineStyle(SeriesLineStyle.SOLID); series.setMarker(SeriesMarker.CIRCLE); - series.setMarkerColor(SeriesColor.BLUE); + series.setMarkerColor(XChartTheme.BLUE); } diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart07.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart07.java new file mode 100644 index 0000000000000000000000000000000000000000..4cfb46349386edc4ef8e0db8d36f6a5d8bdfaf33 --- /dev/null +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart07.java @@ -0,0 +1,106 @@ +/** + * Copyright 2015 Knowm Inc. (http://knowm.org) and contributors. + * Copyright 2011-2015 Xeiam LLC (http://xeiam.com) and contributors. + * + * 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 org.knowm.xchart.demo.charts.line; + +import java.util.Arrays; +import java.util.List; + +import org.knowm.xchart.Chart; +import org.knowm.xchart.Series; +import org.knowm.xchart.Series.SeriesType; +import org.knowm.xchart.SeriesMarker; +import org.knowm.xchart.StyleManager.ChartTheme; +import org.knowm.xchart.StyleManager.ChartType; +import org.knowm.xchart.StyleManager.LegendPosition; +import org.knowm.xchart.SwingWrapper; +import org.knowm.xchart.demo.charts.ExampleChart; + +/** + * Line chart with multiple Category Series + * <p> + * Demonstrates the following: + * <ul> + * <li>A Line Chart created from multiple category series types + * <li>GGPlot2 Theme + */ +public class LineChart07 implements ExampleChart { + + public static void main(String[] args) { + + ExampleChart exampleChart = new LineChart07(); + Chart chart = exampleChart.getChart(); + new SwingWrapper(chart).displayChart(); + } + + @Override + public Chart getChart() { + + // Create Chart + Chart chart = new Chart(1024, 768, ChartTheme.GGPlot2); + chart.getStyleManager().setChartType(ChartType.Line); + + // Customize Chart + chart.setChartTitle("ThreadPoolBenchmark"); + chart.setXAxisTitle("Threads"); + chart.setYAxisTitle("Executions"); + chart.getStyleManager().setXAxisLabelRotation(270); + chart.getStyleManager().setLegendPosition(LegendPosition.OutsideE); + chart.getStyleManager().setBarWidthPercentage(0); + chart.getStyleManager().setBarsOverlapped(true); + + // Declare data + List<String> xAxisKeys = Arrays.asList(new String[] { "release-0.5", "release-0.6", "release-0.7", "release-0.8", "release-0.9", "release-1.0.0", "release-1.1.0", "release-1.2.0", "release-1.3.0", + "release-2.0.0", "release-2.1.0", "release-2.2.0", "release-2.3.0", "release-2.4.0", "release-2.5.0", "release-2.6.0", "release-3.0.0", "release-3.1.0", "release-3.2.0", "release-3.3.0", + "release-3.4.0", "release-3.5.0", "release-3.6.0", "release-3.7.0", "release-3.8.0", "release-4.0.0", "release-4.1.0", "release-4.2.0", "release-4.3.0", "release-4.4.0", "release-4.4.1", + "release-4.4.2" }); + String[] seriesNames = new String[] { "Threads:4", "Threads:10", "Threads:20", "Threads:50", "Threads:100", "Threads:150", "Threads:200", "Threads:250", "Threads:500", "Threads:750", + "Threads:1000", "Threads:1500", "Threads:2000", "Threads:2500" }; + Integer[][] dataPerSeries = new Integer[][] { { 117355, 117594, 117551, 117719, 116553, 117304, 118945, 119067, 117803, 118080, 117676, 118599, 118224, 119263, 119455, 119393, 117961, 119254, + 118447, 119428, 118812, 117947, 119405, 119329, 117749, 119331, 119354, 119519, 118494, 119780, 119766, 119742 }, { 127914, 128835, 128953, 128893, 128830, 129012, 129235, 129424, 129400, + 129477, 129065, 129103, 129150, 129434, 129000, 129467, 128994, 129167, 129849, 128702, 134439, 134221, 134277, 134393, 134390, 134581, 134263, 134641, 134672, 137880, 137675, 137943 }, { + 133396, 133977, 133992, 133656, 134406, 134657, 135194, 135497, 134881, 134873, 135065, 135045, 134480, 135004, 135111, 134720, 134639, 135505, 135831, 135974, 140965, 140759, 140545, + 139959, 141063, 141339, 140967, 140927, 141972, 160884, 163402, 164572 }, { 122376, 122236, 122861, 122806, 122775, 122619, 122505, 122585, 122742, 122847, 122660, 122705, 122852, + 122847, 122909, 122788, 122861, 123396, 123430, 122847, 121103, 121013, 120936, 120901, 121096, 120931, 121160, 121112, 121145, 175077, 174483, 175787 }, { 120048, 120226, 120745, + 120669, 120647, 120683, 120499, 120533, 120628, 121059, 120901, 120838, 120845, 120954, 120963, 121055, 120948, 121111, 121239, 121094, 121422, 121249, 120924, 120918, 121061, + 121063, 121065, 121098, 121011, 173280, 173179, 172193 }, { 119712, 119766, 120053, 120217, 119954, 120080, 120167, 119898, 120065, 120253, 120153, 120103, 120070, 120446, + 120347, 120223, 120261, 120629, 120576, 120541, 121405, 121481, 121461, 121387, 121295, 121597, 121592, 121593, 121576, 171415, 170628, 169878 }, { 119807, 120232, 119745, + 119892, 120024, 119854, 119818, 119908, 119685, 119816, 119848, 119919, 119627, 119906, 120242, 119974, 120116, 120472, 120304, 120294, 121308, 121338, 121278, 121292, + 121418, 121570, 121564, 121541, 121571, 170597, 170346, 170434 }, { 121283, 121580, 120720, 120553, 121146, 120016, 119994, 120194, 120149, 120239, 120238, 120031, + 120016, 120314, 120023, 120408, 120315, 120711, 121046, 120850, 121192, 121315, 121198, 121224, 121396, 121398, 121636, 121412, 121252, 168489, 169774, 168750 }, { + 121219, 121594, 122576, 122368, 122874, 121831, 121386, 121433, 121722, 121600, 121158, 121653, 121306, 121652, 121982, 121775, 121819, 122243, 122128, 122067, + 125185, 124972, 125023, 125004, 125120, 125320, 125395, 125134, 124838, 168492, 167673, 167087 }, { 121576, 122197, 121660, 121673, 122047, 120863, 120715, + 120542, 120934, 120936, 120448, 120823, 120546, 121150, 120863, 120946, 120865, 121273, 120848, 121210, 124867, 124927, 124863, 124610, 124633, 124881, + 124887, 124626, 124814, 167504, 167717, 165026 }, { 121822, 121540, 121488, 122055, 121253, 120728, 120626, 120474, 119848, 120129, 120082, 120075, 120429, + 120859, 121228, 120390, 120161, 121465, 121085, 120682, 124287, 124029, 124162, 124185, 124024, 124416, 124558, 124206, 124109, 166816, 167583, + 164828 }, { 121094, 121594, 121273, 121495, 121638, 120419, 119611, 119406, 119381, 120053, 119591, 120080, 120071, 119709, 120008, 120469, 119417, + 120327, 120510, 119873, 123192, 123085, 123388, 123298, 123260, 122982, 123465, 123267, 122856, 164366, 163919, 166612 }, { 120639, 120628, 121443, + 121160, 121245, 119819, 119865, 119300, 119466, 119478, 119870, 119720, 119671, 120333, 119718, 119528, 119581, 120716, 120624, 119585, 121685, + 121978, 123017, 121433, 122190, 122330, 122458, 122090, 122234, 161976, 163628, 158023 }, { 120242, 120674, 120091, 120299, 120662, 119885, + 119480, 119269, 118983, 119290, 119304, 119161, 119875, 118830, 119517, 119980, 119502, 120883, 118953, 119461, 120753, 120526, 120967, + 120244, 122381, 121084, 122404, 121761, 121546, 161230, 160123, 160534 } }; + + // Add data series to chart + for (int i = 0; i < seriesNames.length; i++) { + Series series = chart.addCategorySeries(seriesNames[i], xAxisKeys, Arrays.asList(dataPerSeries[i])); + series.setMarker(SeriesMarker.NONE); + series.setSeriesType(SeriesType.Line); + } + chart.getStyleManager().setYAxisLogarithmic(true); + + return chart; + } +} diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/pie/PieChart01.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/pie/PieChart01.java new file mode 100644 index 0000000000000000000000000000000000000000..a30d580ae9c6b3e86a7cc220ca34459686e887e5 --- /dev/null +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/pie/PieChart01.java @@ -0,0 +1,56 @@ +/** + * Copyright 2015 Knowm Inc. (http://knowm.org) and contributors. + * Copyright 2011-2015 Xeiam LLC (http://xeiam.com) and contributors. + * + * 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 org.knowm.xchart.demo.charts.pie; + +import org.knowm.xchart.Chart; +import org.knowm.xchart.ChartBuilder; +import org.knowm.xchart.StyleManager.ChartType; +import org.knowm.xchart.SwingWrapper; +import org.knowm.xchart.demo.charts.ExampleChart; + +/** + * Pie Chart with 4 Slices + * <p> + * Demonstrates the following: + * <ul> + * <li>Pie Chart + * <li>ChartBuilder + */ +public class PieChart01 implements ExampleChart { + + public static void main(String[] args) { + + ExampleChart exampleChart = new PieChart01(); + Chart chart = exampleChart.getChart(); + new SwingWrapper(chart).displayChart(); + } + + @Override + public Chart getChart() { + + // Create Chart + // TODO remove chartType(ChartType.Pie) + Chart chart = new ChartBuilder().chartType(ChartType.Pie).width(800).height(600).title(getClass().getSimpleName()).xAxisTitle("X").yAxisTitle("Y").build(); + chart.addPieSeries("Pennies", 387); + chart.addPieSeries("Nickels", 234); + chart.addPieSeries("Dimes", 190); + chart.addPieSeries("Quarters", 270); + + return chart; + } + +} diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/theme/ThemeChart03.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/theme/ThemeChart03.java index 5a3990287472fe8ad84f8a470ab427132ddbd455..cfb4a6a667564bd956602c41ebee2e80a3a57ae5 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/theme/ThemeChart03.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/theme/ThemeChart03.java @@ -25,8 +25,6 @@ import java.util.List; import org.knowm.xchart.Chart; import org.knowm.xchart.ChartBuilder; -import org.knowm.xchart.Series; -import org.knowm.xchart.SeriesLineStyle; import org.knowm.xchart.StyleManager.ChartTheme; import org.knowm.xchart.SwingWrapper; import org.knowm.xchart.demo.charts.ExampleChart; @@ -104,8 +102,7 @@ public class ThemeChart03 implements ExampleChart { e.printStackTrace(); } - Series series1 = chart.addSeries("downloads", xData, y1Data); - series1.setLineStyle(SeriesLineStyle.DOT_DOT); + chart.addSeries("downloads", xData, y1Data); chart.addSeries("price", xData, y2Data); return chart; diff --git a/xchart-demo/src/main/java/org/knowm/xchart/standalone/ErrorBarLogTest.java b/xchart-demo/src/main/java/org/knowm/xchart/standalone/ErrorBarLogTest.java index ce8940cfc812f06ccb05ea8aafb961c0506864a8..845fa559b04b696acaf1eb58a45f1d3a71d7f24d 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/standalone/ErrorBarLogTest.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/standalone/ErrorBarLogTest.java @@ -20,10 +20,10 @@ import java.awt.Color; import org.knowm.xchart.Chart; import org.knowm.xchart.Series; -import org.knowm.xchart.SeriesColor; import org.knowm.xchart.SeriesLineStyle; import org.knowm.xchart.SeriesMarker; import org.knowm.xchart.SwingWrapper; +import org.knowm.xchart.internal.style.XChartTheme; /** * @author timmolter @@ -70,13 +70,13 @@ public class ErrorBarLogTest { series2.setMarker(SeriesMarker.NONE); - series2.setLineColor(SeriesColor.RED); + series2.setLineColor(XChartTheme.RED); series3.setLineStyle(SeriesLineStyle.DASH_DASH); series3.setMarker(SeriesMarker.NONE); - series3.setLineColor(SeriesColor.RED); + series3.setLineColor(XChartTheme.RED); new SwingWrapper(mychart).displayChart(); diff --git a/xchart-demo/src/main/java/org/knowm/xchart/standalone/ErrorBarTest.java b/xchart-demo/src/main/java/org/knowm/xchart/standalone/ErrorBarTest.java index d504888466f54a5c64fbd7082fabd0989f29a94f..9b8ff7400aacf1840f9232a97ec81cc2afcdd7cc 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/standalone/ErrorBarTest.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/standalone/ErrorBarTest.java @@ -20,10 +20,10 @@ import java.awt.Color; import org.knowm.xchart.Chart; import org.knowm.xchart.Series; -import org.knowm.xchart.SeriesColor; import org.knowm.xchart.SeriesLineStyle; import org.knowm.xchart.SeriesMarker; import org.knowm.xchart.SwingWrapper; +import org.knowm.xchart.internal.style.XChartTheme; /** * @author timmolter @@ -51,10 +51,10 @@ public class ErrorBarTest { series1.setMarkerColor(Color.MAGENTA); series2.setLineStyle(SeriesLineStyle.DASH_DASH); series2.setMarker(SeriesMarker.NONE); - series2.setLineColor(SeriesColor.RED); + series2.setLineColor(XChartTheme.RED); series3.setLineStyle(SeriesLineStyle.DASH_DASH); series3.setMarker(SeriesMarker.NONE); - series3.setLineColor(SeriesColor.RED); + series3.setLineColor(XChartTheme.RED); new SwingWrapper(mychart).displayChart(); } diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/plot/lines/Example0WithoutHorizontalLines.java b/xchart-demo/src/main/java/org/knowm/xchart/standalone/Example0WithoutHorizontalLines.java similarity index 97% rename from xchart-demo/src/main/java/org/knowm/xchart/demo/charts/plot/lines/Example0WithoutHorizontalLines.java rename to xchart-demo/src/main/java/org/knowm/xchart/standalone/Example0WithoutHorizontalLines.java index e88229ef8a6f865987fe45e7bf7b3106086d385a..286df0778c99204c36d5d95ab1667bf5ed85aa8c 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/plot/lines/Example0WithoutHorizontalLines.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/standalone/Example0WithoutHorizontalLines.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.knowm.xchart.demo.charts.plot.lines; +package org.knowm.xchart.standalone; import java.util.ArrayList; import java.util.List; diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/plot/lines/Example0WithoutVerticalAndHorizontalLines.java b/xchart-demo/src/main/java/org/knowm/xchart/standalone/Example0WithoutVerticalAndHorizontalLines.java similarity index 97% rename from xchart-demo/src/main/java/org/knowm/xchart/demo/charts/plot/lines/Example0WithoutVerticalAndHorizontalLines.java rename to xchart-demo/src/main/java/org/knowm/xchart/standalone/Example0WithoutVerticalAndHorizontalLines.java index c2342e8562decc5afd2eac88ee190424e4410a76..9463c65da6623c08f78c771c513fdfd3e5075f54 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/plot/lines/Example0WithoutVerticalAndHorizontalLines.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/standalone/Example0WithoutVerticalAndHorizontalLines.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.knowm.xchart.demo.charts.plot.lines; +package org.knowm.xchart.standalone; import java.util.ArrayList; import java.util.List; diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/plot/lines/Example0WithoutVerticalLines.java b/xchart-demo/src/main/java/org/knowm/xchart/standalone/Example0WithoutVerticalLines.java similarity index 97% rename from xchart-demo/src/main/java/org/knowm/xchart/demo/charts/plot/lines/Example0WithoutVerticalLines.java rename to xchart-demo/src/main/java/org/knowm/xchart/standalone/Example0WithoutVerticalLines.java index 645cb6da8b9ba7b367bf3d3342342306e93c8c5d..4602df17ca10c9e4e1be665f7a18862e068b335c 100644 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/plot/lines/Example0WithoutVerticalLines.java +++ b/xchart-demo/src/main/java/org/knowm/xchart/standalone/Example0WithoutVerticalLines.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.knowm.xchart.demo.charts.plot.lines; +package org.knowm.xchart.standalone; import java.util.ArrayList; import java.util.List; diff --git a/xchart/src/main/java/org/knowm/xchart/Chart.java b/xchart/src/main/java/org/knowm/xchart/Chart.java index b19f2f09632c3592cf11f2cdbdadadd333df5841..d8714285ca14ffb32f76540f4ffdc6115eabd8e2 100644 --- a/xchart/src/main/java/org/knowm/xchart/Chart.java +++ b/xchart/src/main/java/org/knowm/xchart/Chart.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.Map; import org.knowm.xchart.StyleManager.ChartTheme; -import org.knowm.xchart.internal.chartpart.ChartPainter; +import org.knowm.xchart.internal.chartpart.ChartInternal; import org.knowm.xchart.internal.style.Theme; /** @@ -32,7 +32,10 @@ import org.knowm.xchart.internal.style.Theme; */ public class Chart { - private final ChartPainter chartPainter; + /** + * Hides ugly details mostly related to painting the chart and managing the added series. Not to be exposed to outside. + */ + private final ChartInternal chartInternal; /** * Constructor @@ -42,7 +45,7 @@ public class Chart { */ public Chart(int width, int height) { - chartPainter = new ChartPainter(width, height); + chartInternal = new ChartInternal(width, height); } /** @@ -66,8 +69,8 @@ public class Chart { */ public Chart(int width, int height, Theme theme) { - chartPainter = new ChartPainter(width, height); - chartPainter.getStyleManager().setTheme(theme); + chartInternal = new ChartInternal(width, height); + chartInternal.getStyleManager().setTheme(theme); } /** @@ -91,7 +94,7 @@ public class Chart { */ public void paint(Graphics2D g, int width, int height) { - chartPainter.paint(g, width, height); + chartInternal.paint(g, width, height); } /** @@ -99,11 +102,25 @@ public class Chart { */ public void paint(Graphics2D g) { - chartPainter.paint(g); + chartInternal.paint(g); } /** - * Add a series to the chart using Collections + * Add a series for a X-Y type chart using Lists with error bars + * + * @param seriesName + * @param xData the X-Axis data + * @param yData the Y-Axis data + * @param errorBars the error bar data + * @return A Series object that you can set properties on + */ + public Series addSeries(String seriesName, List<?> xData, List<? extends Number> yData, List<? extends Number> errorBars) { + + return chartInternal.addSeries(seriesName, xData, yData, errorBars); + } + + /** + * Add a series for a X-Y type chart using Lists * * @param seriesName * @param xData the X-Axis data @@ -112,11 +129,11 @@ public class Chart { */ public Series addSeries(String seriesName, List<?> xData, List<? extends Number> yData) { - return chartPainter.getAxisPair().addSeries(seriesName, xData, yData, null); + return addSeries(seriesName, xData, yData, null); } /** - * Add a Number series to the chart using Collections with error bars + * Add a series for a Category type chart using Lists with error bars * * @param seriesName * @param xData the X-Axis data @@ -124,13 +141,38 @@ public class Chart { * @param errorBars the error bar data * @return A Series object that you can set properties on */ - public Series addSeries(String seriesName, List<?> xData, List<? extends Number> yData, List<? extends Number> errorBars) { + public Series addCategorySeries(String seriesName, List<?> xData, List<? extends Number> yData, List<? extends Number> errorBars) { + + return chartInternal.addCategorySeries(seriesName, xData, yData, errorBars); + } + + /** + * Add a series for a Category type chart using Lists + * + * @param seriesName + * @param xData the X-Axis data + * @param yData the Y-Axis data + * @return A Series object that you can set properties on + */ + public Series addCategorySeries(String seriesName, List<?> xData, List<? extends Number> yData) { + + return addCategorySeries(seriesName, xData, yData, null); + } + + /** + * Add a series for a Pie type chart + * + * @param seriesName + * @param value + * @return + */ + public Series addPieSeries(String seriesName, Number value) { - return chartPainter.getAxisPair().addSeries(seriesName, xData, yData, errorBars); + return chartInternal.addPieSeries(seriesName, value); } /** - * Add a series to the chart using double arrays + * Add a series for a X-Y type chart using using double arrays * * @param seriesName * @param xData the X-Axis data @@ -143,7 +185,7 @@ public class Chart { } /** - * Add a series to the chart using double arrays with error bars + * Add a series for a X-Y type chart using using double arrays with error bars * * @param seriesName * @param xData the X-Axis data @@ -172,11 +214,11 @@ public class Chart { } } - return chartPainter.getAxisPair().addSeries(seriesName, xDataNumber, yDataNumber, errorBarDataNumber); + return addSeries(seriesName, xDataNumber, yDataNumber, errorBarDataNumber); } /** - * Add a series to the chart using int arrays + * Add a series for a X-Y type chart using using int arrays * * @param seriesName * @param xData the X-Axis data @@ -189,7 +231,7 @@ public class Chart { } /** - * Add a series to the chart using int arrays with error bars + * Add a series for a X-Y type chart using using int arrays with error bars * * @param seriesName * @param xData the X-Axis data @@ -218,7 +260,7 @@ public class Chart { } } - return chartPainter.getAxisPair().addSeries(seriesName, xDataNumber, yDataNumber, errorBarDataNumber); + return addSeries(seriesName, xDataNumber, yDataNumber, errorBarDataNumber); } /** @@ -228,7 +270,7 @@ public class Chart { */ public void setChartTitle(String title) { - chartPainter.getChartTitle().setText(title); + chartInternal.getChartTitle().setText(title); } /** @@ -238,7 +280,7 @@ public class Chart { */ public void setXAxisTitle(String title) { - chartPainter.getAxisPair().getXAxis().getAxisTitle().setText(title); + chartInternal.getAxisPair().getXAxis().getAxisTitle().setText(title); } /** @@ -248,7 +290,7 @@ public class Chart { */ public void setYAxisTitle(String title) { - chartPainter.getAxisPair().getYAxis().getAxisTitle().setText(title); + chartInternal.getAxisPair().getYAxis().getAxisTitle().setText(title); } /** @@ -258,22 +300,22 @@ public class Chart { */ public StyleManager getStyleManager() { - return chartPainter.getStyleManager(); + return chartInternal.getStyleManager(); } public int getWidth() { - return chartPainter.getWidth(); + return chartInternal.getWidth(); } public int getHeight() { - return chartPainter.getHeight(); + return chartInternal.getHeight(); } public Map<String, Series> getSeriesMap() { - return chartPainter.getAxisPair().getSeriesMap(); + return chartInternal.getSeriesMap(); } } diff --git a/xchart/src/main/java/org/knowm/xchart/QuickChart.java b/xchart/src/main/java/org/knowm/xchart/QuickChart.java index 2b47a647b30b9db734b3736e90147ce712855257..bf795a2d5c8517e6f2441cff154ec84be09cd6f8 100644 --- a/xchart/src/main/java/org/knowm/xchart/QuickChart.java +++ b/xchart/src/main/java/org/knowm/xchart/QuickChart.java @@ -105,7 +105,7 @@ public final class QuickChart { * @param yData A Collection containing Y-Axis data * @return a Chart Object */ - public static Chart getChart(String chartTitle, String xTitle, String yTitle, String seriesName, List<Number> xData, List<Number> yData) { + public static Chart getChart(String chartTitle, String xTitle, String yTitle, String seriesName, List<? extends Number> xData, List<? extends Number> yData) { // Create Chart Chart chart = new Chart(WIDTH, HEIGHT); diff --git a/xchart/src/main/java/org/knowm/xchart/Series.java b/xchart/src/main/java/org/knowm/xchart/Series.java index f5d1d66f0654d02a8aafb82a1a2bfa342aa400d3..574c71cbcbd3540d2e3acb3d2e5816ac257656e7 100644 --- a/xchart/src/main/java/org/knowm/xchart/Series.java +++ b/xchart/src/main/java/org/knowm/xchart/Series.java @@ -35,9 +35,11 @@ import org.knowm.xchart.internal.style.SeriesColorMarkerLineStyle; public class Series { public enum SeriesType { - Line, Area + Line, Scatter, Area, Bar, Pie } + private SeriesType seriesType = null; + private String name = ""; private List<?> xData; @@ -46,8 +48,6 @@ public class Series { private List<? extends Number> yData; private AxisType yAxisType; - private SeriesType seriesType; - private List<? extends Number> errorBars; /** the minimum value of axis range */ @@ -108,6 +108,7 @@ public class Series { stroke = seriesColorMarkerLineStyle.getStroke(); calculateMinMax(); + } /** diff --git a/xchart/src/main/java/org/knowm/xchart/SeriesColor.java b/xchart/src/main/java/org/knowm/xchart/SeriesColor.java index 71444a2d0971b5bc924847585d565eaacb323144..756d504f80a25decf6fe29db7ffd3283f430f419 100644 --- a/xchart/src/main/java/org/knowm/xchart/SeriesColor.java +++ b/xchart/src/main/java/org/knowm/xchart/SeriesColor.java @@ -20,78 +20,37 @@ import java.awt.Color; /** * Pre-defined Colors used for Series Lines and Markers - * + * * @author timmolter */ -public enum SeriesColor { - - /** BLUE */ - BLUE(0, new Color(0, 55, 255, 180)), - - /** ORANGE */ - ORANGE(1, new Color(255, 172, 0, 180)), - - /** PURPLE */ - PURPLE(2, new Color(128, 0, 255, 180)), - - /** GREEN */ - GREEN(3, new Color(0, 205, 0, 180)), - - /** RED */ - RED(4, new Color(205, 0, 0, 180)), - - /** YELLOW */ - YELLOW(5, new Color(255, 215, 0, 180)), - - /** MAGENTA */ - MAGENTA(6, new Color(255, 0, 255, 180)), - - /** PINK */ - PINK(7, new Color(255, 166, 201, 180)), - - /** LIGHT_GREY */ - LIGHT_GREY(8, new Color(207, 207, 207, 180)), - - /** CYAN */ - CYAN(9, new Color(0, 255, 255, 180)), - - /** BROWN */ - BROWN(10, new Color(102, 56, 10, 180)), - - /** BLACK */ - BLACK(11, new Color(0, 0, 0, 180)); - - /** The index */ - private int index; +public class SeriesColor { /** The AWT Color */ private Color color; /** * Constructor - * - * @param index + * * @param color */ - private SeriesColor(int index, Color color) { + public SeriesColor(Color color) { - this.index = index; this.color = color; } /** - * Gets the SeriesColor's index - * - * @return + * Constructor + * + * @param color */ - public Integer getIndex() { + public SeriesColor(int r, int g, int b, int a) { - return index; + this.color = new Color(r, g, b, a); } /** * Gets the SeriesColor's AWT Color - * + * * @return the AWT Color */ public Color getColor() { @@ -99,15 +58,15 @@ public enum SeriesColor { return color; } - /** - * get the AWT Color given a SeriesColor - * - * @param seriesColor - * @return the AWT Color - */ - public Color getAWTColor(SeriesColor seriesColor) { - - return seriesColor.color; - } + // /** + // * get the AWT Color given a SeriesColor + // * + // * @param seriesColor + // * @return the AWT Color + // */ + // public Color getAWTColor(SeriesColor seriesColor) { + // + // return seriesColor.color; + // } } diff --git a/xchart/src/main/java/org/knowm/xchart/StyleManager.java b/xchart/src/main/java/org/knowm/xchart/StyleManager.java index a2f4f3ef8ec2495e707419e25d1a815e4b9b3478..b7c0acfbf2bee32930fde289f17e04d8ec9fe327 100644 --- a/xchart/src/main/java/org/knowm/xchart/StyleManager.java +++ b/xchart/src/main/java/org/knowm/xchart/StyleManager.java @@ -24,6 +24,7 @@ import java.util.TimeZone; import org.knowm.xchart.internal.style.GGPlot2Theme; import org.knowm.xchart.internal.style.MatlabTheme; +import org.knowm.xchart.internal.style.SeriesColorMarkerLineStyleCycler; import org.knowm.xchart.internal.style.Theme; import org.knowm.xchart.internal.style.XChartTheme; @@ -34,12 +35,9 @@ import org.knowm.xchart.internal.style.XChartTheme; */ public class StyleManager { - /** - * Note: For Area Charts, the X-Axis data must be in ascending order. - */ public enum ChartType { - Line, Scatter, Area, Bar + Line, Scatter, Area, Bar, Pie } public enum LegendPosition { @@ -79,6 +77,7 @@ public class StyleManager { private Color chartBackgroundColor; public Color chartFontColor; private int chartPadding; + private SeriesColorMarkerLineStyleCycler seriesColorMarkerLineStyleCycler; // Chart Title /////////////////////////////// private Font chartTitleFont; @@ -171,6 +170,7 @@ public class StyleManager { chartBackgroundColor = theme.getChartBackgroundColor(); chartFontColor = theme.getChartFontColor(); chartPadding = theme.getChartPadding(); + seriesColorMarkerLineStyleCycler = theme.getSeriesColorMarkerLineStyleCycler(); // Chart Title /////////////////////////////// chartTitleFont = theme.getChartTitleFont(); @@ -325,6 +325,16 @@ public class StyleManager { return chartPadding; } + public SeriesColorMarkerLineStyleCycler getSeriesColorMarkerLineStyleCycler() { + + return seriesColorMarkerLineStyleCycler; + } + + public void setSeriesColorMarkerLineStyleCycler(SeriesColorMarkerLineStyleCycler seriesColorMarkerLineStyleCycler) { + + this.seriesColorMarkerLineStyleCycler = seriesColorMarkerLineStyleCycler; + } + // Chart Title /////////////////////////////// /** @@ -933,7 +943,6 @@ public class StyleManager { this.isPlotGridVerticalLinesVisible = isPlotGridLinesVisible; } - @Deprecated public boolean isPlotGridLinesVisible() { return isPlotGridHorizontalLinesVisible && isPlotGridVerticalLinesVisible; diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Axis.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Axis.java index 572f8493cfd8701e11d8b805445185ff36ce123d..5eeb50756ba62166198d2da11088584c729a94b7 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Axis.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Axis.java @@ -22,9 +22,11 @@ import java.awt.font.FontRenderContext; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; +import java.util.List; import org.knowm.xchart.StyleManager.ChartType; import org.knowm.xchart.StyleManager.LegendPosition; +import org.knowm.xchart.internal.chartpart.ChartInternal.ChartInternalType; /** * Axis @@ -107,6 +109,7 @@ public class Axis implements ChartPart { // System.out.println(min); // System.out.println(max); + // NaN indicates String axis data, so min and max play no role if (this.min == Double.NaN || min < this.min) { this.min = min; } @@ -121,7 +124,7 @@ public class Axis implements ChartPart { protected void setAxisType(AxisType axisType) { if (this.axisType != null && this.axisType != axisType) { - throw new IllegalArgumentException("Date and Number Axes cannot be mixed on the same chart!! "); + throw new IllegalArgumentException("Different Axes (Date, Number, String) cannot be mixed on the same chart!!"); } this.axisType = axisType; } @@ -141,6 +144,12 @@ public class Axis implements ChartPart { // determine Axis bounds if (direction == Direction.Y) { // Y-Axis - gets called first + if (getChartInternal().getChartInternalType() == ChartInternalType.Pie) { + bounds = new Rectangle2D.Double(getChartInternal().getStyleManager().getChartPadding(), getChartInternal().getChartTitle().getSizeHint(), 0, getChartInternal().getHeight() - getChartInternal() + .getChartTitle().getSizeHint() - getChartInternal().getStyleManager().getPlotPadding() - getChartInternal().getStyleManager().getChartPadding()); + return; + } + // first determine the height of // calculate paint zone @@ -150,8 +159,8 @@ public class Axis implements ChartPart { // | // | // ---- - double xOffset = getChartPainter().getStyleManager().getChartPadding(); - double yOffset = getChartPainter().getChartTitle().getSizeHint(); + double xOffset = getChartInternal().getStyleManager().getChartPadding(); + double yOffset = getChartInternal().getChartTitle().getSizeHint(); ///////////////////////// int i = 1; // just twice through is all it takes @@ -162,22 +171,22 @@ public class Axis implements ChartPart { double approximateXAxisWidth = - getChartPainter().getWidth() + getChartInternal().getWidth() - - width // y-axis approx. width + - width // y-axis approx. width - - (getChartPainter().getStyleManager().getLegendPosition() == LegendPosition.OutsideE ? getChartPainter().getChartLegend().getLegendBoxWidth() : 0) + - (getChartInternal().getStyleManager().getLegendPosition() == LegendPosition.OutsideE ? getChartInternal().getChartLegend().getLegendBoxWidth() : 0) - - 2 * getChartPainter().getStyleManager().getChartPadding() + - 2 * getChartInternal().getStyleManager().getChartPadding() - - (getChartPainter().getStyleManager().isYAxisTicksVisible() ? (getChartPainter().getStyleManager().getPlotPadding()) : 0) + - (getChartInternal().getStyleManager().isYAxisTicksVisible() ? (getChartInternal().getStyleManager().getPlotPadding()) : 0) - - (getChartPainter().getStyleManager().getLegendPosition() == LegendPosition.OutsideE && getChartPainter().getStyleManager().isLegendVisible() ? getChartPainter().getStyleManager() - .getChartPadding() : 0) + - (getChartInternal().getStyleManager().getLegendPosition() == LegendPosition.OutsideE && getChartInternal().getStyleManager().isLegendVisible() ? getChartInternal().getStyleManager() + .getChartPadding() : 0) ; - height = getChartPainter().getHeight() - yOffset - axisPair.getXAxis().getXAxisHeightHint(approximateXAxisWidth) - getChartPainter().getStyleManager().getPlotPadding() - getChartPainter() + height = getChartInternal().getHeight() - yOffset - axisPair.getXAxis().getXAxisHeightHint(approximateXAxisWidth) - getChartInternal().getStyleManager().getPlotPadding() - getChartInternal() .getStyleManager().getChartPadding(); width = getYAxisWidthHint(height); @@ -200,7 +209,7 @@ public class Axis implements ChartPart { xOffset = paintZone.getX(); yOffset = paintZone.getY(); - width = (getChartPainter().getStyleManager().isYAxisTitleVisible() ? axisTitle.getBounds().getWidth() : 0) + axisTick.getBounds().getWidth(); + width = (getChartInternal().getStyleManager().isYAxisTitleVisible() ? axisTitle.getBounds().getWidth() : 0) + axisTick.getBounds().getWidth(); height = paintZone.getHeight(); bounds = new Rectangle2D.Double(xOffset, yOffset, width, height); @@ -210,35 +219,42 @@ public class Axis implements ChartPart { } else { // X-Axis + if (getChartInternal().getChartInternalType() == ChartInternalType.Pie) { + bounds = new Rectangle2D.Double(getChartInternal().getStyleManager().getChartPadding(), getChartInternal().getHeight() - getChartInternal().getStyleManager().getChartPadding(), + getChartInternal().getWidth() - getChartInternal().getChartTitle().getSizeHint() - getChartInternal().getStyleManager().getPlotPadding() - (getChartInternal().getStyleManager() + .getLegendPosition() == LegendPosition.OutsideE ? getChartInternal().getChartLegend().getLegendBoxWidth() : 0), 0); + return; + } + // calculate paint zone // |____________________| - double xOffset = axisPair.getYAxis().getBounds().getWidth() + (getChartPainter().getStyleManager().isYAxisTicksVisible() ? getChartPainter().getStyleManager().getPlotPadding() : 0) - + getChartPainter().getStyleManager().getChartPadding(); - double yOffset = axisPair.getYAxis().getBounds().getY() + axisPair.getYAxis().getBounds().getHeight() + getChartPainter().getStyleManager().getPlotPadding(); + double xOffset = axisPair.getYAxis().getBounds().getWidth() + (getChartInternal().getStyleManager().isYAxisTicksVisible() ? getChartInternal().getStyleManager().getPlotPadding() : 0) + + getChartInternal().getStyleManager().getChartPadding(); + double yOffset = axisPair.getYAxis().getBounds().getY() + axisPair.getYAxis().getBounds().getHeight() + getChartInternal().getStyleManager().getPlotPadding(); double width = - getChartPainter().getWidth() + getChartInternal().getWidth() - - axisPair.getYAxis().getBounds().getWidth() // y-axis was already painted + - axisPair.getYAxis().getBounds().getWidth() // y-axis was already painted - - (getChartPainter().getStyleManager().getLegendPosition() == LegendPosition.OutsideE ? getChartPainter().getChartLegend().getLegendBoxWidth() : 0) + - (getChartInternal().getStyleManager().getLegendPosition() == LegendPosition.OutsideE ? getChartInternal().getChartLegend().getLegendBoxWidth() : 0) - - 2 * getChartPainter().getStyleManager().getChartPadding() + - 2 * getChartInternal().getStyleManager().getChartPadding() - - (getChartPainter().getStyleManager().isYAxisTicksVisible() ? (getChartPainter().getStyleManager().getPlotPadding()) : 0) + - (getChartInternal().getStyleManager().isYAxisTicksVisible() ? (getChartInternal().getStyleManager().getPlotPadding()) : 0) - - (getChartPainter().getStyleManager().getLegendPosition() == LegendPosition.OutsideE && getChartPainter().getStyleManager().isLegendVisible() ? getChartPainter().getStyleManager() - .getChartPadding() : 0) + - (getChartInternal().getStyleManager().getLegendPosition() == LegendPosition.OutsideE && getChartInternal().getStyleManager().isLegendVisible() ? getChartInternal().getStyleManager() + .getChartPadding() : 0) ; // double height = this.getXAxisHeightHint(width); // System.out.println("height: " + height); // the Y-Axis was already draw at this point so we know how much vertical room is left for the X-Axis - double height = getChartPainter().getHeight() - axisPair.getYAxis().getBounds().getY() - axisPair.getYAxis().getBounds().getHeight() - getChartPainter().getStyleManager().getChartPadding() - - getChartPainter().getStyleManager().getPlotPadding(); + double height = getChartInternal().getHeight() - axisPair.getYAxis().getBounds().getY() - axisPair.getYAxis().getBounds().getHeight() - getChartInternal().getStyleManager().getChartPadding() + - getChartInternal().getStyleManager().getPlotPadding(); // System.out.println("height2: " + height2); Rectangle2D xAxisRectangle = new Rectangle2D.Double(xOffset, yOffset, width, height); @@ -268,22 +284,27 @@ public class Axis implements ChartPart { */ private double getXAxisHeightHint(double workingSpace) { + if (getChartInternal().getChartInternalType() == ChartInternalType.Pie) { + return 0.0; + } + // Axis title double titleHeight = 0.0; - if (axisTitle.getText() != null && !axisTitle.getText().trim().equalsIgnoreCase("") && getChartPainter().getStyleManager().isXAxisTitleVisible()) { - TextLayout textLayout = new TextLayout(axisTitle.getText(), getChartPainter().getStyleManager().getAxisTitleFont(), new FontRenderContext(null, true, false)); + if (axisTitle.getText() != null && !axisTitle.getText().trim().equalsIgnoreCase("") && getChartInternal().getStyleManager().isXAxisTitleVisible()) { + TextLayout textLayout = new TextLayout(axisTitle.getText(), getChartInternal().getStyleManager().getAxisTitleFont(), new FontRenderContext(null, true, false)); Rectangle2D rectangle = textLayout.getBounds(); - titleHeight = rectangle.getHeight() + getChartPainter().getStyleManager().getAxisTitlePadding(); + titleHeight = rectangle.getHeight() + getChartInternal().getStyleManager().getAxisTitlePadding(); } // Axis tick labels double axisTickLabelsHeight = 0.0; - if (getChartPainter().getStyleManager().isXAxisTicksVisible()) { + if (getChartInternal().getStyleManager().isXAxisTicksVisible()) { // get some real tick labels // System.out.println("XAxisHeightHint"); // System.out.println("workingSpace: " + workingSpace); this.axisTickCalculator = getAxisTickCalculator(workingSpace); + String sampleLabel = ""; // find the longest String in all the labels for (int i = 0; i < axisTickCalculator.getTickLabels().size(); i++) { @@ -295,35 +316,40 @@ public class Axis implements ChartPart { // System.out.println("sampleLabel: " + sampleLabel); // get the height of the label including rotation - TextLayout textLayout = new TextLayout(sampleLabel.length() == 0 ? " " : sampleLabel, getChartPainter().getStyleManager().getAxisTickLabelsFont(), new FontRenderContext(null, true, false)); - AffineTransform rot = getChartPainter().getStyleManager().getXAxisLabelRotation() == 0 ? null : AffineTransform.getRotateInstance(-1 * Math.toRadians(getChartPainter().getStyleManager() + TextLayout textLayout = new TextLayout(sampleLabel.length() == 0 ? " " : sampleLabel, getChartInternal().getStyleManager().getAxisTickLabelsFont(), new FontRenderContext(null, true, false)); + AffineTransform rot = getChartInternal().getStyleManager().getXAxisLabelRotation() == 0 ? null : AffineTransform.getRotateInstance(-1 * Math.toRadians(getChartInternal().getStyleManager() .getXAxisLabelRotation())); Shape shape = textLayout.getOutline(rot); Rectangle2D rectangle = shape.getBounds(); - axisTickLabelsHeight = rectangle.getHeight() + getChartPainter().getStyleManager().getAxisTickPadding() + getChartPainter().getStyleManager().getAxisTickMarkLength(); + axisTickLabelsHeight = rectangle.getHeight() + getChartInternal().getStyleManager().getAxisTickPadding() + getChartInternal().getStyleManager().getAxisTickMarkLength(); } return titleHeight + axisTickLabelsHeight; } private double getYAxisWidthHint(double workingSpace) { + if (getChartInternal().getChartInternalType() == ChartInternalType.Pie) { + return 0.0; + } + // Axis title double titleHeight = 0.0; - if (axisTitle.getText() != null && !axisTitle.getText().trim().equalsIgnoreCase("") && getChartPainter().getStyleManager().isYAxisTitleVisible()) { - TextLayout textLayout = new TextLayout(axisTitle.getText(), getChartPainter().getStyleManager().getAxisTitleFont(), new FontRenderContext(null, true, false)); + if (axisTitle.getText() != null && !axisTitle.getText().trim().equalsIgnoreCase("") && getChartInternal().getStyleManager().isYAxisTitleVisible()) { + TextLayout textLayout = new TextLayout(axisTitle.getText(), getChartInternal().getStyleManager().getAxisTitleFont(), new FontRenderContext(null, true, false)); Rectangle2D rectangle = textLayout.getBounds(); - titleHeight = rectangle.getHeight() + getChartPainter().getStyleManager().getAxisTitlePadding(); + titleHeight = rectangle.getHeight() + getChartInternal().getStyleManager().getAxisTitlePadding(); } // Axis tick labels double axisTickLabelsHeight = 0.0; - if (getChartPainter().getStyleManager().isYAxisTicksVisible()) { + if (getChartInternal().getStyleManager().isYAxisTicksVisible()) { // get some real tick labels // System.out.println("XAxisHeightHint"); // System.out.println("workingSpace: " + workingSpace); this.axisTickCalculator = getAxisTickCalculator(workingSpace); + String sampleLabel = ""; // find the longest String in all the labels for (int i = 0; i < axisTickCalculator.getTickLabels().size(); i++) { @@ -333,46 +359,64 @@ public class Axis implements ChartPart { } // get the height of the label including rotation - TextLayout textLayout = new TextLayout(sampleLabel.length() == 0 ? " " : sampleLabel, getChartPainter().getStyleManager().getAxisTickLabelsFont(), new FontRenderContext(null, true, false)); + TextLayout textLayout = new TextLayout(sampleLabel.length() == 0 ? " " : sampleLabel, getChartInternal().getStyleManager().getAxisTickLabelsFont(), new FontRenderContext(null, true, false)); Rectangle2D rectangle = textLayout.getBounds(); - axisTickLabelsHeight = rectangle.getWidth() + getChartPainter().getStyleManager().getAxisTickPadding() + getChartPainter().getStyleManager().getAxisTickMarkLength(); + axisTickLabelsHeight = rectangle.getWidth() + getChartInternal().getStyleManager().getAxisTickPadding() + getChartInternal().getStyleManager().getAxisTickMarkLength(); } return titleHeight + axisTickLabelsHeight; } private AxisTickCalculator getAxisTickCalculator(double workingSpace) { - if (getDirection() == Direction.X && getChartPainter().getStyleManager().getChartType() == ChartType.Bar) { + // X-Axis + if (getDirection() == Direction.X) { - return new AxisTickBarChartCalculator(getDirection(), workingSpace, getMin(), getMax(), getChartPainter()); + if (getChartInternal().getChartInternalType() == ChartInternalType.Category) { - } - else if (getDirection() == Direction.X && getChartPainter().getStyleManager().isXAxisLogarithmic() && getAxisType() != AxisType.Date) { + List<?> categories = (List<?>) getChartInternal().getSeriesMap().values().iterator().next().getXData(); + AxisType axisType = getChartInternal().getAxisPair().getXAxis().getAxisType(); + return new AxisTickCalculator_Category(getDirection(), workingSpace, categories, axisType, getChartInternal().getStyleManager()); + } + else if (getChartInternal().getChartInternalType() == ChartInternalType.Pie) { + return null; + } + else if (getChartInternal().getChartInternalType() == ChartInternalType.XY && getAxisType() == AxisType.Date) { - return new AxisTickLogarithmicCalculator(getDirection(), workingSpace, getMin(), getMax(), getChartPainter().getStyleManager()); + return new AxisTickCalculator_Date(getDirection(), workingSpace, min, max, getChartInternal().getStyleManager()); + } + else if (getChartInternal().getStyleManager().isXAxisLogarithmic()) { + return new AxisTickCalculator_Logarithmic(getDirection(), workingSpace, min, max, getChartInternal().getStyleManager()); + } + else { + return new AxisTickCalculator_Number(getDirection(), workingSpace, min, max, getChartInternal().getStyleManager()); + + } } - else if (getDirection() == Direction.Y && getChartPainter().getStyleManager().isYAxisLogarithmic() && getAxisType() != AxisType.Date) { - return new AxisTickLogarithmicCalculator(getDirection(), workingSpace, getMin(), getMax(), getChartPainter().getStyleManager()); + // Y-Axis + else { - } - else if (getAxisType() == AxisType.Date) { + if (getChartInternal().getChartInternalType() == ChartInternalType.Pie) { + return null; + } + else if (getChartInternal().getStyleManager().isYAxisLogarithmic() && getAxisType() != AxisType.Date) { - return new AxisTickDateCalculator(getDirection(), workingSpace, getMin(), getMax(), getChartPainter().getStyleManager()); + return new AxisTickCalculator_Logarithmic(getDirection(), workingSpace, min, max, getChartInternal().getStyleManager()); + } + else { + return new AxisTickCalculator_Number(getDirection(), workingSpace, min, max, getChartInternal().getStyleManager()); + } } - else { // number - return new AxisTickNumericalCalculator(getDirection(), workingSpace, getMin(), getMax(), getChartPainter().getStyleManager()); - } } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return axisPair.getChartPainter(); + return axisPair.getChartInternal(); } // Getters ///////////////////////////////////////////////// @@ -382,12 +426,12 @@ public class Axis implements ChartPart { return axisType; } - public double getMin() { + protected double getMin() { return min; } - public double getMax() { + protected double getMax() { return max; } @@ -422,4 +466,48 @@ public class Axis implements ChartPart { return this.axisTickCalculator; } + public void overrideMinMax() { + + if (direction == Direction.X) { // X-Axis + + double overrideXAxisMinValue = min; + double overrideXAxisMaxValue = max; + + // override min and maxValue if specified + if (getChartInternal().getStyleManager().getXAxisMin() != null && getChartInternal().getStyleManager().getChartType() != ChartType.Bar) { // bar chart cannot have a max or min TODO is this true? + overrideXAxisMinValue = getChartInternal().getStyleManager().getXAxisMin(); + } + if (getChartInternal().getStyleManager().getXAxisMax() != null && getChartInternal().getStyleManager().getChartType() != ChartType.Bar) { // bar chart cannot have a max or min + overrideXAxisMaxValue = getChartInternal().getStyleManager().getXAxisMax(); + } + min = overrideXAxisMinValue; + max = overrideXAxisMaxValue; + } + else { + + double overrideYAxisMinValue = min; + double overrideYAxisMaxValue = max; + // override min/max value for bar charts' Y-Axis + if (getChartInternal().getStyleManager().getChartType() == ChartType.Bar) { // this is the Y-Axis for a bar chart + if (min > 0.0 && max > 0.0) { + overrideYAxisMinValue = 0.0; + } + if (min < 0.0 && max < 0.0) { + overrideYAxisMaxValue = 0.0; + } + } + + // override min and maxValue if specified + if (getChartInternal().getStyleManager().getYAxisMin() != null) { + overrideYAxisMinValue = getChartInternal().getStyleManager().getYAxisMin(); + } + if (getChartInternal().getStyleManager().getYAxisMax() != null) { + overrideYAxisMaxValue = getChartInternal().getStyleManager().getYAxisMax(); + } + min = overrideYAxisMinValue; + max = overrideYAxisMaxValue; + } + + } + } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisPair.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisPair.java index a874dd98711f64746d750f392ae26f0000ac4149..ca45d6ffa933006334189210a0c874a3a8a8d5bd 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisPair.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisPair.java @@ -17,18 +17,7 @@ package org.knowm.xchart.internal.chartpart; import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.knowm.xchart.Series; -import org.knowm.xchart.StyleManager.ChartType; -import org.knowm.xchart.internal.chartpart.Axis.AxisType; -import org.knowm.xchart.internal.style.SeriesColorMarkerLineStyleCycler; +import java.awt.geom.Rectangle2D; /** * @author timmolter @@ -36,111 +25,25 @@ import org.knowm.xchart.internal.style.SeriesColorMarkerLineStyleCycler; public class AxisPair implements ChartPart { /** parent */ - private final ChartPainter chartPainter; - - private Map<String, Series> seriesMap = new LinkedHashMap<String, Series>(); + private final ChartInternal chartInternal; private Axis xAxis; private Axis yAxis; - private SeriesColorMarkerLineStyleCycler seriesColorMarkerLineStyleCycler = new SeriesColorMarkerLineStyleCycler(); - /** * Constructor * - * @param the parent chartPainter + * @param the parent chartInternal */ - public AxisPair(ChartPainter chartPainter) { + public AxisPair(ChartInternal chartInternal) { - this.chartPainter = chartPainter; + this.chartInternal = chartInternal; // add axes xAxis = new Axis(this, Axis.Direction.X); yAxis = new Axis(this, Axis.Direction.Y); } - /** - * @param seriesName - * @param xData - * @param yData - * @param errorBars - * @return Series - */ - public Series addSeries(String seriesName, List<?> xData, List<? extends Number> yData, List<? extends Number> errorBars) { - - // Sanity checks - if (seriesName == null) { - throw new IllegalArgumentException("Series Name cannot be null!!!"); - } - if (yData == null) { - throw new IllegalArgumentException("Y-Axis data cannot be null!!!"); - } - if (yData.size() == 0) { - throw new IllegalArgumentException("Y-Axis data cannot be empty!!!"); - } - if (xData != null && xData.size() == 0) { - throw new IllegalArgumentException("X-Axis data cannot be empty!!!"); - } - // Sanity check - if (errorBars != null && errorBars.size() != yData.size()) { - throw new IllegalArgumentException("errorbars and Y-Axis sizes are not the same!!!"); - } - - Series series = null; - if (xData != null) { - - // Sanity check - if (xData.size() != yData.size()) { - throw new IllegalArgumentException("X and Y-Axis sizes are not the same!!!"); - } - // inspect the series to see what kind of data it contains (Number, Date or String) - Iterator<?> itr = xData.iterator(); - Object dataPoint = itr.next(); - if (dataPoint instanceof Number) { - xAxis.setAxisType(AxisType.Number); - } - else if (dataPoint instanceof Date) { - xAxis.setAxisType(AxisType.Date); - } - else if (dataPoint instanceof String) { - if (getChartPainter().getStyleManager().getChartType() != ChartType.Bar) { - throw new RuntimeException("X-Axis data types of String can only be used for Bar Charts!!!"); - } - xAxis.setAxisType(AxisType.String); - } - else { - throw new RuntimeException("Series data must be either Number, Date or String type!!!"); - } - yAxis.setAxisType(AxisType.Number); - series = new Series(seriesName, xData, xAxis.getAxisType(), yData, yAxis.getAxisType(), errorBars, seriesColorMarkerLineStyleCycler.getNextSeriesColorMarkerLineStyle()); - } - else { // generate xData - List<Double> generatedXData = new ArrayList<Double>(); - for (int i = 1; i < yData.size() + 1; i++) { - generatedXData.add((double) i); - } - xAxis.setAxisType(AxisType.Number); - yAxis.setAxisType(AxisType.Number); - 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); - } - - if (seriesMap.keySet().contains(seriesName)) { - throw new IllegalArgumentException("Series name >" + seriesName + "< has already been used. Use unique names for each series!!!"); - } - - seriesMap.put(seriesName, series); - - return series; - } - @Override public void paint(Graphics2D g) { @@ -149,24 +52,19 @@ public class AxisPair implements ChartPart { } @Override - public Rectangle getBounds() { + public Rectangle2D getBounds() { return null; // should never be called } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return chartPainter; + return chartInternal; } // Getters ///////////////////////////////////////////////// - public Map<String, Series> getSeriesMap() { - - return seriesMap; - } - public Axis getXAxis() { return xAxis; diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTick.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTick.java index b99262b074b7d09a23ff2fc12bd56421d38629ec..469d10c010484f38d8dced2e029b6d291f129a5b 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTick.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTick.java @@ -57,35 +57,35 @@ public class AxisTick implements ChartPart { @Override public void paint(Graphics2D g) { - double workingSpace = 0.0; - // Y-Axis - if (axis.getDirection() == Axis.Direction.Y) { - workingSpace = axis.getPaintZone().getHeight(); // number of pixels the axis has to work with for drawing AxisTicks - // System.out.println("workingspace= " + workingSpace); - } - // X-Axis - else if (axis.getDirection() == Axis.Direction.X) { - workingSpace = axis.getPaintZone().getWidth(); // number of pixels the axis has to work with for drawing AxisTicks - // System.out.println("workingspace= " + workingSpace); - } - + // double workingSpace = 0.0; + // // Y-Axis + // if (axis.getDirection() == Axis.Direction.Y) { + // workingSpace = axis.getPaintZone().getHeight(); // number of pixels the axis has to work with for drawing AxisTicks + // // System.out.println("workingspace= " + workingSpace); + // } + // // X-Axis + // else if (axis.getDirection() == Axis.Direction.X) { + // workingSpace = axis.getPaintZone().getWidth(); // number of pixels the axis has to work with for drawing AxisTicks + // // System.out.println("workingspace= " + workingSpace); + // } + // // System.out.println("AxisTick: " + axis.getDirection()); // System.out.println("workingSpace: " + workingSpace); - if (axis.getDirection() == Axis.Direction.Y && getChartPainter().getStyleManager().isYAxisTicksVisible()) { + if (axis.getDirection() == Axis.Direction.Y && getChartInternal().getStyleManager().isYAxisTicksVisible()) { axisTickLabels.paint(g); axisTickMarks.paint(g); bounds = new Rectangle2D.Double( - axisTickLabels.getBounds().getX(), + axisTickLabels.getBounds().getX(), - axisTickLabels.getBounds().getY(), + axisTickLabels.getBounds().getY(), - axisTickLabels.getBounds().getWidth() + getChartPainter().getStyleManager().getAxisTickPadding() + axisTickMarks.getBounds().getWidth(), + axisTickLabels.getBounds().getWidth() + getChartInternal().getStyleManager().getAxisTickPadding() + axisTickMarks.getBounds().getWidth(), - axisTickMarks.getBounds().getHeight() + axisTickMarks.getBounds().getHeight() ); @@ -93,13 +93,22 @@ public class AxisTick implements ChartPart { // g.draw(bounds); } - else if (axis.getDirection() == Axis.Direction.X && getChartPainter().getStyleManager().isXAxisTicksVisible()) { + else if (axis.getDirection() == Axis.Direction.X && getChartInternal().getStyleManager().isXAxisTicksVisible()) { axisTickLabels.paint(g); axisTickMarks.paint(g); - bounds = new Rectangle2D.Double(axisTickMarks.getBounds().getX(), axisTickMarks.getBounds().getY(), axisTickLabels.getBounds().getWidth(), axisTickMarks.getBounds().getHeight() - + getChartPainter().getStyleManager().getAxisTickPadding() + axisTickLabels.getBounds().getHeight()); + bounds = new Rectangle2D.Double( + + axisTickMarks.getBounds().getX(), + + axisTickMarks.getBounds().getY(), + + axisTickLabels.getBounds().getWidth(), + + axisTickMarks.getBounds().getHeight() + getChartInternal().getStyleManager().getAxisTickPadding() + axisTickLabels.getBounds().getHeight() + + ); // g.setColor(Color.red); // g.draw(bounds); @@ -109,9 +118,9 @@ public class AxisTick implements ChartPart { } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return axis.getChartPainter(); + return axis.getChartInternal(); } // Getters ///////////////////////////////////////////////// @@ -126,13 +135,4 @@ public class AxisTick implements ChartPart { return axisTickLabels; } - // public List<Double> getTickLocations() { - // - // return axisTickCalculator.getTickLocations(); - // } - // - // public List<String> getTickLabels() { - // - // return axisTickCalculator.getTickLabels(); - // } } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator.java index a6d1672d606054ce561c7f9e90ef56e1e81a0567..5a41416987210bec93779bd6d1cff4ece74e8db0 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator.java @@ -25,8 +25,6 @@ import java.util.LinkedList; import java.util.List; import org.knowm.xchart.StyleManager; -import org.knowm.xchart.StyleManager.ChartType; -import org.knowm.xchart.internal.Utils; import org.knowm.xchart.internal.chartpart.Axis.Direction; /** @@ -61,40 +59,10 @@ public abstract class AxisTickCalculator { */ public AxisTickCalculator(Direction axisDirection, double workingSpace, double minValue, double maxValue, StyleManager styleManager) { - // override min/max value for bar charts' Y-Axis - double overrideMinValue = minValue; - double overrideMaxValue = maxValue; - if (styleManager.getChartType() == ChartType.Bar && axisDirection == Direction.Y) { // this is the Y-Axis for a bar chart - if (minValue > 0.0 && maxValue > 0.0) { - overrideMinValue = 0.0; - } - if (minValue < 0.0 && maxValue < 0.0) { - overrideMaxValue = 0.0; - } - } - - if (styleManager.getChartType() == ChartType.Bar && styleManager.isYAxisLogarithmic()) { - int logMin = (int) Math.floor(Math.log10(minValue)); - overrideMinValue = Utils.pow(10, logMin); - } - - // override min and maxValue if specified - if (axisDirection == Direction.X && styleManager.getXAxisMin() != null && styleManager.getChartType() != ChartType.Bar) { // bar chart cannot have a max or min - overrideMinValue = styleManager.getXAxisMin(); - } - if (axisDirection == Direction.Y && styleManager.getYAxisMin() != null) { - overrideMinValue = styleManager.getYAxisMin(); - } - if (axisDirection == Direction.X && styleManager.getXAxisMax() != null && styleManager.getChartType() != ChartType.Bar) { // bar chart cannot have a max or min - overrideMaxValue = styleManager.getXAxisMax(); - } - if (axisDirection == Direction.Y && styleManager.getYAxisMax() != null) { - overrideMaxValue = styleManager.getYAxisMax(); - } this.axisDirection = axisDirection; this.workingSpace = workingSpace; - this.minValue = overrideMinValue; - this.maxValue = overrideMaxValue; + this.minValue = minValue; + this.maxValue = maxValue; this.styleManager = styleManager; } @@ -104,7 +72,7 @@ public abstract class AxisTickCalculator { * @param gridStep * @return */ - double getFirstPosition(double gridStep) { + double getFirstPosition(double gridStep) { // System.out.println("******"); @@ -129,7 +97,7 @@ public abstract class AxisTickCalculator { * @param tickSpacingHint * @return */ - boolean willLabelsFitInTickSpaceHint(List<String> tickLabels, int tickSpacingHint) { + boolean willLabelsFitInTickSpaceHint(List<String> tickLabels, int tickSpacingHint) { // Assume that for Y-Axis the ticks will all fit based on their tickSpace hint because the text is usually horizontal and "short". This more applies to the X-Axis. if (this.axisDirection == Direction.Y) { diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickBarChartCalculator.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Category.java similarity index 66% rename from xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickBarChartCalculator.java rename to xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Category.java index bb5e343afeeda4b30ebf4ff87d047ca44658b142..c0bf69b19b80b1365c9015540a66fc7dfa2ff992 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickBarChartCalculator.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Category.java @@ -21,34 +21,35 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; -import org.knowm.xchart.Series; +import org.knowm.xchart.StyleManager; import org.knowm.xchart.internal.Utils; import org.knowm.xchart.internal.chartpart.Axis.AxisType; import org.knowm.xchart.internal.chartpart.Axis.Direction; /** - * This class encapsulates the logic to generate the axis tick mark and axis tick label data for rendering the axis ticks for decimal axes + * This class encapsulates the logic to generate the axis tick mark and axis tick label data for rendering the axis ticks for String axes * * @author timmolter */ -public class AxisTickBarChartCalculator extends AxisTickCalculator { +public class AxisTickCalculator_Category extends AxisTickCalculator { /** * Constructor * * @param axisDirection * @param workingSpace - * @param minValue - * @param maxValue + * @param categories + * @param axisType * @param styleManager */ - public AxisTickBarChartCalculator(Direction axisDirection, double workingSpace, double minValue, double maxValue, ChartPainter chart) { + public AxisTickCalculator_Category(Direction axisDirection, double workingSpace, List<?> categories, AxisType axisType, StyleManager styleManager) { - super(axisDirection, workingSpace, minValue, maxValue, chart.getStyleManager()); - calculate(chart); + super(axisDirection, workingSpace, Double.NaN, Double.NaN, styleManager); + + calculate(categories, axisType); } - private void calculate(ChartPainter chartPainter) { + private void calculate(List<?> categories, AxisType axisType) { // tick space - a percentage of the working space available for ticks int tickSpace = (int) (styleManager.getAxisTickSpacePercentage() * workingSpace); // in plot space @@ -56,18 +57,6 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { // where the tick should begin in the working space in pixels double margin = Utils.getTickStartOffset(workingSpace, tickSpace); - List<?> categories = (List<?>) chartPainter.getAxisPair().getSeriesMap().values().iterator().next().getXData(); - - // verify all series have exactly the same xAxis - if (chartPainter.getAxisPair().getSeriesMap().size() > 1) { - - for (Series series : chartPainter.getAxisPair().getSeriesMap().values()) { - if (!series.getXData().equals(categories)) { - throw new IllegalArgumentException("X-Axis data must exactly match all other Series X-Axis data for Bar Charts!!"); - } - } - } - // generate all tickLabels and tickLocations from the first to last position double gridStep = (tickSpace / (double) categories.size()); double firstPosition = gridStep / 2.0; @@ -75,10 +64,10 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { // set up String formatters that may be encountered NumberFormatter numberFormatter = null; SimpleDateFormat simpleDateformat = null; - if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) { + if (axisType == AxisType.Number) { numberFormatter = new NumberFormatter(styleManager); } - else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Date) { + else if (axisType == AxisType.Date) { if (styleManager.getDatePattern() == null) { throw new RuntimeException("You need to set the Date Formatting Pattern!!!"); } @@ -89,15 +78,15 @@ public class AxisTickBarChartCalculator extends AxisTickCalculator { int counter = 0; for (Object category : categories) { - if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.String) { + if (axisType == AxisType.String) { tickLabels.add(category.toString()); double tickLabelPosition = margin + firstPosition + gridStep * counter++; tickLocations.add(tickLabelPosition); } - else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Number) { + else if (axisType == AxisType.Number) { tickLabels.add(numberFormatter.formatNumber(new BigDecimal(category.toString()), minValue, maxValue, axisDirection)); } - else if (chartPainter.getAxisPair().getXAxis().getAxisType() == AxisType.Date) { + else if (axisType == AxisType.Date) { tickLabels.add(simpleDateformat.format((((Date) category).getTime()))); } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickDateCalculator.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Date.java similarity index 97% rename from xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickDateCalculator.java rename to xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Date.java index c76ba457243a747305fa18e138e293970f5aa744..4b641abc0ce609191e9e69f78a0d005b1d9545a6 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickDateCalculator.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Date.java @@ -30,7 +30,7 @@ import org.knowm.xchart.internal.chartpart.Axis.Direction; * * @author timmolter */ -public class AxisTickDateCalculator extends AxisTickCalculator { +public class AxisTickCalculator_Date extends AxisTickCalculator { private static final long MILLIS_SCALE = TimeUnit.MILLISECONDS.toMillis(1L); private static final long SEC_SCALE = TimeUnit.SECONDS.toMillis(1L); @@ -108,7 +108,7 @@ public class AxisTickDateCalculator extends AxisTickCalculator { * @param maxValue * @param styleManager */ - public AxisTickDateCalculator(Direction axisDirection, double workingSpace, double minValue, double maxValue, StyleManager styleManager) { + public AxisTickCalculator_Date(Direction axisDirection, double workingSpace, double minValue, double maxValue, StyleManager styleManager) { super(axisDirection, workingSpace, minValue, maxValue, styleManager); diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickLogarithmicCalculator.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Logarithmic.java similarity index 82% rename from xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickLogarithmicCalculator.java rename to xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Logarithmic.java index ce9bac51199c0a011423d0fb1dcecd366e733f8e..28ef661a2f0a0f4271e5a97e2b781cdcfa9db875 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickLogarithmicCalculator.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Logarithmic.java @@ -27,7 +27,7 @@ import org.knowm.xchart.internal.chartpart.Axis.Direction; * * @author timmolter */ -public class AxisTickLogarithmicCalculator extends AxisTickCalculator { +public class AxisTickCalculator_Logarithmic extends AxisTickCalculator { NumberFormatter numberFormatter = null; @@ -40,7 +40,7 @@ public class AxisTickLogarithmicCalculator extends AxisTickCalculator { * @param maxValue * @param styleManager */ - public AxisTickLogarithmicCalculator(Direction axisDirection, double workingSpace, double minValue, double maxValue, StyleManager styleManager) { + public AxisTickCalculator_Logarithmic(Direction axisDirection, double workingSpace, double minValue, double maxValue, StyleManager styleManager) { super(axisDirection, workingSpace, minValue, maxValue, styleManager); numberFormatter = new NumberFormatter(styleManager); @@ -74,18 +74,18 @@ public class AxisTickLogarithmicCalculator extends AxisTickCalculator { // System.out.println("logMin: " + logMin); // System.out.println("logMax: " + logMax); - if (axisDirection == Direction.Y && styleManager.getYAxisMin() != null) { - logMin = (int) (Math.log10(styleManager.getYAxisMin())); // no floor - } - if (axisDirection == Direction.Y && styleManager.getYAxisMax() != null) { - logMax = (int) (Math.log10(styleManager.getYAxisMax())); // no floor - } - if (axisDirection == Direction.X && styleManager.getXAxisMin() != null) { - logMin = (int) (Math.log10(styleManager.getXAxisMin())); // no floor - } - if (axisDirection == Direction.X && styleManager.getXAxisMax() != null) { - logMax = (int) (Math.log10(styleManager.getXAxisMax())); // no floor - } + // if (axisDirection == Direction.Y && styleManager.getYAxisMin() != null) { + // logMin = (int) (Math.log10(styleManager.getYAxisMin())); // no floor + // } + // if (axisDirection == Direction.Y && styleManager.getYAxisMax() != null) { + // logMax = (int) (Math.log10(styleManager.getYAxisMax())); // no floor + // } + // if (axisDirection == Direction.X && styleManager.getXAxisMin() != null) { + // logMin = (int) (Math.log10(styleManager.getXAxisMin())); // no floor + // } + // if (axisDirection == Direction.X && styleManager.getXAxisMax() != null) { + // logMax = (int) (Math.log10(styleManager.getXAxisMax())); // no floor + // } double firstPosition = Utils.pow(10, logMin); // System.out.println("firstPosition: " + firstPosition); diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickNumericalCalculator.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Number.java similarity index 96% rename from xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickNumericalCalculator.java rename to xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Number.java index 3b42ed26cd16468779c5e34afb287b66d7971bc3..4cbdce015560734524b693cd22077bb4987d353f 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickNumericalCalculator.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Number.java @@ -28,7 +28,7 @@ import org.knowm.xchart.internal.chartpart.Axis.Direction; * * @author timmolter */ -public class AxisTickNumericalCalculator extends AxisTickCalculator { +public class AxisTickCalculator_Number extends AxisTickCalculator { NumberFormatter numberFormatter = null; @@ -41,7 +41,7 @@ public class AxisTickNumericalCalculator extends AxisTickCalculator { * @param maxValue * @param styleManager */ - public AxisTickNumericalCalculator(Direction axisDirection, double workingSpace, double minValue, double maxValue, StyleManager styleManager) { + public AxisTickCalculator_Number(Direction axisDirection, double workingSpace, double minValue, double maxValue, StyleManager styleManager) { super(axisDirection, workingSpace, minValue, maxValue, styleManager); numberFormatter = new NumberFormatter(styleManager); diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickLabels.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickLabels.java index 90a8b3b0dce833e77d3f24c0399e73270b48902e..89fd605545fbcdfa45a5b859ed4ad34ed82d5fbe 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickLabels.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickLabels.java @@ -55,11 +55,11 @@ public class AxisTickLabels implements ChartPart { @Override public void paint(Graphics2D g) { - g.setFont(getChartPainter().getStyleManager().getAxisTickLabelsFont()); + g.setFont(getChartInternal().getStyleManager().getAxisTickLabelsFont()); - g.setColor(getChartPainter().getStyleManager().getAxisTickLabelsColor()); + g.setColor(getChartInternal().getStyleManager().getAxisTickLabelsColor()); - if (axisTick.getAxis().getDirection() == Axis.Direction.Y && getChartPainter().getStyleManager().isYAxisTicksVisible()) { // Y-Axis + if (axisTick.getAxis().getDirection() == Axis.Direction.Y && getChartInternal().getStyleManager().isYAxisTicksVisible()) { // Y-Axis double xWidth = axisTick.getAxis().getAxisTitle().getBounds().getWidth(); double xOffset = axisTick.getAxis().getAxisTitle().getBounds().getX() + xWidth; @@ -77,7 +77,7 @@ public class AxisTickLabels implements ChartPart { if (tickLabel != null && flippedTickLocation > yOffset && flippedTickLocation < yOffset + height) { // some are null for logarithmic axes FontRenderContext frc = g.getFontRenderContext(); - TextLayout axisLabelTextLayout = new TextLayout(tickLabel, getChartPainter().getStyleManager().getAxisTickLabelsFont(), frc); + TextLayout axisLabelTextLayout = new TextLayout(tickLabel, getChartInternal().getStyleManager().getAxisTickLabelsFont(), frc); Rectangle2D tickLabelBounds = axisLabelTextLayout.getBounds(); double boundWidth = tickLabelBounds.getWidth(); if (boundWidth > maxTickLabelWidth) { @@ -99,7 +99,7 @@ public class AxisTickLabels implements ChartPart { AffineTransform at = new AffineTransform(); double boundWidth = tickLabelBounds.getWidth(); double xPos; - switch (getChartPainter().getStyleManager().getYAxisLabelAlignment()) { + switch (getChartInternal().getStyleManager().getYAxisLabelAlignment()) { case Right: xPos = xOffset + maxTickLabelWidth - boundWidth; break; @@ -124,7 +124,7 @@ public class AxisTickLabels implements ChartPart { } // X-Axis - else if (axisTick.getAxis().getDirection() == Axis.Direction.X && getChartPainter().getStyleManager().isXAxisTicksVisible()) { + else if (axisTick.getAxis().getDirection() == Axis.Direction.X && getChartInternal().getStyleManager().isXAxisTicksVisible()) { double xOffset = axisTick.getAxis().getPaintZone().getX(); double yOffset = axisTick.getAxis().getAxisTitle().getBounds().getY(); @@ -143,18 +143,18 @@ public class AxisTickLabels implements ChartPart { if (tickLabel != null && shiftedTickLocation > xOffset && shiftedTickLocation < xOffset + width) { // some are null for logarithmic axes FontRenderContext frc = g.getFontRenderContext(); - TextLayout textLayout = new TextLayout(tickLabel, getChartPainter().getStyleManager().getAxisTickLabelsFont(), frc); + TextLayout textLayout = new TextLayout(tickLabel, getChartInternal().getStyleManager().getAxisTickLabelsFont(), frc); // System.out.println(textLayout.getOutline(null).getBounds().toString()); // Shape shape = v.getOutline(); - AffineTransform rot = AffineTransform.getRotateInstance(-1 * Math.toRadians(getChartPainter().getStyleManager().getXAxisLabelRotation()), 0, 0); + AffineTransform rot = AffineTransform.getRotateInstance(-1 * Math.toRadians(getChartInternal().getStyleManager().getXAxisLabelRotation()), 0, 0); Shape shape = textLayout.getOutline(rot); Rectangle2D tickLabelBounds = shape.getBounds2D(); AffineTransform orig = g.getTransform(); AffineTransform at = new AffineTransform(); double xPos; - switch (getChartPainter().getStyleManager().getXAxisLabelAlignment()) { + switch (getChartInternal().getStyleManager().getXAxisLabelAlignment()) { case Left: xPos = shiftedTickLocation; break; @@ -166,7 +166,7 @@ public class AxisTickLabels implements ChartPart { xPos = shiftedTickLocation - tickLabelBounds.getWidth() / 2.0; } // System.out.println("tickLabelBounds: " + tickLabelBounds.toString()); - double shiftX = -1 * tickLabelBounds.getX() * Math.sin(Math.toRadians(getChartPainter().getStyleManager().getXAxisLabelRotation())); + double shiftX = -1 * tickLabelBounds.getX() * Math.sin(Math.toRadians(getChartInternal().getStyleManager().getXAxisLabelRotation())); double shiftY = -1 * (tickLabelBounds.getY() + tickLabelBounds.getHeight()); // System.out.println(shiftX); // System.out.println("shiftY: " + shiftY); @@ -200,8 +200,8 @@ public class AxisTickLabels implements ChartPart { } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return axisTick.getChartPainter(); + return axisTick.getChartInternal(); } } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickMarks.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickMarks.java index 53c0c03b9732a948789466227e88b92be7f4c52a..1c05c65bcf158b3760501abc8974966cd5de6f8a 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickMarks.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickMarks.java @@ -51,21 +51,21 @@ public class AxisTickMarks implements ChartPart { @Override public void paint(Graphics2D g) { - g.setColor(getChartPainter().getStyleManager().getAxisTickMarksColor()); - g.setStroke(getChartPainter().getStyleManager().getAxisTickMarksStroke()); + g.setColor(getChartInternal().getStyleManager().getAxisTickMarksColor()); + g.setStroke(getChartInternal().getStyleManager().getAxisTickMarksStroke()); - if (axisTick.getAxis().getDirection() == Axis.Direction.Y && getChartPainter().getStyleManager().isYAxisTicksVisible()) { // Y-Axis + if (axisTick.getAxis().getDirection() == Axis.Direction.Y && getChartInternal().getStyleManager().isYAxisTicksVisible()) { // Y-Axis - double xOffset = axisTick.getAxisTickLabels().getBounds().getX() + axisTick.getAxisTickLabels().getBounds().getWidth() + getChartPainter().getStyleManager().getAxisTickPadding(); + double xOffset = axisTick.getAxisTickLabels().getBounds().getX() + axisTick.getAxisTickLabels().getBounds().getWidth() + getChartInternal().getStyleManager().getAxisTickPadding(); double yOffset = axisTick.getAxis().getPaintZone().getY(); // bounds - bounds = new Rectangle2D.Double(xOffset, yOffset, getChartPainter().getStyleManager().getAxisTickMarkLength(), axisTick.getAxis().getPaintZone().getHeight()); + bounds = new Rectangle2D.Double(xOffset, yOffset, getChartInternal().getStyleManager().getAxisTickMarkLength(), axisTick.getAxis().getPaintZone().getHeight()); // g.setColor(Color.yellow); // g.draw(bounds); // tick marks - if (getChartPainter().getStyleManager().isAxisTicksMarksVisible()) { + if (getChartInternal().getStyleManager().isAxisTicksMarksVisible()) { for (int i = 0; i < axisTick.getAxis().getAxisTickCalculator().getTickLabels().size(); i++) { @@ -73,16 +73,16 @@ public class AxisTickMarks implements ChartPart { double flippedTickLocation = yOffset + axisTick.getAxis().getPaintZone().getHeight() - tickLocation; if (flippedTickLocation > bounds.getY() && flippedTickLocation < bounds.getY() + bounds.getHeight()) { - Shape line = new Line2D.Double(xOffset, flippedTickLocation, xOffset + getChartPainter().getStyleManager().getAxisTickMarkLength(), flippedTickLocation); + Shape line = new Line2D.Double(xOffset, flippedTickLocation, xOffset + getChartInternal().getStyleManager().getAxisTickMarkLength(), flippedTickLocation); g.draw(line); } } } // Line - if (getChartPainter().getStyleManager().isAxisTicksLineVisible()) { + if (getChartInternal().getStyleManager().isAxisTicksLineVisible()) { - Shape line = new Line2D.Double(xOffset + getChartPainter().getStyleManager().getAxisTickMarkLength(), yOffset, xOffset + getChartPainter().getStyleManager().getAxisTickMarkLength(), yOffset + Shape line = new Line2D.Double(xOffset + getChartInternal().getStyleManager().getAxisTickMarkLength(), yOffset, xOffset + getChartInternal().getStyleManager().getAxisTickMarkLength(), yOffset + axisTick.getAxis().getPaintZone().getHeight()); g.draw(line); @@ -90,19 +90,19 @@ public class AxisTickMarks implements ChartPart { } // X-Axis - else if (axisTick.getAxis().getDirection() == Axis.Direction.X && getChartPainter().getStyleManager().isXAxisTicksVisible()) { + else if (axisTick.getAxis().getDirection() == Axis.Direction.X && getChartInternal().getStyleManager().isXAxisTicksVisible()) { double xOffset = axisTick.getAxis().getPaintZone().getX(); - double yOffset = axisTick.getAxisTickLabels().getBounds().getY() - getChartPainter().getStyleManager().getAxisTickPadding(); + double yOffset = axisTick.getAxisTickLabels().getBounds().getY() - getChartInternal().getStyleManager().getAxisTickPadding(); // bounds - bounds = new Rectangle2D.Double(xOffset, yOffset - getChartPainter().getStyleManager().getAxisTickMarkLength(), axisTick.getAxis().getPaintZone().getWidth(), getChartPainter().getStyleManager() + bounds = new Rectangle2D.Double(xOffset, yOffset - getChartInternal().getStyleManager().getAxisTickMarkLength(), axisTick.getAxis().getPaintZone().getWidth(), getChartInternal().getStyleManager() .getAxisTickMarkLength()); // g.setColor(Color.yellow); // g.draw(bounds); // tick marks - if (getChartPainter().getStyleManager().isAxisTicksMarksVisible()) { + if (getChartInternal().getStyleManager().isAxisTicksMarksVisible()) { for (int i = 0; i < axisTick.getAxis().getAxisTickCalculator().getTickLabels().size(); i++) { @@ -111,26 +111,26 @@ public class AxisTickMarks implements ChartPart { if (shiftedTickLocation > bounds.getX() && shiftedTickLocation < bounds.getX() + bounds.getWidth()) { - Shape line = new Line2D.Double(shiftedTickLocation, yOffset, xOffset + tickLocation, yOffset - getChartPainter().getStyleManager().getAxisTickMarkLength()); + Shape line = new Line2D.Double(shiftedTickLocation, yOffset, xOffset + tickLocation, yOffset - getChartInternal().getStyleManager().getAxisTickMarkLength()); g.draw(line); } } } // Line - if (getChartPainter().getStyleManager().isAxisTicksLineVisible()) { + if (getChartInternal().getStyleManager().isAxisTicksLineVisible()) { - g.setStroke(getChartPainter().getStyleManager().getAxisTickMarksStroke()); - g.drawLine((int) xOffset, (int) (yOffset - getChartPainter().getStyleManager().getAxisTickMarkLength()), (int) (xOffset + axisTick.getAxis().getPaintZone().getWidth()), (int) (yOffset - - getChartPainter().getStyleManager().getAxisTickMarkLength())); + g.setStroke(getChartInternal().getStyleManager().getAxisTickMarksStroke()); + g.drawLine((int) xOffset, (int) (yOffset - getChartInternal().getStyleManager().getAxisTickMarkLength()), (int) (xOffset + axisTick.getAxis().getPaintZone().getWidth()), (int) (yOffset + - getChartInternal().getStyleManager().getAxisTickMarkLength())); } } } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return axisTick.getChartPainter(); + return axisTick.getChartInternal(); } } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTitle.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTitle.java index de029e27d97c75b4ba8cffabbcebdc95f119443c..92dfb716ff4799572f438c405e02ffc8a242946c 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTitle.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTitle.java @@ -58,15 +58,15 @@ public class AxisTitle implements ChartPart { bounds = new Rectangle2D.Double(); - g.setColor(getChartPainter().getStyleManager().getChartFontColor()); - g.setFont(getChartPainter().getStyleManager().getAxisTitleFont()); + g.setColor(getChartInternal().getStyleManager().getChartFontColor()); + g.setFont(getChartInternal().getStyleManager().getAxisTitleFont()); if (axis.getDirection() == Axis.Direction.Y) { - if (text != null && !text.trim().equalsIgnoreCase("") && getChartPainter().getStyleManager().isYAxisTitleVisible()) { + if (text != null && !text.trim().equalsIgnoreCase("") && getChartInternal().getStyleManager().isYAxisTitleVisible()) { FontRenderContext frc = g.getFontRenderContext(); - TextLayout nonRotatedTextLayout = new TextLayout(text, getChartPainter().getStyleManager().getAxisTitleFont(), frc); + TextLayout nonRotatedTextLayout = new TextLayout(text, getChartInternal().getStyleManager().getAxisTitleFont(), frc); Rectangle2D nonRotatedRectangle = nonRotatedTextLayout.getBounds(); // /////////////////////////////////////////////// @@ -89,7 +89,7 @@ public class AxisTitle implements ChartPart { // System.out.println(nonRotatedRectangle.getHeight()); // bounds - bounds = new Rectangle2D.Double(xOffset - nonRotatedRectangle.getHeight(), yOffset - nonRotatedRectangle.getWidth(), nonRotatedRectangle.getHeight() + getChartPainter().getStyleManager() + bounds = new Rectangle2D.Double(xOffset - nonRotatedRectangle.getHeight(), yOffset - nonRotatedRectangle.getWidth(), nonRotatedRectangle.getHeight() + getChartInternal().getStyleManager() .getAxisTitlePadding(), nonRotatedRectangle.getWidth()); // g.setColor(Color.blue); // g.draw(bounds); @@ -101,10 +101,10 @@ public class AxisTitle implements ChartPart { } else { - if (text != null && !text.trim().equalsIgnoreCase("") && getChartPainter().getStyleManager().isXAxisTitleVisible()) { + if (text != null && !text.trim().equalsIgnoreCase("") && getChartInternal().getStyleManager().isXAxisTitleVisible()) { FontRenderContext frc = g.getFontRenderContext(); - TextLayout textLayout = new TextLayout(text, getChartPainter().getStyleManager().getAxisTitleFont(), frc); + TextLayout textLayout = new TextLayout(text, getChartInternal().getStyleManager().getAxisTitleFont(), frc); Rectangle2D rectangle = textLayout.getBounds(); // System.out.println(rectangle); @@ -120,7 +120,7 @@ public class AxisTitle implements ChartPart { g.fill(shape); g.setTransform(orig); - bounds = new Rectangle2D.Double(xOffset, yOffset - getChartPainter().getStyleManager().getAxisTitlePadding(), rectangle.getWidth(), rectangle.getHeight() + getChartPainter().getStyleManager() + bounds = new Rectangle2D.Double(xOffset, yOffset - getChartInternal().getStyleManager().getAxisTitlePadding(), rectangle.getWidth(), rectangle.getHeight() + getChartInternal().getStyleManager() .getAxisTitlePadding()); // g.setColor(Color.blue); // g.draw(bounds); @@ -136,9 +136,9 @@ public class AxisTitle implements ChartPart { } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return axis.getChartPainter(); + return axis.getChartInternal(); } // Getters ///////////////////////////////////////////////// diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartInternal.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartInternal.java new file mode 100644 index 0000000000000000000000000000000000000000..c3780597a7f387833253cca1b3a299cb8edcecbc --- /dev/null +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartInternal.java @@ -0,0 +1,435 @@ +/** + * Copyright 2015 Knowm Inc. (http://knowm.org) and contributors. + * Copyright 2011-2015 Xeiam LLC (http://xeiam.com) and contributors. + * + * 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 org.knowm.xchart.internal.chartpart; + +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.knowm.xchart.Series; +import org.knowm.xchart.StyleManager; +import org.knowm.xchart.internal.chartpart.Axis.AxisType; + +/** + * @author timmolter + */ +public class ChartInternal { + + private int width; + private int height; + + protected enum ChartInternalType { + + XY, Category, Pie + } + + private ChartInternalType chartInternalType = null; + + private Map<String, Series> seriesMap = new LinkedHashMap<String, Series>(); + + private final StyleManager styleManager; + + // Chart Parts + private Legend chartLegend; + private AxisPair axisPair; + private Plot plot; + private ChartTitle chartTitle; + + /** + * Constructor + * + * @param width + * @param height + */ + public ChartInternal(int width, int height) { + + this.width = width; + this.height = height; + + styleManager = new StyleManager(); + + chartLegend = new Legend(this); + axisPair = new AxisPair(this); + plot = new Plot(this); + chartTitle = new ChartTitle(this); + } + + /** + * @param seriesName + * @param xData + * @param yData + * @param errorBars + * @return Series + */ + public Series addSeries(String seriesName, List<?> xData, List<? extends Number> yData, List<? extends Number> errorBars) { + + if (chartInternalType != null && chartInternalType != ChartInternalType.XY) { + throw new IllegalArgumentException("Cannot mix x-y, category and/or pie series types! Don't call addSeries() and/or addCategorySeries() and/or addPieSeries() for the same chart!"); + } + chartInternalType = ChartInternalType.XY; + + // Sanity checks + sanityCheck(seriesName, xData, yData, errorBars); + + Series series = null; + if (xData != null) { + + // Sanity check + if (xData.size() != yData.size()) { + throw new IllegalArgumentException("X and Y-Axis sizes are not the same!!!"); + } + + // inspect the series to see what kind of data it contains (Number, Date) + AxisType axisType = setXAxisType(xData); + if (!(axisType == AxisType.Number || axisType == AxisType.Date)) { + throw new IllegalArgumentException("X-Axis data must be of type Number or Date for X-Y chart types!!!"); + } + + axisPair.getYAxis().setAxisType(AxisType.Number); + series = new Series(seriesName, xData, axisPair.getXAxis().getAxisType(), yData, axisPair.getYAxis().getAxisType(), errorBars, styleManager.getSeriesColorMarkerLineStyleCycler() + .getNextSeriesColorMarkerLineStyle()); + } + else { // generate xData + List<Double> generatedXData = new ArrayList<Double>(); + for (int i = 1; i < yData.size() + 1; i++) { + generatedXData.add((double) i); + } + axisPair.getXAxis().setAxisType(AxisType.Number); + axisPair.getYAxis().setAxisType(AxisType.Number); + series = new Series(seriesName, generatedXData, axisPair.getXAxis().getAxisType(), yData, axisPair.getYAxis().getAxisType(), errorBars, styleManager.getSeriesColorMarkerLineStyleCycler() + .getNextSeriesColorMarkerLineStyle()); + } + + // set series type + setSeriesType(series); + + if (seriesMap.keySet().contains(seriesName)) { + throw new IllegalArgumentException("Series name >" + seriesName + "< has already been used. Use unique names for each series!!!"); + } + + seriesMap.put(seriesName, series); + + return series; + } + + /** + * @param seriesName + * @param xData + * @param yData + * @param errorBars + * @return Series + */ + public Series addCategorySeries(String seriesName, List<?> xData, List<? extends Number> yData, List<? extends Number> errorBars) { + + if (chartInternalType != null && chartInternalType != ChartInternalType.Category) { + throw new IllegalArgumentException("Cannot mix x-y, category and/or pie series types! Don't call addSeries() and/or addCategorySeries() and/or addPieSeries() for the same chart!"); + } + chartInternalType = ChartInternalType.Category; + + // Sanity checks + sanityCheck(seriesName, xData, yData, errorBars); + if (xData == null) { + throw new IllegalArgumentException("Y-Axis data cannot be null!!!"); + } + if (xData.size() != yData.size()) { + throw new IllegalArgumentException("X and Y-Axis sizes are not the same!!!"); + } + // verify all series have exactly the same xAxis + if (seriesMap.size() > 0) { // there was already a series added + if (!seriesMap.entrySet().iterator().next().getValue().getXData().equals(xData)) { + throw new IllegalArgumentException("X-Axis data must exactly match all other Series X-Axis data for Category Charts!!"); + } + } + + // inspect the series to see what kind of data it contains (Number, Date, String) + setXAxisType(xData); + + axisPair.getYAxis().setAxisType(AxisType.Number); + Series series = new Series(seriesName, xData, axisPair.getXAxis().getAxisType(), yData, axisPair.getYAxis().getAxisType(), errorBars, styleManager.getSeriesColorMarkerLineStyleCycler() + .getNextSeriesColorMarkerLineStyle()); + + // set series type + setSeriesType(series); + + if (seriesMap.keySet().contains(seriesName)) { + throw new IllegalArgumentException("Series name >" + seriesName + "< has already been used. Use unique names for each series!!!"); + } + seriesMap.put(seriesName, series); + + return series; + } + + public Series addPieSeries(String sliceName, Number value) { + + if (chartInternalType != null && chartInternalType != ChartInternalType.Pie) { + throw new IllegalArgumentException("Cannot mix x-y, category and/or pie series types! Don't call addSeries() and/or addCategorySeries() and/or addPieSeries() for the same chart!"); + } + chartInternalType = ChartInternalType.Pie; + + axisPair.getXAxis().setAxisType(AxisType.String); + + axisPair.getYAxis().setAxisType(AxisType.Number); + Series series = new Series(sliceName, Arrays.asList(new String[] { sliceName }), axisPair.getXAxis().getAxisType(), Arrays.asList(new Number[] { value }), axisPair.getYAxis().getAxisType(), null, + styleManager.getSeriesColorMarkerLineStyleCycler().getNextSeriesColorMarkerLineStyle()); + + // set series type + setSeriesType(series); + + if (seriesMap.keySet().contains(sliceName)) { + throw new IllegalArgumentException("Series name >" + sliceName + "< has already been used. Use unique names for each series!!!"); + } + seriesMap.put(sliceName, series); + + return series; + } + + private void sanityCheck(String seriesName, List<?> xData, List<? extends Number> yData, List<? extends Number> errorBars) { + + if (seriesName == null) { + throw new IllegalArgumentException("Series Name cannot be null!!!"); + } + if (yData == null) { + throw new IllegalArgumentException("Y-Axis data cannot be null!!!"); + } + if (yData.size() == 0) { + throw new IllegalArgumentException("Y-Axis data cannot be empty!!!"); + } + if (xData != null && xData.size() == 0) { + throw new IllegalArgumentException("X-Axis data cannot be empty!!!"); + } + if (errorBars != null && errorBars.size() != yData.size()) { + throw new IllegalArgumentException("errorbars and Y-Axis sizes are not the same!!!"); + } + + } + + /** + * Sets the axis type based on the data contained in the xData argument + * + * @param xData + * @return + */ + private AxisType setXAxisType(List<?> xData) { + + AxisType axisType; + + Iterator<?> itr = xData.iterator(); + Object dataPoint = itr.next(); + if (dataPoint instanceof Number) { + axisType = AxisType.Number; + axisPair.getXAxis().setAxisType(axisType); + } + else if (dataPoint instanceof Date) { + axisType = AxisType.Date; + axisPair.getXAxis().setAxisType(axisType); + } + else if (dataPoint instanceof String) { + axisType = AxisType.String; + axisPair.getXAxis().setAxisType(axisType); + } + else { + throw new IllegalArgumentException("Series data must be either Number, Date or String type!!!"); + } + return axisType; + } + + /** + * set series type based on chart type, but only if it's not explicitly set on the series yet. + * + * @param series + */ + private void setSeriesType(Series series) { + + switch (getStyleManager().getChartType()) { + case Line: + if (series.getSeriesType() == null) { + series.setSeriesType(Series.SeriesType.Line); + } + break; + case Area: + if (series.getSeriesType() == null) { + series.setSeriesType(Series.SeriesType.Area); + } + break; + case Scatter: + if (series.getSeriesType() == null) { + series.setSeriesType(Series.SeriesType.Scatter); + } + break; + case Bar: + if (series.getSeriesType() == null) { + series.setSeriesType(Series.SeriesType.Bar); + } + break; + case Pie: + if (series.getSeriesType() == null) { + series.setSeriesType(Series.SeriesType.Pie); + } + break; + default: + if (series.getSeriesType() == null) { + series.setSeriesType(Series.SeriesType.Line); + } + break; + } + } + + /** + * @param g + * @param width + * @param height + */ + public void paint(Graphics2D g, int width, int height) { + + this.width = width; + this.height = height; + paint(g); + } + + /** + * @param g + */ + public void paint(Graphics2D g) { + + // Sanity checks + if (getSeriesMap().isEmpty()) { + throw new RuntimeException("No series defined for Chart!!!"); + } + + // calc axis min and max + axisPair.getXAxis().resetMinMax(); + axisPair.getYAxis().resetMinMax(); + for (Series series : getSeriesMap().values()) { + // add min/max to axes + // System.out.println(series.getxMin()); + // System.out.println(series.getxMax()); + // System.out.println(series.getyMin()); + // System.out.println(series.getyMax()); + // System.out.println("****"); + axisPair.getXAxis().addMinMax(series.getXMin(), series.getXMax()); + axisPair.getYAxis().addMinMax(series.getYMin(), series.getYMax()); + } + + axisPair.getXAxis().overrideMinMax(); + axisPair.getYAxis().overrideMinMax(); + + // logarithmic + + if (getStyleManager().isXAxisLogarithmic() && axisPair.getXAxis().getMin() <= 0.0) { + throw new IllegalArgumentException("Series data (accounting for error bars too) cannot be less or equal to zero for a logarithmic X-Axis!!!"); + } + if (getStyleManager().isYAxisLogarithmic() && axisPair.getYAxis().getMin() <= 0.0) { + // System.out.println(axisPair.getyAxis().getMin()); + throw new IllegalArgumentException("Series data (accounting for error bars too) cannot be less or equal to zero for a logarithmic Y-Axis!!!"); + } + + // paint chart main background + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // global rendering hint + g.setColor(styleManager.getChartBackgroundColor()); + Shape rect = new Rectangle2D.Double(0, 0, width, height); + g.fill(rect); + + // now that we added all the series, we can calculate the legend size + chartLegend.determineLegendBoxSize(); + + axisPair.paint(g); + plot.paint(g); + chartTitle.paint(g); + chartLegend.paint(g); + + g.dispose(); + } + + /** + * for internal usage + * + * @return + */ + public ChartTitle getChartTitle() { + + return chartTitle; + } + + /** + * for internal usage + * + * @return + */ + protected Legend getChartLegend() { + + return chartLegend; + } + + /** + * for internal usage + * + * @return + */ + public AxisPair getAxisPair() { + + return axisPair; + } + + /** + * for internal usage + * + * @return + */ + protected Plot getPlot() { + + return plot; + } + + public ChartInternalType getChartInternalType() { + + return chartInternalType; + } + + public int getWidth() { + + return width; + } + + public int getHeight() { + + return height; + } + + public Map<String, Series> getSeriesMap() { + + return seriesMap; + } + + /** + * Gets the Chart's style manager, which can be used to customize the Chart's appearance + * + * @return the style manager + */ + public StyleManager getStyleManager() { + + return styleManager; + } + +} diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartPainter.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartPainter.java deleted file mode 100644 index 097202ac0b83bb4653a120522a277a05ca1e3c83..0000000000000000000000000000000000000000 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartPainter.java +++ /dev/null @@ -1,181 +0,0 @@ -/** - * Copyright 2015 Knowm Inc. (http://knowm.org) and contributors. - * Copyright 2011-2015 Xeiam LLC (http://xeiam.com) and contributors. - * - * 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 org.knowm.xchart.internal.chartpart; - -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.geom.Rectangle2D; - -import org.knowm.xchart.Series; -import org.knowm.xchart.StyleManager; - -/** - * @author timmolter - */ -public class ChartPainter { - - private int width; - private int height; - - private final StyleManager styleManager; - - // Chart Parts - private Legend chartLegend; - private AxisPair axisPair; - private Plot plot; - private ChartTitle chartTitle; - - /** - * Constructor - * - * @param width - * @param height - */ - public ChartPainter(int width, int height) { - - this.width = width; - this.height = height; - - styleManager = new StyleManager(); - - chartLegend = new Legend(this); - axisPair = new AxisPair(this); - plot = new Plot(this); - chartTitle = new ChartTitle(this); - } - - /** - * @param g - * @param width - * @param height - */ - public void paint(Graphics2D g, int width, int height) { - - this.width = width; - this.height = height; - paint(g); - } - - /** - * @param g - */ - public void paint(Graphics2D g) { - - // calc axis min and max - axisPair.getXAxis().resetMinMax(); - axisPair.getYAxis().resetMinMax(); - - for (Series series : getAxisPair().getSeriesMap().values()) { - // add min/max to axis - // System.out.println(series.getxMin()); - // System.out.println(series.getxMax()); - // System.out.println(series.getyMin()); - // System.out.println(series.getyMax()); - // System.out.println("****"); - axisPair.getXAxis().addMinMax(series.getXMin(), series.getXMax()); - axisPair.getYAxis().addMinMax(series.getYMin(), series.getYMax()); - } - - // Sanity checks - if (axisPair.getSeriesMap().isEmpty()) { - throw new RuntimeException("No series defined for Chart!!!"); - } - if (getStyleManager().isXAxisLogarithmic() && axisPair.getXAxis().getMin() <= 0.0) { - throw new IllegalArgumentException("Series data (accounting for error bars too) cannot be less or equal to zero for a logarithmic X-Axis!!!"); - } - if (getStyleManager().isYAxisLogarithmic() && axisPair.getYAxis().getMin() <= 0.0) { - // System.out.println(axisPair.getyAxis().getMin()); - throw new IllegalArgumentException("Series data (accounting for error bars too) cannot be less or equal to zero for a logarithmic Y-Axis!!!"); - } - - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // global rendering hint - g.setColor(styleManager.getChartBackgroundColor()); - Shape rect = new Rectangle2D.Double(0, 0, width, height); - g.fill(rect); - - // now that we added all the series, we can calculate the legend size - chartLegend.determineLegendBoxSize(); - - axisPair.paint(g); - plot.paint(g); - chartTitle.paint(g); - chartLegend.paint(g); - - g.dispose(); - } - - /** - * for internal usage - * - * @return - */ - public ChartTitle getChartTitle() { - - return chartTitle; - } - - /** - * for internal usage - * - * @return - */ - public Legend getChartLegend() { - - return chartLegend; - } - - /** - * for internal usage - * - * @return - */ - public AxisPair getAxisPair() { - - return axisPair; - } - - /** - * for internal usage - * - * @return - */ - public Plot getPlot() { - - return plot; - } - - public int getWidth() { - - return width; - } - - public int getHeight() { - - return height; - } - - /** - * Gets the Chart's style manager, which can be used to customize the Chart's appearance - * - * @return the style manager - */ - public StyleManager getStyleManager() { - - return styleManager; - } -} diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartPart.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartPart.java index b6e48fc5ff3c6671f5166a5f2fe17299e795fc43..6cba8ff526accffbc761be8ecfc538fdcfc1d2a5 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartPart.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartPart.java @@ -30,6 +30,6 @@ public interface ChartPart { public void paint(final Graphics2D g); - public ChartPainter getChartPainter(); + public ChartInternal getChartInternal(); } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartTitle.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartTitle.java index 2c861eac690cb958963c3febae4214aa1fe2916d..4bfe55aa91a66a525586034c2fce091f94ffdaf4 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartTitle.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/ChartTitle.java @@ -30,7 +30,7 @@ import java.awt.geom.Rectangle2D; public class ChartTitle implements ChartPart { /** parent */ - private final ChartPainter chartPainter; + private final ChartInternal chartInternal; /** the title text */ private String text = ""; // default to "" @@ -41,11 +41,11 @@ public class ChartTitle implements ChartPart { /** * Constructor * - * @param chartPainter + * @param chartInternal */ - public ChartTitle(ChartPainter chartPainter) { + public ChartTitle(ChartInternal chartInternal) { - this.chartPainter = chartPainter; + this.chartInternal = chartInternal; } /** @@ -56,10 +56,10 @@ public class ChartTitle implements ChartPart { public void setText(String text) { if (text.trim().equalsIgnoreCase("")) { - chartPainter.getStyleManager().setChartTitleVisible(false); + chartInternal.getStyleManager().setChartTitleVisible(false); } else { - chartPainter.getStyleManager().setChartTitleVisible(true); + chartInternal.getStyleManager().setChartTitleVisible(true); } this.text = text; } @@ -71,57 +71,57 @@ public class ChartTitle implements ChartPart { */ protected int getSizeHint() { - if (chartPainter.getStyleManager().isChartTitleVisible()) { + if (chartInternal.getStyleManager().isChartTitleVisible()) { - TextLayout textLayout = new TextLayout(text, chartPainter.getStyleManager().getChartTitleFont(), new FontRenderContext(null, true, false)); + TextLayout textLayout = new TextLayout(text, chartInternal.getStyleManager().getChartTitleFont(), new FontRenderContext(null, true, false)); Rectangle2D rectangle = textLayout.getBounds(); - int titleHeight = (int) ((chartPainter.getStyleManager().isChartTitleVisible() ? rectangle.getHeight() : 0)); - return chartPainter.getStyleManager().getChartPadding() + 2 * chartPainter.getStyleManager().getChartTitlePadding() + titleHeight; + int titleHeight = (int) ((chartInternal.getStyleManager().isChartTitleVisible() ? rectangle.getHeight() : 0)); + return chartInternal.getStyleManager().getChartPadding() + 2 * chartInternal.getStyleManager().getChartTitlePadding() + titleHeight; } else { // TODO make this zero - return chartPainter.getStyleManager().getChartPadding(); + return chartInternal.getStyleManager().getChartPadding(); } } @Override public void paint(Graphics2D g) { - g.setFont(chartPainter.getStyleManager().getChartTitleFont()); + g.setFont(chartInternal.getStyleManager().getChartTitleFont()); - if (chartPainter.getStyleManager().isChartTitleVisible()) { + if (chartInternal.getStyleManager().isChartTitleVisible()) { // create rectangle first for sizing FontRenderContext frc = g.getFontRenderContext(); - TextLayout textLayout = new TextLayout(text, chartPainter.getStyleManager().getChartTitleFont(), frc); + TextLayout textLayout = new TextLayout(text, chartInternal.getStyleManager().getChartTitleFont(), frc); Rectangle2D rectangle = textLayout.getBounds(); - double xOffset = (int) chartPainter.getPlot().getBounds().getX(); - double yOffset = chartPainter.getStyleManager().getChartPadding(); + double xOffset = (int) chartInternal.getPlot().getBounds().getX(); + double yOffset = chartInternal.getStyleManager().getChartPadding(); - if (chartPainter.getStyleManager().isChartTitleBoxVisible()) { + if (chartInternal.getStyleManager().isChartTitleBoxVisible()) { // paint the chart title box - double chartTitleBoxWidth = chartPainter.getPlot().getBounds().getWidth(); - double chartTitleBoxHeight = rectangle.getHeight() + 2 * chartPainter.getStyleManager().getChartTitlePadding(); + double chartTitleBoxWidth = chartInternal.getPlot().getBounds().getWidth(); + double chartTitleBoxHeight = rectangle.getHeight() + 2 * chartInternal.getStyleManager().getChartTitlePadding(); g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); Shape rect = new Rectangle2D.Double(xOffset, yOffset, chartTitleBoxWidth, chartTitleBoxHeight); - g.setColor(chartPainter.getStyleManager().getChartTitleBoxBackgroundColor()); + g.setColor(chartInternal.getStyleManager().getChartTitleBoxBackgroundColor()); g.fill(rect); - g.setColor(chartPainter.getStyleManager().getChartTitleBoxBorderColor()); + g.setColor(chartInternal.getStyleManager().getChartTitleBoxBorderColor()); g.draw(rect); } // paint title - xOffset = chartPainter.getPlot().getBounds().getX() + (chartPainter.getPlot().getBounds().getWidth() - rectangle.getWidth()) / 2.0; - yOffset = chartPainter.getStyleManager().getChartPadding() - rectangle.getY() + chartPainter.getStyleManager().getChartTitlePadding(); + xOffset = chartInternal.getPlot().getBounds().getX() + (chartInternal.getPlot().getBounds().getWidth() - rectangle.getWidth()) / 2.0; + yOffset = chartInternal.getStyleManager().getChartPadding() - rectangle.getY() + chartInternal.getStyleManager().getChartTitlePadding(); bounds = new Rectangle2D.Double(xOffset, yOffset + rectangle.getY(), rectangle.getWidth(), rectangle.getHeight()); // g.setColor(Color.green); // g.draw(bounds); - g.setColor(chartPainter.getStyleManager().getChartFontColor()); + g.setColor(chartInternal.getStyleManager().getChartFontColor()); // textLayout.draw(g, xOffset, yOffset); Shape shape = textLayout.getOutline(null); @@ -142,8 +142,8 @@ public class ChartTitle implements ChartPart { } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return chartPainter; + return chartInternal; } } \ No newline at end of file diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Legend.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Legend.java index c8083fc30f3d4ef193845a04fa19110d3e5e45e8..80ef017a98c7c9668cd2ce65afee0c5671c41f62 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Legend.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Legend.java @@ -28,7 +28,6 @@ import java.util.LinkedHashMap; import java.util.Map; import org.knowm.xchart.Series; -import org.knowm.xchart.StyleManager.ChartType; /** * @author timmolter @@ -45,7 +44,7 @@ public class Legend implements ChartPart { /** * parent */ - private final ChartPainter chartPainter; + private final ChartInternal chartInternal; /** * the bounds @@ -55,11 +54,11 @@ public class Legend implements ChartPart { /** * Constructor * - * @param chartPainter + * @param chartInternal */ - public Legend(ChartPainter chartPainter) { + public Legend(ChartInternal chartInternal) { - this.chartPainter = chartPainter; + this.chartInternal = chartInternal; } /** @@ -67,11 +66,11 @@ public class Legend implements ChartPart { */ public void determineLegendBoxSize() { - if (!chartPainter.getStyleManager().isLegendVisible()) { + if (!chartInternal.getStyleManager().isLegendVisible()) { return; } - boolean isBar = getChartPainter().getStyleManager().getChartType() == ChartType.Bar; + boolean containsBarOrPie = false; // determine legend text content max width double legendTextContentMaxWidth = 0; @@ -79,7 +78,7 @@ public class Legend implements ChartPart { // determine legend content height double legendContentHeight = 0; - for (Series series : chartPainter.getAxisPair().getSeriesMap().values()) { + for (Series series : chartInternal.getSeriesMap().values()) { Map<String, Rectangle2D> seriesBounds = getSeriesTextBounds(series); @@ -90,67 +89,72 @@ public class Legend implements ChartPart { } blockHeight -= MULTI_LINE_SPACE; - blockHeight = Math.max(blockHeight, isBar ? BOX_SIZE : getChartPainter().getStyleManager().getMarkerSize()); + blockHeight = Math.max(blockHeight, (series.getSeriesType() == Series.SeriesType.Bar || series.getSeriesType() == Series.SeriesType.Pie) ? BOX_SIZE : getChartInternal().getStyleManager() + .getMarkerSize()); - legendContentHeight += blockHeight + getChartPainter().getStyleManager().getLegendPadding(); + legendContentHeight += blockHeight + getChartInternal().getStyleManager().getLegendPadding(); + + if (series.getSeriesType() == Series.SeriesType.Bar || series.getSeriesType() == Series.SeriesType.Pie) { + containsBarOrPie = true; + } } // determine legend content width double legendContentWidth = 0; - if (!isBar) { - legendContentWidth = getChartPainter().getStyleManager().getLegendSeriesLineLength() + getChartPainter().getStyleManager().getLegendPadding() + legendTextContentMaxWidth; + if (!containsBarOrPie) { + legendContentWidth = getChartInternal().getStyleManager().getLegendSeriesLineLength() + getChartInternal().getStyleManager().getLegendPadding() + legendTextContentMaxWidth; } else { - legendContentWidth = BOX_SIZE + getChartPainter().getStyleManager().getLegendPadding() + legendTextContentMaxWidth; + legendContentWidth = BOX_SIZE + getChartInternal().getStyleManager().getLegendPadding() + legendTextContentMaxWidth; } // Legend Box - legendBoxWidth = legendContentWidth + 2 * getChartPainter().getStyleManager().getLegendPadding(); - legendBoxHeight = legendContentHeight + 1 * getChartPainter().getStyleManager().getLegendPadding(); + legendBoxWidth = legendContentWidth + 2 * getChartInternal().getStyleManager().getLegendPadding(); + legendBoxHeight = legendContentHeight + 1 * getChartInternal().getStyleManager().getLegendPadding(); } @Override public void paint(Graphics2D g) { - if (!getChartPainter().getStyleManager().isLegendVisible()) { + if (!getChartInternal().getStyleManager().isLegendVisible()) { return; } // if the area to draw a chart on is so small, don't even bother - if (chartPainter.getPlot().getBounds().getWidth() < 30) { + if (chartInternal.getPlot().getBounds().getWidth() < 30) { return; } bounds = new Rectangle2D.Double(); - // g.setFont(chartPainter.getStyleManager().getLegendFont()); + // g.setFont(chartInternal.getStyleManager().getLegendFont()); // legend draw position double xOffset = 0; double yOffset = 0; - switch (getChartPainter().getStyleManager().getLegendPosition()) { + switch (getChartInternal().getStyleManager().getLegendPosition()) { case OutsideE: - xOffset = chartPainter.getWidth() - legendBoxWidth - getChartPainter().getStyleManager().getChartPadding(); - yOffset = chartPainter.getPlot().getBounds().getY() + (chartPainter.getPlot().getBounds().getHeight() - legendBoxHeight) / 2.0; + xOffset = chartInternal.getWidth() - legendBoxWidth - getChartInternal().getStyleManager().getChartPadding(); + yOffset = chartInternal.getPlot().getBounds().getY() + (chartInternal.getPlot().getBounds().getHeight() - legendBoxHeight) / 2.0; break; case InsideNW: - xOffset = chartPainter.getPlot().getBounds().getX() + LEGEND_MARGIN; - yOffset = chartPainter.getPlot().getBounds().getY() + LEGEND_MARGIN; + xOffset = chartInternal.getPlot().getBounds().getX() + LEGEND_MARGIN; + yOffset = chartInternal.getPlot().getBounds().getY() + LEGEND_MARGIN; break; case InsideNE: - xOffset = chartPainter.getPlot().getBounds().getX() + chartPainter.getPlot().getBounds().getWidth() - legendBoxWidth - LEGEND_MARGIN; - yOffset = chartPainter.getPlot().getBounds().getY() + LEGEND_MARGIN; + xOffset = chartInternal.getPlot().getBounds().getX() + chartInternal.getPlot().getBounds().getWidth() - legendBoxWidth - LEGEND_MARGIN; + yOffset = chartInternal.getPlot().getBounds().getY() + LEGEND_MARGIN; break; case InsideSE: - xOffset = chartPainter.getPlot().getBounds().getX() + chartPainter.getPlot().getBounds().getWidth() - legendBoxWidth - LEGEND_MARGIN; - yOffset = chartPainter.getPlot().getBounds().getY() + chartPainter.getPlot().getBounds().getHeight() - legendBoxHeight - LEGEND_MARGIN; + xOffset = chartInternal.getPlot().getBounds().getX() + chartInternal.getPlot().getBounds().getWidth() - legendBoxWidth - LEGEND_MARGIN; + yOffset = chartInternal.getPlot().getBounds().getY() + chartInternal.getPlot().getBounds().getHeight() - legendBoxHeight - LEGEND_MARGIN; break; case InsideSW: - xOffset = chartPainter.getPlot().getBounds().getX() + LEGEND_MARGIN; - yOffset = chartPainter.getPlot().getBounds().getY() + chartPainter.getPlot().getBounds().getHeight() - legendBoxHeight - LEGEND_MARGIN; + xOffset = chartInternal.getPlot().getBounds().getX() + LEGEND_MARGIN; + yOffset = chartInternal.getPlot().getBounds().getY() + chartInternal.getPlot().getBounds().getHeight() - legendBoxHeight - LEGEND_MARGIN; break; case InsideN: - xOffset = chartPainter.getPlot().getBounds().getX() + (chartPainter.getPlot().getBounds().getWidth() - legendBoxWidth) / 2 + LEGEND_MARGIN; - yOffset = chartPainter.getPlot().getBounds().getY() + LEGEND_MARGIN; + xOffset = chartInternal.getPlot().getBounds().getX() + (chartInternal.getPlot().getBounds().getWidth() - legendBoxWidth) / 2 + LEGEND_MARGIN; + yOffset = chartInternal.getPlot().getBounds().getY() + LEGEND_MARGIN; break; default: @@ -160,16 +164,16 @@ public class Legend implements ChartPart { g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10.0f, new float[] { 3.0f, 0.0f }, 0.0f)); Shape rect = new Rectangle2D.Double(xOffset + 1, yOffset + 1, legendBoxWidth - 2, legendBoxHeight - 2); - g.setColor(getChartPainter().getStyleManager().getLegendBackgroundColor()); + g.setColor(getChartInternal().getStyleManager().getLegendBackgroundColor()); g.fill(rect); - g.setColor(getChartPainter().getStyleManager().getLegendBorderColor()); + g.setColor(getChartInternal().getStyleManager().getLegendBorderColor()); g.draw(rect); // Draw legend content inside legend box - double startx = xOffset + getChartPainter().getStyleManager().getLegendPadding(); - double starty = yOffset + getChartPainter().getStyleManager().getLegendPadding(); + double startx = xOffset + getChartInternal().getStyleManager().getLegendPadding(); + double starty = yOffset + getChartInternal().getStyleManager().getLegendPadding(); - for (Series series : chartPainter.getAxisPair().getSeriesMap().values()) { + for (Series series : chartInternal.getSeriesMap().values()) { Map<String, Rectangle2D> seriesTextBounds = getSeriesTextBounds(series); @@ -181,15 +185,16 @@ public class Legend implements ChartPart { } blockHeight -= MULTI_LINE_SPACE; - blockHeight = Math.max(blockHeight, getChartPainter().getStyleManager().getChartType() == ChartType.Bar ? BOX_SIZE : getChartPainter().getStyleManager().getMarkerSize()); + blockHeight = Math.max(blockHeight, (series.getSeriesType() == Series.SeriesType.Bar || series.getSeriesType() == Series.SeriesType.Pie) ? BOX_SIZE : getChartInternal().getStyleManager() + .getMarkerSize()); - if (getChartPainter().getStyleManager().getChartType() != ChartType.Bar) { + if (series.getSeriesType() != Series.SeriesType.Bar && series.getSeriesType() != Series.SeriesType.Pie) { // paint line - if (getChartPainter().getStyleManager().getChartType() != ChartType.Scatter && series.getStroke() != null) { + if (series.getSeriesType() != Series.SeriesType.Scatter && series.getStroke() != null) { g.setColor(series.getStrokeColor()); g.setStroke(series.getStroke()); - Shape line = new Line2D.Double(startx, starty + blockHeight / 2.0, startx + getChartPainter().getStyleManager().getLegendSeriesLineLength(), starty + blockHeight / 2.0); + Shape line = new Line2D.Double(startx, starty + blockHeight / 2.0, startx + getChartInternal().getStyleManager().getLegendSeriesLineLength(), starty + blockHeight / 2.0); g.draw(line); } @@ -202,11 +207,13 @@ public class Legend implements ChartPart { // paint marker if (series.getMarker() != null) { g.setColor(series.getMarkerColor()); - series.getMarker().paint(g, startx + getChartPainter().getStyleManager().getLegendSeriesLineLength() / 2.0, starty + blockHeight / 2.0, getChartPainter().getStyleManager().getMarkerSize()); + series.getMarker().paint(g, startx + getChartInternal().getStyleManager().getLegendSeriesLineLength() / 2.0, starty + blockHeight / 2.0, getChartInternal().getStyleManager() + .getMarkerSize()); } } - else { + else { // bar/pie type series + // paint little box if (series.getStroke() != null) { g.setColor(series.getStrokeColor()); @@ -220,21 +227,21 @@ public class Legend implements ChartPart { // g.draw(boundsTemp); } - // paint series text - g.setColor(chartPainter.getStyleManager().getChartFontColor()); + // paint series text ///////////////////////////////////////////////////// + g.setColor(chartInternal.getStyleManager().getChartFontColor()); double multiLineOffset = 0.0; - if (getChartPainter().getStyleManager().getChartType() != ChartType.Bar) { + if (series.getSeriesType() != Series.SeriesType.Bar && series.getSeriesType() != Series.SeriesType.Pie) { - double x = startx + getChartPainter().getStyleManager().getLegendSeriesLineLength() + getChartPainter().getStyleManager().getLegendPadding(); + double x = startx + getChartInternal().getStyleManager().getLegendSeriesLineLength() + getChartInternal().getStyleManager().getLegendPadding(); for (Map.Entry<String, Rectangle2D> entry : seriesTextBounds.entrySet()) { double height = entry.getValue().getHeight(); - double centerOffsetY = (Math.max(getChartPainter().getStyleManager().getMarkerSize(), height) - height) / 2.0; + double centerOffsetY = (Math.max(getChartInternal().getStyleManager().getMarkerSize(), height) - height) / 2.0; FontRenderContext frc = g.getFontRenderContext(); - TextLayout tl = new TextLayout(entry.getKey(), getChartPainter().getStyleManager().getLegendFont(), frc); + TextLayout tl = new TextLayout(entry.getKey(), getChartInternal().getStyleManager().getLegendFont(), frc); Shape shape = tl.getOutline(null); AffineTransform orig = g.getTransform(); AffineTransform at = new AffineTransform(); @@ -251,18 +258,18 @@ public class Legend implements ChartPart { multiLineOffset += height + MULTI_LINE_SPACE; } - starty += blockHeight + getChartPainter().getStyleManager().getLegendPadding(); + starty += blockHeight + getChartInternal().getStyleManager().getLegendPadding(); } - else { + else { // bar/pie type series - final double x = startx + BOX_SIZE + getChartPainter().getStyleManager().getLegendPadding(); + final double x = startx + BOX_SIZE + getChartInternal().getStyleManager().getLegendPadding(); for (Map.Entry<String, Rectangle2D> entry : seriesTextBounds.entrySet()) { double height = entry.getValue().getHeight(); double centerOffsetY = (Math.max(BOX_SIZE, height) - height) / 2.0; FontRenderContext frc = g.getFontRenderContext(); - TextLayout tl = new TextLayout(entry.getKey(), getChartPainter().getStyleManager().getLegendFont(), frc); + TextLayout tl = new TextLayout(entry.getKey(), getChartInternal().getStyleManager().getLegendFont(), frc); Shape shape = tl.getOutline(null); AffineTransform orig = g.getTransform(); AffineTransform at = new AffineTransform(); @@ -278,7 +285,7 @@ public class Legend implements ChartPart { multiLineOffset += height + MULTI_LINE_SPACE; } - starty += blockHeight + getChartPainter().getStyleManager().getLegendPadding(); + starty += blockHeight + getChartInternal().getStyleManager().getLegendPadding(); } } @@ -299,7 +306,7 @@ public class Legend implements ChartPart { String lines[] = series.getName().split("\\n"); Map<String, Rectangle2D> seriesTextBounds = new LinkedHashMap<String, Rectangle2D>(lines.length); for (String line : lines) { - TextLayout tl = new TextLayout(line, getChartPainter().getStyleManager().getLegendFont(), new FontRenderContext(null, true, false)); + TextLayout tl = new TextLayout(line, getChartInternal().getStyleManager().getLegendFont(), new FontRenderContext(null, true, false)); Shape shape = tl.getOutline(null); Rectangle2D bounds = shape.getBounds2D(); // System.out.println(tl.getAscent()); @@ -329,9 +336,9 @@ public class Legend implements ChartPart { } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return chartPainter; + return chartInternal; } } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Plot.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Plot.java index f48d3bf536778e5376feb8e22cbe36f89b07a2dc..0dfb9a8ae3850e90bda34f7d843cab0e10d50e5b 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Plot.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Plot.java @@ -20,6 +20,7 @@ import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import org.knowm.xchart.StyleManager.ChartType; +import org.knowm.xchart.internal.chartpart.ChartInternal.ChartInternalType; /** * @author timmolter @@ -27,7 +28,7 @@ import org.knowm.xchart.StyleManager.ChartType; public class Plot implements ChartPart { /** parent */ - private final ChartPainter chartPainter; + private final ChartInternal chartInternal; /** the bounds */ private Rectangle2D bounds; @@ -39,11 +40,11 @@ public class Plot implements ChartPart { /** * Constructor * - * @param chartPainter + * @param chartInternal */ - public Plot(ChartPainter chartPainter) { + public Plot(ChartInternal chartInternal) { - this.chartPainter = chartPainter; + this.chartInternal = chartInternal; this.plotSurface = new PlotSurface(this); } @@ -59,35 +60,45 @@ public class Plot implements ChartPart { bounds = new Rectangle2D.Double(); // calculate bounds - double xOffset = chartPainter.getAxisPair().getYAxis().getBounds().getX() + double xOffset = chartInternal.getAxisPair().getYAxis().getBounds().getX() - + chartPainter.getAxisPair().getYAxis().getBounds().getWidth() + + chartInternal.getAxisPair().getYAxis().getBounds().getWidth() - + (chartPainter.getStyleManager().isYAxisTicksVisible() ? (chartPainter.getStyleManager().getPlotPadding()) : 0) + + (chartInternal.getStyleManager().isYAxisTicksVisible() ? (chartInternal.getStyleManager().getPlotPadding()) : 0) ; - double yOffset = chartPainter.getAxisPair().getYAxis().getBounds().getY(); - double width = chartPainter.getAxisPair().getXAxis().getBounds().getWidth(); - double height = chartPainter.getAxisPair().getYAxis().getBounds().getHeight(); + double yOffset = chartInternal.getAxisPair().getYAxis().getBounds().getY(); + double width = chartInternal.getAxisPair().getXAxis().getBounds().getWidth(); + double height = chartInternal.getAxisPair().getYAxis().getBounds().getHeight(); bounds = new Rectangle2D.Double(xOffset, yOffset, width, height); // g.setColor(Color.green); // g.draw(bounds); plotSurface.paint(g); - if (getChartPainter().getStyleManager().getChartType() == ChartType.Bar) { - this.plotContent = new PlotContentBarChart(this); + + if (getChartInternal().getChartInternalType() == ChartInternalType.Category) { + if (getChartInternal().getStyleManager().getChartType() == ChartType.Bar) { + this.plotContent = new PlotContentCategoricalChart_Bar(this); + } + + else { + this.plotContent = new PlotContentCategoricalChart_Line_Area_Scatter(this); + } + } + else if (getChartInternal().getChartInternalType() == ChartInternalType.Pie) { + this.plotContent = new PlotContentCategoricalChart_Pie(this); } else { - this.plotContent = new PlotContentLineChart(this); + this.plotContent = new PlotContentNumericalChart(this); } plotContent.paint(g); } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return chartPainter; + return chartInternal; } } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent.java index 0f07e6d28ead7f2b1555c95f9285b9a5c16e7b57..de74676a44b0934355828dc1f256e8e8030b92c3 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent.java @@ -20,6 +20,8 @@ import java.awt.BasicStroke; import java.awt.Stroke; import java.awt.geom.Rectangle2D; +import org.knowm.xchart.StyleManager; + /** * @author timmolter */ @@ -28,16 +30,20 @@ public abstract class PlotContent implements ChartPart { /** parent */ protected Plot plot; + StyleManager styleManager; + protected final Stroke errorBarStroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); /** * Constructor - * + * * @param plot */ protected PlotContent(Plot plot) { this.plot = plot; + + styleManager = getChartInternal().getStyleManager(); } @Override @@ -47,9 +53,9 @@ public abstract class PlotContent implements ChartPart { } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return plot.getChartPainter(); + return plot.getChartInternal(); } } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentBarChart.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Bar.java similarity index 54% rename from xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentBarChart.java rename to xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Bar.java index 47ae84174623da9419f03c14b835f9ab12d20f46..8a9470a6aa13802eb59370e56c5956d2331cf878 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentBarChart.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Bar.java @@ -17,7 +17,6 @@ package org.knowm.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; @@ -26,20 +25,20 @@ import java.util.Collection; import java.util.Iterator; import org.knowm.xchart.Series; -import org.knowm.xchart.StyleManager; +import org.knowm.xchart.Series.SeriesType; import org.knowm.xchart.internal.Utils; /** * @author timmolter */ -public class PlotContentBarChart extends PlotContent { +public class PlotContentCategoricalChart_Bar extends PlotContent { /** * Constructor * * @param plot */ - protected PlotContentBarChart(Plot plot) { + protected PlotContentCategoricalChart_Bar(Plot plot) { super(plot); } @@ -47,15 +46,18 @@ public class PlotContentBarChart extends PlotContent { @Override public void paint(Graphics2D g) { + // logarithmic + if (getChartInternal().getStyleManager().isYAxisLogarithmic()) { + throw new IllegalArgumentException("Category Charts cannot have logarithmic axes!!! (Not Yet Implemented)"); + } + 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 - Rectangle rectangle = new Rectangle(0, 0, getChartPainter().getWidth(), getChartPainter().getHeight()); + Rectangle2D rectangle = new Rectangle2D.Double(0, 0, getChartInternal().getWidth(), getChartInternal().getHeight()); // g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); // g.setColor(Color.green); // g.draw(rectangle); @@ -69,99 +71,79 @@ public class PlotContentBarChart extends PlotContent { double yTickSpace = styleManager.getAxisTickSpacePercentage() * bounds.getHeight(); double yTopMargin = Utils.getTickStartOffset(bounds.getHeight(), yTickSpace); - int numBars = getChartPainter().getAxisPair().getSeriesMap().values().iterator().next().getXData().size(); - double gridStep = xTickSpace / numBars; + int numCategories = getChartInternal().getSeriesMap().values().iterator().next().getXData().size(); + double gridStep = xTickSpace / numCategories; - // plot series - int seriesCounter = 0; - for (Series series : getChartPainter().getAxisPair().getSeriesMap().values()) { + double yMin = getChartInternal().getAxisPair().getYAxis().getMin(); + double yMax = getChartInternal().getAxisPair().getYAxis().getMax(); - // data points - // Collection<?> xData = series.getXData(); + // TODO only for bar charts necessary + // figure out the general form of the chart + int chartForm = 1; // 1=positive, -1=negative, 0=span + if (yMin > 0.0 && yMax > 0.0) { + chartForm = 1; // positive chart + } + else if (yMin < 0.0 && yMax < 0.0) { + chartForm = -1; // negative chart + } + else { + chartForm = 0;// span chart + } + // System.out.println(yMin); + // System.out.println(yMax); + // System.out.println("chartForm: " + chartForm); - Collection<? extends Number> yData = series.getYData(); - double yMin = getChartPainter().getAxisPair().getYAxis().getMin(); - double yMax = getChartPainter().getAxisPair().getYAxis().getMax(); + // plot series + int seriesCounter = 0; + for (Series series : getChartInternal().getSeriesMap().values()) { - // if min and max positive, set min to zero - if (yMin > 0.0 && yMax > 0.0) { - yMin = 0.0; - } - // if min and max negative, set max to zero - if (yMin < 0.0 && yMax < 0.0) { - yMax = 0.0; + // sanity check + if (Series.SeriesType.Area.equals(series.getSeriesType()) || Series.SeriesType.Pie.equals(series.getSeriesType())) { + throw new RuntimeException("Category-Bar charts only accept Bar, Line and Scatter series types!!!"); } - // override min and maxValue if specified - if (getChartPainter().getStyleManager().getYAxisMin() != null) { - yMin = getChartPainter().getStyleManager().getYAxisMin(); - } - else if (getChartPainter().getStyleManager().isYAxisLogarithmic()) { - // int logMin = (int) Math.floor(Math.log10(getChartPainter().getAxisPair().getyAxis().getMin().doubleValue())); - double logMin = Math.floor(Math.log10(getChartPainter().getAxisPair().getYAxis().getMin())); - // System.out.println("logMin: " + logMin); - // System.out.println("min : " + getChartPainter().getAxisPair().getyAxis().getMin().doubleValue()); - yMin = logMin; - } - if (getChartPainter().getStyleManager().getYAxisMax() != null) { - yMax = getChartPainter().getStyleManager().getYAxisMax(); - } - else if (getChartPainter().getStyleManager().isYAxisLogarithmic()) { - yMax = Math.log10(yMax); - } - // figure out the general form of the chart - int chartForm = 1; // 1=positive, -1=negative, 0=span - if (yMin > 0.0 && yMax > 0.0) { - chartForm = 1; // positive chart - } - else if (yMin < 0.0 && yMax < 0.0) { - chartForm = -1; // negative chart - } - else { - chartForm = 0;// span chart - } - // System.out.println(yMin); - // System.out.println(yMax); + // for line series + double previousX = -Double.MAX_VALUE; + double previousY = -Double.MAX_VALUE; - // all the x-axis data are guaranteed to be the same so we just use the first one - Iterator<? extends Number> yItr = yData.iterator(); + Iterator<? extends Number> yItr = series.getYData().iterator(); Iterator<? extends Number> ebItr = null; Collection<? extends Number> errorBars = series.getErrorBars(); if (errorBars != null) { ebItr = errorBars.iterator(); } - int barCounter = 0; + int categoryCounter = 0; while (yItr.hasNext()) { - double y = ((Number) yItr.next()).doubleValue(); - if (getChartPainter().getStyleManager().isYAxisLogarithmic()) { - y = Math.log10(y); + Number next = yItr.next(); + if (next == null) { + + previousX = -Double.MAX_VALUE; + previousY = -Double.MAX_VALUE; + categoryCounter++; + continue; } + double y = next.doubleValue(); double yTop = 0.0; double yBottom = 0.0; - switch (chartForm) { case 1: // positive chart - // check for points off the chart draw area due to a custom yMin if (y < yMin) { - barCounter++; + categoryCounter++; continue; } - yTop = y; yBottom = yMin; break; case -1: // negative chart - // check for points off the chart draw area due to a custom yMin if (y > yMax) { - barCounter++; + categoryCounter++; continue; } - yTop = yMax; yBottom = y; break; @@ -180,56 +162,84 @@ public class PlotContentBarChart extends PlotContent { } double yTransform = bounds.getHeight() - (yTopMargin + (yTop - yMin) / (yMax - yMin) * yTickSpace); + // double yTransform = bounds.getHeight() - (yTopMargin + (y - yMin) / (yMax - yMin) * yTickSpace); double yOffset = bounds.getY() + yTransform; double zeroTransform = bounds.getHeight() - (yTopMargin + (yBottom - yMin) / (yMax - yMin) * yTickSpace); double zeroOffset = bounds.getY() + zeroTransform; - - // paint bar - boolean isOverlap = true; double xOffset; double barWidth; - if (getChartPainter().getStyleManager().isBarsOverlapped()) { - double barWidthPercentage = getChartPainter().getStyleManager().getBarWidthPercentage(); + + if (getChartInternal().getStyleManager().isBarsOverlapped()) { + double barWidthPercentage = getChartInternal().getStyleManager().getBarWidthPercentage(); barWidth = gridStep * barWidthPercentage; double barMargin = gridStep * (1 - barWidthPercentage) / 2; - xOffset = bounds.getX() + xLeftMargin + gridStep * barCounter++ + barMargin; - g.setColor(series.getStrokeColor()); + xOffset = bounds.getX() + xLeftMargin + gridStep * categoryCounter++ + barMargin; } else { - double barWidthPercentage = getChartPainter().getStyleManager().getBarWidthPercentage(); - barWidth = gridStep / getChartPainter().getAxisPair().getSeriesMap().size() * barWidthPercentage; + double barWidthPercentage = getChartInternal().getStyleManager().getBarWidthPercentage(); + barWidth = gridStep / getChartInternal().getSeriesMap().size() * barWidthPercentage; double barMargin = gridStep * (1 - barWidthPercentage) / 2; - xOffset = bounds.getX() + xLeftMargin + gridStep * barCounter++ + seriesCounter * barWidth + barMargin; - g.setColor(series.getStrokeColor()); + xOffset = bounds.getX() + xLeftMargin + gridStep * categoryCounter++ + seriesCounter * barWidth + barMargin; } - Path2D.Double path = new Path2D.Double(); - path.moveTo(xOffset, yOffset); - path.lineTo(xOffset + barWidth, yOffset); - path.lineTo(xOffset + barWidth, zeroOffset); - path.lineTo(xOffset, zeroOffset); - path.closePath(); - g.setStroke(series.getStroke()); - if (getChartPainter().getStyleManager().isBarFilled()) { - g.fill(path); + + // paint series + if (series.getSeriesType() == SeriesType.Bar) { + // paint bar + g.setColor(series.getStrokeColor()); + Path2D.Double path = new Path2D.Double(); + path.moveTo(xOffset, yOffset); + path.lineTo(xOffset + barWidth, yOffset); + path.lineTo(xOffset + barWidth, zeroOffset); + path.lineTo(xOffset, zeroOffset); + path.closePath(); + g.setStroke(series.getStroke()); + if (getChartInternal().getStyleManager().isBarFilled()) { + g.fill(path); + } + else { + g.draw(path); + } } else { - g.draw(path); + + // paint line + if (Series.SeriesType.Line.equals(series.getSeriesType())) { + + if (series.getStroke() != null) { + + if (previousX != -Double.MAX_VALUE && previousY != -Double.MAX_VALUE) { + g.setColor(series.getStrokeColor()); + g.setStroke(series.getStroke()); + Shape line = new Line2D.Double(previousX, previousY, xOffset + barWidth / 2, yOffset); + g.draw(line); + } + } + } + previousX = xOffset + barWidth / 2; + previousY = yOffset; + + // paint marker + if (series.getMarker() != null) { + g.setColor(series.getMarkerColor()); + series.getMarker().paint(g, previousX, previousY, getChartInternal().getStyleManager().getMarkerSize()); + } + } - // paint errorbars + // paint error bars if (errorBars != null) { double eb = ebItr.next().doubleValue(); // set error bar style - if (getChartPainter().getStyleManager().isErrorBarsColorSeriesColor()) { + if (getChartInternal().getStyleManager().isErrorBarsColorSeriesColor()) { g.setColor(series.getStrokeColor()); } else { - g.setColor(getChartPainter().getStyleManager().getErrorBarsColor()); + g.setColor(getChartInternal().getStyleManager().getErrorBarsColor()); } g.setStroke(errorBarStroke); @@ -259,10 +269,4 @@ public class PlotContentBarChart extends PlotContent { g.setClip(null); } - @Override - public ChartPainter getChartPainter() { - - return plot.getChartPainter(); - } - } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Line_Area_Scatter.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Line_Area_Scatter.java new file mode 100644 index 0000000000000000000000000000000000000000..e8be8fe07a861c8df65cde344e5fa3bd5d2004f9 --- /dev/null +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Line_Area_Scatter.java @@ -0,0 +1,281 @@ +/** + * Copyright 2015 Knowm Inc. (http://knowm.org) and contributors. + * Copyright 2011-2015 Xeiam LLC (http://xeiam.com) and contributors. + * + * 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 org.knowm.xchart.internal.chartpart; + +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Line2D; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; +import java.util.Collection; +import java.util.Iterator; + +import org.knowm.xchart.Series; +import org.knowm.xchart.internal.Utils; + +/** + * @author timmolter + */ +public class PlotContentCategoricalChart_Line_Area_Scatter extends PlotContent { + + /** + * Constructor + * + * @param plot + */ + protected PlotContentCategoricalChart_Line_Area_Scatter(Plot plot) { + + super(plot); + } + + @Override + public void paint(Graphics2D g) { + + // logarithmic + // if (getChartInternal().getStyleManager().isYAxisLogarithmic()) { + // throw new IllegalArgumentException("Category Charts cannot have logarithmic axes!!! (Not Yet Implemented)"); + // } + + Rectangle2D bounds = plot.getBounds(); + // g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + // g.setColor(Color.red); + // g.draw(bounds); + + // if the area to draw a chart on is so small, don't even bother + if (bounds.getWidth() < 30) { + return; + } + + // 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 = g.getClipBounds(); + // g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + // g.setColor(Color.green); + // g.draw(rectangle); + + Rectangle2D rectangle = new Rectangle2D.Double(0, 0, getChartInternal().getWidth(), getChartInternal().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.getAxisTickSpacePercentage() * bounds.getWidth(); + double xLeftMargin = Utils.getTickStartOffset((int) bounds.getWidth(), xTickSpace); + + // Y-Axis + double yTickSpace = styleManager.getAxisTickSpacePercentage() * bounds.getHeight(); + double yTopMargin = Utils.getTickStartOffset((int) bounds.getHeight(), yTickSpace); + + double xMin = getChartInternal().getAxisPair().getXAxis().getMin(); + double xMax = getChartInternal().getAxisPair().getXAxis().getMax(); + double yMin = getChartInternal().getAxisPair().getYAxis().getMin(); + double yMax = getChartInternal().getAxisPair().getYAxis().getMax(); + + // logarithmic + if (getChartInternal().getStyleManager().isXAxisLogarithmic()) { + xMin = Math.log10(xMin); + xMax = Math.log10(xMax); + } + if (getChartInternal().getStyleManager().isYAxisLogarithmic()) { + yMin = Math.log10(yMin); + yMax = Math.log10(yMax); + } + + int numCategories = getChartInternal().getSeriesMap().values().iterator().next().getXData().size(); + double gridStep = xTickSpace / numCategories; + + for (Series series : getChartInternal().getSeriesMap().values()) { + + // sanity check + + if (Series.SeriesType.Bar.equals(series.getSeriesType()) || Series.SeriesType.Pie.equals(series.getSeriesType())) { + throw new RuntimeException("Category-Line,Scatter,Area charts only accept Line, Scatter, and Area series types!!!"); + } + + // data points + Collection<? extends Number> yData = series.getYData(); + + double previousX = -Double.MAX_VALUE; + double previousY = -Double.MAX_VALUE; + + Iterator<? extends Number> yItr = yData.iterator(); + Iterator<? extends Number> ebItr = null; + Collection<? extends Number> errorBars = series.getErrorBars(); + if (errorBars != null) { + ebItr = errorBars.iterator(); + } + Path2D.Double path = null; + + int categoryCounter = 0; + while (yItr.hasNext()) { + + Number next = yItr.next(); + if (next == null) { + + // for area charts + closePath(g, path, previousX, bounds, yTopMargin); + path = null; + + previousX = -Double.MAX_VALUE; + previousY = -Double.MAX_VALUE; + continue; + } + + double yOrig = next.doubleValue(); + + double y = 0.0; + + // System.out.println(y); + if (getChartInternal().getStyleManager().isYAxisLogarithmic()) { + y = Math.log10(yOrig); + } + else { + y = yOrig; + } + // System.out.println(y); + + double yTransform = bounds.getHeight() - (yTopMargin + (y - yMin) / (yMax - yMin) * yTickSpace); + + // a check if all y data are the exact same values + if (Math.abs(yMax - yMin) / 5 == 0.0) { + yTransform = bounds.getHeight() / 2.0; + } + + double xOffset = bounds.getX() + xLeftMargin + categoryCounter++ * gridStep + gridStep / 2; + double yOffset = bounds.getY() + yTransform; + // System.out.println(xTransform); + // System.out.println(xOffset); + // System.out.println(yTransform); + // System.out.println(yOffset); + // System.out.println("---"); + + // paint line + if (Series.SeriesType.Line.equals(series.getSeriesType()) || Series.SeriesType.Area.equals(series.getSeriesType())) { + + if (series.getStroke() != null) { + + if (previousX != -Double.MAX_VALUE && previousY != -Double.MAX_VALUE) { + g.setColor(series.getStrokeColor()); + g.setStroke(series.getStroke()); + Shape line = new Line2D.Double(previousX, previousY, xOffset, yOffset); + g.draw(line); + } + } + } + + // paint area + if (Series.SeriesType.Area.equals(series.getSeriesType())) { + + if (previousX != -Double.MAX_VALUE && previousY != -Double.MAX_VALUE) { + + g.setColor(series.getFillColor()); + double yBottomOfArea = bounds.getY() + bounds.getHeight() - yTopMargin; + + if (path == null) { + path = new Path2D.Double(); + path.moveTo(previousX, yBottomOfArea); + path.lineTo(previousX, previousY); + } + path.lineTo(xOffset, yOffset); + } + if (xOffset < previousX) { + throw new RuntimeException("X-Data must be in ascending order for Area Charts!!!"); + } + } + + previousX = xOffset; + previousY = yOffset; + + // paint marker + if (series.getMarker() != null) { + g.setColor(series.getMarkerColor()); + series.getMarker().paint(g, xOffset, yOffset, getChartInternal().getStyleManager().getMarkerSize()); + } + + // paint error bars + if (errorBars != null) { + + double eb = ebItr.next().doubleValue(); + + // set error bar style + if (getChartInternal().getStyleManager().isErrorBarsColorSeriesColor()) { + g.setColor(series.getStrokeColor()); + } + else { + g.setColor(getChartInternal().getStyleManager().getErrorBarsColor()); + } + g.setStroke(errorBarStroke); + + // Top value + double topValue = 0.0; + if (getChartInternal().getStyleManager().isYAxisLogarithmic()) { + topValue = yOrig + eb; + topValue = Math.log10(topValue); + } + else { + topValue = y + eb; + } + double topEBTransform = bounds.getHeight() - (yTopMargin + (topValue - yMin) / (yMax - yMin) * yTickSpace); + double topEBOffset = bounds.getY() + topEBTransform; + + // Bottom value + double bottomValue = 0.0; + if (getChartInternal().getStyleManager().isYAxisLogarithmic()) { + bottomValue = yOrig - eb; + // System.out.println(bottomValue); + bottomValue = Math.log10(bottomValue); + } + else { + bottomValue = y - eb; + } + double bottomEBTransform = bounds.getHeight() - (yTopMargin + (bottomValue - yMin) / (yMax - yMin) * yTickSpace); + double bottomEBOffset = bounds.getY() + bottomEBTransform; + + // Draw it + Shape line = new Line2D.Double(xOffset, topEBOffset, xOffset, bottomEBOffset); + g.draw(line); + line = new Line2D.Double(xOffset - 3, bottomEBOffset, xOffset + 3, bottomEBOffset); + g.draw(line); + line = new Line2D.Double(xOffset - 3, topEBOffset, xOffset + 3, topEBOffset); + g.draw(line); + } + } + + // close any open path for area charts + closePath(g, path, previousX, bounds, yTopMargin); + } + g.setClip(null); + + } + + /** + * Closes a path for area charts if one is available. + */ + private void closePath(Graphics2D g, Path2D.Double path, double previousX, Rectangle2D bounds, double yTopMargin) { + + if (path != null) { + double yBottomOfArea = bounds.getY() + bounds.getHeight() - yTopMargin; + path.lineTo(previousX, yBottomOfArea); + path.closePath(); + g.fill(path); + } + } + +} diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Pie.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Pie.java new file mode 100644 index 0000000000000000000000000000000000000000..5d694dc232f2b765408ebcb41a9e4984ae4aac2a --- /dev/null +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Pie.java @@ -0,0 +1,129 @@ +/** + * Copyright 2015 Knowm Inc. (http://knowm.org) and contributors. + * Copyright 2011-2015 Xeiam LLC (http://xeiam.com) and contributors. + * + * 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 org.knowm.xchart.internal.chartpart; + +import java.awt.Graphics2D; +import java.awt.geom.Arc2D; +import java.awt.geom.Rectangle2D; + +import org.knowm.xchart.Series; + +/** + * @author timmolter + */ +public class PlotContentCategoricalChart_Pie extends PlotContent { + + /** + * Constructor + * + * @param plot + */ + protected PlotContentCategoricalChart_Pie(Plot plot) { + + super(plot); + } + + @Override + public void paint(Graphics2D g) { + + // plot area bounds + Rectangle2D bounds = plot.getBounds(); + // g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + // g.setColor(Color.red); + // g.draw(bounds); + + // if the area to draw a chart on is so small, don't even bother + if (bounds.getWidth() < 30) { + return; + } + + // clip bounds TODO Do we need this? + Rectangle2D rectangle = new Rectangle2D.Double(0, 0, getChartInternal().getWidth(), getChartInternal().getHeight()); + // g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + // g.setColor(Color.green); + // g.draw(rectangle); + g.setClip(bounds.createIntersection(rectangle)); + + // pie bounds + double percentage = .70; + double halfBorderPercentage = (1 - percentage) / 2.0; + Rectangle2D pieBounds = new Rectangle2D.Double(bounds.getX() + bounds.getWidth() * halfBorderPercentage, bounds.getY() + bounds.getHeight() * halfBorderPercentage, bounds.getWidth() * percentage, + bounds.getHeight() * percentage); + // g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); + // g.setColor(Color.black); + // g.draw(pieBounds); + + // get total + double total = 0.0; + for (Series series : getChartInternal().getSeriesMap().values()) { + + String x = (String) series.getXData().iterator().next(); + Number y = series.getYData().iterator().next(); + + total += y.doubleValue(); + } + + // draw pie slices + double curValue = 0.0; + double startAngle = 0; + for (Series series : getChartInternal().getSeriesMap().values()) { + + // String x = (String) series.getXData().iterator().next(); + Number y = series.getYData().iterator().next(); + + startAngle = (curValue * 360 / total); + double arcAngle = (y.doubleValue() * 360 / total); + g.setColor(series.getFillColor()); + g.fill(new Arc2D.Double(pieBounds.getX(), pieBounds.getY(), pieBounds.getWidth(), pieBounds.getHeight(), startAngle, arcAngle, Arc2D.PIE)); + g.setColor(getChartInternal().getStyleManager().getPlotBackgroundColor()); + g.draw(new Arc2D.Double(pieBounds.getX(), pieBounds.getY(), pieBounds.getWidth(), pieBounds.getHeight(), startAngle, arcAngle, Arc2D.PIE)); + curValue += y.doubleValue(); + } + + g.setClip(null); + + } + + // private double[] getPercentageVector(Collection<? extends Number> collection) { + // + // float total = 0.0f; + // + // double[] vectorCenters = new double[collection.size()]; + // Iterator<? extends Number> yItr = collection.iterator(); + // + // int counter = 0; + // while (yItr.hasNext()) { + // + // Number next = yItr.next(); + // + // double y = next.doubleValue(); + // System.out.println(y); + // vectorCenters[counter] = vectorCenters[counter] + y; + // + // total += vectorCenters[counter++]; + // } + // + // double[] vectorPercentages = new double[vectorCenters.length]; + // + // for (int i = 0; i < vectorPercentages.length; i++) { + // vectorPercentages[i] = vectorCenters[i] / total; + // } + // + // return vectorPercentages; + // } + +} diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentLineChart.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentNumericalChart.java similarity index 68% rename from xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentLineChart.java rename to xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentNumericalChart.java index 2dd4d2b46effc488532e50fcee4911d2d41ed547..ac9a5c858786d1b5efda0e9337e9e237b87bf9e9 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentLineChart.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentNumericalChart.java @@ -17,7 +17,6 @@ package org.knowm.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; @@ -27,22 +26,20 @@ import java.util.Date; import java.util.Iterator; import org.knowm.xchart.Series; -import org.knowm.xchart.StyleManager; -import org.knowm.xchart.StyleManager.ChartType; import org.knowm.xchart.internal.Utils; import org.knowm.xchart.internal.chartpart.Axis.AxisType; /** * @author timmolter */ -public class PlotContentLineChart extends PlotContent { +public class PlotContentNumericalChart extends PlotContent { /** * Constructor * * @param plot */ - protected PlotContentLineChart(Plot plot) { + protected PlotContentNumericalChart(Plot plot) { super(plot); } @@ -60,8 +57,6 @@ public class PlotContentLineChart extends PlotContent { return; } - 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 = g.getClipBounds(); @@ -69,7 +64,7 @@ public class PlotContentLineChart extends PlotContent { // g.setColor(Color.green); // g.draw(rectangle); - Rectangle rectangle = new Rectangle(0, 0, getChartPainter().getWidth(), getChartPainter().getHeight()); + Rectangle2D rectangle = new Rectangle2D.Double(0, 0, getChartInternal().getWidth(), getChartInternal().getHeight()); // g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); // g.setColor(Color.green); // g.draw(rectangle); @@ -85,44 +80,34 @@ public class PlotContentLineChart extends PlotContent { double yTickSpace = styleManager.getAxisTickSpacePercentage() * bounds.getHeight(); double yTopMargin = Utils.getTickStartOffset((int) bounds.getHeight(), yTickSpace); - for (Series series : getChartPainter().getAxisPair().getSeriesMap().values()) { + double xMin = getChartInternal().getAxisPair().getXAxis().getMin(); + double xMax = getChartInternal().getAxisPair().getXAxis().getMax(); + double yMin = getChartInternal().getAxisPair().getYAxis().getMin(); + double yMax = getChartInternal().getAxisPair().getYAxis().getMax(); - // data points - Collection<?> xData = series.getXData(); - // System.out.println(xData); - double xMin = getChartPainter().getAxisPair().getXAxis().getMin(); - double xMax = getChartPainter().getAxisPair().getXAxis().getMax(); + // logarithmic + if (getChartInternal().getStyleManager().isXAxisLogarithmic()) { + xMin = Math.log10(xMin); + xMax = Math.log10(xMax); + } + if (getChartInternal().getStyleManager().isYAxisLogarithmic()) { + yMin = Math.log10(yMin); + yMax = Math.log10(yMax); + } - Collection<? extends Number> yData = series.getYData(); - double yMin = getChartPainter().getAxisPair().getYAxis().getMin(); - double yMax = getChartPainter().getAxisPair().getYAxis().getMax(); + for (Series series : getChartInternal().getSeriesMap().values()) { - // override min and maxValue if specified - if (getChartPainter().getStyleManager().getXAxisMin() != null) { - xMin = getChartPainter().getStyleManager().getXAxisMin(); - } - if (getChartPainter().getStyleManager().getYAxisMin() != null) { - yMin = getChartPainter().getStyleManager().getYAxisMin(); - } - if (getChartPainter().getStyleManager().getXAxisMax() != null) { - xMax = getChartPainter().getStyleManager().getXAxisMax(); - } - if (getChartPainter().getStyleManager().getYAxisMax() != null) { - yMax = getChartPainter().getStyleManager().getYAxisMax(); + // sanity check + if (Series.SeriesType.Bar.equals(series.getSeriesType())) { + throw new RuntimeException("X-Y charts only accept Line, Scatter, and Area series types!!!"); } - // logarithmic - if (getChartPainter().getStyleManager().isXAxisLogarithmic()) { - xMin = Math.log10(xMin); - xMax = Math.log10(xMax); - } - if (getChartPainter().getStyleManager().isYAxisLogarithmic()) { - yMin = Math.log10(yMin); - yMax = Math.log10(yMax); - } + // data points + Collection<?> xData = series.getXData(); + Collection<? extends Number> yData = series.getYData(); - double previousX = Integer.MIN_VALUE; - double previousY = Integer.MIN_VALUE; + double previousX = -Double.MAX_VALUE; + double previousY = -Double.MAX_VALUE; Iterator<?> xItr = xData.iterator(); Iterator<? extends Number> yItr = yData.iterator(); @@ -136,18 +121,17 @@ public class PlotContentLineChart extends PlotContent { while (xItr.hasNext()) { double x = 0.0; - if (getChartPainter().getAxisPair().getXAxis().getAxisType() == AxisType.Number) { + if (getChartInternal().getAxisPair().getXAxis().getAxisType() == AxisType.Number) { x = ((Number) xItr.next()).doubleValue(); - // System.out.println(x); } - else if (getChartPainter().getAxisPair().getXAxis().getAxisType() == AxisType.Date) { + else if (getChartInternal().getAxisPair().getXAxis().getAxisType() == AxisType.Date) { x = ((Date) xItr.next()).getTime(); - // System.out.println(x); } - - if (getChartPainter().getStyleManager().isXAxisLogarithmic()) { + // System.out.println(x); + if (getChartInternal().getStyleManager().isXAxisLogarithmic()) { x = Math.log10(x); } + // System.out.println(x); Number next = yItr.next(); if (next == null) { @@ -156,8 +140,8 @@ public class PlotContentLineChart extends PlotContent { closePath(g, path, previousX, bounds, yTopMargin); path = null; - previousX = Integer.MIN_VALUE; - previousY = Integer.MIN_VALUE; + previousX = -Double.MAX_VALUE; + previousY = -Double.MAX_VALUE; continue; } @@ -166,7 +150,7 @@ public class PlotContentLineChart extends PlotContent { double y = 0.0; // System.out.println(y); - if (getChartPainter().getStyleManager().isYAxisLogarithmic()) { + if (getChartInternal().getStyleManager().isYAxisLogarithmic()) { y = Math.log10(yOrig); } else { @@ -189,24 +173,30 @@ public class PlotContentLineChart extends PlotContent { double xOffset = bounds.getX() + xTransform; double yOffset = bounds.getY() + yTransform; - // System.out.println(yOffset); + // System.out.println(xTransform); + // System.out.println(xOffset); // System.out.println(yTransform); + // System.out.println(yOffset); + // System.out.println("---"); // paint line - if (series.getStroke() != null && getChartPainter().getStyleManager().getChartType() != ChartType.Scatter) { + if (Series.SeriesType.Line.equals(series.getSeriesType()) || Series.SeriesType.Area.equals(series.getSeriesType())) { - if (previousX != Integer.MIN_VALUE && previousY != Integer.MIN_VALUE) { - g.setColor(series.getStrokeColor()); - g.setStroke(series.getStroke()); - Shape line = new Line2D.Double(previousX, previousY, xOffset, yOffset); - g.draw(line); + if (series.getStroke() != null) { + + if (previousX != -Double.MAX_VALUE && previousY != -Double.MAX_VALUE) { + g.setColor(series.getStrokeColor()); + g.setStroke(series.getStroke()); + Shape line = new Line2D.Double(previousX, previousY, xOffset, yOffset); + g.draw(line); + } } } // paint area - if (getChartPainter().getStyleManager().getChartType() == ChartType.Area || Series.SeriesType.Area.equals(series.getSeriesType())) { + if (Series.SeriesType.Area.equals(series.getSeriesType())) { - if (previousX != Integer.MIN_VALUE && previousY != Integer.MIN_VALUE) { + if (previousX != -Double.MAX_VALUE && previousY != -Double.MAX_VALUE) { g.setColor(series.getFillColor()); double yBottomOfArea = bounds.getY() + bounds.getHeight() - yTopMargin; @@ -229,26 +219,26 @@ public class PlotContentLineChart extends PlotContent { // paint marker if (series.getMarker() != null) { g.setColor(series.getMarkerColor()); - series.getMarker().paint(g, xOffset, yOffset, getChartPainter().getStyleManager().getMarkerSize()); + series.getMarker().paint(g, xOffset, yOffset, getChartInternal().getStyleManager().getMarkerSize()); } - // paint errorbars + // paint error bars if (errorBars != null) { double eb = ebItr.next().doubleValue(); // set error bar style - if (getChartPainter().getStyleManager().isErrorBarsColorSeriesColor()) { + if (getChartInternal().getStyleManager().isErrorBarsColorSeriesColor()) { g.setColor(series.getStrokeColor()); } else { - g.setColor(getChartPainter().getStyleManager().getErrorBarsColor()); + g.setColor(getChartInternal().getStyleManager().getErrorBarsColor()); } g.setStroke(errorBarStroke); // Top value double topValue = 0.0; - if (getChartPainter().getStyleManager().isYAxisLogarithmic()) { + if (getChartInternal().getStyleManager().isYAxisLogarithmic()) { topValue = yOrig + eb; topValue = Math.log10(topValue); } @@ -260,7 +250,7 @@ public class PlotContentLineChart extends PlotContent { // Bottom value double bottomValue = 0.0; - if (getChartPainter().getStyleManager().isYAxisLogarithmic()) { + if (getChartInternal().getStyleManager().isYAxisLogarithmic()) { bottomValue = yOrig - eb; // System.out.println(bottomValue); bottomValue = Math.log10(bottomValue); diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotSurface.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotSurface.java index b21d3226ca797d0bb6c80e31c907681c7995b1f3..ad6f11f50d3546756ee6e27e1f204e164888e1f0 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotSurface.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotSurface.java @@ -23,6 +23,7 @@ import java.awt.geom.Rectangle2D; import java.util.List; import org.knowm.xchart.StyleManager.ChartType; +import org.knowm.xchart.internal.chartpart.ChartInternal.ChartInternalType; /** * Draws the plot background, the plot border and the horizontal and vertical grid lines @@ -57,24 +58,24 @@ public class PlotSurface implements ChartPart { // paint plot background Shape rect = new Rectangle2D.Double(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight()); - g.setColor(getChartPainter().getStyleManager().getPlotBackgroundColor()); + g.setColor(getChartInternal().getStyleManager().getPlotBackgroundColor()); g.fill(rect); // paint plot border - if (getChartPainter().getStyleManager().isPlotBorderVisible()) { - g.setColor(getChartPainter().getStyleManager().getPlotBorderColor()); + if (getChartInternal().getStyleManager().isPlotBorderVisible()) { + g.setColor(getChartInternal().getStyleManager().getPlotBorderColor()); // g.setStroke(getChartPainter().getStyleManager().getAxisTickMarksStroke()); g.draw(rect); } // paint grid lines and/or inner plot ticks - if (getChartPainter().getStyleManager().isPlotGridHorizontalLinesVisible() - || getChartPainter().getStyleManager().isPlotGridVerticalLinesVisible() - || getChartPainter().getStyleManager().isPlotTicksMarksVisible() - ) { + if (getChartInternal().getAxisPair().getYAxis().getAxisTickCalculator() == null) {// like for Pie Charts + return; + } - // horizontal - List<Double> yAxisTickLocations = getChartPainter().getAxisPair().getYAxis().getAxisTickCalculator().getTickLocations(); + // horizontal + if (getChartInternal().getStyleManager().isPlotGridHorizontalLinesVisible() || getChartInternal().getStyleManager().isPlotTicksMarksVisible()) { + List<Double> yAxisTickLocations = getChartInternal().getAxisPair().getYAxis().getAxisTickCalculator().getTickLocations(); for (int i = 0; i < yAxisTickLocations.size(); i++) { double yOffset = bounds.getY() + bounds.getHeight() - yAxisTickLocations.get(i); @@ -82,37 +83,35 @@ public class PlotSurface implements ChartPart { if (yOffset > bounds.getY() && yOffset < bounds.getY() + bounds.getHeight()) { // draw lines - if (getChartPainter().getStyleManager().isPlotGridHorizontalLinesVisible()) { + if (getChartInternal().getStyleManager().isPlotGridHorizontalLinesVisible()) { - g.setColor(getChartPainter().getStyleManager().getPlotGridLinesColor()); - g.setStroke(getChartPainter().getStyleManager().getPlotGridLinesStroke()); + g.setColor(getChartInternal().getStyleManager().getPlotGridLinesColor()); + g.setStroke(getChartInternal().getStyleManager().getPlotGridLinesStroke()); Shape line = new Line2D.Double(bounds.getX(), yOffset, bounds.getX() + bounds.getWidth(), yOffset); g.draw(line); } // tick marks - if (getChartPainter().getStyleManager().isPlotTicksMarksVisible()) { + if (getChartInternal().getStyleManager().isPlotTicksMarksVisible()) { - g.setColor(getChartPainter().getStyleManager().getAxisTickMarksColor()); - g.setStroke(getChartPainter().getStyleManager().getAxisTickMarksStroke()); - Shape line = new Line2D.Double(bounds.getX(), yOffset, bounds.getX() + getChartPainter().getStyleManager().getAxisTickMarkLength(), yOffset); + g.setColor(getChartInternal().getStyleManager().getAxisTickMarksColor()); + g.setStroke(getChartInternal().getStyleManager().getAxisTickMarksStroke()); + Shape line = new Line2D.Double(bounds.getX(), yOffset, bounds.getX() + getChartInternal().getStyleManager().getAxisTickMarkLength(), yOffset); g.draw(line); - line = new Line2D.Double(bounds.getX() + bounds.getWidth(), yOffset, bounds.getX() + bounds.getWidth() - getChartPainter().getStyleManager().getAxisTickMarkLength(), yOffset); + line = new Line2D.Double(bounds.getX() + bounds.getWidth(), yOffset, bounds.getX() + bounds.getWidth() - getChartInternal().getStyleManager().getAxisTickMarkLength(), yOffset); g.draw(line); } } } + } - // vertical - if (getChartPainter().getStyleManager().getChartType() != ChartType.Bar - - && (getChartPainter().getStyleManager().isPlotGridVerticalLinesVisible() - - || getChartPainter().getStyleManager().isPlotTicksMarksVisible()) + // vertical + if ((getChartInternal().getChartInternalType() == ChartInternalType.XY || (getChartInternal().getChartInternalType() == ChartInternalType.Category && getChartInternal().getStyleManager() + .getChartType() != ChartType.Bar))) { - ) { + if ((getChartInternal().getStyleManager().isPlotGridVerticalLinesVisible() || getChartInternal().getStyleManager().isPlotTicksMarksVisible())) { - List<Double> xAxisTickLocations = getChartPainter().getAxisPair().getXAxis().getAxisTickCalculator().getTickLocations(); + List<Double> xAxisTickLocations = getChartInternal().getAxisPair().getXAxis().getAxisTickCalculator().getTickLocations(); for (int i = 0; i < xAxisTickLocations.size(); i++) { double tickLocation = xAxisTickLocations.get(i); @@ -121,22 +120,22 @@ public class PlotSurface implements ChartPart { if (xOffset > bounds.getX() && xOffset < bounds.getX() + bounds.getWidth()) { // draw lines - if (getChartPainter().getStyleManager().isPlotGridVerticalLinesVisible()) { - g.setColor(getChartPainter().getStyleManager().getPlotGridLinesColor()); - g.setStroke(getChartPainter().getStyleManager().getPlotGridLinesStroke()); + if (getChartInternal().getStyleManager().isPlotGridVerticalLinesVisible()) { + g.setColor(getChartInternal().getStyleManager().getPlotGridLinesColor()); + g.setStroke(getChartInternal().getStyleManager().getPlotGridLinesStroke()); Shape line = new Line2D.Double(xOffset, bounds.getY(), xOffset, bounds.getY() + bounds.getHeight()); g.draw(line); } // tick marks - if (getChartPainter().getStyleManager().isPlotTicksMarksVisible()) { + if (getChartInternal().getStyleManager().isPlotTicksMarksVisible()) { - g.setColor(getChartPainter().getStyleManager().getAxisTickMarksColor()); - g.setStroke(getChartPainter().getStyleManager().getAxisTickMarksStroke()); + g.setColor(getChartInternal().getStyleManager().getAxisTickMarksColor()); + g.setStroke(getChartInternal().getStyleManager().getAxisTickMarksStroke()); - Shape line = new Line2D.Double(xOffset, bounds.getY(), xOffset, bounds.getY() + getChartPainter().getStyleManager().getAxisTickMarkLength()); + Shape line = new Line2D.Double(xOffset, bounds.getY(), xOffset, bounds.getY() + getChartInternal().getStyleManager().getAxisTickMarkLength()); g.draw(line); - line = new Line2D.Double(xOffset, bounds.getY() + bounds.getHeight(), xOffset, bounds.getY() + bounds.getHeight() - getChartPainter().getStyleManager().getAxisTickMarkLength()); + line = new Line2D.Double(xOffset, bounds.getY() + bounds.getHeight(), xOffset, bounds.getY() + bounds.getHeight() - getChartInternal().getStyleManager().getAxisTickMarkLength()); g.draw(line); } } @@ -146,9 +145,9 @@ public class PlotSurface implements ChartPart { } @Override - public ChartPainter getChartPainter() { + public ChartInternal getChartInternal() { - return plot.getChartPainter(); + return plot.getChartInternal(); } } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/style/GGPlot2Theme.java b/xchart/src/main/java/org/knowm/xchart/internal/style/GGPlot2Theme.java index 24a6337bbb573091586b7f1add5e4adba5761349..ac9a333526090be89bef6f9e5decd8c5ac780299 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/style/GGPlot2Theme.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/style/GGPlot2Theme.java @@ -20,8 +20,13 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Stroke; +import java.util.ArrayList; +import java.util.List; import org.knowm.xchart.ChartColor; +import org.knowm.xchart.SeriesColor; +import org.knowm.xchart.SeriesLineStyle; +import org.knowm.xchart.SeriesMarker; import org.knowm.xchart.StyleManager.LegendPosition; /** @@ -29,6 +34,22 @@ import org.knowm.xchart.StyleManager.LegendPosition; */ public class GGPlot2Theme implements Theme { + // The color blind friendly palette + // public static SeriesColor BLACK = new SeriesColor(0, 0, 0, 255); + // public static SeriesColor ORANGE = new SeriesColor(230, 159, 0, 255); + // public static SeriesColor SKY_BLUE = new SeriesColor(86, 180, 233, 255); + // public static SeriesColor BLUISH_GREEN = new SeriesColor(0, 158, 115, 255); + // public static SeriesColor YELLOW = new SeriesColor(240, 228, 66, 255); + // public static SeriesColor BLUE = new SeriesColor(0, 114, 178, 255); + // public static SeriesColor VERMILLION = new SeriesColor(213, 94, 0, 255); + // public static SeriesColor REDDISH_PURPLE = new SeriesColor(204, 121, 167, 255); + + public static SeriesColor RED = new SeriesColor(248, 118, 109, 255); + public static SeriesColor YELLOW_GREEN = new SeriesColor(163, 165, 0, 255); + public static SeriesColor GREEN = new SeriesColor(0, 191, 125, 255); + public static SeriesColor BLUE = new SeriesColor(0, 176, 246, 255); + public static SeriesColor PURPLE = new SeriesColor(231, 107, 243, 255); + // Chart Style /////////////////////////////// @Override @@ -49,6 +70,12 @@ public class GGPlot2Theme implements Theme { return 10; } + @Override + public SeriesColorMarkerLineStyleCycler getSeriesColorMarkerLineStyleCycler() { + + return new XChartSeriesColorMarkerLineStyleCycler(); + } + // Chart Title /////////////////////////////// @Override @@ -244,20 +271,18 @@ public class GGPlot2Theme implements Theme { return true; } - @Override public boolean isPlotGridVerticalLinesVisible() { return true; } - @Override public boolean isPlotGridHorizontalLinesVisible() { return true; } - + @Override public Color getPlotBackgroundColor() { @@ -335,4 +360,54 @@ public class GGPlot2Theme implements Theme { return false; } + + public class XChartSeriesColorMarkerLineStyleCycler extends SeriesColorMarkerLineStyleCycler { + + @Override + public List<SeriesColor> getSeriesColorList() { + + // 1. Color + List<SeriesColor> seriesColorMap = new ArrayList<SeriesColor>(); + + // The color blind friendly palette + // seriesColorMap.add(BLACK); + // seriesColorMap.add(ORANGE); + // seriesColorMap.add(SKY_BLUE); + // seriesColorMap.add(BLUISH_GREEN); + // seriesColorMap.add(YELLOW); + // seriesColorMap.add(BLUE); + // seriesColorMap.add(VERMILLION); + // seriesColorMap.add(REDDISH_PURPLE); + + seriesColorMap.add(RED); + seriesColorMap.add(YELLOW_GREEN); + seriesColorMap.add(GREEN); + seriesColorMap.add(BLUE); + seriesColorMap.add(PURPLE); + + return seriesColorMap; + } + + @Override + public List<SeriesMarker> getSeriesMarkerList() { + + // 2. Marker + List<SeriesMarker> seriesMarkerList = new ArrayList<SeriesMarker>(); + seriesMarkerList.add(SeriesMarker.CIRCLE); + seriesMarkerList.add(SeriesMarker.DIAMOND); + return seriesMarkerList; + } + + @Override + public List<SeriesLineStyle> getLineStyleList() { + + // 3. Stroke + List<SeriesLineStyle> seriesLineStyleList = new ArrayList<SeriesLineStyle>(); + seriesLineStyleList.add(SeriesLineStyle.SOLID); + seriesLineStyleList.add(SeriesLineStyle.DOT_DOT); + seriesLineStyleList.add(SeriesLineStyle.DASH_DASH); + return seriesLineStyleList; + } + + } } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/style/MatlabTheme.java b/xchart/src/main/java/org/knowm/xchart/internal/style/MatlabTheme.java index f0b3f780766798f436ff2fc848d10f1cf105dbd4..8996dde5939b078e418665ef002f3fce255cd57e 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/style/MatlabTheme.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/style/MatlabTheme.java @@ -20,8 +20,13 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Stroke; +import java.util.ArrayList; +import java.util.List; import org.knowm.xchart.ChartColor; +import org.knowm.xchart.SeriesColor; +import org.knowm.xchart.SeriesLineStyle; +import org.knowm.xchart.SeriesMarker; import org.knowm.xchart.StyleManager.LegendPosition; /** @@ -29,6 +34,14 @@ import org.knowm.xchart.StyleManager.LegendPosition; */ public class MatlabTheme implements Theme { + public static SeriesColor BLUE = new SeriesColor(0, 0, 255, 255); + public static SeriesColor GREEN = new SeriesColor(0, 128, 0, 255); + public static SeriesColor RED = new SeriesColor(255, 0, 0, 255); + public static SeriesColor TURQUOISE = new SeriesColor(0, 191, 191, 255); + public static SeriesColor MAGENTA = new SeriesColor(191, 0, 191, 255); + public static SeriesColor YELLOW = new SeriesColor(191, 191, 0, 255); + public static SeriesColor DARK_GREY = new SeriesColor(64, 64, 64, 255); + // Chart Style /////////////////////////////// @Override @@ -49,6 +62,12 @@ public class MatlabTheme implements Theme { return 10; } + @Override + public SeriesColorMarkerLineStyleCycler getSeriesColorMarkerLineStyleCycler() { + + return new MatlabSeriesColorMarkerLineStyleCycler(); + } + // Chart Title /////////////////////////////// @Override @@ -249,13 +268,13 @@ public class MatlabTheme implements Theme { return true; } - + @Override public boolean isPlotGridHorizontalLinesVisible() { return true; } - + @Override public Color getPlotBackgroundColor() { @@ -334,4 +353,43 @@ public class MatlabTheme implements Theme { return false; } + + public class MatlabSeriesColorMarkerLineStyleCycler extends SeriesColorMarkerLineStyleCycler { + + @Override + public List<SeriesColor> getSeriesColorList() { + + // 1. Color + List<SeriesColor> seriesColorMap = new ArrayList<SeriesColor>(); + seriesColorMap.add(BLUE); + seriesColorMap.add(GREEN); + seriesColorMap.add(RED); + seriesColorMap.add(TURQUOISE); + seriesColorMap.add(MAGENTA); + seriesColorMap.add(YELLOW); + seriesColorMap.add(DARK_GREY); + return seriesColorMap; + } + + @Override + public List<SeriesMarker> getSeriesMarkerList() { + + // 2. Marker + List<SeriesMarker> seriesMarkerList = new ArrayList<SeriesMarker>(); + seriesMarkerList.add(SeriesMarker.NONE); + return seriesMarkerList; + } + + @Override + public List<SeriesLineStyle> getLineStyleList() { + + // 3. Stroke + List<SeriesLineStyle> seriesLineStyleList = new ArrayList<SeriesLineStyle>(); + seriesLineStyleList.add(SeriesLineStyle.SOLID); + seriesLineStyleList.add(SeriesLineStyle.DASH_DASH); + seriesLineStyleList.add(SeriesLineStyle.DOT_DOT); + return seriesLineStyleList; + } + + } } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/style/SeriesColorMarkerLineStyleCycler.java b/xchart/src/main/java/org/knowm/xchart/internal/style/SeriesColorMarkerLineStyleCycler.java index f73af62a83a857cae352931c027c78715844e439..31399dcb7a329a27aa8f162421d313d6e84e1f40 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/style/SeriesColorMarkerLineStyleCycler.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/style/SeriesColorMarkerLineStyleCycler.java @@ -16,9 +16,7 @@ */ package org.knowm.xchart.internal.style; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.Map; +import java.util.List; import org.knowm.xchart.SeriesColor; import org.knowm.xchart.SeriesLineStyle; @@ -28,19 +26,25 @@ import org.knowm.xchart.SeriesMarker; * Cycles through the different colors, markers, and strokes in a predetermined way * <p> * This is an internal class that should not be used be clients - * + * * @author timmolter */ -public class SeriesColorMarkerLineStyleCycler { +public abstract class SeriesColorMarkerLineStyleCycler { + + public abstract List<SeriesColor> getSeriesColorList(); + + public abstract List<SeriesMarker> getSeriesMarkerList(); - /** a map holding the SeriesColors */ - private final Map<Integer, SeriesColor> seriesColorMap = new HashMap<Integer, SeriesColor>(); + public abstract List<SeriesLineStyle> getLineStyleList(); + + /** a List holding the SeriesColors */ + private final List<SeriesColor> seriesColorList; /** a map holding the SeriesMarkers */ - private final Map<Integer, SeriesMarker> seriesMarkerMap = new HashMap<Integer, SeriesMarker>(); + private final List<SeriesMarker> seriesMarkerList; /** a map holding the SeriesLineStyles */ - private final Map<Integer, SeriesLineStyle> seriesLineStyleMap = new HashMap<Integer, SeriesLineStyle>(); + private final List<SeriesLineStyle> seriesLineStyleList; /** an internal counter */ private int colorCounter = 0; @@ -52,51 +56,36 @@ public class SeriesColorMarkerLineStyleCycler { */ public SeriesColorMarkerLineStyleCycler() { - // 1. Color - for (SeriesColor seriesColor : EnumSet.allOf(SeriesColor.class)) { - seriesColorMap.put(seriesColor.getIndex(), seriesColor); - } - - // 2. Marker - for (SeriesMarker seriesMarker : EnumSet.allOf(SeriesMarker.class)) { - if (seriesMarker.getIndex() >= 0) { // skip SeriesMarker.NONE - seriesMarkerMap.put(seriesMarker.getIndex(), seriesMarker); - } - } - - // 3. Stroke - for (SeriesLineStyle seriesLineStyle : EnumSet.allOf(SeriesLineStyle.class)) { - if (seriesLineStyle.getIndex() >= 0) { // skip SeriesLineStyle.NONE - seriesLineStyleMap.put(seriesLineStyle.getIndex(), seriesLineStyle); - } - } + seriesColorList = getSeriesColorList(); + seriesMarkerList = getSeriesMarkerList(); + seriesLineStyleList = getLineStyleList(); } /** * Get the next SeriesColorMarkerLineStyle - * + * * @return the next SeriesColorMarkerLineStyle */ public SeriesColorMarkerLineStyle getNextSeriesColorMarkerLineStyle() { // 1. Color - cycle through colors one by one - if (colorCounter >= seriesColorMap.size()) { + if (colorCounter >= seriesColorList.size()) { colorCounter = 0; strokeCounter++; } - SeriesColor seriesColor = seriesColorMap.get(colorCounter++); + SeriesColor seriesColor = seriesColorList.get(colorCounter++); // 2. Stroke - cycle through strokes one by one but only after a color cycle - if (strokeCounter >= seriesLineStyleMap.size()) { + if (strokeCounter >= seriesLineStyleList.size()) { strokeCounter = 0; } - SeriesLineStyle seriesLineStyle = seriesLineStyleMap.get(strokeCounter); + SeriesLineStyle seriesLineStyle = seriesLineStyleList.get(strokeCounter); // 3. Marker - cycle through markers one by one - if (markerCounter >= seriesMarkerMap.size()) { + if (markerCounter >= seriesMarkerList.size()) { markerCounter = 0; } - SeriesMarker marker = seriesMarkerMap.get(markerCounter++); + SeriesMarker marker = seriesMarkerList.get(markerCounter++); return new SeriesColorMarkerLineStyle(seriesColor.getColor(), marker.getMarker(), seriesLineStyle.getBasicStroke()); } diff --git a/xchart/src/main/java/org/knowm/xchart/internal/style/Theme.java b/xchart/src/main/java/org/knowm/xchart/internal/style/Theme.java index c593bf92c572d4cf3ed58e3888368589188f4d6b..84dfdff38f40fd9df292ed8d9378f1f9e9df1cc0 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/style/Theme.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/style/Theme.java @@ -35,6 +35,8 @@ public interface Theme { public int getChartPadding(); + public SeriesColorMarkerLineStyleCycler getSeriesColorMarkerLineStyleCycler(); + // Chart Title /////////////////////////////// public Font getChartTitleFont(); @@ -104,9 +106,9 @@ public interface Theme { // Chart Plot Area /////////////////////////////// public boolean isPlotGridLinesVisible(); - + public boolean isPlotGridVerticalLinesVisible(); - + public boolean isPlotGridHorizontalLinesVisible(); public Color getPlotBackgroundColor(); diff --git a/xchart/src/main/java/org/knowm/xchart/internal/style/XChartTheme.java b/xchart/src/main/java/org/knowm/xchart/internal/style/XChartTheme.java index fb69b0610c7d0d68927edb152a646bdc353c9a3e..ff561f759a671b1501bc76cc22e7fdff35f04baf 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/style/XChartTheme.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/style/XChartTheme.java @@ -20,8 +20,14 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Stroke; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; import org.knowm.xchart.ChartColor; +import org.knowm.xchart.SeriesColor; +import org.knowm.xchart.SeriesLineStyle; +import org.knowm.xchart.SeriesMarker; import org.knowm.xchart.StyleManager.LegendPosition; /** @@ -29,6 +35,30 @@ import org.knowm.xchart.StyleManager.LegendPosition; */ public class XChartTheme implements Theme { + // original XChart colors + // public static SeriesColor BLUE = new SeriesColor(0, 55, 255, 180); + // public static SeriesColor ORANGE = new SeriesColor(255, 172, 0, 180); + // public static SeriesColor PURPLE = new SeriesColor(128, 0, 255, 180); + // public static SeriesColor GREEN = new SeriesColor(0, 205, 0, 180); + // public static SeriesColor RED = new SeriesColor(205, 0, 0, 180); + // public static SeriesColor YELLOW = new SeriesColor(255, 215, 0, 180); + // public static SeriesColor MAGENTA = new SeriesColor(255, 0, 255, 180); + // public static SeriesColor PINK = new SeriesColor(255, 166, 201, 180); + // public static SeriesColor LIGHT_GREY = new SeriesColor(207, 207, 207, 180); + // public static SeriesColor CYAN = new SeriesColor(0, 255, 255, 180); + // public static SeriesColor BROWN = new SeriesColor(102, 56, 10, 180); + // public static SeriesColor BLACK = new SeriesColor(0, 0, 0, 180); + + // printer-friendly colors from http://colorbrewer2.org/ + public static SeriesColor RED = new SeriesColor(228, 26, 28, 180); + public static SeriesColor GREEN = new SeriesColor(55, 126, 184, 180); + public static SeriesColor BLUE = new SeriesColor(77, 175, 74, 180); + public static SeriesColor PURPLE = new SeriesColor(152, 78, 163, 180); + public static SeriesColor ORANGE = new SeriesColor(255, 127, 0, 180); + // public static SeriesColor YELLOW = new SeriesColor(255, 255, 51, 180); + // public static SeriesColor BROWN = new SeriesColor(166, 86, 40, 180); + // public static SeriesColor PINK = new SeriesColor(247, 129, 191, 180); + // Chart Style /////////////////////////////// @Override @@ -49,6 +79,12 @@ public class XChartTheme implements Theme { return 10; } + @Override + public SeriesColorMarkerLineStyleCycler getSeriesColorMarkerLineStyleCycler() { + + return new XChartSeriesColorMarkerLineStyleCycler(); + } + // Chart Title /////////////////////////////// @Override @@ -249,13 +285,13 @@ public class XChartTheme implements Theme { return true; } - + @Override public boolean isPlotGridHorizontalLinesVisible() { return true; } - + @Override public Color getPlotBackgroundColor() { @@ -334,4 +370,64 @@ public class XChartTheme implements Theme { return false; } + public class XChartSeriesColorMarkerLineStyleCycler extends SeriesColorMarkerLineStyleCycler { + + @Override + public List<SeriesColor> getSeriesColorList() { + + // 1. Color + List<SeriesColor> seriesColorMap = new ArrayList<SeriesColor>(); + // seriesColorMap.add(BLUE); + // seriesColorMap.add(ORANGE); + // seriesColorMap.add(PURPLE); + // seriesColorMap.add(GREEN); + // seriesColorMap.add(RED); + // seriesColorMap.add(YELLOW); + // seriesColorMap.add(MAGENTA); + // seriesColorMap.add(PINK); + // seriesColorMap.add(LIGHT_GREY); + // seriesColorMap.add(CYAN); + // seriesColorMap.add(BROWN); + // seriesColorMap.add(BLACK); + + seriesColorMap.add(RED); + seriesColorMap.add(GREEN); + seriesColorMap.add(BLUE); + seriesColorMap.add(PURPLE); + seriesColorMap.add(ORANGE); + // seriesColorMap.add(YELLOW); + // seriesColorMap.add(BROWN); + // seriesColorMap.add(PINK); + + return seriesColorMap; + } + + @Override + public List<SeriesMarker> getSeriesMarkerList() { + + // 2. Marker + List<SeriesMarker> seriesMarkerList = new ArrayList<SeriesMarker>(); + for (SeriesMarker seriesMarker : EnumSet.allOf(SeriesMarker.class)) { + if (seriesMarker.getIndex() >= 0) { // skip SeriesMarker.NONE + seriesMarkerList.add(seriesMarker); + } + } + return seriesMarkerList; + } + + @Override + public List<SeriesLineStyle> getLineStyleList() { + + // 3. Stroke + List<SeriesLineStyle> seriesLineStyleList = new ArrayList<SeriesLineStyle>(); + for (SeriesLineStyle seriesLineStyle : EnumSet.allOf(SeriesLineStyle.class)) { + if (seriesLineStyle.getIndex() >= 0) { // skip SeriesLineStyle.NONE + seriesLineStyleList.add(seriesLineStyle); + } + } + return seriesLineStyleList; + } + + } + }