Java tutorial
/******************************************************************************* * Copyright (C) 2005, 2010 Wolfgang Schramm and Contributors * * 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 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., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA *******************************************************************************/ package net.tourbook.statistics; import java.util.ArrayList; import java.util.Formatter; import net.tourbook.application.TourbookPlugin; import net.tourbook.chart.BarChartMinMaxKeeper; import net.tourbook.chart.Chart; import net.tourbook.chart.ChartDataModel; import net.tourbook.chart.ChartDataSerie; import net.tourbook.chart.ChartDataXSerie; import net.tourbook.chart.ChartDataYSerie; import net.tourbook.chart.ChartToolTipInfo; import net.tourbook.chart.Util; import net.tourbook.chart.IChartInfoProvider; import net.tourbook.colors.GraphColorProvider; import net.tourbook.data.TourPerson; import net.tourbook.data.TourType; import net.tourbook.database.TourDatabase; import net.tourbook.preferences.ITourbookPreferences; import net.tourbook.ui.TourTypeFilter; import net.tourbook.ui.UI; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.IPostSelectionProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPartSite; public class StatisticTourNumbers extends YearStatistic { private final IPreferenceStore _prefStore = TourbookPlugin.getDefault().getPreferenceStore(); private IPropertyChangeListener _prefChangeListener; private final BarChartMinMaxKeeper _minMaxKeeperStatAltitudeCounter = new BarChartMinMaxKeeper(); private final BarChartMinMaxKeeper _minMaxKeeperStatAltitudeSum = new BarChartMinMaxKeeper(); private final BarChartMinMaxKeeper _minMaxKeeperStatDistanceCounter = new BarChartMinMaxKeeper(); private final BarChartMinMaxKeeper _minMaxKeeperStatDistanceSum = new BarChartMinMaxKeeper(); private final BarChartMinMaxKeeper _minMaxKeeperStatDurationCounter = new BarChartMinMaxKeeper(); private final BarChartMinMaxKeeper _minMaxKeeperStatDurationSum = new BarChartMinMaxKeeper(); private int[] _statDistanceUnits; private int[] _statAltitudeUnits; private int[] _statTimeUnits; private int[][] _statDistanceCounterLow; private int[][] _statDistanceCounterHigh; private int[][] _statDistanceCounterColorIndex; private int[][] _statDistanceSumLow; private int[][] _statDistanceSumHigh; private int[][] _statDistanceSumColorIndex; private int[][] _statAltitudeCounterLow; private int[][] _statAltitudeCounterHigh; private int[][] _statAltitudeCounterColorIndex; private int[][] _statAltitudeSumLow; private int[][] _statAltitudeSumHigh; private int[][] _statAltitudeSumColorIndex; private int[][] _statTimeCounterLow; private int[][] _statTimeCounterHigh; private int[][] _statTimeCounterColorIndex; private int[][] _statTimeSumLow; private int[][] _statTimeSumHigh; private int[][] _statTimeSumColorIndex; private int _currentYear; private TourPerson _activePerson; private TourTypeFilter _activeTourTypeFilter; private boolean _isSynchScaleEnabled; private TourDayData _tourDayData; private IViewSite _viewSite; /* * UI controls */ private Composite _statisticPage; private Chart _chartDistanceCounter; private Chart _chartDistanceSum; private Chart _chartDurationCounter; private Chart _chartDurationSum; private Chart _chartAltitudeCounter; private Chart _chartAltitudeSum; public StatisticTourNumbers() { } @Override public void activateActions(final IWorkbenchPartSite partSite) { } void addPrefListener(final Composite container) { // create pref listener _prefChangeListener = new IPropertyChangeListener() { public void propertyChange(final PropertyChangeEvent event) { final String property = event.getProperty(); // test if the color or statistic data have changed if (property.equals(ITourbookPreferences.GRAPH_COLORS_HAS_CHANGED) || property.equals(ITourbookPreferences.STAT_DISTANCE_NUMBERS) || property.equals(ITourbookPreferences.STAT_DISTANCE_LOW_VALUE) || property.equals(ITourbookPreferences.STAT_DISTANCE_INTERVAL) || property.equals(ITourbookPreferences.STAT_ALTITUDE_NUMBERS) || property.equals(ITourbookPreferences.STAT_ALTITUDE_LOW_VALUE) || property.equals(ITourbookPreferences.STAT_ALTITUDE_INTERVAL) || property.equals(ITourbookPreferences.STAT_DURATION_NUMBERS) || property.equals(ITourbookPreferences.STAT_DURATION_LOW_VALUE) || property.equals(ITourbookPreferences.STAT_DURATION_INTERVAL)) { // get the changed preferences getPreferences(); /* * reset min/max keeper because they can be changed when the pref has changed */ resetMinMaxKeeper(); // update chart refreshStatistic(_activePerson, _activeTourTypeFilter, _currentYear, 1, false); } } }; // add pref listener _prefStore.addPropertyChangeListener(_prefChangeListener); // remove pref listener container.addDisposeListener(new DisposeListener() { public void widgetDisposed(final DisposeEvent e) { _prefStore.removePropertyChangeListener(_prefChangeListener); } }); } public boolean canTourBeVisible() { return false; } @Override public void createControl(final Composite parent, final IViewSite viewSite, final IPostSelectionProvider postSelectionProvider) { super.createControl(parent); _viewSite = viewSite; // create statistic page _statisticPage = new Composite(parent, SWT.BORDER | SWT.FLAT); _statisticPage.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // remove colored border _statisticPage.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); final GridLayout gl = new GridLayout(2, true); gl.marginHeight = 0; gl.marginWidth = 0; gl.verticalSpacing = 0; gl.horizontalSpacing = 0; _statisticPage.setLayout(gl); _chartDistanceCounter = new Chart(_statisticPage, SWT.NONE); _chartDistanceSum = new Chart(_statisticPage, SWT.NONE); _chartAltitudeCounter = new Chart(_statisticPage, SWT.NONE); _chartAltitudeSum = new Chart(_statisticPage, SWT.NONE); _chartDurationCounter = new Chart(_statisticPage, SWT.NONE); _chartDurationSum = new Chart(_statisticPage, SWT.NONE); _chartDistanceCounter.setToolBarManager(viewSite.getActionBars().getToolBarManager(), true); addPrefListener(parent); getPreferences(); } /** * calculate data for all statistics * * @param tourDayData */ private void createStatisticData(final TourDayData tourDayData) { int colorOffset = 0; if (_activeTourTypeFilter.showUndefinedTourTypes()) { colorOffset = StatisticServices.TOUR_TYPE_COLOR_INDEX_OFFSET; } final ArrayList<TourType> tourTypeList = TourDatabase.getActiveTourTypes(); final int colorLength = colorOffset + tourTypeList.size(); final int distanceLength = _statDistanceUnits.length; final int altitudeLength = _statAltitudeUnits.length; final int timeLength = _statTimeUnits.length; _statDistanceCounterLow = new int[colorLength][distanceLength]; _statDistanceCounterHigh = new int[colorLength][distanceLength]; _statDistanceCounterColorIndex = new int[colorLength][distanceLength]; _statDistanceSumLow = new int[colorLength][distanceLength]; _statDistanceSumHigh = new int[colorLength][distanceLength]; _statDistanceSumColorIndex = new int[colorLength][distanceLength]; _statAltitudeCounterLow = new int[colorLength][altitudeLength]; _statAltitudeCounterHigh = new int[colorLength][altitudeLength]; _statAltitudeCounterColorIndex = new int[colorLength][altitudeLength]; _statAltitudeSumLow = new int[colorLength][altitudeLength]; _statAltitudeSumHigh = new int[colorLength][altitudeLength]; _statAltitudeSumColorIndex = new int[colorLength][altitudeLength]; _statTimeCounterLow = new int[colorLength][timeLength]; _statTimeCounterHigh = new int[colorLength][timeLength]; _statTimeCounterColorIndex = new int[colorLength][timeLength]; _statTimeSumLow = new int[colorLength][timeLength]; _statTimeSumHigh = new int[colorLength][timeLength]; _statTimeSumColorIndex = new int[colorLength][timeLength]; // loop: all tours for (int tourIndex = 0; tourIndex < tourDayData.distanceHigh.length; tourIndex++) { final int typeColorIndex = tourDayData.typeColorIndex[tourIndex]; int unitIndex; final int diffDistance = (tourDayData.distanceHigh[tourIndex] - tourDayData.distanceLow[tourIndex] + 500) / 1000; final int diffAltitude = tourDayData.altitudeHigh[tourIndex] - tourDayData.altitudeLow[tourIndex]; final int diffTime = tourDayData.timeHigh[tourIndex] - tourDayData.timeLow[tourIndex]; unitIndex = createTourStatData(diffDistance, _statDistanceUnits, _statDistanceCounterHigh[typeColorIndex], _statDistanceSumHigh[typeColorIndex]); _statDistanceCounterColorIndex[typeColorIndex][unitIndex] = typeColorIndex; _statDistanceSumColorIndex[typeColorIndex][unitIndex] = typeColorIndex; unitIndex = createTourStatData(diffAltitude, _statAltitudeUnits, _statAltitudeCounterHigh[typeColorIndex], _statAltitudeSumHigh[typeColorIndex]); _statAltitudeCounterColorIndex[typeColorIndex][unitIndex] = typeColorIndex; _statAltitudeSumColorIndex[typeColorIndex][unitIndex] = typeColorIndex; unitIndex = createTourStatData(diffTime, _statTimeUnits, _statTimeCounterHigh[typeColorIndex], _statTimeSumHigh[typeColorIndex]); _statTimeCounterColorIndex[typeColorIndex][unitIndex] = typeColorIndex; _statTimeSumColorIndex[typeColorIndex][unitIndex] = typeColorIndex; } updateLowHighValues(_statDistanceCounterLow, _statDistanceCounterHigh); updateLowHighValues(_statDistanceSumLow, _statDistanceSumHigh); updateLowHighValues(_statAltitudeCounterLow, _statAltitudeCounterHigh); updateLowHighValues(_statAltitudeSumLow, _statAltitudeSumHigh); updateLowHighValues(_statTimeCounterLow, _statTimeCounterHigh); updateLowHighValues(_statTimeSumLow, _statTimeSumHigh); } /** * create tool tip info */ private ChartToolTipInfo createToolTipProvider(final int serieIndex, final String toolTipLabel) { final String tourTypeName = getTourTypeName(serieIndex, _activeTourTypeFilter); final ChartToolTipInfo toolTipInfo = new ChartToolTipInfo(); toolTipInfo.setTitle(tourTypeName); toolTipInfo.setLabel(toolTipLabel); return toolTipInfo; } private void createToolTipProviderAltitude(final ChartDataModel chartModel) { chartModel.setCustomData(ChartDataModel.BAR_TOOLTIP_INFO_PROVIDER, new IChartInfoProvider() { public ChartToolTipInfo getToolTipInfo(final int serieIndex, final int valueIndex) { String toolTipLabel; final StringBuilder infoText = new StringBuilder(); if (valueIndex == 0) { infoText.append(Messages.numbers_info_altitude_down); infoText.append(NEW_LINE); infoText.append(Messages.numbers_info_altitude_total); toolTipLabel = new Formatter() .format(infoText.toString(), _statAltitudeUnits[valueIndex], UI.UNIT_LABEL_ALTITUDE, _statAltitudeCounterHigh[serieIndex][valueIndex], // _statAltitudeSumHigh[serieIndex][valueIndex], UI.UNIT_LABEL_ALTITUDE) .toString(); } else if (valueIndex == _statAltitudeUnits.length - 1) { infoText.append(Messages.numbers_info_altitude_up); infoText.append(NEW_LINE); infoText.append(Messages.numbers_info_altitude_total); toolTipLabel = new Formatter() .format(infoText.toString(), _statAltitudeUnits[valueIndex - 1], UI.UNIT_LABEL_ALTITUDE, _statAltitudeCounterHigh[serieIndex][valueIndex], // _statAltitudeSumHigh[serieIndex][valueIndex], UI.UNIT_LABEL_ALTITUDE) .toString(); } else { infoText.append(Messages.numbers_info_altitude_between); infoText.append(NEW_LINE); infoText.append(Messages.numbers_info_altitude_total); toolTipLabel = new Formatter() .format(infoText.toString(), _statAltitudeUnits[valueIndex - 1], _statAltitudeUnits[valueIndex], UI.UNIT_LABEL_ALTITUDE, _statAltitudeCounterHigh[serieIndex][valueIndex], // _statAltitudeSumHigh[serieIndex][valueIndex], UI.UNIT_LABEL_ALTITUDE) .toString(); } return createToolTipProvider(serieIndex, toolTipLabel); } }); } private void createToolTipProviderDistance(final ChartDataModel chartModel) { chartModel.setCustomData(ChartDataModel.BAR_TOOLTIP_INFO_PROVIDER, new IChartInfoProvider() { public ChartToolTipInfo getToolTipInfo(final int serieIndex, final int valueIndex) { String toolTipLabel; final StringBuilder sb = new StringBuilder(); final int distance = _statDistanceSumHigh[serieIndex][valueIndex]; final int counter = _statDistanceCounterHigh[serieIndex][valueIndex]; if (valueIndex == 0) { sb.append(Messages.numbers_info_distance_down); sb.append(NEW_LINE); sb.append(Messages.numbers_info_distance_total); toolTipLabel = new Formatter().format(sb.toString(), _statDistanceUnits[valueIndex], UI.UNIT_LABEL_DISTANCE, counter, distance, UI.UNIT_LABEL_DISTANCE).toString(); } else if (valueIndex == _statDistanceUnits.length - 1) { sb.append(Messages.numbers_info_distance_up); sb.append(NEW_LINE); sb.append(Messages.numbers_info_distance_total); toolTipLabel = new Formatter().format(sb.toString(), _statDistanceUnits[valueIndex - 1], UI.UNIT_LABEL_DISTANCE, counter, distance, UI.UNIT_LABEL_DISTANCE).toString(); } else { sb.append(Messages.numbers_info_distance_between); sb.append(NEW_LINE); sb.append(Messages.numbers_info_distance_total); toolTipLabel = new Formatter().format(sb.toString(), _statDistanceUnits[valueIndex - 1], _statDistanceUnits[valueIndex], UI.UNIT_LABEL_DISTANCE, counter, distance, UI.UNIT_LABEL_DISTANCE).toString(); } return createToolTipProvider(serieIndex, toolTipLabel); } }); } private void createToolTipProviderDuration(final ChartDataModel chartModel) { chartModel.setCustomData(ChartDataModel.BAR_TOOLTIP_INFO_PROVIDER, new IChartInfoProvider() { public ChartToolTipInfo getToolTipInfo(final int serieIndex, final int valueIndex) { String toolTipLabel; final StringBuilder toolTipFormat = new StringBuilder(); if (valueIndex == 0) { toolTipFormat.append(Messages.numbers_info_time_down); toolTipFormat.append(NEW_LINE); toolTipFormat.append(Messages.numbers_info_time_total); toolTipLabel = new Formatter().format(toolTipFormat.toString(), Util.formatValue(_statTimeUnits[valueIndex], ChartDataSerie.AXIS_UNIT_HOUR_MINUTE), _statTimeCounterHigh[serieIndex][valueIndex], Util.formatValue( _statTimeSumHigh[serieIndex][valueIndex], ChartDataSerie.AXIS_UNIT_HOUR_MINUTE)) .toString(); } else if (valueIndex == _statTimeUnits.length - 1) { toolTipFormat.append(Messages.numbers_info_time_up); toolTipFormat.append(NEW_LINE); toolTipFormat.append(Messages.numbers_info_time_total); toolTipLabel = new Formatter().format(toolTipFormat.toString(), Util.formatValue(_statTimeUnits[valueIndex - 1], ChartDataSerie.AXIS_UNIT_HOUR_MINUTE), _statTimeCounterHigh[serieIndex][valueIndex], Util.formatValue( _statTimeSumHigh[serieIndex][valueIndex], ChartDataSerie.AXIS_UNIT_HOUR_MINUTE)) .toString(); } else { toolTipFormat.append(Messages.numbers_info_time_between); toolTipFormat.append(NEW_LINE); toolTipFormat.append(Messages.numbers_info_time_total); toolTipLabel = new Formatter().format(toolTipFormat.toString(), Util.formatValue(_statTimeUnits[valueIndex - 1], ChartDataSerie.AXIS_UNIT_HOUR_MINUTE), Util.formatValue(_statTimeUnits[valueIndex], ChartDataSerie.AXIS_UNIT_HOUR_MINUTE), _statTimeCounterHigh[serieIndex][valueIndex], Util.formatValue( _statTimeSumHigh[serieIndex][valueIndex], ChartDataSerie.AXIS_UNIT_HOUR_MINUTE)) .toString(); } return createToolTipProvider(serieIndex, toolTipLabel); } }); } /** * calculate the statistic for one tour * * @param tourValue * @param units * @param counter * @param sum * @return */ private int createTourStatData(final int tourValue, final int[] units, final int[] counter, final int[] sum) { int lastUnit = -1; boolean isUnitFound = false; // loop: all units for (int unitIndex = 0; unitIndex < units.length; unitIndex++) { final int unit = units[unitIndex]; if (lastUnit < 0) { // first unit if (tourValue < unit) { isUnitFound = true; } } else { // second and continuous units if (tourValue >= lastUnit && tourValue < unit) { isUnitFound = true; } } if (isUnitFound) { counter[unitIndex]++; sum[unitIndex] += tourValue; // colorIndex[unitIndex]= return unitIndex; } else { lastUnit = unit; } } // if the value was not found, add it to the last unit counter[units.length - 1]++; sum[units.length - 1] += tourValue; return units.length - 1; } @Override public void deactivateActions(final IWorkbenchPartSite partSite) { } private void getPreferences() { final IPreferenceStore store = TourbookPlugin.getDefault().getPreferenceStore(); _statDistanceUnits = getPrefUnits(store, ITourbookPreferences.STAT_DISTANCE_NUMBERS, ITourbookPreferences.STAT_DISTANCE_LOW_VALUE, ITourbookPreferences.STAT_DISTANCE_INTERVAL, ChartDataSerie.AXIS_UNIT_NUMBER); _statAltitudeUnits = getPrefUnits(store, ITourbookPreferences.STAT_ALTITUDE_NUMBERS, ITourbookPreferences.STAT_ALTITUDE_LOW_VALUE, ITourbookPreferences.STAT_ALTITUDE_INTERVAL, ChartDataSerie.AXIS_UNIT_NUMBER); _statTimeUnits = getPrefUnits(store, ITourbookPreferences.STAT_DURATION_NUMBERS, ITourbookPreferences.STAT_DURATION_LOW_VALUE, ITourbookPreferences.STAT_DURATION_INTERVAL, ChartDataSerie.AXIS_UNIT_HOUR_MINUTE); } /** * create the units from the preference configuration * * @param store * @param prefInterval * @param prefLowValue * @param prefNumbers * @param unitType * @return */ private int[] getPrefUnits(final IPreferenceStore store, final String prefNumbers, final String prefLowValue, final String prefInterval, final int unitType) { final int lowValue = store.getInt(prefLowValue); final int interval = store.getInt(prefInterval); final int numbers = store.getInt(prefNumbers); final int[] units = new int[numbers]; for (int number = 0; number < numbers; number++) { if (unitType == ChartDataSerie.AXIS_UNIT_HOUR_MINUTE) { // adjust the values to minutes units[number] = (lowValue * 60) + (interval * number * 60); } else { units[number] = lowValue + (interval * number); } } return units; } public void prefColorChanged() { refreshStatistic(_activePerson, _activeTourTypeFilter, _currentYear, 1, false); } public void refreshStatistic(final TourPerson person, final TourTypeFilter typeId, final int year, final int numberOfYears, final boolean refreshData) { _activePerson = person; _activeTourTypeFilter = typeId; _currentYear = year; _tourDayData = DataProviderTourDay.getInstance().getDayData(person, typeId, year, numberOfYears, isDataDirtyWithReset() || refreshData); // reset min/max values if (_isSynchScaleEnabled == false && refreshData) { resetMinMaxKeeper(); } // hide actions from other statistics final IToolBarManager tbm = _viewSite.getActionBars().getToolBarManager(); tbm.removeAll(); tbm.update(true); createStatisticData(_tourDayData); updateCharts(); } private void resetMinMaxKeeper() { if (_isSynchScaleEnabled == false) { _minMaxKeeperStatAltitudeCounter.resetMinMax(); _minMaxKeeperStatAltitudeSum.resetMinMax(); _minMaxKeeperStatDistanceCounter.resetMinMax(); _minMaxKeeperStatDistanceSum.resetMinMax(); _minMaxKeeperStatDurationCounter.resetMinMax(); _minMaxKeeperStatDurationSum.resetMinMax(); } } @Override public void resetSelection() { } @Override public void setSynchScale(final boolean isSynchScaleEnabled) { _isSynchScaleEnabled = isSynchScaleEnabled; } private void updateChartAltitude(final Chart statAltitudeChart, final BarChartMinMaxKeeper statAltitudeMinMaxKeeper, final int[][] lowValues, final int[][] highValues, final int[][] colorIndex, final String unit, final String title) { final ChartDataModel chartDataModel = new ChartDataModel(ChartDataModel.CHART_TYPE_BAR); // set the x-axis final ChartDataXSerie xData = new ChartDataXSerie(_statAltitudeUnits); xData.setAxisUnit(ChartDataXSerie.AXIS_UNIT_NUMBER); xData.setUnitLabel(UI.UNIT_LABEL_ALTITUDE); chartDataModel.setXData(xData); // y-axis: altitude final ChartDataYSerie yData = new ChartDataYSerie(ChartDataModel.CHART_TYPE_BAR, ChartDataYSerie.BAR_LAYOUT_STACKED, lowValues, highValues); yData.setAxisUnit(ChartDataSerie.AXIS_UNIT_NUMBER); yData.setUnitLabel(unit); yData.setAllValueColors(0); yData.setYTitle(title); yData.setVisibleMinValue(0); chartDataModel.addYData(yData); StatisticServices.setDefaultColors(yData, GraphColorProvider.PREF_GRAPH_ALTITUDE); StatisticServices.setTourTypeColors(yData, GraphColorProvider.PREF_GRAPH_ALTITUDE, _activeTourTypeFilter); yData.setColorIndex(colorIndex); createToolTipProviderAltitude(chartDataModel); if (_isSynchScaleEnabled) { statAltitudeMinMaxKeeper.setMinMaxValues(chartDataModel); } // set grid size final IPreferenceStore prefStore = TourbookPlugin.getDefault().getPreferenceStore(); statAltitudeChart.setGridDistance(prefStore.getInt(ITourbookPreferences.GRAPH_GRID_HORIZONTAL_DISTANCE), prefStore.getInt(ITourbookPreferences.GRAPH_GRID_VERTICAL_DISTANCE)); // show the new data in the chart statAltitudeChart.updateChart(chartDataModel, true); } /** * @param statDistanceChart * @param statDistanceMinMaxKeeper * @param highValues * @param lowValues * @param statDistanceColorIndex * @param unit * @param title * @param valueDivisor */ private void updateChartDistance(final Chart statDistanceChart, final BarChartMinMaxKeeper statDistanceMinMaxKeeper, final int[][] lowValues, final int[][] highValues, final int[][] colorIndex, final String unit, final String title, final int valueDivisor) { final ChartDataModel chartDataModel = new ChartDataModel(ChartDataModel.CHART_TYPE_BAR); // set the x-axis final ChartDataXSerie xData = new ChartDataXSerie(_statDistanceUnits); xData.setAxisUnit(ChartDataXSerie.AXIS_UNIT_NUMBER); xData.setUnitLabel(UI.UNIT_LABEL_DISTANCE); chartDataModel.setXData(xData); // y-axis: distance final ChartDataYSerie yData = new ChartDataYSerie(ChartDataModel.CHART_TYPE_BAR, ChartDataYSerie.BAR_LAYOUT_STACKED, lowValues, highValues); yData.setAxisUnit(ChartDataSerie.AXIS_UNIT_NUMBER); yData.setUnitLabel(unit); yData.setAllValueColors(0); yData.setYTitle(title); yData.setVisibleMinValue(0); yData.setValueDivisor(valueDivisor); chartDataModel.addYData(yData); StatisticServices.setDefaultColors(yData, GraphColorProvider.PREF_GRAPH_DISTANCE); StatisticServices.setTourTypeColors(yData, GraphColorProvider.PREF_GRAPH_DISTANCE, _activeTourTypeFilter); yData.setColorIndex(colorIndex); createToolTipProviderDistance(chartDataModel); if (_isSynchScaleEnabled) { statDistanceMinMaxKeeper.setMinMaxValues(chartDataModel); } // set grid size final IPreferenceStore prefStore = TourbookPlugin.getDefault().getPreferenceStore(); statDistanceChart.setGridDistance(prefStore.getInt(ITourbookPreferences.GRAPH_GRID_HORIZONTAL_DISTANCE), prefStore.getInt(ITourbookPreferences.GRAPH_GRID_VERTICAL_DISTANCE)); // show the new data fDataModel in the chart statDistanceChart.updateChart(chartDataModel, true); } private void updateCharts() { updateChartDistance(_chartDistanceCounter, _minMaxKeeperStatDistanceCounter, _statDistanceCounterLow, _statDistanceCounterHigh, _statDistanceCounterColorIndex, Messages.NUMBERS_UNIT, Messages.LABEL_GRAPH_DISTANCE, 1); updateChartDistance(_chartDistanceSum, _minMaxKeeperStatDistanceSum, _statDistanceSumLow, _statDistanceSumHigh, _statDistanceSumColorIndex, UI.UNIT_LABEL_DISTANCE, Messages.LABEL_GRAPH_DISTANCE, 1); updateChartAltitude(_chartAltitudeCounter, _minMaxKeeperStatAltitudeCounter, _statAltitudeCounterLow, _statAltitudeCounterHigh, _statAltitudeCounterColorIndex, Messages.NUMBERS_UNIT, Messages.LABEL_GRAPH_ALTITUDE); updateChartAltitude(_chartAltitudeSum, _minMaxKeeperStatAltitudeSum, _statAltitudeSumLow, _statAltitudeSumHigh, _statAltitudeSumColorIndex, UI.UNIT_LABEL_ALTITUDE, Messages.LABEL_GRAPH_ALTITUDE); updateChartTime(_chartDurationCounter, _minMaxKeeperStatDurationCounter, _statTimeCounterLow, _statTimeCounterHigh, _statTimeCounterColorIndex, ChartDataXSerie.AXIS_UNIT_NUMBER, Messages.NUMBERS_UNIT, Messages.LABEL_GRAPH_TIME); updateChartTime(_chartDurationSum, _minMaxKeeperStatDurationSum, _statTimeSumLow, _statTimeSumHigh, _statTimeSumColorIndex, ChartDataXSerie.AXIS_UNIT_HOUR_MINUTE, Messages.LABEL_GRAPH_TIME_UNIT, Messages.LABEL_GRAPH_TIME); } private void updateChartTime(final Chart statDurationChart, final BarChartMinMaxKeeper statDurationMinMaxKeeper, final int[][] lowValues, final int[][] highValues, final int[][] colorIndex, final int yUnit, final String unit, final String title) { final ChartDataModel chartDataModel = new ChartDataModel(ChartDataModel.CHART_TYPE_BAR); // set the x-axis final ChartDataXSerie xData = new ChartDataXSerie(_statTimeUnits); xData.setAxisUnit(ChartDataSerie.AXIS_UNIT_HOUR_MINUTE); xData.setUnitLabel(UI.UNIT_LABEL_TIME); chartDataModel.setXData(xData); // y-axis: altitude final ChartDataYSerie yData = new ChartDataYSerie(ChartDataModel.CHART_TYPE_BAR, ChartDataYSerie.BAR_LAYOUT_STACKED, lowValues, highValues); yData.setAxisUnit(yUnit); yData.setUnitLabel(unit); yData.setAllValueColors(0); yData.setYTitle(title); yData.setVisibleMinValue(0); chartDataModel.addYData(yData); StatisticServices.setDefaultColors(yData, GraphColorProvider.PREF_GRAPH_TIME); StatisticServices.setTourTypeColors(yData, GraphColorProvider.PREF_GRAPH_TIME, _activeTourTypeFilter); yData.setColorIndex(colorIndex); createToolTipProviderDuration(chartDataModel); if (_isSynchScaleEnabled) { statDurationMinMaxKeeper.setMinMaxValues(chartDataModel); } // set grid size final IPreferenceStore prefStore = TourbookPlugin.getDefault().getPreferenceStore(); statDurationChart.setGridDistance(prefStore.getInt(ITourbookPreferences.GRAPH_GRID_HORIZONTAL_DISTANCE), prefStore.getInt(ITourbookPreferences.GRAPH_GRID_VERTICAL_DISTANCE)); // show the new data data model in the chart statDurationChart.updateChart(chartDataModel, true); } /** * update the low and high values so they are stacked on each other * * @param lowValues * @param highValues */ private void updateLowHighValues(final int[][] lowValues, final int[][] highValues) { for (int colorIndex = 0; colorIndex < highValues.length; colorIndex++) { if (colorIndex > 0) { for (int valueIndex = 0; valueIndex < highValues[0].length; valueIndex++) { if (highValues[colorIndex][valueIndex] > 0) { final int previousHighValue = highValues[colorIndex - 1][valueIndex]; highValues[colorIndex][valueIndex] += previousHighValue; } } } } } @Override public void updateToolBar(final boolean refreshToolbar) { } }