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