eu.hydrologis.geopaparazzi.chart.ProfileChartActivity.java Source code

Java tutorial

Introduction

Here is the source code for eu.hydrologis.geopaparazzi.chart.ProfileChartActivity.java

Source

/*
 * Geopaparazzi - Digital field mapping on Android based devices
 * Copyright (C) 2010  HydroloGIS (www.hydrologis.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, either version 3 of the License, or
 * (at your option) any later version.
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

package eu.hydrologis.geopaparazzi.chart;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.PointF;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.androidplot.ui.AnchorPosition;
import com.androidplot.ui.DynamicTableModel;
import com.androidplot.ui.SizeLayoutType;
import com.androidplot.ui.SizeMetrics;
import com.androidplot.ui.XLayoutStyle;
import com.androidplot.ui.YLayoutStyle;
import com.androidplot.util.PixelUtils;
import com.androidplot.xy.BoundaryMode;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XYGraphWidget;
import com.androidplot.xy.XYLegendWidget;
import com.androidplot.xy.XYPlot;
import com.androidplot.xy.XYSeries;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import eu.geopaparazzi.library.database.GPLog;
import eu.geopaparazzi.library.util.DynamicDoubleArray;
import eu.geopaparazzi.library.util.Utilities;
import eu.hydrologis.geopaparazzi.R;
import eu.hydrologis.geopaparazzi.database.DaoGpsLog;
import eu.hydrologis.geopaparazzi.util.Constants;
import eu.hydrologis.geopaparazzi.util.Line;

/**
 * The profile chart activity.
 *
 * @author Andrea Antonello
 */
public class ProfileChartActivity extends Activity implements View.OnTouchListener, View.OnClickListener {

    private XYPlot xyPlotSpeed, xyPlotElev;
    private LineAndPointFormatter seriesSpeedFormat, seriesElevFormat;

