altosuilib/micropeak: Add state markers to micropeak graph
authorKeith Packard <keithp@keithp.com>
Sun, 10 Feb 2013 04:24:33 +0000 (20:24 -0800)
committerKeith Packard <keithp@keithp.com>
Sun, 10 Feb 2013 08:30:32 +0000 (00:30 -0800)
I think this makes the micropeak graph as functional as the altosui graph

Signed-off-by: Keith Packard <keithp@keithp.com>
13 files changed:
altosuilib/AltosUIDataPoint.java
altosuilib/AltosUIEnable.java
altosuilib/AltosUIGraph.java
altosuilib/AltosUIGrapher.java [new file with mode: 0644]
altosuilib/AltosUIMarker.java [new file with mode: 0644]
altosuilib/AltosUISeries.java
altosuilib/Makefile.am
micropeak/MicroData.java
micropeak/MicroDataPoint.java
micropeak/MicroGraph.java
micropeak/MicroPeak.java
micropeak/MicroStats.java
micropeak/MicroStatsTable.java

index 38857fd19e3699108de7f2b8b894ec9fa4139525..a98f7cdb3f91a5394f26e83365e678e071164a45 100644 (file)
@@ -20,4 +20,6 @@ package org.altusmetrum.altosuilib_1;
 public interface AltosUIDataPoint {
        public abstract double x();
        public abstract double y(int index);
-}
\ No newline at end of file
+       public abstract int id(int index);
+       public abstract String id_name(int index);
+}
index e5695fa0db96ea34ce034a80134e87730fffe061..297cf3208b4544a6e6294ec3ad81c410065417c5 100644 (file)
@@ -41,28 +41,28 @@ public class AltosUIEnable extends Container {
        int     y;
 
        class GraphElement implements ActionListener {
-               AltosUISeries   series;
+               AltosUIGrapher  grapher;
                JLabel          label;
                JRadioButton    enable;
                String          name;
 
                public void actionPerformed(ActionEvent ae) {
-                       series.set_enable(enable.isSelected());
+                       grapher.set_enable(enable.isSelected());
                }
 
-               GraphElement (String name, AltosUISeries series, boolean enabled) {
+               GraphElement (String name, AltosUIGrapher grapher, boolean enabled) {
                        this.name = name;
-                       this.series = series;
+                       this.grapher = grapher;
                        label = new JLabel(name);
                        enable = new JRadioButton("Enable", enabled);
-                       series.set_enable(enabled);                       
+                       grapher.set_enable(enabled);                      
                        enable.addActionListener(this);
                }
        }
 
-       public void add(String name, AltosUISeries series, boolean enabled) {
+       public void add(String name, AltosUIGrapher grapher, boolean enabled) {
 
-               GraphElement    e = new GraphElement(name, series, enabled);
+               GraphElement    e = new GraphElement(name, grapher, enabled);
 
                /* Add label */
                GridBagConstraints c = new GridBagConstraints();
index e79e36ba7d3bddb7e1c62c56ca1940500e68edd1..e212093ab64c516fa2a222a7cc0370b518d59cec 100644 (file)
@@ -41,8 +41,9 @@ public class AltosUIGraph implements AltosUnitsListener {
        public ChartPanel               panel;
        NumberAxis                      xAxis;
        AltosUIEnable                   enable;
-       ArrayList<AltosUISeries>        series;
+       ArrayList<AltosUIGrapher>       graphers;
        AltosUIDataSet                  dataSet;
+       int                             index;
 
        static final private Color gridline_color = new Color(0, 0, 0);
        static final private Color border_color = new Color(255, 255, 255);
@@ -52,7 +53,7 @@ public class AltosUIGraph implements AltosUnitsListener {
                return panel;
        }
 
-       public void addSeries(int index, String label, int fetch, AltosUnits units, Color color) {
+       public void addSeries(String label, int fetch, AltosUnits units, Color color) {
                AltosUISeries           series = new AltosUISeries(label, fetch, units, color);
                XYSeriesCollection      dataset = new XYSeriesCollection(series);
 
@@ -63,22 +64,30 @@ public class AltosUIGraph implements AltosUnitsListener {
                plot.mapDatasetToRangeAxis(index, index);
                if (enable != null)
                        enable.add(label, series, true);
-               this.series.add(series);
+               this.graphers.add(series);
+               index++;
        }
        
+       public void addMarker(String label, int fetch, Color color) {
+               AltosUIMarker           marker = new AltosUIMarker(fetch, color, plot);
+               if (enable != null)
+                       enable.add(label, marker, true);
+               this.graphers.add(marker);
+       }
+
        public void resetData() {
-               for (AltosUISeries s : series)
-                       s.clear();
+               for (AltosUIGrapher g : graphers)
+                       g.clear();
                if (dataSet != null) {
                        for (AltosUIDataPoint dataPoint : dataSet.dataPoints())
-                               for (AltosUISeries s : series)
-                                       s.add(dataPoint);
+                               for (AltosUIGrapher g : graphers)
+                                       g.add(dataPoint);
                }
        }
 
        public void units_changed(boolean imperial_units) {
-               for (AltosUISeries s : series)
-                       s.set_units();
+               for (AltosUIGrapher g : graphers)
+                       g.set_units();
                resetData();
        }
 
@@ -96,7 +105,8 @@ public class AltosUIGraph implements AltosUnitsListener {
        public AltosUIGraph(AltosUIEnable enable) {
 
                this.enable = enable;
-               this.series = new ArrayList<AltosUISeries>();
+               this.graphers = new ArrayList<AltosUIGrapher>();
+               this.index = 0;
 
                xAxis = new NumberAxis("Time (s)");
                
diff --git a/altosuilib/AltosUIGrapher.java b/altosuilib/AltosUIGrapher.java
new file mode 100644 (file)
index 0000000..c627fec
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altosuilib_1;
+
+import java.io.*;
+import java.util.ArrayList;
+
+import java.awt.*;
+import javax.swing.*;
+import org.altusmetrum.altoslib_1.*;
+
+import org.jfree.ui.*;
+import org.jfree.chart.*;
+import org.jfree.chart.plot.*;
+import org.jfree.chart.axis.*;
+import org.jfree.chart.renderer.*;
+import org.jfree.chart.renderer.xy.*;
+import org.jfree.chart.labels.*;
+import org.jfree.data.xy.*;
+import org.jfree.data.*;
+
+interface AltosUIGrapher {
+
+       public abstract void set_units();
+       
+       public abstract void clear();
+
+       public abstract void add(AltosUIDataPoint dataPoint);
+
+       public abstract void set_enable(boolean enable);
+}
diff --git a/altosuilib/AltosUIMarker.java b/altosuilib/AltosUIMarker.java
new file mode 100644 (file)
index 0000000..560153f
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altosuilib_1;
+
+import java.io.*;
+import java.util.ArrayList;
+
+import java.awt.*;
+import javax.swing.*;
+import org.altusmetrum.altoslib_1.*;
+
+import org.jfree.ui.*;
+import org.jfree.chart.*;
+import org.jfree.chart.plot.*;
+import org.jfree.chart.axis.*;
+import org.jfree.chart.renderer.*;
+import org.jfree.chart.renderer.xy.*;
+import org.jfree.chart.labels.*;
+import org.jfree.data.xy.*;
+import org.jfree.data.*;
+
+public class AltosUIMarker implements AltosUIGrapher {
+       ArrayList<ValueMarker>  markers;
+       int                     last_id;
+       XYPlot                  plot;
+       boolean                 enabled;
+       int                     fetch;
+       Color                   color;
+       
+       private void remove_markers() {
+               for (ValueMarker marker : markers)
+                       plot.removeDomainMarker(marker);
+       }
+
+       private void add_markers() {
+               for (ValueMarker marker : markers)
+                       plot.addDomainMarker(marker);
+       }
+
+       public void set_units() {
+       }
+
+       public void set_enable(boolean enable) {
+               if (enabled == enable)
+                       return;
+               if (enable)
+                       add_markers();
+               else
+                       remove_markers();
+               enabled = enable;
+       }
+
+       public void clear() {
+               if (enabled)
+                       remove_markers();
+               markers = new ArrayList<ValueMarker>();
+       }
+
+       public void add(AltosUIDataPoint dataPoint) {
+               int id = dataPoint.id(fetch);
+               if (id < 0)
+                       return;
+               if (id == last_id)
+                       return;
+               ValueMarker marker = new ValueMarker(dataPoint.x());
+               marker.setLabel(dataPoint.id_name(fetch));
+               marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT);
+               marker.setLabelTextAnchor(TextAnchor.TOP_LEFT);
+               marker.setPaint(color);
+               if (enabled)
+                       plot.addDomainMarker(marker);
+               markers.add(marker);
+               last_id = id;
+       }
+
+       public AltosUIMarker (int fetch, Color color, XYPlot plot, boolean enable) {
+               markers = new ArrayList<ValueMarker>();
+               last_id = -1;
+               this.fetch = fetch;
+               this.color = color;
+               this.plot = plot;
+               this.enabled = enable;
+       }
+
+       public AltosUIMarker (int fetch, Color color, XYPlot plot) {
+               this(fetch, color, plot, true);
+       }
+}
\ No newline at end of file
index ea76e7418590a05b5195bd8099e2fccef7438133..26679471a0ff39b80c24fb412464f2a62b92ed68 100644 (file)
@@ -34,54 +34,66 @@ import org.jfree.chart.labels.*;
 import org.jfree.data.xy.*;
 import org.jfree.data.*;
 
-public class AltosUISeries extends XYSeries {
-       NumberAxis      axis;
+public class AltosUISeries extends XYSeries implements AltosUIGrapher {
+       AltosUIAxis     axis;
        String          label;
        AltosUnits      units;
        Color           color;
        XYItemRenderer  renderer;
        int             fetch;
+       boolean         enable;
        
-       void set_units() {
-               String  units_string = units.show_units();
-               axis.setLabel(String.format("%s (%s)", label, units_string));
-
+       public void set_units() {
+               axis.set_units();
                StandardXYToolTipGenerator      ttg;
 
                String  example = units.graph_format(4);
 
-               ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})", units_string),
+               ttg = new StandardXYToolTipGenerator(String.format("{1}s: {2}%s ({0})",
+                                                                  units.show_units()),
                                                     new java.text.DecimalFormat(example),
                                                     new java.text.DecimalFormat(example));
                renderer.setBaseToolTipGenerator(ttg);
        }
 
-       void set_enable(boolean enable) {
-               renderer.setSeriesVisible(0, enable);
-               axis.setVisible(enable);
+       public void set_enable(boolean enable) {
+               if (this.enable != enable) {
+                       this.enable = enable;
+                       renderer.setSeriesVisible(0, enable);
+                       axis.set_enable(enable);
+               }
        }
 
        public void add(AltosUIDataPoint dataPoint) {
                super.add(dataPoint.x(), dataPoint.y(fetch));
        }
 
-       public void set_axis(NumberAxis axis) {
-               this.axis = axis;
-       }
-
-       public AltosUISeries (String label, int fetch, AltosUnits units, Color color) {
+       public AltosUISeries (String label, int fetch, AltosUnits units, Color color,
+                             boolean enable, AltosUIAxis axis) {
                super(label);
                this.label = label;
                this.fetch = fetch;
                this.units = units;
                this.color = color;
+               this.enable = enable;
+               this.axis = axis;
 
-               axis = new NumberAxis();
-               axis.setLabelPaint(color);
-               axis.setTickLabelPaint(color);
+               axis.ref(this.enable);
 
                renderer = new XYLineAndShapeRenderer(true, false);
                renderer.setSeriesPaint(0, color);
                set_units();
        }
+
+       public AltosUISeries (String label, int fetch, AltosUnits units, Color color, boolean enable) {
+               this(label, fetch, units, color,
+                    enable,
+                    new AltosUIAxis(label, units, color));
+       }
+
+       public AltosUISeries (String label, int fetch, AltosUnits units, Color color) {
+               this(label, fetch, units, color,
+                    true,
+                    new AltosUIAxis(label, units, color));
+       }
 }
index e338b7cd03d344311e54402ecb4d209d5747c19d..faf7921f0c7866d74717950365aacadfbca4c188 100644 (file)
@@ -14,14 +14,17 @@ altosuilib_JAVA = \
        AltosFontListener.java \
        AltosPositionListener.java \
        AltosUIConfigure.java \
+       AltosUIAxis.java \
        AltosUIDataPoint.java \
        AltosUIDataSet.java \
        AltosUIGraph.java \
+       AltosUIGrapher.java \
        AltosUIDialog.java \
        AltosUIEnable.java \
        AltosUIFrame.java \
        AltosUILib.java \
        AltosUIListener.java \
+       AltosUIMarker.java \
        AltosUIPreferencesBackend.java \
        AltosUIPreferences.java \
        AltosUISeries.java \
index 26e3c07dc41851e75efd886a6ac900655633cab8..4c0ed4c3312bf1de84e5a6947f5d1e1865e9837b 100644 (file)
@@ -98,6 +98,7 @@ public class MicroData implements AltosUIDataSet {
        private double          ground_altitude;
        private ArrayList<Integer>      bytes;
        String                  name;
+       MicroStats              stats;
        
        class FileEndedException extends Exception {
        }
@@ -380,6 +381,7 @@ public class MicroData implements AltosUIDataSet {
                        crc_valid = crc == current_crc;
 
                        time_step = 0.192;
+                       stats = new MicroStats(this);
                } catch (FileEndedException fe) {
                        throw new IOException("File Ended Unexpectedly");
                } catch (NonHexcharException ne) {
index a81eb0d357dba3f34e28daf3f54e8655f1bcb968..61faf794e1edb10a51339726f3716a7a46230563 100644 (file)
@@ -20,15 +20,17 @@ package org.altusmetrum.micropeak;
 import org.altusmetrum.altosuilib_1.*;
 
 public class MicroDataPoint implements AltosUIDataPoint {
-       public double   time;
-       public double   pressure;
-       public double   height;
-       public double   speed;
-       public double   accel;
+       public double           time;
+       public double           pressure;
+       public double           height;
+       public double           speed;
+       public double           accel;
+       public MicroStats       stats;
 
        public static final int data_height = 0;
        public static final int data_speed = 1;
        public static final int data_accel = 2;
+       public static final int data_state = 3;
 
        public double x() {
                return time;
@@ -47,12 +49,26 @@ public class MicroDataPoint implements AltosUIDataPoint {
                }
        }
 
-       public MicroDataPoint (double pressure, double height, double speed, double accel, double time) {
+       public int id(int index) {
+               if (index == data_state) {
+                       return stats.state(time);
+               }
+               return 0;
+       }
+
+       public String id_name(int index) {
+               if (index == data_state)
+                       return stats.state_name(time);
+               return "";
+       }
+
+       public MicroDataPoint (double pressure, double height, double speed, double accel, double time, MicroStats stats) {
                this.pressure = pressure;
                this.height = height;
                this.speed = speed;
                this.accel = accel;
                this.time = time;
+               this.stats = stats;
        }
 
        public MicroDataPoint(MicroData data, int i) {
@@ -60,6 +76,7 @@ public class MicroDataPoint implements AltosUIDataPoint {
                     data.height(i),
                     data.speed(i),
                     data.acceleration(i),
-                    data.time(i));
+                    data.time(i),
+                    data.stats);
        }
 }
\ No newline at end of file
index 0071a160ef988a3cc44dfda02279c7aadef0b915..50508a61b42cbcb0f46bf9fc45b685caba6c6e30 100644 (file)
@@ -40,12 +40,14 @@ public class MicroGraph extends AltosUIGraph {
        static final private Color height_color = new Color(194,31,31);
        static final private Color speed_color = new Color(31,194,31);
        static final private Color accel_color = new Color(31,31,194);
+       static final private Color state_color = new Color(3,3,3);
 
        public MicroGraph(AltosUIEnable enable) {
                super(enable);
 
-               addSeries(0, "Height", MicroDataPoint.data_height, AltosConvert.height, height_color);
-               addSeries(1, "Speed", MicroDataPoint.data_speed, AltosConvert.speed, speed_color);
-               addSeries(2, "Acceleration", MicroDataPoint.data_accel, AltosConvert.accel, accel_color);
+               addSeries("Height", MicroDataPoint.data_height, AltosConvert.height, height_color);
+               addSeries("Speed", MicroDataPoint.data_speed, AltosConvert.speed, speed_color);
+               addSeries("Acceleration", MicroDataPoint.data_accel, AltosConvert.accel, accel_color);
+               addMarker("State", MicroDataPoint.data_state, state_color);
        }
 }
\ No newline at end of file
index 871d5cc34658e98d835ac2d6b5a94f730321540a..57f17dbe4780abb310feb062688a401572cf9187 100644 (file)
@@ -31,9 +31,10 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene
        File            filename;
        MicroGraph      graph;
        AltosUIEnable   enable;
-       MicroStatsTable stats;
+       MicroStatsTable statsTable;
        MicroRaw        raw;
        MicroData       data;
+       MicroStats      stats;
        Container       container;
        JTabbedPane     pane;
        static int      number_of_windows;
@@ -45,8 +46,9 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene
                        return mp.SetData(data);
                }
                this.data = data;
+               stats = new MicroStats(data);
                graph.setDataSet(data);
-               stats.setData(data);
+               statsTable.setStats(stats);
                raw.setData(data);
                setTitle(data.name);
                return this;
@@ -232,18 +234,18 @@ public class MicroPeak extends MicroFrame implements ActionListener, ItemListene
                addWindowListener(new WindowAdapter() {
                        @Override
                        public void windowClosing(WindowEvent e) {
-                               stats.tell_closing();
+                               statsTable.tell_closing();
                                Close();
                        }
                });
 
                enable = new AltosUIEnable();
                graph = new MicroGraph(enable);
-               stats = new MicroStatsTable();
+               statsTable = new MicroStatsTable();
                raw = new MicroRaw();
                pane.add(graph.panel, "Graph");
                pane.add(enable, "Configure Graph");
-               pane.add(stats, "Statistics");
+               pane.add(statsTable, "Statistics");
                JScrollPane scroll = new JScrollPane(raw);
                pane.add(scroll, "Raw Data");
                pane.doLayout();
index abc1296bbcee04d4abca80aa2b253bcd1e8ab0a0..99479cb4aeff3c69a1e69c71fdd2560608faad2a 100644 (file)
@@ -150,6 +150,43 @@ public class MicroStats {
                return descent_height() / descent_duration();
        }
 
+       public static final int state_startup = -1;
+       public static final int state_pad = 0;
+       public static final int state_boost = 1;
+       public static final int state_coast = 2;
+       public static final int state_descent = 3;
+       public static final int state_landed = 4;
+
+       static final String state_names[] = {
+               "pad",
+               "boost",
+               "coast",
+               "descent",
+               "landed"
+       };
+
+       public int state(double t) {
+               if (t >= landed_time)
+                       return state_landed;
+               if (t >= apogee_time)
+                       return state_descent;
+               if (t >= coast_time)
+                       return state_coast;
+               if (t >= 0)
+                       return state_boost;
+               return state_pad;
+       }
+
+       public static String state_name(int state) {
+               if (state < 0 || state > state_landed)
+                       return "unknown";
+               return state_names[state];
+       }
+
+       public String state_name(double t) {
+               return state_name(state(t));
+       }
+
        public MicroStats(MicroData data) {
 
                this.data = data;
index 5bdf5cb616a942b04ed10074cf6da1f7e763ba29..145bb70ea6dd453ec9730beda5e0dde5615808b5 100644 (file)
@@ -116,10 +116,6 @@ public class MicroStatsTable extends JComponent implements AltosFontListener {
                set_font();
        }
 
-       public void setData(MicroData data) {
-               setStats(new MicroStats(data));
-       }
-
        public MicroStatsTable(MicroStats stats) {
                layout = new GridBagLayout();