From 65d314b433941099983456d41523085e65688845 Mon Sep 17 00:00:00 2001 From: Tim Molter <tim@knowm.org> Date: Sun, 3 Jan 2016 00:28:38 +0100 Subject: [PATCH] issue #121 new chart type: category with line, scatter, area series --- .../org/knowm/xchart/demo/XChartDemo.java | 8 + .../xchart/demo/charts/bar/BarChart09.java | 118 ++------ .../xchart/demo/charts/bar/BarChart10.java | 70 ----- .../xchart/demo/charts/line/LineChart07.java | 106 +++++++ .../PlotContentCategoricalChart_Bar.java | 6 - ...entCategoricalChart_Line_Area_Scatter.java | 281 ++++++++++++++++++ 6 files changed, 413 insertions(+), 176 deletions(-) delete mode 100644 xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart10.java create mode 100644 xchart-demo/src/main/java/org/knowm/xchart/demo/charts/line/LineChart07.java create mode 100644 xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Line_Area_Scatter.java 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 7cacab7e..705ed00e 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,7 @@ 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.realtime.RealtimeChart01; import org.knowm.xchart.demo.charts.realtime.RealtimeChart02; import org.knowm.xchart.demo.charts.realtime.RealtimeChart03; @@ -239,6 +241,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 +288,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/BarChart09.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart09.java index 112736a3..0920bc39 100644 --- 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 @@ -16,13 +16,13 @@ */ package org.knowm.xchart.demo.charts.bar; +import java.util.ArrayList; import java.util.Arrays; -import java.util.List; 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.SeriesMarker; import org.knowm.xchart.StyleManager.ChartTheme; import org.knowm.xchart.StyleManager.ChartType; import org.knowm.xchart.StyleManager.LegendPosition; @@ -30,11 +30,11 @@ import org.knowm.xchart.SwingWrapper; import org.knowm.xchart.demo.charts.ExampleChart; /** - * Category chart with Bar and Line Series + * Category chart with Bar, Line and Scatter Series * <p> * Demonstrates the following: * <ul> - * <li>Mixed series types - Bar and Line + * <li>Mixed series types - Bar, Line and Scatter * <li>Bar Chart styles - overlapped, bar width */ public class BarChart09 implements ExampleChart { @@ -48,105 +48,23 @@ public class BarChart09 implements ExampleChart { @Override public Chart getChart() { + // Create Chart - Chart chart = new Chart(1024, 768, ChartTheme.GGPlot2); - chart.getStyleManager().setChartType(ChartType.Bar); - - // 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); + 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); - // 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); - } + // 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/bar/BarChart10.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart10.java deleted file mode 100644 index 331739b1..00000000 --- a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart10.java +++ /dev/null @@ -1,70 +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.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 and Line Series - * <p> - * Demonstrates the following: - * <ul> - * <li>Mixed series types - Bar, Line and Scatter - * <li>Bar Chart styles - overlapped, bar width - */ -public class BarChart10 implements ExampleChart { - - public static void main(String[] args) { - - ExampleChart exampleChart = new BarChart10(); - 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(.7); - chart.getStyleManager().setBarsOverlapped(true); - - return chart; - } - -} 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 00000000..4cfb4634 --- /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/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Bar.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Bar.java index 50ffed7a..38e2eeae 100644 --- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Bar.java +++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContentCategoricalChart_Bar.java @@ -262,10 +262,4 @@ public class PlotContentCategoricalChart_Bar extends PlotContent { g.setClip(null); } - @Override - public ChartInternal getChartInternal() { - - return plot.getChartInternal(); - } - } 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 00000000..6baa1f65 --- /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.Rectangle; +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); + + Rectangle rectangle = new Rectangle(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())) { + 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); + } + } + +} -- GitLab