    XYSeries seriesSpeed, seriesElev;
    private Line line;
    private ProgressDialog progressDialog;
    private PointF minXYSpeed;
    private PointF maxXYSpeed;
    private PointF minXYElevation;
    private PointF maxXYElevation;
    private TextView infoTextView;
    private double elevDifference;
    private DrawerLayout drawerLayout;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.profilechart);

        int backgroundColor = getResources().getColor(R.color.main_background);
        int decorationsColor = getResources().getColor(R.color.main_decorations_dark);
        int textColor = getResources().getColor(R.color.main_text_color_neutral);

        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            try {
                long logid = extras.getLong(Constants.ID);

                line = DaoGpsLog.getGpslogAsLine(logid, -1);

            } catch (IOException e) {
                GPLog.error(this, e.getLocalizedMessage(), e);
                e.printStackTrace();
            }

        } else {
            Toast.makeText(this, R.string.an_error_occurred_while_creating_the_chart_, Toast.LENGTH_LONG).show();
        }

        final float f26 = PixelUtils.dpToPix(26);
        final float f10 = PixelUtils.dpToPix(10);
        final SizeMetrics sm = new SizeMetrics(0, SizeLayoutType.FILL, 0, SizeLayoutType.FILL);

        xyPlotSpeed = (XYPlot) findViewById(R.id.speed_plot);
        xyPlotElev = (XYPlot) findViewById(R.id.elevation_plot);
        xyPlotSpeed.setOnTouchListener(this);

        infoTextView = (TextView) findViewById(R.id.info_text);
        Button resetButton = (Button) findViewById(R.id.reset_chart_button);
        resetButton.setOnClickListener(this);

        drawerLayout = (DrawerLayout) findViewById(R.id.container_drawer);

        // Disable Hardware Acceleration on the xyPlot view object.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            xyPlotSpeed.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            xyPlotElev.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }

        /*
         * Setup the Plots
         */
        xyPlotSpeed.setPlotMargins(0, 0, 0, 0);
        xyPlotElev.setPlotMargins(0, 0, 0, 0);

        xyPlotSpeed.setPlotPadding(0, 0, 0, 0);
        xyPlotElev.setPlotPadding(0, 0, 0, 0);

        xyPlotElev.getDomainLabelWidget().setVisible(false);
        xyPlotElev.getRangeLabelWidget().setVisible(false);
        xyPlotElev.getTitleWidget().setVisible(false);

        xyPlotElev.setBorderPaint(null);
        xyPlotElev.setBackgroundPaint(null);

        /* 
         * Setup the Graph Widgets
         */
        XYGraphWidget graphWidgetSpeed = xyPlotSpeed.getGraphWidget();
        XYGraphWidget graphWidgetElev = xyPlotElev.getGraphWidget();

        graphWidgetSpeed.setSize(sm);
        graphWidgetElev.setSize(sm);

        graphWidgetSpeed.setMargins(0, 0, 0, 0);
        graphWidgetElev.setMargins(0, 0, 0, 0);

        graphWidgetSpeed.setPadding(f26, f10, f26, f26);
        graphWidgetElev.setPadding(f26, f10, f26, f26);

        graphWidgetSpeed.setRangeAxisPosition(true, false, 4, "10");
        graphWidgetElev.setRangeAxisPosition(false, false, 4, "10");

        graphWidgetSpeed.setRangeLabelVerticalOffset(-3);
        graphWidgetElev.setRangeLabelVerticalOffset(-3);

        graphWidgetSpeed.setRangeOriginLabelPaint(null);
        graphWidgetElev.setRangeOriginLabelPaint(null);

        graphWidgetSpeed.setRangeLabelWidth(0);
        graphWidgetElev.setRangeLabelWidth(0);

        graphWidgetSpeed.setDomainLabelWidth(0);
        graphWidgetElev.setDomainLabelWidth(0);

        graphWidgetElev.setBackgroundPaint(null);
        graphWidgetElev.setDomainLabelPaint(null);
        graphWidgetElev.setGridBackgroundPaint(null);
        graphWidgetElev.setDomainOriginLabelPaint(null);
        graphWidgetElev.setRangeOriginLinePaint(null);
        graphWidgetElev.setDomainGridLinePaint(null);
        graphWidgetElev.setRangeGridLinePaint(null);

        graphWidgetSpeed.getBackgroundPaint().setColor(backgroundColor);
        graphWidgetSpeed.getGridBackgroundPaint().setColor(backgroundColor);

        graphWidgetSpeed.getRangeOriginLinePaint().setColor(decorationsColor);
        graphWidgetSpeed.getRangeOriginLinePaint().setStrokeWidth(3f);
        graphWidgetSpeed.getDomainOriginLinePaint().setColor(decorationsColor);
        graphWidgetSpeed.getDomainOriginLinePaint().setStrokeWidth(3f);

        graphWidgetSpeed.getRangeGridLinePaint().setColor(decorationsColor);
        graphWidgetSpeed.getRangeGridLinePaint().setStrokeWidth(1f);
        graphWidgetSpeed.getDomainGridLinePaint().setColor(decorationsColor);
        graphWidgetSpeed.getDomainGridLinePaint().setStrokeWidth(1f);

        graphWidgetSpeed.getRangeLabelPaint().setColor(textColor);
        graphWidgetSpeed.getDomainLabelPaint().setColor(textColor);
        graphWidgetSpeed.getDomainOriginLabelPaint().setColor(textColor);
        Paint rangeOriginLabelPaint = graphWidgetSpeed.getRangeOriginLabelPaint();
        if (rangeOriginLabelPaint == null) {
            rangeOriginLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            rangeOriginLabelPaint.setStyle(Paint.Style.STROKE);
            graphWidgetSpeed.setRangeOriginLabelPaint(rangeOriginLabelPaint);
        }
        rangeOriginLabelPaint.setColor(textColor);

        graphWidgetSpeed.getRangeLabelPaint().setTextSize(PixelUtils.dpToPix(8));
        graphWidgetElev.getRangeLabelPaint().setTextSize(PixelUtils.dpToPix(8));

        graphWidgetSpeed.getDomainOriginLabelPaint().setTextSize(PixelUtils.dpToPix(8));
        graphWidgetSpeed.getDomainLabelPaint().setTextSize(PixelUtils.dpToPix(8));

        float textSize = graphWidgetSpeed.getRangeLabelPaint().getTextSize();
        graphWidgetSpeed.setRangeLabelVerticalOffset((textSize / 2) * -1);
        graphWidgetElev.setRangeLabelVerticalOffset(graphWidgetSpeed.getRangeLabelVerticalOffset());

        /*
         * Position the Graph Widgets in the Centre
         */
        graphWidgetSpeed.position(0, XLayoutStyle.ABSOLUTE_FROM_CENTER, 0, YLayoutStyle.ABSOLUTE_FROM_CENTER,
                AnchorPosition.CENTER);
        graphWidgetElev.position(0, XLayoutStyle.ABSOLUTE_FROM_CENTER, 0, YLayoutStyle.ABSOLUTE_FROM_CENTER,
                AnchorPosition.CENTER);

        /* 
         * Position the Label Widgets
         */
        xyPlotSpeed.getDomainLabelWidget().setWidth(100);
        xyPlotSpeed.getRangeLabelWidget().setWidth(100);
        xyPlotSpeed.getDomainLabelWidget().position(0, XLayoutStyle.RELATIVE_TO_CENTER, 1,
                YLayoutStyle.ABSOLUTE_FROM_BOTTOM, AnchorPosition.BOTTOM_MIDDLE);
        xyPlotSpeed.getRangeLabelWidget().position(1, XLayoutStyle.ABSOLUTE_FROM_LEFT, -20,
                YLayoutStyle.ABSOLUTE_FROM_CENTER, AnchorPosition.LEFT_BOTTOM);

        /*
         *  Setup and Position the speed Legend
         */
        XYLegendWidget legendWidgetSpeed = xyPlotSpeed.getLegendWidget();
        legendWidgetSpeed.setSize(new SizeMetrics(100, SizeLayoutType.ABSOLUTE, 200, SizeLayoutType.ABSOLUTE));
        legendWidgetSpeed.setPadding(1, 1, 1, 1);
        legendWidgetSpeed.setTableModel(new DynamicTableModel(1, 3));
        legendWidgetSpeed.setIconSizeMetrics(new SizeMetrics(PixelUtils.dpToPix(10), SizeLayoutType.ABSOLUTE,
                PixelUtils.dpToPix(10), SizeLayoutType.ABSOLUTE));
        legendWidgetSpeed.getTextPaint().setColor(textColor);
        legendWidgetSpeed.getTextPaint().setTextSize(PixelUtils.dpToPix(9));
        legendWidgetSpeed.position(PixelUtils.dpToPix(30), XLayoutStyle.ABSOLUTE_FROM_LEFT, f10 + 2,
                YLayoutStyle.ABSOLUTE_FROM_TOP, AnchorPosition.LEFT_TOP);

        /*
         *  Setup and Position the elev Legend
         */
        XYLegendWidget legendWidgetElev = xyPlotElev.getLegendWidget();
        legendWidgetElev.setSize(new SizeMetrics(100, SizeLayoutType.ABSOLUTE, 200, SizeLayoutType.ABSOLUTE));
        legendWidgetElev.setPadding(1, 1, 1, 1);
        legendWidgetElev.setTableModel(new DynamicTableModel(1, 3));
        legendWidgetElev.setIconSizeMetrics(new SizeMetrics(PixelUtils.dpToPix(10), SizeLayoutType.ABSOLUTE,
                PixelUtils.dpToPix(10), SizeLayoutType.ABSOLUTE));
        //        legendWidgetElev.getTextPaint().setColor(textColor);
        legendWidgetElev.getTextPaint().setTextSize(PixelUtils.dpToPix(9));
        legendWidgetElev.getTextPaint().setTextAlign(Align.RIGHT);
        legendWidgetElev.setMarginLeft(185);
        legendWidgetElev.position(PixelUtils.dpToPix(30), XLayoutStyle.ABSOLUTE_FROM_RIGHT, f10 + 2,
                YLayoutStyle.ABSOLUTE_FROM_TOP, AnchorPosition.RIGHT_TOP);

        // Setup the formatters
        int rgbSpeedLine = Color.rgb(0, 200, 0);
        int rgbSpeedPoints = Color.rgb(0, 100, 0);
        int rgbElevLine = Color.rgb(0, 0, 200);
        int rgbElevPoints = Color.rgb(0, 0, 100);

        seriesSpeedFormat = new LineAndPointFormatter(rgbSpeedLine, rgbSpeedPoints, null, null);
        seriesElevFormat = new LineAndPointFormatter(rgbElevLine, rgbElevPoints, null, null);

    }

    @Override
    protected void onResume() {
        super.onResume();

        progressDialog = ProgressDialog.show(this, "", getString(R.string.loading_data));
        new AsyncTask<String, Void, String>() {
            protected String doInBackground(String... params) {
                try {
                    createDatasetFromProfile();
                } catch (Exception e) {
                    return "ERROR";
                }
                return "OK";
            }

            protected void onPostExecute(String msg) {
                if (msg.equals("OK")) {
                    updateView();
                }
                Utilities.dismissProgressDialog(progressDialog);
            }
        }.execute((String) null);

    }

    private void updateView() {

        // Remove all current series from each plot
        for (XYSeries setElement : xyPlotSpeed.getSeriesSet()) {
            xyPlotSpeed.removeSeries(setElement);
        }
        for (XYSeries setElement : xyPlotElev.getSeriesSet()) {
            xyPlotElev.removeSeries(setElement);
        }

        // Add series to each plot as needed.
        xyPlotSpeed.addSeries(seriesSpeed, seriesSpeedFormat);
        xyPlotElev.addSeries(seriesElev, seriesElevFormat);

        // Finalise each Plot based on whether they have any series or not.
        if (!xyPlotElev.getSeriesSet().isEmpty()) {
            xyPlotElev.setVisibility(XYPlot.VISIBLE);
            xyPlotElev.redraw();
        } else {
            xyPlotElev.setVisibility(XYPlot.INVISIBLE);
        }

        if (!xyPlotSpeed.getSeriesSet().isEmpty()) {
            xyPlotSpeed.setVisibility(XYPlot.VISIBLE);
            xyPlotSpeed.redraw();
        } else {
            xyPlotSpeed.setVisibility(XYPlot.INVISIBLE);
        }

        xyPlotSpeed.calculateMinMaxVals();
        minXYSpeed = new PointF(xyPlotSpeed.getCalculatedMinX().floatValue(),
                xyPlotSpeed.getCalculatedMinY().floatValue());
        maxXYSpeed = new PointF(xyPlotSpeed.getCalculatedMaxX().floatValue(),
                xyPlotSpeed.getCalculatedMaxY().floatValue());

        xyPlotElev.calculateMinMaxVals();
        minXYElevation = new PointF(xyPlotElev.getCalculatedMinX().floatValue(),
                xyPlotElev.getCalculatedMinY().floatValue());
        maxXYElevation = new PointF(xyPlotElev.getCalculatedMaxX().floatValue(),
                xyPlotElev.getCalculatedMaxY().floatValue());

        infoTextView.setText("Active elevation diff: " + elevDifference + "m");
    }

    /**
     * Create a dataset based on supplied data that are supposed to be coordinates and elevations for a profile view.
     */
    public void createDatasetFromProfile() throws Exception {
        DynamicDoubleArray lonArray = line.getLonList();
        DynamicDoubleArray latArray = line.getLatList();
        DynamicDoubleArray elevArray = line.getAltimList();
        List<String> dates = line.getDateList();

        double previousLat = 0;
        double previousLon = 0;
        double previousElev = 0;
        double summedDistance = 0.0;
        long previousTime = 0;

        List<Double> xList1 = new ArrayList<Double>(lonArray.size());
        List<Double> yList1 = new ArrayList<Double>(lonArray.size());
        List<Double> yList2 = new ArrayList<Double>(lonArray.size());
        elevDifference = 0;
        for (int i = 0; i < lonArray.size(); i++) {
            double elev = elevArray.get(i);
            double lat = latArray.get(i);
            double lon = lonArray.get(i);
            String dateStr = dates.get(i);
            long time = Long.parseLong(dateStr);

            double distance = 0.0;
            if (i > 0) {
                Location thisLoc = new Location("dummy1"); //$NON-NLS-1$
                thisLoc.setLongitude(lon);
                thisLoc.setLatitude(lat);
                Location thatLoc = new Location("dummy2"); //$NON-NLS-1$
                thatLoc.setLongitude(previousLon);
                thatLoc.setLatitude(previousLat);
                distance = thisLoc.distanceTo(thatLoc);

                double diff = elev - previousElev;
                if (diff > 0)
                    elevDifference = elevDifference + diff;

                double timeSeconds = (time - previousTime) / 1000.0;
                double speed = Math.sqrt(diff * diff + distance * distance) / timeSeconds;

                yList2.add(speed);
            } else {
                yList2.add(0.0);
            }

            previousLat = lat;
            previousLon = lon;
            previousElev = elev;
            previousTime = time;

            summedDistance = summedDistance + distance;

            xList1.add(summedDistance);
            yList1.add(elev);
        }

        // Setup the Series
        seriesElev = new SimpleXYSeries(xList1, yList1, "Elev [m]");
        seriesSpeed = new SimpleXYSeries(xList1, yList2, "Speed [m/s]");
    }

    // Definition of the touch states
    static final int NONE = 0;
    static final int ONE_FINGER_DRAG = 1;
    static final int TWO_FINGERS_DRAG = 2;
    int mode = NONE;

    PointF firstFinger;
    float distBetweenFingers;
    boolean stopThread = false;

    @Override
    public boolean onTouch(View arg0, MotionEvent event) {
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN: // Start gesture
            firstFinger = new PointF(event.getX(), event.getY());
            mode = ONE_FINGER_DRAG;
            stopThread = true;
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            break;
        case MotionEvent.ACTION_POINTER_DOWN: // second finger
            distBetweenFingers = spacing(event);
            // the distance check is done to avoid false alarms
            if (distBetweenFingers > 5f) {
                mode = TWO_FINGERS_DRAG;
            }
            break;
        case MotionEvent.ACTION_MOVE:
            if (mode == ONE_FINGER_DRAG) {
                PointF oldFirstFinger = firstFinger;
                firstFinger = new PointF(event.getX(), event.getY());
                scrollElev(oldFirstFinger.x - firstFinger.x);
                scrollSpeed(oldFirstFinger.x - firstFinger.x);
                xyPlotSpeed.setDomainBoundaries(minXYSpeed.x, maxXYSpeed.x, BoundaryMode.FIXED);
                xyPlotElev.setDomainBoundaries(minXYElevation.x, maxXYElevation.x, BoundaryMode.FIXED);
                xyPlotSpeed.redraw();
                xyPlotElev.redraw();

            } else if (mode == TWO_FINGERS_DRAG) {
                float oldDist = distBetweenFingers;
                distBetweenFingers = spacing(event);
                zoomElev(oldDist / distBetweenFingers);
                zoomSpeed(oldDist / distBetweenFingers);
                xyPlotSpeed.setDomainBoundaries(minXYSpeed.x, maxXYSpeed.x, BoundaryMode.FIXED);
                xyPlotElev.setDomainBoundaries(minXYElevation.x, maxXYElevation.x, BoundaryMode.FIXED);
                xyPlotSpeed.redraw();
                xyPlotElev.redraw();
            }
            break;
        }
        return true;
    }

    private void zoomElev(float scale) {
        float domainSpan = maxXYSpeed.x - minXYSpeed.x;
        float domainMidPoint = maxXYSpeed.x - domainSpan / 2.0f;
        float offset = domainSpan * scale / 2.0f;

        minXYSpeed.x = domainMidPoint - offset;
        maxXYSpeed.x = domainMidPoint + offset;

        minXYSpeed.x = Math.min(minXYSpeed.x, seriesSpeed.getX(seriesSpeed.size() - 3).floatValue());
        maxXYSpeed.x = Math.max(maxXYSpeed.x, seriesSpeed.getX(1).floatValue());
        clampToDomainBoundsElev(domainSpan);
    }

    private void zoomSpeed(float scale) {
        float domainSpan = maxXYElevation.x - minXYElevation.x;
        float domainMidPoint = maxXYElevation.x - domainSpan / 2.0f;
        float offset = domainSpan * scale / 2.0f;

        minXYElevation.x = domainMidPoint - offset;
        maxXYElevation.x = domainMidPoint + offset;

        minXYElevation.x = Math.min(minXYElevation.x, seriesElev.getX(seriesElev.size() - 3).floatValue());
        maxXYElevation.x = Math.max(maxXYElevation.x, seriesElev.getX(1).floatValue());
        clampToDomainBoundsSpeed(domainSpan);
    }

    private void scrollElev(float pan) {
        float domainSpan = maxXYSpeed.x - minXYSpeed.x;
        float step = domainSpan / xyPlotSpeed.getWidth();
        float offset = pan * step;
        minXYSpeed.x = minXYSpeed.x + offset;
        maxXYSpeed.x = maxXYSpeed.x + offset;
        clampToDomainBoundsElev(domainSpan);
    }

    private void scrollSpeed(float pan) {
        float domainSpan = maxXYElevation.x - minXYElevation.x;
        float step = domainSpan / xyPlotElev.getWidth();
        float offset = pan * step;
        minXYElevation.x = minXYElevation.x + offset;
        maxXYElevation.x = maxXYElevation.x + offset;
        clampToDomainBoundsSpeed(domainSpan);
    }

    private void clampToDomainBoundsElev(float domainSpan) {
        float leftBoundary = seriesSpeed.getX(0).floatValue();
        float rightBoundary = seriesSpeed.getX(seriesSpeed.size() - 1).floatValue();
        // enforce left scroll boundary:
        if (minXYSpeed.x < leftBoundary) {
            minXYSpeed.x = leftBoundary;
            maxXYSpeed.x = leftBoundary + domainSpan;
        } else if (maxXYSpeed.x > seriesSpeed.getX(seriesSpeed.size() - 1).floatValue()) {
            maxXYSpeed.x = rightBoundary;
            minXYSpeed.x = rightBoundary - domainSpan;
        }
    }

    private void clampToDomainBoundsSpeed(float domainSpan) {
        float leftBoundary = seriesElev.getX(0).floatValue();
        float rightBoundary = seriesElev.getX(seriesElev.size() - 1).floatValue();
        // enforce left scroll boundary:
        if (minXYElevation.x < leftBoundary) {
            minXYElevation.x = leftBoundary;
            maxXYElevation.x = leftBoundary + domainSpan;
        } else if (maxXYElevation.x > seriesElev.getX(seriesElev.size() - 1).floatValue()) {
            maxXYElevation.x = rightBoundary;
            minXYElevation.x = rightBoundary - domainSpan;
        }
    }

    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    @Override
    public void onClick(View v) {
        drawerLayout.closeDrawers();

        minXYSpeed.x = seriesSpeed.getX(0).floatValue();
        maxXYSpeed.x = seriesSpeed.getX(seriesSpeed.size() - 1).floatValue();
        xyPlotSpeed.setDomainBoundaries(minXYSpeed.x, maxXYSpeed.x, BoundaryMode.FIXED);
        minXYElevation.x = seriesElev.getX(0).floatValue();
        maxXYElevation.x = seriesElev.getX(seriesElev.size() - 1).floatValue();
        xyPlotElev.setDomainBoundaries(minXYElevation.x, maxXYSpeed.x, BoundaryMode.FIXED);

        xyPlotElev.redraw();
        xyPlotSpeed.redraw();

    }
}