Repository: knowm/XChart (java)

Issue:
XYChart, individual y axis group decimal pattern
Hi,
is it possible to set the decimal pattern of a Y axis groups?

I only found this function but it affects all Y axis groups : XYChart.getStyler().setYAxisDecimalPattern()

Thanks

Pull request:
[resolves #370] XYChart, individual y axis group decimal pattern
The results are as follows:
![3 0](https://user-images.githubusercontent.com/57353473/72237723-6f238280-3616-11ea-8428-62efed214fc6.png)


Patch:
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 b909af40..48393815 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
@@ -463,10 +463,10 @@ public class Axis<ST extends AxesChartStyler, S extends AxesChartSeries> impleme
       if (axesChartStyler.isYAxisLogarithmic() && getDataType() != Series.DataType.Date) {
 
         return new AxisTickCalculator_Logarithmic(
-            getDirection(), workingSpace, min, max, axesChartStyler);
+            getDirection(), workingSpace, min, max, axesChartStyler, getYIndex());
       } else {
         return new AxisTickCalculator_Number(
-            getDirection(), workingSpace, min, max, axesChartStyler);
+            getDirection(), workingSpace, min, max, axesChartStyler, getYIndex());
       }
     }
   }
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 019acf8b..71ce5ed7 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
@@ -271,6 +271,13 @@ public class AxisPair<ST extends AxesChartStyler, S extends AxesChartSeries> imp
       if (!mainYAxisUsed) {
         yAxis.setDataType(series.getyAxisDataType());
       }
+
+      if (series.getYAxisDecimalPattern() != null) {
+        chart
+            .getStyler()
+            .putYAxisGroupDecimalPatternMap(
+                series.getYAxisGroup(), series.getYAxisDecimalPattern());
+      }
     }
 
     // calculate axis min and max
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Logarithmic.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Logarithmic.java
index f2a47ee8..58c39768 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Logarithmic.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Logarithmic.java
@@ -37,6 +37,30 @@ class AxisTickCalculator_Logarithmic extends AxisTickCalculator_ {
     calculate();
   }
 
