X-Git-Url: https://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fgui%2Fprofile%2FProfileChart.java;h=0dcabcb66785b06f1dd9730fc7f3a7025e34d89e;hb=8c8868ae29b3252f02e094c02307384cf61ba667;hp=17ea32b2a4c004328b1ce1afcaf592b97423780c;hpb=140e9d165f85c3d4f0435a311e091209313faa2a;p=GpsPrune.git diff --git a/tim/prune/gui/profile/ProfileChart.java b/tim/prune/gui/profile/ProfileChart.java index 17ea32b..0dcabcb 100644 --- a/tim/prune/gui/profile/ProfileChart.java +++ b/tim/prune/gui/profile/ProfileChart.java @@ -15,6 +15,8 @@ import javax.swing.JPopupMenu; import tim.prune.I18nManager; import tim.prune.config.ColourScheme; import tim.prune.config.Config; +import tim.prune.data.Field; +import tim.prune.data.FieldList; import tim.prune.data.TrackInfo; import tim.prune.gui.GenericDisplay; @@ -23,6 +25,17 @@ import tim.prune.gui.GenericDisplay; */ public class ProfileChart extends GenericDisplay implements MouseListener { + /** Inner class to handle popup menu clicks */ + class MenuClicker implements ActionListener + { + private Field _field = null; + MenuClicker(Field inField) {_field = inField;} + /** React to menu click by changing the field */ + public void actionPerformed(ActionEvent arg0) { + changeView(_field); + } + } + /** Current scale factor in x direction*/ private double _xScaleFactor = 0.0; /** Data to show on chart */ @@ -33,15 +46,13 @@ public class ProfileChart extends GenericDisplay implements MouseListener private JPopupMenu _popup = null; /** Possible scales to use */ - private static final int[] LINE_SCALES = {10000, 5000, 2000, 1000, 500, 200, 100, 50, 10, 5}; + private static final int[] LINE_SCALES = {10000, 5000, 2000, 1000, 500, 200, 100, 50, 10, 5, 2, 1}; /** Border width around black line */ private static final int BORDER_WIDTH = 6; /** Minimum size for profile chart in pixels */ private static final Dimension MINIMUM_SIZE = new Dimension(200, 110); /** Colour to use for text if no data found */ private static final Color COLOR_NODATA_TEXT = Color.GRAY; - /** Chart type */ - private static enum ChartType {ALTITUDE, SPEED}; /** @@ -54,7 +65,7 @@ public class ProfileChart extends GenericDisplay implements MouseListener _data = new AltitudeData(inTrackInfo.getTrack()); addMouseListener(this); setLayout(new FlowLayout(FlowLayout.LEFT)); - _label = new JLabel("Altitude"); + _label = new JLabel("Altitude"); // text will be replaced later add(_label); makePopup(); } @@ -79,7 +90,6 @@ public class ProfileChart extends GenericDisplay implements MouseListener paintBackground(g, colourScheme); if (_track != null && _track.getNumPoints() > 0) { - _data.init(); _label.setText(_data.getLabel()); int width = getWidth(); int height = getHeight(); @@ -121,11 +131,14 @@ public class ProfileChart extends GenericDisplay implements MouseListener // horizontal lines for scale - set to round numbers eg 500 int lineScale = getLineScale(minValue, maxValue); int scaleValue = (int) (minValue/lineScale + 1) * lineScale; + if (minValue < 0.0) {scaleValue -= lineScale;} int x = 0, y = 0; + final int zeroY = height - BORDER_WIDTH - (int) (yScaleFactor * (0.0 - minValue)); + double value = 0.0; - if (lineScale > 1) + g.setColor(lineColour); + if (lineScale >= 1) { - g.setColor(lineColour); while (scaleValue < maxValue) { y = height - BORDER_WIDTH - (int) (yScaleFactor * (scaleValue - minValue)); @@ -133,6 +146,12 @@ public class ProfileChart extends GenericDisplay implements MouseListener scaleValue += lineScale; } } + else if (minValue < 0.0) + { + // just draw zero line + y = zeroY; + g.drawLine(BORDER_WIDTH + 1, y, width - BORDER_WIDTH - 1, y); + } try { @@ -148,8 +167,22 @@ public class ProfileChart extends GenericDisplay implements MouseListener if (_data.hasData(p)) { value = _data.getData(p); - y = (int) (yScaleFactor * (value - minValue)); - g.fillRect(BORDER_WIDTH+x, height-BORDER_WIDTH - y, barWidth, y); + // Normal case is the minimum value greater than zero + if (minValue >= 0) + { + y = (int) (yScaleFactor * (value - minValue)); + g.fillRect(BORDER_WIDTH+x, height-BORDER_WIDTH - y, barWidth, y); + } + else if (value >= 0.0) { + // Bar upwards from the zero line + y = height-BORDER_WIDTH - (int) (yScaleFactor * (value - minValue)); + g.fillRect(BORDER_WIDTH+x, y, barWidth, zeroY - y); + } + else { + // Bar downwards from the zero line + int barHeight = (int) (yScaleFactor * value); + g.fillRect(BORDER_WIDTH+x, zeroY, barWidth, -barHeight); + } } } // current point (make sure it's drawn last) @@ -170,10 +203,11 @@ public class ProfileChart extends GenericDisplay implements MouseListener catch (NullPointerException npe) { // ignore, probably due to data being changed } // Draw numbers on top of the graph to mark scale - if (lineScale > 1) + if (lineScale >= 1) { int textHeight = g.getFontMetrics().getHeight(); scaleValue = (int) (minValue / lineScale + 1) * lineScale; + if (minValue < 0.0) {scaleValue -= lineScale;} y = 0; g.setColor(currentColour); while (scaleValue < maxValue) @@ -225,23 +259,45 @@ public class ProfileChart extends GenericDisplay implements MouseListener /** * Make the popup menu for right-clicking the chart */ - private void makePopup() + private synchronized void makePopup() { _popup = new JPopupMenu(); JMenuItem altItem = new JMenuItem(I18nManager.getText("fieldname.altitude")); altItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - changeView(ChartType.ALTITUDE); + changeView(Field.ALTITUDE); }}); _popup.add(altItem); JMenuItem speedItem = new JMenuItem(I18nManager.getText("fieldname.speed")); speedItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - changeView(ChartType.SPEED); + changeView(Field.SPEED); }}); _popup.add(speedItem); + JMenuItem vertSpeedItem = new JMenuItem(I18nManager.getText("fieldname.verticalspeed")); + vertSpeedItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) + { + changeView(Field.VERTICAL_SPEED); + }}); + _popup.add(vertSpeedItem); + // Go through track's master field list, see if any other fields to list + boolean addSeparator = true; + FieldList fields = _track.getFieldList(); + for (int i=0; i 0) { + makePopup(); + } repaint(); } @@ -313,18 +376,33 @@ public class ProfileChart extends GenericDisplay implements MouseListener /** * Called by clicking on popup menu to change the view - * @param inType selected chart type + * @param inField field to show */ - private void changeView(ChartType inType) + private void changeView(Field inField) { - if (inType == ChartType.ALTITUDE && !(_data instanceof AltitudeData)) + if (inField == Field.ALTITUDE) { - _data = new AltitudeData(_track); + if (!(_data instanceof AltitudeData)) { + _data = new AltitudeData(_track); + } } - else if (inType == ChartType.SPEED && !(_data instanceof SpeedData)) { - _data = new SpeedData(_track); + else if (inField == Field.SPEED) { + if (!(_data instanceof SpeedData)) { + _data = new SpeedData(_track); + } + } + else if (inField == Field.VERTICAL_SPEED) { + if (!(_data instanceof VerticalSpeedData)) { + _data = new VerticalSpeedData(_track); + } + } + else + { + if (!(_data instanceof ArbitraryData) || ((ArbitraryData)_data).getField() != inField) { + _data = new ArbitraryData(_track, inField); + } } - _data.init(); + _data.init(Config.getUnitSet()); repaint(); }