diff --git a/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart12.java b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart12.java
new file mode 100644
index 000000000..a09846fa3
--- /dev/null
+++ b/xchart-demo/src/main/java/org/knowm/xchart/demo/charts/bar/BarChart12.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2024 EnergĂa Plus. All rights reserved.
+ */
+
+package org.knowm.xchart.demo.charts.bar;
+
+import org.knowm.xchart.CategoryChart;
+import org.knowm.xchart.CategoryChartBuilder;
+import org.knowm.xchart.CategorySeries;
+import org.knowm.xchart.SwingWrapper;
+import org.knowm.xchart.demo.charts.ExampleChart;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Stacked Bars with Overlapped Line Chart
+ *
+ *
Demonstrates the following:
+ *
+ *
+ * - bar series are stacked
+ *
- line series is overlapped
+ */
+public class BarChart12 implements ExampleChart {
+
+ public static void main(String[] args) {
+
+ ExampleChart exampleChart = new BarChart12();
+ CategoryChart chart = exampleChart.getChart();
+ new SwingWrapper<>(chart).displayChart();
+ }
+
+ private static List getMonths() {
+ return Arrays.asList(
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
+ }
+
+ private static List getRandomValues(int count) {
+
+ List values = new ArrayList<>(count);
+ Random rand = new Random();
+ for (int i = 0; i < count; i++) {
+ values.add(rand.nextDouble() * 1000);
+ }
+ return values;
+ }
+
+ @Override
+ public CategoryChart getChart() {
+
+ // Create Chart
+ CategoryChart chart =
+ new CategoryChartBuilder()
+ .width(800)
+ .height(600)
+ .title(getClass().getSimpleName())
+ .xAxisTitle("Month")
+ .yAxisTitle("Consumption")
+ .build();
+
+ // Customize Chart
+ chart.getStyler().setPlotGridVerticalLinesVisible(false);
+ chart.getStyler().setLegendVisible(true);
+ chart.getStyler().setStacked(true);
+ chart
+ .getStyler()
+ .setSeriesColors(
+ new Color[] {
+ Color.decode("#2133D0"),
+ Color.decode("#FF3B47"),
+ Color.decode("#FFBD00"),
+ Color.DARK_GRAY
+ });
+
+ List months = getMonths();
+ List period1Values = getRandomValues(12);
+ List period2Values = getRandomValues(12);
+ List period3Values = getRandomValues(12);
+ List averageValues = new ArrayList<>();
+ for (int i = 0; i < 12; i++) {
+ averageValues.add((period1Values.get(i) + period2Values.get(i) + period3Values.get(i)) / 3);
+ }
+
+ // Series
+ CategorySeries staked1 = chart.addSeries("Period 1", months, period1Values);
+ CategorySeries staked2 = chart.addSeries("Period 2", months, period2Values);
+ CategorySeries staked3 = chart.addSeries("Period 3", months, period3Values);
+ CategorySeries overlappedLine = chart.addSeries("Average", months, averageValues);
+ overlappedLine.setOverlapped(true);
+ overlappedLine.setChartCategorySeriesRenderStyle(CategorySeries.CategorySeriesRenderStyle.Line);
+
+ return chart;
+ }
+
+ @Override
+ public String getExampleChartName() {
+
+ return getClass().getSimpleName() + " - Stacked Bars with Overlapped Line Chart";
+ }
+}
diff --git a/xchart/src/main/java/org/knowm/xchart/CategorySeries.java b/xchart/src/main/java/org/knowm/xchart/CategorySeries.java
index 0b767e8e1..d284e8ec9 100644
--- a/xchart/src/main/java/org/knowm/xchart/CategorySeries.java
+++ b/xchart/src/main/java/org/knowm/xchart/CategorySeries.java
@@ -9,6 +9,8 @@
/** A Series containing category data to be plotted on a Chart */
public class CategorySeries extends AxesChartSeriesCategory {
+ private boolean isOverlapped = false;
+
private CategorySeriesRenderStyle chartCategorySeriesRenderStyle = null;
/**
@@ -42,6 +44,15 @@ public CategorySeries setChartCategorySeriesRenderStyle(
return this;
}
+ public boolean isOverlapped() {
+ return isOverlapped;
+ }
+
+ public CategorySeries setOverlapped(boolean overlapped) {
+ isOverlapped = overlapped;
+ return this;
+ }
+
@Override
public LegendRenderType getLegendRenderType() {
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Category_Bar.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Category_Bar.java
index 23d761483..0b0eeedbc 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Category_Bar.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Category_Bar.java
@@ -174,7 +174,7 @@ public void doPaint(Graphics2D g) {
} else {
yBottom = y;
}
- if (stylerCategory.isStacked()) {
+ if (stylerCategory.isStacked() && !series.isOverlapped()) {
yTop += accumulatedStackOffsetPos[categoryCounter];
yBottom += accumulatedStackOffsetPos[categoryCounter];
accumulatedStackOffsetPos[categoryCounter] += (yTop - yBottom);
@@ -190,7 +190,7 @@ public void doPaint(Graphics2D g) {
// yBottom.
}
yBottom = y;
- if (stylerCategory.isStacked()) {
+ if (stylerCategory.isStacked() && !series.isOverlapped()) {
yTop -= accumulatedStackOffsetNeg[categoryCounter];
yBottom -= accumulatedStackOffsetNeg[categoryCounter];
accumulatedStackOffsetNeg[categoryCounter] += (yTop - yBottom);