+  /**
+   * Constructor
+   *
+   * @param axisDirection
+   * @param workingSpace
+   * @param minValue
+   * @param maxValue
+   * @param styler
+   * @param yIndex
+   */
+  public AxisTickCalculator_Logarithmic(
+      Direction axisDirection,
+      double workingSpace,
+      double minValue,
+      double maxValue,
+      AxesChartStyler styler,
+      int yIndex) {
+
+    super(axisDirection, workingSpace, minValue, maxValue, styler);
+    numberLogFormatter = new NumberLogFormatter(styler, axisDirection, yIndex);
+    axisFormat = numberLogFormatter;
+    calculate();
+  }
+
   private void calculate() {
 
     // a check if all axis data are the exact same values
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Number.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Number.java
index c8df85e5..22e70826 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Number.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/AxisTickCalculator_Number.java
@@ -39,6 +39,30 @@ class AxisTickCalculator_Number extends AxisTickCalculator_ {
     calculate();
   }
 
+  /**
+   * Constructor
+   *
+   * @param axisDirection
+   * @param workingSpace
+   * @param minValue
+   * @param maxValue
+   * @param styler
+   * @param yIndex
+   */
+  public AxisTickCalculator_Number(
+      Direction axisDirection,
+      double workingSpace,
+      double minValue,
+      double maxValue,
+      AxesChartStyler styler,
+      int yIndex) {
+
+    super(axisDirection, workingSpace, minValue, maxValue, styler);
+    numberFormatter = new NumberFormatter(styler, axisDirection, minValue, maxValue, yIndex);
+    axisFormat = numberFormatter;
+    calculate();
+  }
+
   private void calculate() {
 
     // a check if all axis data are the exact same values
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Chart.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Chart.java
index b0363b98..90a706a1 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Chart.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/Chart.java
@@ -4,6 +4,7 @@ import java.awt.Graphics2D;
 import java.awt.RenderingHints;
 import java.awt.Shape;
 import java.awt.geom.Rectangle2D;
+import java.text.DecimalFormat;
 import java.text.Format;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -11,6 +12,7 @@ import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+
 import org.knowm.xchart.internal.series.Series;
 import org.knowm.xchart.style.Styler;
 
@@ -228,6 +230,17 @@ public abstract class Chart<ST extends Styler, S extends Series> {
     return axisPair.getYAxis().getAxisTickCalculator().getAxisFormat();
   }
 
+  Format getYAxisFormat(String yAxisDecimalPattern) {
+
+    Format format = null;
+    if (yAxisDecimalPattern != null) {
+      format = new DecimalFormat(yAxisDecimalPattern);
+    } else {
+      format = axisPair.getYAxis().getAxisTickCalculator().getAxisFormat();
+    }
+    return format;
+  }
+
   public ArrayList<ChartPart> getPlotParts() {
 
     return plotParts;
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/NumberFormatter.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/NumberFormatter.java
index 4a0fba23..baa73c11 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/NumberFormatter.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/NumberFormatter.java
@@ -12,6 +12,7 @@ class NumberFormatter extends Format {
   private final double min;
   private final double max;
   private final NumberFormat numberFormat;
+  private int yIndex;
 
   /** Constructor */
   public NumberFormatter(
@@ -24,6 +25,26 @@ class NumberFormatter extends Format {
     numberFormat = NumberFormat.getNumberInstance(styler.getLocale());
   }
 
+  /**
+   * Constructor
+   *
+   * @param styler
+   * @param axisDirection
+   * @param min
+   * @param max
+   * @param yIndex
+   */
+  public NumberFormatter(
+      AxesChartStyler styler, Axis.Direction axisDirection, double min, double max, int yIndex) {
+
+    this.styler = styler;
+    this.axisDirection = axisDirection;
+    this.min = min;
+    this.max = max;
+    this.yIndex = yIndex;
+    numberFormat = NumberFormat.getNumberInstance(styler.getLocale());
+  }
+
   private String getFormatPattern(double value) {
 
     // System.out.println("value: " + value);
@@ -97,8 +118,14 @@ class NumberFormatter extends Format {
     if (axisDirection == Axis.Direction.X && styler.getXAxisDecimalPattern() != null) {
 
       decimalPattern = styler.getXAxisDecimalPattern();
-    } else if (axisDirection == Axis.Direction.Y && styler.getYAxisDecimalPattern() != null) {
-      decimalPattern = styler.getYAxisDecimalPattern();
+    } else if (axisDirection == Axis.Direction.Y
+        && (styler.getYAxisGroupDecimalPatternMap().get(yIndex) != null
+            || styler.getYAxisDecimalPattern() != null)) {
+      if (styler.getYAxisGroupDecimalPatternMap().get(yIndex) != null) {
+        decimalPattern = styler.getYAxisGroupDecimalPatternMap().get(yIndex);
+      } else {
+        decimalPattern = styler.getYAxisDecimalPattern();
+      }
     } else if (styler.getDecimalPattern() != null) {
       decimalPattern = styler.getDecimalPattern();
     } else {
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/NumberLogFormatter.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/NumberLogFormatter.java
index 8b133fdc..cc48d2a6 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/NumberLogFormatter.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/NumberLogFormatter.java
@@ -9,6 +9,7 @@ class NumberLogFormatter extends Format {
   private final AxesChartStyler styler;
   private final Axis.Direction axisDirection;
   private final NumberFormat numberFormat;
+  private int yIndex;
 
   /** Constructor */
   public NumberLogFormatter(AxesChartStyler styler, Axis.Direction axisDirection) {
@@ -18,6 +19,21 @@ class NumberLogFormatter extends Format {
     numberFormat = NumberFormat.getNumberInstance(styler.getLocale());
   }
 
+  /**
+   * Constructor
+   *
+   * @param styler
+   * @param axisDirection
+   * @param yIndex
+   */
+  public NumberLogFormatter(AxesChartStyler styler, Axis.Direction axisDirection, int yIndex) {
+
+    this.styler = styler;
+    this.axisDirection = axisDirection;
+    this.yIndex = yIndex;
+    numberFormat = NumberFormat.getNumberInstance(styler.getLocale());
+  }
+
   @Override
   public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
 
@@ -28,8 +44,14 @@ class NumberLogFormatter extends Format {
     if (axisDirection == Axis.Direction.X && styler.getXAxisDecimalPattern() != null) {
 
       decimalPattern = styler.getXAxisDecimalPattern();
-    } else if (axisDirection == Axis.Direction.Y && styler.getYAxisDecimalPattern() != null) {
-      decimalPattern = styler.getYAxisDecimalPattern();
+    } else if (axisDirection == Axis.Direction.Y
+        && (styler.getYAxisGroupDecimalPatternMap().get(yIndex) != null
+            || styler.getYAxisDecimalPattern() != null)) {
+      if (styler.getYAxisGroupDecimalPatternMap().get(yIndex) != null) {
+        decimalPattern = styler.getYAxisGroupDecimalPatternMap().get(yIndex);
+      } else {
+        decimalPattern = styler.getYAxisDecimalPattern();
+      }
     } else if (styler.getDecimalPattern() != null) {
 
       decimalPattern = styler.getDecimalPattern();
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_XY.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_XY.java
index 2e997b43..dfb7632a 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_XY.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_XY.java
@@ -299,7 +299,7 @@ public class PlotContent_XY<ST extends AxesChartStyler, S extends XYSeries>
                 xOffset,
                 yOffset,
                 chart.getXAxisFormat().format(x),
-                chart.getYAxisFormat().format(yOrig));
+                chart.getYAxisFormat(series.getYAxisDecimalPattern()).format(yOrig));
           }
         }
 
@@ -308,7 +308,7 @@ public class PlotContent_XY<ST extends AxesChartStyler, S extends XYSeries>
               xOffset,
               yOffset,
               chart.getXAxisFormat().format(x),
-              chart.getYAxisFormat().format(yOrig),
+              chart.getYAxisFormat(series.getYAxisDecimalPattern()).format(yOrig),
               series.getName());
         }
       }
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/series/Series.java b/xchart/src/main/java/org/knowm/xchart/internal/series/Series.java
index 84e17d4f..7ca8d0e0 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/series/Series.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/series/Series.java
@@ -16,6 +16,8 @@ public abstract class Series {
   private boolean showInLegend = true;
   private boolean isEnabled = true;
   private int yAxisGroup = 0;
+  /** the yAxis decimalPattern */
+  private String yAxisDecimalPattern;
 
   /**
    * Constructor
@@ -98,6 +100,17 @@ public abstract class Series {
     return this;
   }
 
+  public String getYAxisDecimalPattern() {
+
+    return yAxisDecimalPattern;
+  }
+
+  public Series setYAxisDecimalPattern(String yAxisDecimalPattern) {
+
+    this.yAxisDecimalPattern = yAxisDecimalPattern;
+    return this;
+  }
+
   public enum DataType {
     Number,
     Date,
diff --git a/xchart/src/main/java/org/knowm/xchart/style/AxesChartStyler.java b/xchart/src/main/java/org/knowm/xchart/style/AxesChartStyler.java
index 2d4d08b7..ec28e76f 100644
--- a/xchart/src/main/java/org/knowm/xchart/style/AxesChartStyler.java
+++ b/xchart/src/main/java/org/knowm/xchart/style/AxesChartStyler.java
@@ -3,6 +3,7 @@ package org.knowm.xchart.style;
 import java.awt.*;
 import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
 import java.util.TimeZone;
 
 /** @author timmolter */
@@ -61,6 +62,7 @@ public abstract class AxesChartStyler extends Styler {
   private String datePattern;
   private String xAxisDecimalPattern;
   private String yAxisDecimalPattern;
+  private Map<Integer, String> yAxisGroupDecimalPatternMap;
   private boolean xAxisLogarithmicDecadeOnly;
   private boolean yAxisLogarithmicDecadeOnly;
 
@@ -114,6 +116,7 @@ public abstract class AxesChartStyler extends Styler {
     this.datePattern = null; // if not null, this override pattern will be used
     this.xAxisDecimalPattern = null;
     this.yAxisDecimalPattern = null;
+    this.yAxisGroupDecimalPatternMap = new HashMap<>();
     this.xAxisLogarithmicDecadeOnly = true;
     this.yAxisLogarithmicDecadeOnly = true;
 
@@ -796,6 +799,16 @@ public abstract class AxesChartStyler extends Styler {
     return this;
   }
 
+  public Map<Integer, String> getYAxisGroupDecimalPatternMap() {
+
+    return yAxisGroupDecimalPatternMap;
+  }
+
+  public void putYAxisGroupDecimalPatternMap(int yIndex, String yAxisDecimalPattern) {
+
+    yAxisGroupDecimalPatternMap.put(yIndex, yAxisDecimalPattern);
+  }
+
   public boolean isXAxisLogarithmicDecadeOnly() {
     return xAxisLogarithmicDecadeOnly;
   }


Test patch:
diff --git a/xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue370.java b/xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue370.java
new file mode 100644
index 00000000..9dfd760c
--- /dev/null
+++ b/xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue370.java
@@ -0,0 +1,60 @@
+package org.knowm.xchart.standalone.issues;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.knowm.xchart.SwingWrapper;
+import org.knowm.xchart.XYChart;
+import org.knowm.xchart.XYChartBuilder;
+import org.knowm.xchart.XYSeries;
+import org.knowm.xchart.XYSeries.XYSeriesRenderStyle;
+import org.knowm.xchart.style.Styler.LegendPosition;
+
+public class TestForIssue370 {
+
+  public static void main(String[] args) {
+
+    TestForIssue370 testForIssue370 = new TestForIssue370();
+    List<XYChart> charts = new ArrayList<>();
+    charts.add(testForIssue370.getChart("Group yAxis DecimalPattern", false));
+    charts.add(testForIssue370.getChart("Group yAxis DecimalPattern Logarithmic", true));
+    new SwingWrapper<XYChart>(charts).displayChartMatrix();
+  }
+
+  public XYChart getChart(String title, boolean isYAxisLogarithmic) {
+
+    // Create Chart
+    XYChart chart =
+        new XYChartBuilder()
+            .width(600)
+            .height(400)
+            .title(title)
+            .xAxisTitle("X")
+            .yAxisTitle("Y")
+            .build();
+
+    // Customize Chart
+    chart.getStyler().setLegendPosition(LegendPosition.OutsideE);
+    chart.getStyler().setAxisTitlesVisible(false);
+    chart.getStyler().setDefaultSeriesRenderStyle(XYSeriesRenderStyle.Line);
+    chart.getStyler().setToolTipsEnabled(true);
+    chart.getStyler().setToolTipsAlwaysVisible(true);
+    chart.getStyler().setYAxisLogarithmic(isYAxisLogarithmic);
+
+    // Series
+    chart.addSeries("a", new double[] {1, 2, 3, 4, 5}, new double[] {400, 200, 300, 200, 100});
+    XYSeries b =
+        chart.addSeries(
+            "b",
+            new double[] {1, 2, 3, 4, 5},
+            new double[] {0.00012328, 0.0015467, 0.019879, 0.19859, 1.59681});
+    b.setYAxisGroup(1);
+    if (isYAxisLogarithmic) {
+      b.setYAxisDecimalPattern("#0.##E0");
+    } else {
+      b.setYAxisDecimalPattern("0.0000");
+    }
+
+    return chart;
+  }
+}