Repository: knowm/XChart (java)

Issue:
Custom text at data points
Hi,

I was wondering if it is possible to add custom text at each data point, resulting in a chart similar to that shown below:
![image](https://user-images.githubusercontent.com/39590308/41645661-e4933f6e-7471-11e8-8db3-29bdb318ba33.png)


Pull request:
[resolves #270] Improve custom text at data points
`AxesChartSeries` class add `isCustomToolTips` attributes.

The effect is as follows：
![issue_270](https://user-images.githubusercontent.com/57353473/77734376-841f8780-7043-11ea-9693-f8f30263557d.png)


Patch:
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Bubble.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Bubble.java
index a1758027..6851768f 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Bubble.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Bubble.java
@@ -53,7 +53,6 @@ public class PlotContent_Bubble<ST extends BubbleStyler, S extends BubbleSeries>
       }
 
       String[] toolTips = series.getToolTips();
-      boolean hasCustomToolTips = toolTips != null;
 
       double yMin = chart.getYAxis(series.getYAxisGroup()).getMin();
       double yMax = chart.getYAxis(series.getYAxisGroup()).getMax();
@@ -141,10 +140,12 @@ public class PlotContent_Bubble<ST extends BubbleStyler, S extends BubbleSeries>
           g.draw(bubble);
           // add data labels
           if (toolTipsEnabled) {
-            if (hasCustomToolTips) {
-              String tt = toolTips[i];
-              if (tt != null) {
-                chart.toolTips.addData(bubble, xOffset, yOffset, 0, tt);
+            if (series.isCustomToolTips()) {
+              if (toolTips != null) {
+                String tt = toolTips[i];
+                if (tt != null && !"".equals(tt)) {
+                  chart.toolTips.addData(bubble, xOffset, yOffset, 0, tt);
+                }
               }
             } else {
               chart.toolTips.addData(
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 57c5ec10..e53755d0 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
@@ -141,7 +141,6 @@ public class PlotContent_Category_Bar<ST extends CategoryStyler, S extends Categ
         continue;
       }
       String[] toolTips = series.getToolTips();
-      boolean hasCustomToolTips = toolTips != null;
 
       yMin = chart.getYAxis(series.getYAxisGroup()).getMin();
       yMax = chart.getYAxis(series.getYAxisGroup()).getMax();
@@ -512,10 +511,12 @@ public class PlotContent_Category_Bar<ST extends CategoryStyler, S extends Categ
             yPoint = yOffset;
           }
 
-          if (hasCustomToolTips) {
-            String tt = toolTips[categoryCounter - 1];
-            if (tt != null) {
-              chart.toolTips.addData(rect, xOffset, yPoint, barWidth, tt);
+          if (series.isCustomToolTips()) {
+            if (toolTips != null) {
+              String tt = toolTips[categoryCounter - 1];
+              if (tt != null && !"".equals(tt)) {
+                chart.toolTips.addData(rect, xOffset, yPoint, barWidth, tt);
+              }
             }
           } else {
             chart.toolTips.addData(
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Category_Line_Area_Scatter.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Category_Line_Area_Scatter.java
index d391e88a..ce382f42 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Category_Line_Area_Scatter.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_Category_Line_Area_Scatter.java
@@ -53,7 +53,6 @@ public class PlotContent_Category_Line_Area_Scatter<
         continue;
       }
       String[] toolTips = series.getToolTips();
-      boolean hasCustomToolTips = toolTips != null;
 
       Axis yAxis = chart.getYAxis(series.getYAxisGroup());
       double yMin = yAxis.getMin();
@@ -234,10 +233,12 @@ public class PlotContent_Category_Line_Area_Scatter<
         }
 
         if (toolTipsEnabled) {
-          if (hasCustomToolTips) {
-            String tt = toolTips[categoryCounter];
-            if (tt != null) {
-              chart.toolTips.addData(xOffset, yOffset, tt);
+          if (series.isCustomToolTips()) {
+            if (toolTips != null) {
+              String tt = toolTips[categoryCounter];
+              if (tt != null && !"".equals(tt)) {
+                chart.toolTips.addData(xOffset, yOffset, tt);
+              }
             }
           } else {
             chart.toolTips.addData(
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_OHLC.java b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_OHLC.java
index c81cb95e..122215f7 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_OHLC.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/chartpart/PlotContent_OHLC.java
@@ -66,7 +66,7 @@ public class PlotContent_OHLC<ST extends AxesChartStyler, S extends OHLCSeries>
       }
 
       String[] toolTips = series.getToolTips();
-      boolean hasCustomToolTips = toolTips != null;
+
       if (series.getOhlcSeriesRenderStyle() == OHLCSeriesRenderStyle.Line) {
         paintLine(g, series, lineLabelMap);
         continue;
@@ -209,10 +209,12 @@ public class PlotContent_OHLC<ST extends AxesChartStyler, S extends OHLCSeries>
 
         // add data labels
         if (toolTipsEnabled) {
-          if (hasCustomToolTips) {
-            String tt = toolTips[i];
-            if (tt != null) {
-              chart.toolTips.addData(toolTipArea, xOffset, highOffset, candleHalfWidth * 2, tt);
+          if (series.isCustomToolTips()) {
+            if (toolTips != null) {
+              String tt = toolTips[i];
+              if (tt != null && !"".equals(tt)) {
+                chart.toolTips.addData(toolTipArea, xOffset, highOffset, candleHalfWidth * 2, tt);
+              }
             }
           } else {
 
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 dfb7632a..d4620b5d 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
@@ -78,7 +78,6 @@ public class PlotContent_XY<ST extends AxesChartStyler, S extends XYSeries>
 
       boolean toolTipsEnabled = chart.getStyler().isToolTipsEnabled();
       String[] toolTips = series.getToolTips();
-      boolean hasCustomToolTips = toolTips != null;
 
       double yZeroTransform =
           getBounds().getHeight() - (yTopMargin + (0 - yMin) / (yMax - yMin) * yTickSpace);
@@ -289,10 +288,12 @@ public class PlotContent_XY<ST extends AxesChartStyler, S extends XYSeries>
 
         // add data labels
         if (toolTipsEnabled) {
-          if (hasCustomToolTips) {
-            String tt = toolTips[i];
-            if (tt != null) {
-              chart.toolTips.addData(xOffset, yOffset, tt);
+          if (series.isCustomToolTips()) {
+            if (toolTips != null) {
+              String tt = toolTips[i];
+              if (tt != null && !"".equals(tt)) {
+                chart.toolTips.addData(xOffset, yOffset, tt);
+              }
             }
           } else {
             chart.toolTips.addData(
diff --git a/xchart/src/main/java/org/knowm/xchart/internal/series/AxesChartSeries.java b/xchart/src/main/java/org/knowm/xchart/internal/series/AxesChartSeries.java
index a6433403..9a075f79 100644
--- a/xchart/src/main/java/org/knowm/xchart/internal/series/AxesChartSeries.java
+++ b/xchart/src/main/java/org/knowm/xchart/internal/series/AxesChartSeries.java
@@ -28,6 +28,8 @@ public abstract class AxesChartSeries extends Series {
 
   protected String[] toolTips;
 
+  protected boolean isCustomToolTips;
+
   /**
    * Constructor
    *
@@ -140,4 +142,15 @@ public abstract class AxesChartSeries extends Series {
 
     this.toolTips = toolTips;
   }
+
+  public boolean isCustomToolTips() {
+
+    return isCustomToolTips;
+  }
+
+  public AxesChartSeries setCustomToolTips(boolean isCustomToolTips) {
+
+    this.isCustomToolTips = isCustomToolTips;
+    return this;
+  }
 }


Test patch:
diff --git a/xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue227.java b/xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue227.java
index 7a8df3ed..9d0e530b 100644
--- a/xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue227.java
+++ b/xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue227.java
@@ -94,7 +94,7 @@ public class TestForIssue227 {
         count = ((AxesChartSeriesNumericalNoErrorBars) series).getXData().length;
       } else if (series instanceof CategorySeries) {
         count = ((CategorySeries) series).getYData().size();
-      } else if (series instanceof OHLCSeries) {
+      } else if (series instanceof OHLCSeries && ((OHLCSeries) series).getOpenData() != null) {
         count = ((OHLCSeries) series).getOpenData().length;
       } else if (series instanceof BubbleSeries) {
         count = ((BubbleSeries) series).getXData().length;
@@ -106,6 +106,7 @@ public class TestForIssue227 {
         continue;
       }
       String[] toolTips = getToolTips(series.getName(), count);
+      ((AxesChartSeries) series).setCustomToolTips(true);
       ((AxesChartSeries) series).setToolTips(toolTips);
       flag = true;
     }
diff --git a/xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue270.java b/xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue270.java
new file mode 100644
index 00000000..c42924de
--- /dev/null
+++ b/xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue270.java
@@ -0,0 +1,36 @@
+package org.knowm.xchart.standalone.issues;
+
+import org.knowm.xchart.SwingWrapper;
+import org.knowm.xchart.XYChart;
+import org.knowm.xchart.XYChartBuilder;
+import org.knowm.xchart.XYSeries;
+import org.knowm.xchart.style.Styler.LegendPosition;
+
+public class TestForIssue270 {
+
+  public static void main(String[] args) {
+
+    // Create Chart
+    XYChart chart =
+        new XYChartBuilder()
+            .width(800)
+            .height(600)
+            .title("TestForIssue270")
+            .xAxisTitle("X")
+            .yAxisTitle("y")
+            .build();
+
+    // Customize Chart
+    chart.getStyler().setLegendPosition(LegendPosition.OutsideE);
+    chart.getStyler().setToolTipsEnabled(true);
+    chart.getStyler().setToolTipsAlwaysVisible(true);
+
+    // Series
+    XYSeries a = chart.addSeries("a", new double[] {1, 2, 3, 4, 5}, new double[] {-1, 6, 9, 6, 5});
+    a.setCustomToolTips(true);
+
+    chart.addSeries("b", new double[] {1, 2, 3, 4, 5}, new double[] {9, 7, 3, -3, 8});
+
+    new SwingWrapper<>(chart).displayChart();
+  }
+}