Show value on marker
authorBill Kuker <bkuker@billkuker.com>
Sun, 24 Oct 2010 18:53:33 +0000 (18:53 +0000)
committerBill Kuker <bkuker@billkuker.com>
Sun, 24 Oct 2010 18:53:33 +0000 (18:53 +0000)
src/com/billkuker/rocketry/motorsim/visual/Chart.java

index ab6dc73f1125ae71ec177c4513f1727dd49f6138..6f3b65729cb27fa6bae72dd30e2d97c530a8ebd2 100644 (file)
@@ -2,6 +2,7 @@ package com.billkuker.rocketry.motorsim.visual;
 \r
 import java.awt.BorderLayout;\r
 import java.awt.Color;\r
+import java.awt.Font;\r
 import java.lang.reflect.InvocationTargetException;\r
 import java.lang.reflect.Method;\r
 import java.util.Collection;\r
@@ -29,6 +30,8 @@ import org.jfree.chart.plot.PlotOrientation;
 import org.jfree.chart.plot.ValueMarker;\r
 import org.jfree.data.xy.XYSeries;\r
 import org.jfree.data.xy.XYSeriesCollection;\r
+import org.jfree.ui.RectangleInsets;\r
+import org.jfree.ui.TextAnchor;\r
 import org.jscience.physics.amount.Amount;\r
 \r
 import com.billkuker.rocketry.motorsim.Burn;\r
@@ -100,7 +103,6 @@ public class Chart<X extends Quantity, Y extends Quantity> extends JPanel {
        Object source;\r
        Method f;\r
 \r
-       @SuppressWarnings("unchecked")\r
        public Chart(Unit<X> xUnit, Unit<Y> yUnit, Object source, String method)\r
                        throws NoSuchMethodException {\r
                super(new BorderLayout());\r
@@ -136,9 +138,54 @@ public class Chart<X extends Quantity, Y extends Quantity> extends JPanel {
                        marker = new ValueMarker(m.doubleValue(xUnit));\r
                        marker.setPaint(Color.blue);\r
                        marker.setAlpha(0.8f);\r
+                       marker.setLabel(RocketScience.approx(getNear(m)));\r
+                       \r
+                       marker.setLabelTextAnchor(TextAnchor.TOP_LEFT);\r
+                       marker.setLabelOffset(new RectangleInsets(0,-5,0,0));\r
+                       \r
+                       marker.setLabelFont(new Font(Font.DIALOG, Font.BOLD, 12));\r
                        chart.getXYPlot().addDomainMarker(marker);\r
                }\r
        }\r
+       \r
+       /**\r
+        * Get the Y value at or near a given X\r
+        * For display use only!\r
+        * \r
+        * @param ax\r
+        * @return\r
+        */\r
+       private Amount<Y> getNear(final Amount<X> ax){\r
+               if ( dataset.getSeriesCount() != 1 )\r
+                       return null;\r
+               final XYSeries s = dataset.getSeries(0);\r
+               final double x = ax.doubleValue(xUnit);\r
+               int idx = s.getItemCount() / 2;\r
+               int delta = s.getItemCount() / 4;\r
+               while(true){\r
+                       if ( s.getX(idx).doubleValue() < x ){\r
+                               idx += delta;\r
+                       } else {\r
+                               idx -= delta;\r
+                       }\r
+                       delta = delta / 2;\r
+                       if ( delta < 1 ){\r
+                               int idxL = idx-1;\r
+                               int idxH = idx;\r
+                               final double lowerX = s.getX(idxL).doubleValue();\r
+                               final double higherX = s.getX(idxH).doubleValue();\r
+                               final double sampleXDiff = higherX - lowerX;\r
+                               final double xDiff = x - lowerX;\r
+                               final double dist = xDiff / sampleXDiff;\r
+                               final double lowerY = s.getY(idxL).doubleValue();\r
+                               final double higherY = s.getY(idxH).doubleValue();\r
+                               final double y = lowerY + dist * (higherY - lowerY);\r
+                               \r
+                               \r
+                               return Amount.valueOf( y, yUnit);\r
+                       }\r
+               }\r
+       }\r
 \r
        public void setDomain(final Iterable<Amount<X>> d) {\r
                stop = true;\r
@@ -163,7 +210,7 @@ public class Chart<X extends Quantity, Y extends Quantity> extends JPanel {
                stop = false;\r
                int sz = 0;\r
                if (d instanceof Collection) {\r
-                       sz = ((Collection) d).size();\r
+                       sz = ((Collection<Amount<X>>) d).size();\r
                        int sk2 = sz / 200;\r
                        if (skip < sk2)\r
                                skip = sk2;\r