altosui: Check for map and stats table when changing units/fonts in graph
[fw/altos] / altosui / AltosGraphUI.java
index 527a7d280b138b4718b149c7b4b7800bf930e205..2d00fb45a74be84e0198d1c7c4c8c195c8b07544 100644 (file)
@@ -1,6 +1,19 @@
-
-// Copyright (c) 2010 Anthony Towns
-// GPL v2 or later
+/*
+ * Copyright © 2010 Anthony Towns
+ *
+ * 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 or any later version 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 altosui;
 
@@ -10,303 +23,91 @@ import java.util.ArrayList;
 import java.awt.*;
 import java.awt.event.*;
 import javax.swing.*;
-import javax.swing.filechooser.FileNameExtensionFilter;
-import javax.swing.table.*;
-import org.altusmetrum.AltosLib.*;
+import org.altusmetrum.altoslib_5.*;
+import org.altusmetrum.altosuilib_3.*;
 
 import org.jfree.chart.ChartPanel;
-import org.jfree.chart.ChartUtilities;
 import org.jfree.chart.JFreeChart;
-import org.jfree.chart.axis.AxisLocation;
-import org.jfree.ui.ApplicationFrame;
 import org.jfree.ui.RefineryUtilities;
 
-public class AltosGraphUI extends AltosFrame 
+public class AltosGraphUI extends AltosUIFrame implements AltosFontListener, AltosUnitsListener
 {
-    JTabbedPane        pane;
-
-    static final private Color red = new Color(194,31,31);
-    static final private Color green = new Color(31,194,31);
-    static final private Color blue = new Color(31,31,194);
-    static final private Color black = new Color(31,31,31);
-    static final private Color yellow = new Color(194,194,31);
-    static final private Color cyan = new Color(31,194,194);
-    static final private Color magenta = new Color(194,31,194);
-
-    static private class OverallGraphs {
-        AltosGraphTime.Element height = 
-            new AltosGraphTime.TimeSeries("Height (m)", "Height (AGL)", red) {
-                public void gotTimeData(double time, AltosDataPoint d) {
-                       double  height = d.height();
-                       if (height != AltosRecord.MISSING)
-                               series.add(time, d.height()); 
-                } 
-            };
-    
-        AltosGraphTime.Element speed =
-            new AltosGraphTime.TimeSeries("Speed (m/s)", "Vertical Speed", green) { 
-                public void gotTimeData(double time, AltosDataPoint d) {
-                   double      speed;
-                   if (d.state() < Altos.ao_flight_drogue && d.has_accel()) {
-                       speed = d.accel_speed();
-                    } else {
-                       speed = d.baro_speed();
-                    }
-                   if (speed != AltosRecord.MISSING)
-                       series.add(time, speed);
-                }
-            };
-    
-        AltosGraphTime.Element acceleration =
-            new AltosGraphTime.TimeSeries("Acceleration (m/s\u00B2)", 
-                    "Axial Acceleration", blue) 
-            {
-                public void gotTimeData(double time, AltosDataPoint d) {
-                   double acceleration = d.acceleration();
-                   if (acceleration != AltosRecord.MISSING)
-                       series.add(time, acceleration);
-                }
-            };
-    
-        AltosGraphTime.Element temperature =
-            new AltosGraphTime.TimeSeries("Temperature (\u00B0C)", 
-                    "Board temperature", red) 
-            {
-                public void gotTimeData(double time, AltosDataPoint d) {
-                   double temp = d.temperature();
-                   if (temp != AltosRecord.MISSING)
-                       series.add(time, d.temperature());
-                }
-            };
-    
-        AltosGraphTime.Element drogue_voltage =
-            new AltosGraphTime.TimeSeries("Voltage (V)", "Drogue Continuity", yellow) 
-            {
-                public void gotTimeData(double time, AltosDataPoint d) {
-                   double v = d.drogue_voltage();
-                   if (v != AltosRecord.MISSING)
-                       series.add(time, v);
-                }
-            };
-    
-        AltosGraphTime.Element main_voltage =
-            new AltosGraphTime.TimeSeries("Voltage (V)", "Main Continuity", magenta) 
-            {
-                public void gotTimeData(double time, AltosDataPoint d) {
-                   double v = d.main_voltage();
-                   if (v != AltosRecord.MISSING)
-                       series.add(time, v);
-                }
-            };
-    
-        AltosGraphTime.Element e_pad    = new AltosGraphTime.StateMarker(Altos.ao_flight_pad, "Pad");
-        AltosGraphTime.Element e_boost  = new AltosGraphTime.StateMarker(Altos.ao_flight_boost, "Boost");
-        AltosGraphTime.Element e_fast   = new AltosGraphTime.StateMarker(Altos.ao_flight_fast, "Fast");
-        AltosGraphTime.Element e_coast  = new AltosGraphTime.StateMarker(Altos.ao_flight_coast, "Coast");
-       AltosGraphTime.Element e_drogue = new AltosGraphTime.StateMarker(Altos.ao_flight_drogue, "Drogue");
-       AltosGraphTime.Element e_main   = new AltosGraphTime.StateMarker(Altos.ao_flight_main, "Main");
-        AltosGraphTime.Element e_landed = new AltosGraphTime.StateMarker(Altos.ao_flight_landed, "Landed");
-    
-        protected AltosGraphTime myAltosGraphTime(String suffix) {
-            return (new AltosGraphTime("Overall " + suffix))
-                .addElement(e_boost)
-               .addElement(e_fast)
-               .addElement(e_coast)
-                .addElement(e_drogue)
-                .addElement(e_main)
-                .addElement(e_landed);
-        }
-    
-        public ArrayList<AltosGraph> graphs() {
-            ArrayList<AltosGraph> graphs = new ArrayList<AltosGraph>();
-    
-           graphs.add( myAltosGraphTime("Summary")
-                       .addElement(height)
-                       .addElement(speed)
-                       .addElement(acceleration) );
-
-           graphs.add( myAltosGraphTime("Summary")
-                       .addElement(height)
-                       .addElement(speed));
-    
-            graphs.add( myAltosGraphTime("Altitude")
-                    .addElement(height) );
-    
-            graphs.add( myAltosGraphTime("Speed")
-                    .addElement(speed) );
-    
-           graphs.add( myAltosGraphTime("Acceleration")
-                       .addElement(acceleration) );
-    
-            graphs.add( myAltosGraphTime("Temperature")
-                    .addElement(temperature) );
-    
-           graphs.add( myAltosGraphTime("Continuity")
-                       .addElement(drogue_voltage)
-                       .addElement(main_voltage) );
-    
-            return graphs;
-        }
-    }
-    
-    static private class AscentGraphs extends OverallGraphs {
-        protected AltosGraphTime myAltosGraphTime(String suffix) {
-            return (new AltosGraphTime("Ascent " + suffix) {
-                public void addData(AltosDataPoint d) {
-                    int state = d.state();
-                    if (Altos.ao_flight_boost <= state && state <= Altos.ao_flight_coast) {
-                        super.addData(d);
-                    }
-                }
-            }).addElement(e_boost)
-              .addElement(e_fast)
-              .addElement(e_coast);
-        }
-    }
-    
-    static private class DescentGraphs extends OverallGraphs {
-        protected AltosGraphTime myAltosGraphTime(String suffix) {
-            return (new AltosGraphTime("Descent " + suffix) {
-                public void addData(AltosDataPoint d) {
-                    int state = d.state();
-                    if (Altos.ao_flight_drogue <= state && state <= Altos.ao_flight_main) {
-                        super.addData(d);
-                    }
-                }
-            }).addElement(e_drogue)
-              .addElement(e_main);
-            // ((XYGraph)graph[8]).ymin = new Double(-50);
-        }
-    }
-
-       public AltosGraphUI(AltosRecordIterable records, String name) throws InterruptedException, IOException {
-               super(String.format("Altos Graph %s", name));
-
-               AltosDataPointReader reader = new AltosDataPointReader (records);
-               if (reader == null)
-                       return;
-        
-               if (reader.has_accel)
-                   init(reader, records, 0);
-               else
-                   init(reader, records, 1);
+       JTabbedPane             pane;
+       AltosGraph              graph;
+       AltosUIEnable           enable;
+       AltosUIMap              map;
+       AltosState              state;
+       AltosGraphDataSet       graphDataSet;
+       AltosFlightStats        stats;
+       AltosFlightStatsTable   statsTable;
+       boolean                 has_gps;
+
+       void fill_map(AltosStateIterable states) {
+               boolean         any_gps = false;
+               for (AltosState state : states) {
+                       if (state.gps != null && state.gps.locked && state.gps.nsat >= 4) {
+                               if (map == null)
+                                       map = new AltosUIMap();
+                               map.show(state, null);
+                               has_gps = true;
+                       }
+               }
        }
 
-//    public AltosGraphUI(AltosDataPointReader data, int which)
-    //  {
-//        super("Altos Graph");
-//        init(data, which);
-//    }
-
-    private void init(AltosDataPointReader data, AltosRecordIterable records, int which) throws InterruptedException, IOException {
-       pane = new JTabbedPane();
+       public void font_size_changed(int font_size) {
+               if (map != null)
+                       map.font_size_changed(font_size);
+               if (statsTable != null)
+                       statsTable.font_size_changed(font_size);
+       }
 
-        AltosGraph graph = createGraph(data, which);
+       public void units_changed(boolean imperial_units) {
+               if (map != null)
+                       map.units_changed(imperial_units);
+       }
 
-        JFreeChart chart = graph.createChart();
-        ChartPanel chartPanel = new ChartPanel(chart);
-        chartPanel.setMouseWheelEnabled(true);
-        chartPanel.setPreferredSize(new java.awt.Dimension(800, 500));
-        pane.add(graph.title, chartPanel);
+       AltosGraphUI(AltosStateIterable states, File file) throws InterruptedException, IOException {
+               super(file.getName());
+               state = null;
 
-       AltosFlightStatsTable stats = new AltosFlightStatsTable(new AltosFlightStats(records));
-       pane.add("Flight Statistics", stats);
+               pane = new JTabbedPane();
 
-       setContentPane (pane);
+               enable = new AltosUIEnable();
 
-        pack();
+               stats = new AltosFlightStats(states);
+               graphDataSet = new AltosGraphDataSet(states);
 
-        RefineryUtilities.centerFrameOnScreen(this);
+               graph = new AltosGraph(enable, stats, graphDataSet);
 
-        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
-        setVisible(true);
-    }
+               statsTable = new AltosFlightStatsTable(stats);
 
-    private static AltosGraph createGraph(Iterable<AltosDataPoint> data,
-            int which)
-    {
-        return createGraphsWhich(data, which).get(0);
-    }
+               pane.add("Flight Graph", graph.panel);
+               pane.add("Configure Graph", enable);
+               pane.add("Flight Statistics", statsTable);
 
-    private static ArrayList<AltosGraph> createGraphs(
-            Iterable<AltosDataPoint> data)
-    {
-        return createGraphsWhich(data, -1);
-    }
+               has_gps = false;
+               fill_map(states);
+               if (has_gps)
+                       pane.add("Map", map);
 
-    private static ArrayList<AltosGraph> createGraphsWhich(
-            Iterable<AltosDataPoint> data, int which)
-    {
-        ArrayList<AltosGraph> graph = new ArrayList<AltosGraph>();
-        graph.addAll((new OverallGraphs()).graphs());
-//        graph.addAll((new AscentGraphs()).graphs());
-//        graph.addAll((new DescentGraphs()).graphs());
+               setContentPane (pane);
 
-        if (which > 0) {
-            if (which >= graph.size()) {
-                which = 0;
-            }
-            AltosGraph g = graph.get(which);
-            graph = new ArrayList<AltosGraph>();
-            graph.add(g);
-        }
+               AltosUIPreferences.register_font_listener(this);
+               AltosPreferences.register_units_listener(this);
 
-        for (AltosDataPoint dp : data) {
-            for (AltosGraph g : graph) {
-                g.addData(dp);
-            }
-        }
+               addWindowListener(new WindowAdapter() {
+                               @Override
+                               public void windowClosing(WindowEvent e) {
+                                       setVisible(false);
+                                       dispose();
+                                       AltosUIPreferences.unregister_font_listener(AltosGraphUI.this);
+                                       AltosPreferences.unregister_units_listener(AltosGraphUI.this);
+                               }
+                       });
+               pack();
 
-        return graph;
-    }
+               setVisible(true);
+               if (state != null && has_gps)
+                       map.centre(state);
+       }
 }
-
-/* gnuplot bits...
- *
-300x400
-
---------------------------------------------------------
-TOO HARD! :)
-
-"ascent-gps-accuracy.png" "Vertical error margin to apogee - GPS v Baro (m)"
-    5:($7 < 6 ? $24-$11 : 1/0)
-"descent-gps-accuracy.png" "Vertical error margin during descent - GPS v Baro (m)"
-    5:($7 < 6 ? 1/0 : $24-$11)
-
-set output "overall-gps-accuracy.png"
-set ylabel "distance above sea level (m)"
-plot "telemetry.csv" using 5:11 with lines ti "baro altitude" axis x1y1, \
-    "telemetry.csv" using 5:24 with lines ti "gps altitude" axis x1y1
-
-set term png tiny size 700,700 enhanced
-set xlabel "m"
-set ylabel "m"
-set polar
-set grid polar
-set rrange[*:*]
-set angles degrees
-
-set output "overall-gps-path.png"
-#:30 with yerrorlines
-plot "telemetry.csv" using (90-$33):($7 == 2 ? $31 : 1/0) with lines ti "pad", \
-    "telemetry.csv" using (90-$33):($7 == 3 ? $31 : 1/0) with lines ti "boost", \
-    "telemetry.csv" using (90-$33):($7 == 4 ? $31 : 1/0) with lines ti "fast", \
-    "telemetry.csv" using (90-$33):($7 == 5 ? $31 : 1/0) with lines ti "coast", \
-    "telemetry.csv" using (90-$33):($7 == 6 ? $31 : 1/0) with lines ti "drogue", \
-    "telemetry.csv" using (90-$33):($7 == 7 ? $31 : 1/0) with lines ti "main", \
-    "telemetry.csv" using (90-$33):($7 == 8 ? $31 : 1/0) with lines ti "landed"
-
-set output "ascent-gps-path.png"
-plot "telemetry.csv" using (90-$33):($7 == 2 ? $31 : 1/0):30 with lines ti "pad", \
-    "telemetry.csv" using (90-$33):($7 == 3 ? $31 : 1/0):20 with lines ti "boost", \
-    "telemetry.csv" using (90-$33):($7 == 4 ? $31 : 1/0):10 with lines ti "fast", \
-    "telemetry.csv" using (90-$33):($7 == 5 ? $31 : 1/0):5 with lines ti "coast"
-
-set output "descent-gps-path.png"
-plot "telemetry.csv" using (90-$33):($7 == 6 ? $31 : 1/0) with lines ti "drogue", \
-    "telemetry.csv" using (90-$33):($7 == 7 ? $31 : 1/0) with lines ti "main", \
-    "telemetry.csv" using (90-$33):($7 == 8 ? $31 : 1/0) with lines ti "landed"
-
- */
-
-