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.text.DateFormat; import java.util.Calendar; import java.util.Date; import java.util.Formatter; import java.util.GregorianCalendar; 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.ChartSegments; import net.tourbook.chart.ChartToolTipInfo; import net.tourbook.chart.IChartInfoProvider; import net.tourbook.colors.GraphColorProvider; import net.tourbook.data.TourPerson; import net.tourbook.preferences.ITourbookPreferences; import net.tourbook.ui.TourTypeFilter; import net.tourbook.ui.UI; import net.tourbook.util.Util; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.IPostSelectionProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPartSite; public abstract class StatisticWeek extends YearStatistic { private Chart _chart; private final BarChartMinMaxKeeper _minMaxKeeper = new BarChartMinMaxKeeper(); private TourPerson _activePerson; private TourTypeFilter _activeTourTypeFilter; private int _currentYear; private int _numberOfYears; private boolean _isSynchScaleEnabled; private final DateFormat _dateFormatter = DateFormat.getDateInstance(DateFormat.FULL); private TourDataWeek _tourWeekData; private Calendar _calendar = GregorianCalendar.getInstance(); private int _firstDayOfWeek; private int _minimalDaysInFirstWeek; private static IPreferenceStore _prefStore = TourbookPlugin.getDefault().getPreferenceStore(); @Override public void activateActions(final IWorkbenchPartSite partSite) { _chart.updateChartActionHandlers(); } public boolean canTourBeVisible() { return false; } abstract ChartDataModel createChartDataModel(); /** * create segments for each week */ ChartSegments createChartSegments() { final int segmentStart[] = new int[_numberOfYears]; final int segmentEnd[] = new int[_numberOfYears]; final String[] segmentTitle = new String[_numberOfYears]; final int oldestYear = _currentYear - _numberOfYears + 1; final int[] yearWeeks = _tourWeekData.yearWeeks; int weekCounter = 0; int yearIndex = 0; // get start/end and title for each segment for (final int weeks : yearWeeks) { segmentStart[yearIndex] = weekCounter; segmentEnd[yearIndex] = weekCounter + weeks - 1; segmentTitle[yearIndex] = Integer.toString(oldestYear + yearIndex); weekCounter += weeks; yearIndex++; } final ChartSegments weekSegments = new ChartSegments(); weekSegments.valueStart = segmentStart; weekSegments.valueEnd = segmentEnd; weekSegments.segmentTitle = segmentTitle; weekSegments.years = _tourWeekData.years; weekSegments.yearWeeks = yearWeeks; weekSegments.yearDays = _tourWeekData.yearDays; return weekSegments; } @Override public void createControl(final Composite parent, final IViewSite viewSite, final IPostSelectionProvider postSelectionProvider) { super.createControl(parent); // create statistic chart _chart = new Chart(parent, SWT.BORDER | SWT.FLAT); _chart.setShowZoomActions(true); _chart.setCanScrollZoomedChart(true); _chart.setToolBarManager(viewSite.getActionBars().getToolBarManager(), false); } private ChartToolTipInfo createToolTipInfo(final int serieIndex, final int valueIndex) { final int oldestYear = _currentYear - _numberOfYears + 1; _calendar.set(oldestYear, 0, 1); /* * adjust calendar to the first day in the first week, it took a while to figure this out */ int weekOfYear = (short) _calendar.get(Calendar.WEEK_OF_YEAR); final int dayOfWeek = _calendar.get(Calendar.DAY_OF_WEEK); int dayOffset; if (weekOfYear == 1) { // week 1 dayOffset = _firstDayOfWeek - dayOfWeek; } else { // week 52/53 dayOffset = _firstDayOfWeek - dayOfWeek; if (dayOffset < 0) { dayOffset += 7; } } final int dayOffsetAll = (valueIndex * 7) + dayOffset; _calendar.add(Calendar.DAY_OF_YEAR, dayOffsetAll); // validate calendar week final int checkDayOfWeek = _calendar.get(Calendar.DAY_OF_WEEK); if (_firstDayOfWeek != checkDayOfWeek) { System.out.println("first day in first week is incorrect\t_firstDayOfWeek=" //$NON-NLS-1$ + _firstDayOfWeek + " != " //$NON-NLS-1$ + checkDayOfWeek); } weekOfYear = (short) _calendar.get(Calendar.WEEK_OF_YEAR); final short weekYear = (short) Util.getYearForWeek(_calendar); final Date dateStart = _calendar.getTime(); _calendar.add(Calendar.DAY_OF_YEAR, 6); final Date dateEnd = _calendar.getTime(); final String beginDate = _dateFormatter.format(dateStart); final String endDate = _dateFormatter.format(dateEnd); final Integer recordingTime = _tourWeekData.recordingTime[serieIndex][valueIndex]; final Integer drivingTime = _tourWeekData.drivingTime[serieIndex][valueIndex]; final int breakTime = recordingTime - drivingTime; final String tourTypeName = getTourTypeName(serieIndex, _activeTourTypeFilter); /* * tool tip: title */ final StringBuilder titleFormat = new StringBuilder(); titleFormat.append(Messages.tourtime_info_week); titleFormat.append(NEW_LINE); final String toolTipTitle = new Formatter().format(titleFormat.toString(), // tourTypeName, weekOfYear, weekYear // ).toString(); /* * // tool tip: label */ final StringBuilder toolTipFormat = new StringBuilder(); toolTipFormat.append(Messages.tourtime_info_date_week); toolTipFormat.append(NEW_LINE); toolTipFormat.append(NEW_LINE); toolTipFormat.append(Messages.tourtime_info_distance_tour); toolTipFormat.append(NEW_LINE); toolTipFormat.append(Messages.tourtime_info_altitude); toolTipFormat.append(NEW_LINE); toolTipFormat.append(NEW_LINE); toolTipFormat.append(Messages.tourtime_info_recording_time); toolTipFormat.append(NEW_LINE); toolTipFormat.append(Messages.tourtime_info_driving_time); toolTipFormat.append(NEW_LINE); toolTipFormat.append(Messages.tourtime_info_break_time); final String toolTipLabel = new Formatter().format(toolTipFormat.toString(), // // beginDate, endDate, // (float) _tourWeekData.distanceHigh[serieIndex][valueIndex] / 1000, UI.UNIT_LABEL_DISTANCE, // _tourWeekData.altitudeHigh[serieIndex][valueIndex], UI.UNIT_LABEL_ALTITUDE, // recordingTime / 3600, (recordingTime % 3600) / 60, // drivingTime / 3600, (drivingTime % 3600) / 60, // breakTime / 3600, (breakTime % 3600) / 60 // ).toString(); /* * create tool tip info */ final ChartToolTipInfo toolTipInfo = new ChartToolTipInfo(); toolTipInfo.setTitle(toolTipTitle); toolTipInfo.setLabel(toolTipLabel); return toolTipInfo; } // System.out.println(UI.EMPTY_STRING// // + ("_firstDayOfWeek=" + _firstDayOfWeek + "\t")// // + ("dayOffset=" + dayOffset + "\t")// // + ("dayOffsetAll=" + dayOffsetAll + "\t")// // + ("DAY_OF_WEEK=" + _calendar.get(Calendar.DAY_OF_WEEK) + "\t")// // + ("date=" // + _calendar.get(Calendar.DAY_OF_MONTH) // + "." // + (_calendar.get(Calendar.MONTH) + 1) // + "." // + _calendar.get(Calendar.YEAR) + "\t")// // + ("DAY_OF_MONTH=" + _calendar.get(Calendar.DAY_OF_MONTH) + "\t")// // + ("WEEK_OF_YEAR=" + _calendar.get(Calendar.WEEK_OF_YEAR) + "\t")// // + ("WEEK_OF_MONTH=" + _calendar.get(Calendar.WEEK_OF_MONTH) + "\t")// // + ("DAY_OF_WEEK_IN_MONTH=" + _calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH) + "\t")// // // // ); // private void debugWeekNumber() { // // final int firstYear = 2000; // // DateTime dt = (new DateTime()).withYear(firstYear) // .withWeekOfWeekyear(1) // .withDayOfWeek(DateTimeConstants.MONDAY); // // Calendar calendar = GregorianCalendar.getInstance(); //// calendar.setFirstDayOfWeek(4); // // for (int currentYear = firstYear; currentYear <= 2010; currentYear++) { // //// dt = dt.withYear(currentYear).withWeekOfWeekyear(1).withDayOfWeek(DateTimeConstants.MONDAY); // dt = dt.withYear(currentYear).withMonthOfYear(1).withDayOfYear(1); // // calendar.set(currentYear, 0, 1); // // printDayAndWeek(currentYear, dt, calendar); // // } // // System.out.println(); // } // // private void printDayAndWeek(int currentYear, DateTime dt, Calendar calendar) { // // System.out.print(// //// currentYear //// + ": " // +dt.getDayOfMonth() // // + "." // + dt.getMonthOfYear() // + "." // + dt.getYear() // + "-" // + dt.getWeekOfWeekyear() // + "-" // + dt.weekOfWeekyear().getMaximumValue() // + "\t" // // // ); // // System.out.println(calendar.get(Calendar.DAY_OF_MONTH) // + "." // + (calendar.get(Calendar.MONTH) + 1) // + "." // + calendar.get(Calendar.YEAR) // + " - " // + calendar.get(Calendar.WEEK_OF_YEAR) // + " - " // + calendar.getActualMaximum(Calendar.WEEK_OF_YEAR) // // // ); // } private int[] createWeekData() { final int weekCounter = _tourWeekData.altitudeHigh[0].length; final int allWeeks[] = new int[weekCounter]; for (int weekIndex = 0; weekIndex < weekCounter; weekIndex++) { allWeeks[weekIndex] = weekIndex; } // debugWeekNumber(); return allWeeks; } void createXDataWeek(final ChartDataModel chartDataModel) { // set the x-axis final ChartDataXSerie xData = new ChartDataXSerie(createWeekData()); xData.setAxisUnit(ChartDataSerie.X_AXIS_UNIT_WEEK); xData.setChartSegments(createChartSegments()); chartDataModel.setXData(xData); } void createYDataAltitude(final ChartDataModel chartDataModel) { // altitude final ChartDataYSerie yData = new ChartDataYSerie(ChartDataModel.CHART_TYPE_BAR, ChartDataYSerie.BAR_LAYOUT_STACKED, _tourWeekData.altitudeLow, _tourWeekData.altitudeHigh); yData.setYTitle(Messages.LABEL_GRAPH_ALTITUDE); yData.setUnitLabel(UI.UNIT_LABEL_ALTITUDE); yData.setAxisUnit(ChartDataSerie.AXIS_UNIT_NUMBER); yData.setAllValueColors(0); yData.setVisibleMinValue(0); StatisticServices.setTourTypeColors(yData, GraphColorProvider.PREF_GRAPH_ALTITUDE, _activeTourTypeFilter); StatisticServices.setTourTypeColorIndex(yData, _tourWeekData.typeIds, _activeTourTypeFilter); StatisticServices.setDefaultColors(yData, GraphColorProvider.PREF_GRAPH_ALTITUDE); chartDataModel.addYData(yData); } void createYDataDistance(final ChartDataModel chartDataModel) { // distance final ChartDataYSerie yData = new ChartDataYSerie(ChartDataModel.CHART_TYPE_BAR, ChartDataYSerie.BAR_LAYOUT_STACKED, _tourWeekData.distanceLow, _tourWeekData.distanceHigh); yData.setYTitle(Messages.LABEL_GRAPH_DISTANCE); yData.setUnitLabel(UI.UNIT_LABEL_DISTANCE); yData.setAxisUnit(ChartDataSerie.AXIS_UNIT_NUMBER); yData.setAllValueColors(0); yData.setValueDivisor(1000); yData.setVisibleMinValue(0); StatisticServices.setTourTypeColors(yData, GraphColorProvider.PREF_GRAPH_DISTANCE, _activeTourTypeFilter); StatisticServices.setTourTypeColorIndex(yData, _tourWeekData.typeIds, _activeTourTypeFilter); StatisticServices.setDefaultColors(yData, GraphColorProvider.PREF_GRAPH_DISTANCE); chartDataModel.addYData(yData); } void createYDataDuration(final ChartDataModel chartDataModel) { // duration final ChartDataYSerie yData = new ChartDataYSerie(ChartDataModel.CHART_TYPE_BAR, ChartDataYSerie.BAR_LAYOUT_STACKED, _tourWeekData.timeLow, _tourWeekData.timeHigh); yData.setYTitle(Messages.LABEL_GRAPH_TIME); yData.setUnitLabel(Messages.LABEL_GRAPH_TIME_UNIT); yData.setAxisUnit(ChartDataSerie.AXIS_UNIT_HOUR_MINUTE); yData.setAllValueColors(0); yData.setVisibleMinValue(0); StatisticServices.setTourTypeColors(yData, GraphColorProvider.PREF_GRAPH_TIME, _activeTourTypeFilter); StatisticServices.setTourTypeColorIndex(yData, _tourWeekData.typeIds, _activeTourTypeFilter); StatisticServices.setDefaultColors(yData, GraphColorProvider.PREF_GRAPH_TIME); chartDataModel.addYData(yData); } @Override public void deactivateActions(final IWorkbenchPartSite partSite) { } public void prefColorChanged() { refreshStatistic(_activePerson, _activeTourTypeFilter, _currentYear, _numberOfYears, false); } public void refreshStatistic(final TourPerson person, final TourTypeFilter typeId, final int currentYear, final int numberOfYears, final boolean refreshData) { _activePerson = person; _activeTourTypeFilter = typeId; _currentYear = currentYear; _numberOfYears = numberOfYears; _tourWeekData = DataProviderTourWeek.getInstance().getWeekData(person, typeId, currentYear, numberOfYears, isDataDirtyWithReset() || refreshData); // set week start values _firstDayOfWeek = _prefStore.getInt(ITourbookPreferences.CALENDAR_WEEK_FIRST_DAY_OF_WEEK); _minimalDaysInFirstWeek = _prefStore.getInt(ITourbookPreferences.CALENDAR_WEEK_MIN_DAYS_IN_FIRST_WEEK); _calendar.setFirstDayOfWeek(_firstDayOfWeek); _calendar.setMinimalDaysInFirstWeek(_minimalDaysInFirstWeek); // reset min/max values if (_isSynchScaleEnabled == false && refreshData) { _minMaxKeeper.resetMinMax(); } final ChartDataModel chartDataModel = createChartDataModel(); setChartProviders(chartDataModel); if (_isSynchScaleEnabled) { _minMaxKeeper.setMinMaxValues(chartDataModel); } // set grid size final IPreferenceStore prefStore = TourbookPlugin.getDefault().getPreferenceStore(); _chart.setGridDistance(prefStore.getInt(ITourbookPreferences.GRAPH_GRID_HORIZONTAL_DISTANCE), prefStore.getInt(ITourbookPreferences.GRAPH_GRID_VERTICAL_DISTANCE)); _chart.updateChart(chartDataModel, true); } @Override public void resetSelection() { _chart.setSelectedBars(null); } private void setChartProviders(final ChartDataModel chartModel) { // set tool tip info chartModel.setCustomData(ChartDataModel.BAR_TOOLTIP_INFO_PROVIDER, new IChartInfoProvider() { public ChartToolTipInfo getToolTipInfo(final int serieIndex, final int valueIndex) { return createToolTipInfo(serieIndex, valueIndex); } }); } @Override public void setSynchScale(final boolean isSynchScaleEnabled) { _isSynchScaleEnabled = isSynchScaleEnabled; } @Override public void updateToolBar(final boolean refreshToolbar) { _chart.fillToolbar(refreshToolbar); } }