diff options
| author | Anthony Towns <aj@erisian.com.au> | 2010-11-25 09:10:50 +1000 | 
|---|---|---|
| committer | Anthony Towns <aj@erisian.com.au> | 2010-11-25 09:10:50 +1000 | 
| commit | f01096c4b42f9a4720ed0414826c2a283a992545 (patch) | |
| tree | 0d9bebaa5e1b4b171abe6aa642ff7a33a72c6146 /altosui/AltosGraphTime.java | |
| parent | 357826aa9c7b42c59f5d52b8eb016d73b6da0c7f (diff) | |
| parent | 3fbefb3eea981d34a09496cf8abf0119de2e35bf (diff) | |
Merge branch 'buttonbox' of git://git.gag.com/fw/altos into buttonbox
Diffstat (limited to 'altosui/AltosGraphTime.java')
| -rw-r--r-- | altosui/AltosGraphTime.java | 233 | 
1 files changed, 233 insertions, 0 deletions
| diff --git a/altosui/AltosGraphTime.java b/altosui/AltosGraphTime.java new file mode 100644 index 00000000..a5451280 --- /dev/null +++ b/altosui/AltosGraphTime.java @@ -0,0 +1,233 @@ + +// Copyright (c) 2010 Anthony Towns +// GPL v2 or later + +package altosui; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.HashMap; + +import org.jfree.chart.ChartUtilities; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.AxisLocation; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.labels.StandardXYToolTipGenerator; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.plot.ValueMarker; +import org.jfree.chart.renderer.xy.StandardXYItemRenderer; +import org.jfree.chart.renderer.xy.XYItemRenderer; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; +import org.jfree.ui.RectangleAnchor; +import org.jfree.ui.TextAnchor; + +class AltosGraphTime extends AltosGraph { +    static interface Element { +        void attachGraph(AltosGraphTime g); +        void gotTimeData(double time, AltosDataPoint d); +        void addToPlot(AltosGraphTime g, XYPlot plot); +    } + +    static class TimeAxis implements Element { +        private int axis; +        private Color color; +        private String label; +        private AxisLocation locn; +        private double min_y = Double.NaN; + +        public TimeAxis(int axis, String label, Color color, AxisLocation locn) +        { +            this.axis = axis; +            this.color = color; +            this.label = label; +            this.locn = locn; +        } + +        public void setLowerBound(double min_y) { +            this.min_y = min_y; +        } + +        public void attachGraph(AltosGraphTime g) { return; } +        public void gotTimeData(double time, AltosDataPoint d) { return; } + +        public void addToPlot(AltosGraphTime g, XYPlot plot) { +            NumberAxis numAxis = new NumberAxis(label); +            if (!Double.isNaN(min_y)) +                numAxis.setLowerBound(min_y); +            plot.setRangeAxis(axis, numAxis); +            plot.setRangeAxisLocation(axis, locn); +            numAxis.setLabelPaint(color); +            numAxis.setTickLabelPaint(color); +            numAxis.setAutoRangeIncludesZero(false); +        } +    } + +    abstract static class TimeSeries implements Element { +        protected XYSeries series; +        private String axisName; +        private Color color; + +        public TimeSeries(String axisName, String label, Color color) { +            this.series = new XYSeries(label); +            this.axisName = axisName; +            this.color = color; +        } + +        public void attachGraph(AltosGraphTime g) { +            g.setAxis(this, axisName, color); +        } +        abstract public void gotTimeData(double time, AltosDataPoint d); + +        public void addToPlot(AltosGraphTime g, XYPlot plot) { +            XYSeriesCollection dataset = new XYSeriesCollection(); +            dataset.addSeries(this.series); + +            XYItemRenderer renderer = new StandardXYItemRenderer(); +            renderer.setSeriesPaint(0, color); + +            int dataNum = g.getDataNum(this); +            int axisNum = g.getAxisNum(this); + +            plot.setDataset(dataNum, dataset); +            plot.mapDatasetToRangeAxis(dataNum, axisNum); +            plot.setRenderer(dataNum, renderer); +        } +    } + +    static class StateMarker implements Element { +        private double val = Double.NaN; +        private String name; +        private int state; + +        StateMarker(int state, String name) { +            this.state = state; +            this.name = name; +        } + +        public void attachGraph(AltosGraphTime g) { return; } +        public void gotTimeData(double time, AltosDataPoint d) { +            if (Double.isNaN(val) || time < val) { +                if (d.state() == state) { +                    val = time; +                } +            } +        } + +        public void addToPlot(AltosGraphTime g, XYPlot plot) { +            if (Double.isNaN(val)) +                return; + +            ValueMarker m = new ValueMarker(val); +            m.setLabel(name); +            m.setLabelAnchor(RectangleAnchor.TOP_RIGHT); +            m.setLabelTextAnchor(TextAnchor.TOP_LEFT); +            plot.addDomainMarker(m); +        } +    } + +    private String callsign = null; +    private Integer serial = null; +    private Integer flight = null;  + +    private String title; +    private ArrayList<Element> elements; +    private HashMap<String,Integer> axes; +    private HashMap<Element,Integer> datasets; +    private ArrayList<Integer> datasetAxis; + +    public AltosGraphTime(String title) { +        this.filename = title.toLowerCase().replaceAll("[^a-z0-9]","_")+".png"; +        this.title = title; +        this.elements = new ArrayList<Element>(); +        this.axes = new HashMap<String,Integer>(); +        this.datasets = new HashMap<Element,Integer>(); +        this.datasetAxis = new ArrayList<Integer>(); +    } + +    public AltosGraphTime addElement(Element e) { +        e.attachGraph(this); +        elements.add(e); +        return this; +    } + +    public void setAxis(Element ds, String axisName, Color color) { +        Integer axisNum = axes.get(axisName); +        int dsNum = datasetAxis.size(); +        if (axisNum == null) { +            axisNum = newAxis(axisName, color); +        } +        datasets.put(ds, dsNum); +        datasetAxis.add(axisNum); +    } + +    public int getAxisNum(Element ds) { +        return datasetAxis.get( datasets.get(ds) ).intValue(); +    } +    public int getDataNum(Element ds) { +        return datasets.get(ds).intValue(); +    } + +    private Integer newAxis(String name, Color color) { +        int cnt = axes.size(); +        AxisLocation locn = AxisLocation.BOTTOM_OR_LEFT; +        if (cnt > 0) { +            locn = AxisLocation.TOP_OR_RIGHT; +        } +        Integer res = new Integer(cnt); +        axes.put(name, res); +        this.addElement(new TimeAxis(cnt, name, color, locn)); +        return res; +    } + +    public void addData(AltosDataPoint d) { +        double time = d.time(); +        for (Element e : elements) { +            e.gotTimeData(time, d); +        } +        if (callsign == null) callsign = d.callsign(); +        if (serial == null) serial = new Integer(d.serial()); +        if (flight == null) flight = new Integer(d.flight()); +    } + +    public JFreeChart createChart() { +        NumberAxis xAxis = new NumberAxis("Time (s)"); +        xAxis.setAutoRangeIncludesZero(false); +        XYItemRenderer renderer = new XYLineAndShapeRenderer(true, false); +        XYPlot plot = new XYPlot(); +        plot.setDomainAxis(xAxis); +        plot.setRenderer(renderer); +        plot.setOrientation(PlotOrientation.VERTICAL); + +        if (serial != null && flight != null) { +            title = serial + "/" + flight + ": " + title; +        } +        if (callsign != null) { +            title = callsign + " - " + title; +        } + +        renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); +        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, +                                plot, true); +        ChartUtilities.applyCurrentTheme(chart); + +        plot.setDomainPannable(true); +        plot.setRangePannable(true); +    +        for (Element e : elements) { +            e.addToPlot(this, plot); +        } + +        return chart; +    } + +    public void toPNG() throws java.io.IOException { +        if (axes.size() > 1) { +            toPNG(800, 500); +        } else { +            toPNG(300, 500); +        } +    } +} | 
