X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=tim%2Fprune%2Ffunction%2Fcharts%2FCharter.java;fp=tim%2Fprune%2Ffunction%2Fcharts%2FCharter.java;h=0000000000000000000000000000000000000000;hp=5b7ae83c29470ae7fa51306446554c10514405d2;hb=ce6f2161b8596f7018d6a76bff79bc9e571f35fd;hpb=2d8cb72e84d5cc1089ce77baf1e34ea3ea2f8465 diff --git a/tim/prune/function/charts/Charter.java b/tim/prune/function/charts/Charter.java deleted file mode 100644 index 5b7ae83..0000000 --- a/tim/prune/function/charts/Charter.java +++ /dev/null @@ -1,620 +0,0 @@ -package tim.prune.function.charts; - -import java.awt.BorderLayout; -import java.awt.FlowLayout; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.OutputStreamWriter; - -import javax.swing.BorderFactory; -import javax.swing.BoxLayout; -import javax.swing.ButtonGroup; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JDialog; -import javax.swing.JFileChooser; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; -import javax.swing.SwingConstants; - -import tim.prune.App; -import tim.prune.ExternalTools; -import tim.prune.GenericFunction; -import tim.prune.I18nManager; -import tim.prune.config.Config; -import tim.prune.data.DataPoint; -import tim.prune.data.Distance; -import tim.prune.data.Field; -import tim.prune.data.Timestamp; -import tim.prune.data.Track; -import tim.prune.gui.profile.SpeedData; -import tim.prune.gui.profile.VerticalSpeedData; -import tim.prune.load.GenericFileFilter; - -/** - * Class to manage the generation of charts using gnuplot - */ -public class Charter extends GenericFunction -{ - /** dialog object, cached */ - private JDialog _dialog = null; - /** radio button for distance axis */ - private JRadioButton _distanceRadio = null; - /** radio button for time axis */ - private JRadioButton _timeRadio = null; - /** array of checkboxes for specifying y axes */ - private JCheckBox[] _yAxesBoxes = null; - /** radio button for svg output */ - private JRadioButton _svgRadio = null; - /** file chooser for saving svg file */ - private JFileChooser _fileChooser = null; - /** text field for svg width */ - private JTextField _svgWidthField = null; - /** text field for svg height */ - private JTextField _svgHeightField = null; - - /** Default dimensions of Svg file */ - private static final String DEFAULT_SVG_WIDTH = "800"; - private static final String DEFAULT_SVG_HEIGHT = "400"; - - - /** - * Constructor from superclass - * @param inApp app object - */ - public Charter(App inApp) - { - super(inApp); - } - - /** - * @return key for function name - */ - public String getNameKey() - { - return "function.charts"; - } - - /** - * Show the dialog - */ - public void begin() - { - // First check if gnuplot is available - if (!ExternalTools.isToolInstalled(ExternalTools.TOOL_GNUPLOT)) - { - _app.showErrorMessage(getNameKey(), "dialog.charts.gnuplotnotfound"); - return; - } - // Make dialog window - if (_dialog == null) - { - _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()), true); - _dialog.setLocationRelativeTo(_parentFrame); - _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); - _dialog.getContentPane().add(makeDialogComponents()); - _dialog.pack(); - } - if (setupDialog(_app.getTrackInfo().getTrack())) { - _dialog.setVisible(true); - } - else { - _app.showErrorMessage(getNameKey(), "dialog.charts.needaltitudeortimes"); - } - } - - - /** - * Make the dialog components - * @return panel containing gui elements - */ - private JPanel makeDialogComponents() - { - JPanel dialogPanel = new JPanel(); - dialogPanel.setLayout(new BorderLayout()); - - JPanel mainPanel = new JPanel(); - mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); - // x axis choice - JPanel axisPanel = new JPanel(); - axisPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("dialog.charts.xaxis"))); - _distanceRadio = new JRadioButton(I18nManager.getText("fieldname.distance")); - _distanceRadio.setSelected(true); - _timeRadio = new JRadioButton(I18nManager.getText("fieldname.time")); - ButtonGroup axisGroup = new ButtonGroup(); - axisGroup.add(_distanceRadio); axisGroup.add(_timeRadio); - axisPanel.add(_distanceRadio); axisPanel.add(_timeRadio); - mainPanel.add(axisPanel); - - // y axis choices - JPanel yPanel = new JPanel(); - yPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("dialog.charts.yaxis"))); - _yAxesBoxes = new JCheckBox[4]; // dist altitude speed vertspeed (time not available on y axis) - _yAxesBoxes[0] = new JCheckBox(I18nManager.getText("fieldname.distance")); - _yAxesBoxes[1] = new JCheckBox(I18nManager.getText("fieldname.altitude")); - _yAxesBoxes[1].setSelected(true); - _yAxesBoxes[2] = new JCheckBox(I18nManager.getText("fieldname.speed")); - _yAxesBoxes[3] = new JCheckBox(I18nManager.getText("fieldname.verticalspeed")); - for (int i=0; i<4; i++) { - yPanel.add(_yAxesBoxes[i]); - } - mainPanel.add(yPanel); - - // Add validation to prevent choosing invalid (ie dist/dist) combinations - ActionListener xAxisListener = new ActionListener() { - public void actionPerformed(ActionEvent e) { - enableYbox(0, _timeRadio.isSelected()); - } - }; - _timeRadio.addActionListener(xAxisListener); - _distanceRadio.addActionListener(xAxisListener); - - // output buttons - JPanel outputPanel = new JPanel(); - outputPanel.setBorder(BorderFactory.createTitledBorder(I18nManager.getText("dialog.charts.output"))); - outputPanel.setLayout(new BorderLayout()); - JPanel radiosPanel = new JPanel(); - JRadioButton screenRadio = new JRadioButton(I18nManager.getText("dialog.charts.screen")); - screenRadio.setSelected(true); - _svgRadio = new JRadioButton(I18nManager.getText("dialog.charts.svg")); - ButtonGroup outputGroup = new ButtonGroup(); - outputGroup.add(screenRadio); outputGroup.add(_svgRadio); - radiosPanel.add(screenRadio); radiosPanel.add(_svgRadio); - outputPanel.add(radiosPanel, BorderLayout.NORTH); - // panel for svg width, height - JPanel sizePanel = new JPanel(); - sizePanel.setLayout(new GridLayout(2, 2, 10, 1)); - JLabel widthLabel = new JLabel(I18nManager.getText("dialog.charts.svgwidth")); - widthLabel.setHorizontalAlignment(SwingConstants.RIGHT); - sizePanel.add(widthLabel); - _svgWidthField = new JTextField(DEFAULT_SVG_WIDTH, 5); - sizePanel.add(_svgWidthField); - JLabel heightLabel = new JLabel(I18nManager.getText("dialog.charts.svgheight")); - heightLabel.setHorizontalAlignment(SwingConstants.RIGHT); - sizePanel.add(heightLabel); - _svgHeightField = new JTextField(DEFAULT_SVG_HEIGHT, 5); - sizePanel.add(_svgHeightField); - - outputPanel.add(sizePanel, BorderLayout.EAST); - mainPanel.add(outputPanel); - dialogPanel.add(mainPanel, BorderLayout.CENTER); - - // button panel on bottom - JPanel buttonPanel = new JPanel(); - buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); - // ok button - JButton okButton = new JButton(I18nManager.getText("button.ok")); - okButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - showChart(_app.getTrackInfo().getTrack()); - _dialog.setVisible(false); - } - }); - buttonPanel.add(okButton); - // Cancel button - JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); - cancelButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - _dialog.setVisible(false); - } - }); - buttonPanel.add(cancelButton); - dialogPanel.add(buttonPanel, BorderLayout.SOUTH); - return dialogPanel; - } - - - /** - * Set up the dialog according to the track contents - * @param inTrack track object - * @return true if it's all ok - */ - private boolean setupDialog(Track inTrack) - { - boolean hasTimes = inTrack.hasData(Field.TIMESTAMP); - boolean hasAltitudes = inTrack.hasAltitudeData(); - _timeRadio.setEnabled(hasTimes); - - // Add checks to prevent choosing unavailable combinations - if (!hasTimes) { - _distanceRadio.setSelected(true); - } - enableYbox(0, !_distanceRadio.isSelected()); - enableYbox(1, hasAltitudes); - enableYbox(2, hasTimes); - enableYbox(3, hasTimes && hasAltitudes); - return (hasTimes || hasAltitudes); - } - - - /** - * Enable or disable the given y axis checkbox - * @param inIndex index of checkbox - * @param inFlag true to enable - */ - private void enableYbox(int inIndex, boolean inFlag) - { - _yAxesBoxes[inIndex].setEnabled(inFlag); - if (!inFlag) { - _yAxesBoxes[inIndex].setSelected(inFlag); - } - } - - /** - * Show the chart for the specified track - * @param inTrack track object containing data - */ - private void showChart(Track inTrack) - { - int numCharts = 0; - for (int i=0; i<_yAxesBoxes.length; i++) { - if (_yAxesBoxes[i].isSelected()) { - numCharts++; - } - } - // Select default chart if none selected - if (numCharts == 0) { - _yAxesBoxes[1].setSelected(true); - numCharts = 1; - } - int[] heights = getHeights(numCharts); - - boolean showSvg = _svgRadio.isSelected(); - File svgFile = null; - if (showSvg) { - svgFile = selectSvgFile(); - if (svgFile == null) {showSvg = false;} - } - OutputStreamWriter writer = null; - try - { - final String gnuplotPath = Config.getConfigString(Config.KEY_GNUPLOT_PATH); - Process process = Runtime.getRuntime().exec(gnuplotPath + " -persist"); - writer = new OutputStreamWriter(process.getOutputStream()); - if (showSvg) - { - writer.write("set terminal svg size " + getSvgValue(_svgWidthField, DEFAULT_SVG_WIDTH) + " " - + getSvgValue(_svgHeightField, DEFAULT_SVG_HEIGHT) + "\n"); - writer.write("set out '" + svgFile.getAbsolutePath() + "'\n"); - } - else { - // For screen output, gnuplot should use the default terminal (windows or x11 or wxt or something) - } - if (numCharts > 1) { - writer.write("set multiplot layout " + numCharts + ",1\n"); - } - // Loop over possible charts - int chartNum = 0; - for (int c=0; c<_yAxesBoxes.length; c++) - { - if (_yAxesBoxes[c].isSelected()) - { - writer.write("set size 1," + (0.01*heights[chartNum*2+1]) + "\n"); - writer.write("set origin 0," + (0.01*heights[chartNum*2]) + "\n"); - writeChart(writer, inTrack, _distanceRadio.isSelected(), c); - chartNum++; - } - } - // Close multiplot if open - if (numCharts > 1) { - writer.write("unset multiplot\n"); - } - } - catch (Exception e) { - _app.showErrorMessageNoLookup(getNameKey(), e.getMessage()); - } - finally { - try { - // Close writer - if (writer != null) writer.close(); - } - catch (Exception e) {} // ignore - } - } - - - /** - * Parse the given text field's value and return as string - * @param inField text field to read from - * @param inDefault default value if not valid - * @return value of svg dimension as string - */ - private static String getSvgValue(JTextField inField, String inDefault) - { - int value = 0; - try { - value = Integer.parseInt(inField.getText()); - } - catch (Exception e) {} // ignore, value stays zero - if (value > 0) { - return "" + value; - } - return inDefault; - } - - - /** - * Write out the selected chart to the given Writer object - * @param inWriter writer object - * @param inTrack Track containing data - * @param inDistance true if x axis is distance - * @param inYaxis index of y axis - * @throws IOException if writing error occurred - */ - private static void writeChart(OutputStreamWriter inWriter, Track inTrack, boolean inDistance, int inYaxis) - throws IOException - { - ChartSeries xValues = null, yValues = null; - ChartSeries distValues = getDistanceValues(inTrack); - // Choose x values according to axis - if (inDistance) { - xValues = distValues; - } - else { - xValues = getTimeValues(inTrack); - } - // Choose y values according to axis - switch (inYaxis) - { - case 0: // y axis is distance - yValues = distValues; - break; - case 1: // y axis is altitude - yValues = getAltitudeValues(inTrack); - break; - case 2: // y axis is speed - yValues = getSpeedValues(inTrack); - break; - case 3: // y axis is vertical speed - yValues = getVertSpeedValues(inTrack); - break; - } - // Make a temporary data file for the output (one per subchart) - File tempFile = File.createTempFile("gpsprunedata", null); - tempFile.deleteOnExit(); - // write out values for x and y to temporary file - FileWriter tempFileWriter = null; - try { - tempFileWriter = new FileWriter(tempFile); - tempFileWriter.write("# Temporary data file for GpsPrune charts\n\n"); - for (int i=0; i