From 8415ea46a0a58394e96c03fa8339d3aa3ac3d65a Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Tue, 22 Jan 2013 09:07:43 +0100 Subject: [PATCH 01/37] Added PolarSheetsEntryPoint just some raw constructs for starting with polar sheets development --- java/com.sap.sailing.gwt.ui/PolarSheets.css | 133 ++++++++++++++++++ .../ui/polarsheets/PolarSheetsEntryPoint.java | 11 ++ .../sap/sailing/gwt/ui/PolarSheets.gwt.xml | 30 ++++ 3 files changed, 174 insertions(+) create mode 100644 java/com.sap.sailing.gwt.ui/PolarSheets.css create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsEntryPoint.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/PolarSheets.gwt.xml diff --git a/java/com.sap.sailing.gwt.ui/PolarSheets.css b/java/com.sap.sailing.gwt.ui/PolarSheets.css new file mode 100644 index 00000000000..d423ec58e1d --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/PolarSheets.css @@ -0,0 +1,133 @@ +@import url(fontface.css); +@import url(CommonControls.css); + +/** Add css rules here for your application. */ +/* + body #calendar:after + content: " "; + display: block; + height: 0; + clear: both; + visibility: hidden; +*/ + +.clear { + clear: both; + font-size: 1px; + height: 0px; + line-height: 0px; + margin: -1px 0 0; + width: 100%; } + +.cover { + left: -1000px; + overflow: hidden; + position: absolute; + top: -1000px; } + +body { + background: #fff; + font-family: 'UbuntuRegular', Arial, Verdana, sans-serif; + line-height: 1; + font-size: 14px; + font-weight: 400; + padding: 85px 0 120px 0; + margin: 0; + } + +/** Example rules used by the template application (remove for your app) */ +h1 { + font-size: 2em; + font-weight: bold; + color: #777777; + margin: 40px 0px 70px; + text-align: center; + } + +table { + border-collapse: separate; } + +.leaderboardMargin { + margin: 5px; +} + +.leaderboardContent { +} + +.leaderboardContent td, .leaderboardContent th { + vertical-align: bottom; + line-height: 1.3; + padding-top: 2px; +} + +.leaderboardContent-toolbar { + +} + +.leaderboardLabel { + border-bottom: 2px solid #007dc0; + font-weight: bold; + margin: 5px; + } + +.refreshAndSettings { + background: #f2f2f2; + border-bottom: 2px solid #fff; + border-top: 2px solid #fff; + height: 30px; } + +.refreshAndSettings table td { + padding: 0 10px 0 0;} + +.refreshAndSettings table table td{ + padding: 0 0 0 0;} + +input.magnifier{ + display: block; + margin: 3px auto 0 auto !important; +} + +body, table td, select, button { + font-family: 'UbuntuLight', Arial, Verdana, sans-serif; + font-size: 14px; +} + +.busyIndicator-simpleBusyIndicator { + margin-top: 7px; +} + +.errorLabel { + color: #FF0000; +} + +.abstractChartPanel-importantMessageOfChart { + font-family: 'UbuntuBold',Arial,Verdana,sans-serif; + font-size: 20px; + height: 70px; + margin: 0 auto; + padding: 49px 0 0 80px; + width: 300px; + color: #7c7c7c; + background: url(images/important-message.png) left center no-repeat; +} + +.LeaderboardHeader { + position: relative; + margin: 0 auto; + width: 400px; + text-align: center; + font-family: 'UbuntuRegular', Arial, Verdana, sans-serif; + font-size: 18px; + color: #fff; + margin-top: 22px; +} + +.leaderboardHeading { + font-size: 16px; + font-family: 'UbuntuRegular', Arial, Verdana, sans-serif; + font-weight: bold; +} + +.gwt-DialogBox { + z-index: 20; +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsEntryPoint.java new file mode 100644 index 00000000000..7dee5676175 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsEntryPoint.java @@ -0,0 +1,11 @@ +package com.sap.sailing.gwt.ui.polarsheets; + +import java.util.logging.Logger; + +import com.sap.sailing.gwt.ui.client.AbstractEntryPoint; + +public class PolarSheetsEntryPoint extends AbstractEntryPoint { + + private static final Logger logger = Logger.getLogger(PolarSheetsEntryPoint.class.getName()); + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/PolarSheets.gwt.xml b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/PolarSheets.gwt.xml new file mode 100644 index 00000000000..5225cb33d96 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/PolarSheets.gwt.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 4414a170e71b98a0e24b999e65351f4384f01c2c Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Tue, 22 Jan 2013 16:05:20 +0100 Subject: [PATCH 02/37] Added tracked races composite to polar sheets panel too many buttons like untracking and removing still showing we just want to select races in this case. also added filtering for the trackedraces --- java/com.sap.sailing.gwt.ui/PolarSheets.html | 33 +++++ .../SailingGWT Remote Profiling.launch | 4 +- java/com.sap.sailing.gwt.ui/SailingGWT.launch | 4 +- .../TrackedRacesListComposite.java | 136 +++++++++++------- .../polarsheets/FilteredTrackedRacesList.java | 32 +++++ .../ui/polarsheets/PolarSheetsEntryPoint.java | 60 +++++++- .../gwt/ui/polarsheets/PolarSheetsPanel.java | 90 ++++++++++++ .../gwt/ui/polarsheets/RaceFilter.java | 47 ++++++ .../sap/sailing/gwt/ui/PolarSheets.gwt.xml | 2 +- 9 files changed, 346 insertions(+), 62 deletions(-) create mode 100644 java/com.sap.sailing.gwt.ui/PolarSheets.html create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/RaceFilter.java diff --git a/java/com.sap.sailing.gwt.ui/PolarSheets.html b/java/com.sap.sailing.gwt.ui/PolarSheets.html new file mode 100644 index 00000000000..39cb1b74a67 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/PolarSheets.html @@ -0,0 +1,33 @@ + + + + + + SAP Sailing Analytics Polar Sheets + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.gwt.ui/SailingGWT Remote Profiling.launch b/java/com.sap.sailing.gwt.ui/SailingGWT Remote Profiling.launch index 194bef6417f..3c38c4ca347 100755 --- a/java/com.sap.sailing.gwt.ui/SailingGWT Remote Profiling.launch +++ b/java/com.sap.sailing.gwt.ui/SailingGWT Remote Profiling.launch @@ -4,7 +4,7 @@ - + @@ -48,7 +48,7 @@ - + diff --git a/java/com.sap.sailing.gwt.ui/SailingGWT.launch b/java/com.sap.sailing.gwt.ui/SailingGWT.launch index b2618376ad5..e32f7e6c78d 100644 --- a/java/com.sap.sailing.gwt.ui/SailingGWT.launch +++ b/java/com.sap.sailing.gwt.ui/SailingGWT.launch @@ -4,7 +4,7 @@ - + @@ -47,7 +47,7 @@ - + diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesListComposite.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesListComposite.java index f0f43a848c4..2d15b38c887 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesListComposite.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesListComposite.java @@ -64,7 +64,8 @@ import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent; * Shows the currently tracked events/races in a table. Updated if subscribed as an {@link RegattaDisplayer}, e.g., with * the {@link AdminConsoleEntryPoint}. */ -public class TrackedRacesListComposite extends SimplePanel implements Component, RegattaDisplayer, RaceSelectionChangeListener { +public class TrackedRacesListComposite extends SimplePanel implements Component, + RegattaDisplayer, RaceSelectionChangeListener { private final long DEFAULT_LIVE_DELAY_IN_MILLISECONDS = 5000; private final Set raceIsTrackedRaceChangeListener; @@ -78,9 +79,9 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< private final CellTable raceTable; private ListDataProvider raceList; - + private Iterable allRaces; - + private final VerticalPanel panel; private DateTimeFormatRenderer dateFormatter = new DateTimeFormatRenderer( @@ -102,7 +103,7 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< private final Button btnSetDelayToLive; private final TextBox filterRacesTextbox; - + private final TrackedRacesSettings settings; public static class AnchorCell extends AbstractCell { @@ -130,12 +131,12 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< this.raceSelectionProvider = raceSelectionProvider; this.stringMessages = stringMessages; this.raceIsTrackedRaceChangeListener = new HashSet(); - + raceList = new ListDataProvider(); selectionModel = multiSelection ? new MultiSelectionModel() : new SingleSelectionModel(); settings = new TrackedRacesSettings(); settings.setDelayToLiveInSeconds(DEFAULT_LIVE_DELAY_IN_MILLISECONDS / 1000l); - + panel = new VerticalPanel(); setWidget(panel); @@ -162,8 +163,7 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class); raceTable = new CellTable(/* pageSize */10000, tableRes); raceTable.ensureDebugId("TrackedRaces"); - ListHandler columnSortHandler = new ListHandler( - raceList.getList()); + ListHandler columnSortHandler = new ListHandler(raceList.getList()); TextColumn regattaNameColumn = new TextColumn() { @Override public String getValue(RaceDTO raceDTO) { @@ -245,7 +245,8 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< return 0; } int val = -1; - val = (t1 != null && t2 != null && ascending) ? (t1.name.compareTo(t2.name)) : -(t2.name.compareTo(t1.name)); + val = (t1 != null && t2 != null && ascending) ? (t1.name.compareTo(t2.name)) : -(t2.name + .compareTo(t1.name)); return val; } @@ -259,8 +260,7 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< @Override public String getValue(RaceDTO raceDTO) { if (raceDTO.startOfRace != null) { - return dateFormatter.render(raceDTO.startOfRace) + " " - + timeFormatter.render(raceDTO.startOfRace); + return dateFormatter.render(raceDTO.startOfRace) + " " + timeFormatter.render(raceDTO.startOfRace); } return ""; @@ -334,7 +334,7 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< raceTable.addColumn(raceTrackedColumn, stringMessages.tracked()); raceTable.addColumn(hasWindDataColumn, "Wind data"); raceTable.addColumn(hasGPSDataColumn, "GPS data"); - + raceTable.addColumn(raceLiveDelayColumn, stringMessages.delayInSeconds()); raceTable.setWidth("300px"); raceTable.setSelectionModel(selectionModel); @@ -360,7 +360,8 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< for (RaceDTO selectedRace : selectedRaces) { selectedRaceIdentifiers.add(selectedRace.getRaceIdentifier()); } - TrackedRacesListComposite.this.raceSelectionProvider.setSelection(selectedRaceIdentifiers, TrackedRacesListComposite.this); + TrackedRacesListComposite.this.raceSelectionProvider.setSelection(selectedRaceIdentifiers, + TrackedRacesListComposite.this); } } }); @@ -403,7 +404,7 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< } }); trackedRacesButtonPanel.add(btnRefresh); - + btnSetDelayToLive = new Button(stringMessages.setDelayToLive() + "..."); btnSetDelayToLive.ensureDebugId("SetDelayToLive"); btnSetDelayToLive.addClickHandler(new ClickHandler() { @@ -418,8 +419,9 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< private void showSetDelayToLiveDialog() { TrackedRacesSettings settings = new TrackedRacesSettings(); settings.setDelayToLiveInSeconds(DEFAULT_LIVE_DELAY_IN_MILLISECONDS); - - SettingsDialog settingsDialog = new SettingsDialog(this, stringMessages); + + SettingsDialog settingsDialog = new SettingsDialog(this, + stringMessages); settingsDialog.show(); } @@ -427,7 +429,7 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< RaceDTO result = null; if (raceList != null) { for (RaceDTO race : raceList.getList()) { - if(race.getRaceIdentifier().equals(raceIdentifier)) { + if (race.getRaceIdentifier().equals(raceIdentifier)) { result = race; break; } @@ -452,7 +454,8 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< if (raceList != null) { for (RaceDTO race : raceList.getList()) { String regattaName = race.getRegattaName(); - if (regattaName.equals(raceIdentifier.getRegattaName()) && race.name.equals(raceIdentifier.getRaceName())) { + if (regattaName.equals(raceIdentifier.getRegattaName()) + && race.name.equals(raceIdentifier.getRaceName())) { dontFireNextSelectionChangeEvent = true; selectionModel.setSelected(race, true); break; @@ -462,8 +465,9 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< } public void clearSelection() { - List emptySelection = Collections.emptyList(); - raceSelectionProvider.setSelection(emptySelection, /* listenersNotToNotify */ this); + List emptySelection = Collections.emptyList(); + raceSelectionProvider.setSelection(emptySelection, /* listenersNotToNotify */ + this); if (raceList != null) { for (RaceDTO race : raceList.getList()) { selectionModel.setSelected(race, false); @@ -473,6 +477,40 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< @Override public void fillRegattas(List regattas) { + setUiElementVisibilty(regattas); + List newAllRaces = new ArrayList(); + List newAllRegattas = new ArrayList(); + List newAllRaceIdentifiers = new ArrayList(); + for (RegattaDTO regatta : regattas) { + newAllRegattas.add(regatta); + for (RaceDTO race : regatta.races) { + if (race != null) { + if (raceCompliesToFilter(race)) { + newAllRaces.add(race); + newAllRaceIdentifiers.add(race.getRaceIdentifier()); + } + } + } + } + allRaces = newAllRaces; + fillRaceListFromAvailableRacesApplyingFilter(); + raceSelectionProvider.setAllRaces(newAllRaceIdentifiers); // have this + // object be + // notified; + // triggers + // onRaceSelectionChange + } + + /** + * Allows subclasses to add a racefilter, so that only races with specific characteristics are displayed. + * @param race + * @return + */ + protected boolean raceCompliesToFilter(RaceDTO race) { + return true; + } + + private void setUiElementVisibilty(List regattas) { if (regattas.isEmpty()) { raceTable.setVisible(false); btnUntrack.setVisible(false); @@ -488,27 +526,12 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< noTrackedRacesLabel.setVisible(false); btnSetDelayToLive.setVisible(true); } - List newAllRaces = new ArrayList(); - List newAllRegattas = new ArrayList(); - List newAllRaceIdentifiers = new ArrayList(); - for (RegattaDTO regatta : regattas) { - newAllRegattas.add(regatta); - for (RaceDTO race : regatta.races) { - if (race != null) { - newAllRaces.add(race); - newAllRaceIdentifiers.add(race.getRaceIdentifier()); - } - } - } - allRaces = newAllRaces; - fillRaceListFromAvailableRacesApplyingFilter(); - raceSelectionProvider.setAllRaces(newAllRaceIdentifiers); // have this object be notified; triggers onRaceSelectionChange } public void addRaceSelectionChangeListener(RaceSelectionChangeListener listener) { this.raceSelectionProvider.addRaceSelectionChangeListener(listener); } - + public void addTrackedRaceChangeListener(TrackedRaceChangedListener listener) { this.raceIsTrackedRaceChangeListener.add(listener); } @@ -534,22 +557,21 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< private void removeAndUntrackRace(final RaceDTO race) { final RegattaNameAndRaceName regattaNameAndRaceName = (RegattaNameAndRaceName) race.getRaceIdentifier(); - sailingService.removeAndUntrackRace(regattaNameAndRaceName, - new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - errorReporter.reportError("Exception trying to stop tracking race " + race.name + "in regatta " - + race.getRegattaName() + ": " + caught.getMessage()); - } + sailingService.removeAndUntrackRace(regattaNameAndRaceName, new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError("Exception trying to stop tracking race " + race.name + "in regatta " + + race.getRegattaName() + ": " + caught.getMessage()); + } - @Override - public void onSuccess(Void result) { - regattaRefresher.fillRegattas(); - for (TrackedRaceChangedListener listener : raceIsTrackedRaceChangeListener) { - listener.changeTrackingRace(regattaNameAndRaceName, false); - } - } - }); + @Override + public void onSuccess(Void result) { + regattaRefresher.fillRegattas(); + for (TrackedRaceChangedListener listener : raceIsTrackedRaceChangeListener) { + listener.changeTrackingRace(regattaNameAndRaceName, false); + } + } + }); } private void fillRaceListFromAvailableRacesApplyingFilter() { @@ -579,7 +601,15 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< } // now sort again according to selected criterion ColumnSortEvent.fire(raceTable, raceTable.getColumnSortList()); - onRaceSelectionChange(raceSelectionProvider.getSelectedRaces()); // update selection based on underlying domain race selection model + onRaceSelectionChange(raceSelectionProvider.getSelectedRaces()); // update + // selection + // based + // on + // underlying + // domain + // race + // selection + // model } @Override @@ -602,7 +632,7 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< public SettingsDialogComponent getSettingsDialogComponent() { return new TrackedRacesSettingsDialogComponent(settings, stringMessages); } - + @Override public void updateSettings(TrackedRacesSettings newSettings) { settings.setDelayToLiveInSeconds(newSettings.getDelayToLiveInSeconds()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java new file mode 100644 index 00000000000..2e92d734c92 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java @@ -0,0 +1,32 @@ +package com.sap.sailing.gwt.ui.polarsheets; + +import com.sap.sailing.gwt.ui.adminconsole.TrackedRacesListComposite; +import com.sap.sailing.gwt.ui.client.ErrorReporter; +import com.sap.sailing.gwt.ui.client.RaceSelectionProvider; +import com.sap.sailing.gwt.ui.client.RegattaRefresher; +import com.sap.sailing.gwt.ui.client.SailingServiceAsync; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.RaceDTO; + +public class FilteredTrackedRacesList extends TrackedRacesListComposite { + + private RaceFilter filter; + + public FilteredTrackedRacesList(SailingServiceAsync sailingService, ErrorReporter errorReporter, + RegattaRefresher regattaRefresher, RaceSelectionProvider raceSelectionProvider, + StringMessages stringMessages, boolean hasMultiSelection, RaceFilter filter) { + super(sailingService, errorReporter, regattaRefresher, raceSelectionProvider, stringMessages, hasMultiSelection); + this.filter = filter; + } + + @Override + protected boolean raceCompliesToFilter(RaceDTO race) { + if (filter!=null) { + return filter.compliesToFilter(race); + } + return true; + } + + + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsEntryPoint.java index 7dee5676175..f1d0511829e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsEntryPoint.java @@ -1,11 +1,63 @@ package com.sap.sailing.gwt.ui.polarsheets; -import java.util.logging.Logger; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.google.gwt.user.client.ui.DockLayoutPanel; +import com.google.gwt.user.client.ui.RootLayoutPanel; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.ScrollPanel; import com.sap.sailing.gwt.ui.client.AbstractEntryPoint; +import com.sap.sailing.gwt.ui.client.RegattaDisplayer; +import com.sap.sailing.gwt.ui.client.RegattaRefresher; +import com.sap.sailing.gwt.ui.shared.RegattaDTO; -public class PolarSheetsEntryPoint extends AbstractEntryPoint { - - private static final Logger logger = Logger.getLogger(PolarSheetsEntryPoint.class.getName()); +public class PolarSheetsEntryPoint extends AbstractEntryPoint implements RegattaRefresher { + + // private static final Logger logger = + // Logger.getLogger(PolarSheetsEntryPoint.class.getName()); + + private Set regattaDisplayers; + + @Override + protected void doOnModuleLoad() { + super.doOnModuleLoad(); + regattaDisplayers = new HashSet(); + createUI(); + fillRegattas(); + } + + private void createUI() { + RootPanel rootPanel = RootPanel.get(); + DockLayoutPanel mainPanel = new DockLayoutPanel(Unit.PX); + RootLayoutPanel.get().add(mainPanel); + ScrollPanel contentScrollPanel = new ScrollPanel(); + PolarSheetsPanel polarSheetsPanel = new PolarSheetsPanel(sailingService, this, stringMessages, this); + polarSheetsPanel.addStyleName(PolarSheetsPanel.POLARSHEETS_STYLE); + regattaDisplayers.add(polarSheetsPanel); + contentScrollPanel.setWidget(polarSheetsPanel); + mainPanel.add(contentScrollPanel); + rootPanel.add(mainPanel); + } + + @Override + public void fillRegattas() { + sailingService.getRegattas(new AsyncCallback>() { + @Override + public void onSuccess(List result) { + for (RegattaDisplayer regattaDisplayer : regattaDisplayers) { + regattaDisplayer.fillRegattas(result); + } + } + + @Override + public void onFailure(Throwable caught) { + reportError("Remote Procedure Call getRegattas() - Failure"); + } + }); + } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java new file mode 100644 index 00000000000..1abb6f18297 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -0,0 +1,90 @@ +package com.sap.sailing.gwt.ui.polarsheets; + +import java.util.List; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.FormPanel; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.gwt.ui.client.ErrorReporter; +import com.sap.sailing.gwt.ui.client.RaceSelectionChangeListener; +import com.sap.sailing.gwt.ui.client.RaceSelectionModel; +import com.sap.sailing.gwt.ui.client.RegattaDisplayer; +import com.sap.sailing.gwt.ui.client.SailingServiceAsync; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.RegattaDTO; + +public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeListener, + RegattaDisplayer { + + // TODO UI stuff + public static final String POLARSHEETS_STYLE = "polarSheets"; + + private FlowPanel mainPanel; + private SailingServiceAsync sailingService; + private FilteredTrackedRacesList filteredTrackedRacesList; + private ErrorReporter errorReporter; + private StringMessages stringMessages; + private RaceSelectionModel raceSelectionProvider; + private PolarSheetsEntryPoint polarSheetsEntryPoint; + private List selectedRaces; + + public PolarSheetsPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter, + StringMessages stringMessages, PolarSheetsEntryPoint polarSheetsEntryPoint) { + this.polarSheetsEntryPoint = polarSheetsEntryPoint; + this.sailingService = sailingService; + this.errorReporter = errorReporter; + this.stringMessages = stringMessages; + + this.mainPanel = new FlowPanel(); + mainPanel.setSize("100%", "100%"); + setWidget(mainPanel); + addFilteredTrackedRacesList(); + } + + private void addFilteredTrackedRacesList() { + VerticalPanel trackedRacesPanel = new VerticalPanel(); + trackedRacesPanel.setWidth("100%"); + + createFilteredTrackedList(); + trackedRacesPanel.add(filteredTrackedRacesList); + + Button polarSheetGenerationStartButton = createPolarSheetCalculationStartButton(); + trackedRacesPanel.add(polarSheetGenerationStartButton); + mainPanel.add(trackedRacesPanel); + } + + private Button createPolarSheetCalculationStartButton() { + Button polarSheetGenerationStartButton = new Button("Generate Polar Sheet"); + polarSheetGenerationStartButton.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent arg0) { + // TODO Auto-generated method stub + + } + }); + return polarSheetGenerationStartButton; + } + + private void createFilteredTrackedList() { + raceSelectionProvider = new RaceSelectionModel(); + filteredTrackedRacesList = new FilteredTrackedRacesList(sailingService, errorReporter, polarSheetsEntryPoint, + raceSelectionProvider, stringMessages, true, new RaceFilter(true, true)); + raceSelectionProvider.addRaceSelectionChangeListener(this); + } + + @Override + public void onRaceSelectionChange(List selectedRaces) { + this.selectedRaces = selectedRaces; + } + + @Override + public void fillRegattas(List regattas) { + filteredTrackedRacesList.fillRegattas(regattas); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/RaceFilter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/RaceFilter.java new file mode 100644 index 00000000000..9da90b8c2ac --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/RaceFilter.java @@ -0,0 +1,47 @@ +package com.sap.sailing.gwt.ui.polarsheets; + +import com.sap.sailing.gwt.ui.shared.RaceDTO; + +public class RaceFilter { + + private Boolean withGpsFixes; + private Boolean withWindData; + + + + + public RaceFilter(Boolean withGpsFixes, Boolean withWindData) { + this.withGpsFixes = withGpsFixes; + this.withWindData = withWindData; + } + + + + + public boolean compliesToFilter(RaceDTO race) { + if (!compliesToGpsFixFilter(race) || !compliesToWindDataFilter(race)) { + return false; + } + return true; + } + + + private boolean compliesToGpsFixFilter(RaceDTO race) { + if (withGpsFixes!=null) { + if (race.trackedRace.hasGPSData != withGpsFixes) { + return false; + } + } + return true; + } + + private boolean compliesToWindDataFilter(RaceDTO race) { + if (withGpsFixes!=null) { + if (race.trackedRace.hasWindData != withWindData) { + return false; + } + } + return true; + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/PolarSheets.gwt.xml b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/PolarSheets.gwt.xml index 5225cb33d96..ae2af017d01 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/PolarSheets.gwt.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/PolarSheets.gwt.xml @@ -1,7 +1,7 @@ - + From 81f807d6bea48f48d7aaa368cdfb1f1797538793 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Wed, 23 Jan 2013 10:15:12 +0100 Subject: [PATCH 03/37] Changed TrackedRacesListComposite to comply to master branch --- .../TrackedRacesListComposite.java | 642 ++---------------- 1 file changed, 68 insertions(+), 574 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesListComposite.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesListComposite.java index 2d15b38c887..b1a73864242 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesListComposite.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesListComposite.java @@ -1,373 +1,103 @@ package com.sap.sailing.gwt.ui.adminconsole; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; -import com.google.gwt.cell.client.AbstractCell; -import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.event.dom.client.KeyUpEvent; -import com.google.gwt.event.dom.client.KeyUpHandler; -import com.google.gwt.i18n.client.DateTimeFormat; -import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; -import com.google.gwt.safehtml.client.SafeHtmlTemplates; -import com.google.gwt.safehtml.shared.SafeHtml; -import com.google.gwt.safehtml.shared.SafeHtmlBuilder; -import com.google.gwt.safehtml.shared.SafeHtmlUtils; -import com.google.gwt.text.client.DateTimeFormatRenderer; -import com.google.gwt.user.cellview.client.CellTable; -import com.google.gwt.user.cellview.client.Column; -import com.google.gwt.user.cellview.client.ColumnSortEvent; -import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler; -import com.google.gwt.user.cellview.client.ColumnSortList; -import com.google.gwt.user.cellview.client.TextColumn; -import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; -import com.google.gwt.user.client.ui.HasVerticalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; -import com.google.gwt.user.client.ui.Label; -import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.TextBox; -import com.google.gwt.user.client.ui.VerticalPanel; -import com.google.gwt.user.client.ui.Widget; -import com.google.gwt.view.client.ListDataProvider; -import com.google.gwt.view.client.MultiSelectionModel; -import com.google.gwt.view.client.SelectionChangeEvent; -import com.google.gwt.view.client.SelectionChangeEvent.Handler; -import com.google.gwt.view.client.SelectionModel; -import com.google.gwt.view.client.SingleSelectionModel; -import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.RegattaNameAndRaceName; import com.sap.sailing.gwt.ui.client.ErrorReporter; -import com.sap.sailing.gwt.ui.client.RaceSelectionChangeListener; import com.sap.sailing.gwt.ui.client.RaceSelectionProvider; import com.sap.sailing.gwt.ui.client.RegattaDisplayer; import com.sap.sailing.gwt.ui.client.RegattaRefresher; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sailing.gwt.ui.client.URLFactory; import com.sap.sailing.gwt.ui.shared.RaceDTO; import com.sap.sailing.gwt.ui.shared.RegattaDTO; -import com.sap.sailing.gwt.ui.shared.components.Component; import com.sap.sailing.gwt.ui.shared.components.SettingsDialog; -import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent; /** * Shows the currently tracked events/races in a table. Updated if subscribed as an {@link RegattaDisplayer}, e.g., with * the {@link AdminConsoleEntryPoint}. */ -public class TrackedRacesListComposite extends SimplePanel implements Component, - RegattaDisplayer, RaceSelectionChangeListener { - private final long DEFAULT_LIVE_DELAY_IN_MILLISECONDS = 5000; - +public class TrackedRacesListComposite extends AbstractTrackedRacesListComposite { + private final Set raceIsTrackedRaceChangeListener; - private final boolean multiSelection; + private Button btnUntrack; + private Button btnRemoveRace; - private boolean dontFireNextSelectionChangeEvent; - - private final SelectionModel selectionModel; - - private final CellTable raceTable; - - private ListDataProvider raceList; - - private Iterable allRaces; - - private final VerticalPanel panel; - - private DateTimeFormatRenderer dateFormatter = new DateTimeFormatRenderer( - DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT)); - private DateTimeFormatRenderer timeFormatter = new DateTimeFormatRenderer( - DateTimeFormat.getFormat(PredefinedFormat.TIME_LONG)); - - private final Label noTrackedRacesLabel; - - private final SailingServiceAsync sailingService; - private final ErrorReporter errorReporter; - private final RegattaRefresher regattaRefresher; - private final RaceSelectionProvider raceSelectionProvider; - private final StringMessages stringMessages; - - private final Button btnUntrack; - private final Button btnRefresh; - private final Button btnRemoveRace; - private final Button btnSetDelayToLive; - - private final TextBox filterRacesTextbox; - - private final TrackedRacesSettings settings; - - public static class AnchorCell extends AbstractCell { - - @Override - public void render(com.google.gwt.cell.client.Cell.Context context, SafeHtml safeHtml, SafeHtmlBuilder sb) { - sb.append(safeHtml); - } - } - - interface AnchorTemplates extends SafeHtmlTemplates { - @SafeHtmlTemplates.Template("{1}") - SafeHtml cell(String url, String displayName); - } - - private static AnchorTemplates ANCHORTEMPLATE = GWT.create(AnchorTemplates.class); + private Button btnSetDelayToLive; public TrackedRacesListComposite(final SailingServiceAsync sailingService, final ErrorReporter errorReporter, final RegattaRefresher regattaRefresher, RaceSelectionProvider raceSelectionProvider, final StringMessages stringMessages, boolean hasMultiSelection) { - this.sailingService = sailingService; - this.errorReporter = errorReporter; - this.regattaRefresher = regattaRefresher; - this.multiSelection = hasMultiSelection; - this.raceSelectionProvider = raceSelectionProvider; - this.stringMessages = stringMessages; + super(sailingService, errorReporter, regattaRefresher, raceSelectionProvider, stringMessages, hasMultiSelection); this.raceIsTrackedRaceChangeListener = new HashSet(); + } - raceList = new ListDataProvider(); - selectionModel = multiSelection ? new MultiSelectionModel() : new SingleSelectionModel(); - settings = new TrackedRacesSettings(); - settings.setDelayToLiveInSeconds(DEFAULT_LIVE_DELAY_IN_MILLISECONDS / 1000l); + private void showSetDelayToLiveDialog() { + TrackedRacesSettings settings = new TrackedRacesSettings(); + settings.setDelayToLiveInSeconds(DEFAULT_LIVE_DELAY_IN_MILLISECONDS); + + SettingsDialog settingsDialog = new SettingsDialog(this, stringMessages); + settingsDialog.show(); + } - panel = new VerticalPanel(); - setWidget(panel); - HorizontalPanel filterPanel = new HorizontalPanel(); - panel.add(filterPanel); - Label lblFilterRaces = new Label(stringMessages.filterRacesByName() + ":"); - lblFilterRaces.setWordWrap(false); - filterPanel.setSpacing(5); - filterPanel.add(lblFilterRaces); - filterPanel.setCellVerticalAlignment(lblFilterRaces, HasVerticalAlignment.ALIGN_MIDDLE); - filterRacesTextbox = new TextBox(); - filterRacesTextbox.addKeyUpHandler(new KeyUpHandler() { + + + + public void addTrackedRaceChangeListener(TrackedRaceChangedListener listener) { + this.raceIsTrackedRaceChangeListener.add(listener); + } + + private void stopTrackingRace(final RaceDTO race) { + final RegattaAndRaceIdentifier regattaAndRaceIdentifier = race.getRaceIdentifier(); + sailingService.stopTrackingRace(regattaAndRaceIdentifier, new AsyncCallback() { @Override - public void onKeyUp(KeyUpEvent event) { - fillRaceListFromAvailableRacesApplyingFilter(); + public void onFailure(Throwable caught) { + errorReporter.reportError("Exception trying to stop tracking race " + race.name + "in event " + + race.getRegattaName() + ": " + caught.getMessage()); + } + + @Override + public void onSuccess(Void result) { + regattaRefresher.fillRegattas(); + for (TrackedRaceChangedListener listener : raceIsTrackedRaceChangeListener) { + listener.changeTrackingRace(regattaAndRaceIdentifier, false); + } } }); - filterPanel.add(filterRacesTextbox); + } - noTrackedRacesLabel = new Label(stringMessages.noRacesYet()); - noTrackedRacesLabel.setWordWrap(false); - panel.add(noTrackedRacesLabel); - - AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class); - raceTable = new CellTable(/* pageSize */10000, tableRes); - raceTable.ensureDebugId("TrackedRaces"); - ListHandler columnSortHandler = new ListHandler(raceList.getList()); - TextColumn regattaNameColumn = new TextColumn() { - @Override - public String getValue(RaceDTO raceDTO) { - return raceDTO.getRegattaName(); - } - }; - regattaNameColumn.setSortable(true); - - columnSortHandler.setComparator(regattaNameColumn, new Comparator() { - @Override - public int compare(RaceDTO t1, RaceDTO t2) { - String regatta1Name = t1.getRegattaName(); - String regatta2Name = t2.getRegattaName(); - boolean ascending = isSortedAscending(); - if (regatta1Name.equals(regatta2Name)) { - return 0; - } - int val = ascending ? regatta1Name.compareTo(regatta2Name) : -(regatta2Name.compareTo(regatta1Name)); - return val; - } - - private boolean isSortedAscending() { - ColumnSortList sortList = raceTable.getColumnSortList(); - return sortList.size() > 0 & sortList.get(0).isAscending(); - } - }); - - TextColumn boatClassNameColumn = new TextColumn() { - @Override - public String getValue(RaceDTO raceDTO) { - return raceDTO.boatClass == null ? "" : raceDTO.boatClass; - } - }; - boatClassNameColumn.setSortable(true); - - columnSortHandler.setComparator(boatClassNameColumn, new Comparator() { - @Override - public int compare(RaceDTO t1, RaceDTO t2) { - String boatClass1 = t1.boatClass; - String boatClass2 = t2.boatClass; - boolean ascending = isSortedAscending(); - if (boatClass1.equals(boatClass2)) { - return 0; - } - int val = ascending ? boatClass1.compareTo(boatClass2) : -(boatClass2.compareTo(boatClass1)); - return val; - } - - private boolean isSortedAscending() { - ColumnSortList sortList = raceTable.getColumnSortList(); - return sortList.size() > 0 & sortList.get(0).isAscending(); - } - }); - - AnchorCell anchorCell = new AnchorCell(); - Column raceNameColumn = new Column(anchorCell) { - @Override - public SafeHtml getValue(RaceDTO raceDTO) { - if (raceDTO.isTracked == true) { - RegattaNameAndRaceName raceIdentifier = (RegattaNameAndRaceName) raceDTO.getRaceIdentifier(); - String debugParam = Window.Location.getParameter("gwt.codesvr"); - String link = URLFactory.INSTANCE.encode("/gwt/RaceBoard.html?raceName=" - + raceIdentifier.getRaceName() + "®attaName=" + raceIdentifier.getRegattaName() - + ((debugParam != null && !debugParam.isEmpty()) ? "&gwt.codesvr=" + debugParam : "")); - return ANCHORTEMPLATE.cell(link, raceDTO.name); - } else { - return SafeHtmlUtils.fromString(raceDTO.name); - } - } - }; - - raceNameColumn.setSortable(true); - - columnSortHandler.setComparator(raceNameColumn, new Comparator() { - @Override - public int compare(RaceDTO t1, RaceDTO t2) { - boolean ascending = isSortedAscending(); - if (t1.name.equals(t2.name)) { - return 0; - } - int val = -1; - val = (t1 != null && t2 != null && ascending) ? (t1.name.compareTo(t2.name)) : -(t2.name - .compareTo(t1.name)); - return val; - } - - private boolean isSortedAscending() { - ColumnSortList sortList = raceTable.getColumnSortList(); - return sortList.size() > 0 & sortList.get(0).isAscending(); - } - }); - - TextColumn raceStartColumn = new TextColumn() { - @Override - public String getValue(RaceDTO raceDTO) { - if (raceDTO.startOfRace != null) { - return dateFormatter.render(raceDTO.startOfRace) + " " + timeFormatter.render(raceDTO.startOfRace); - } - - return ""; - } - }; - raceStartColumn.setSortable(true); - - columnSortHandler.setComparator(raceStartColumn, new Comparator() { - @Override - public int compare(RaceDTO t1, RaceDTO t2) { - if (t1.startOfRace != null && t2.startOfRace != null) { - boolean ascending = isSortedAscending(); - int val = -1; - val = (t1.startOfRace.after(t2.startOfRace) && ascending) ? 1 : -1; - return val; - } - return 0; - } - - private boolean isSortedAscending() { - ColumnSortList sortList = raceTable.getColumnSortList(); - return sortList.size() > 0 & sortList.get(0).isAscending(); - } - }); - - TextColumn raceTrackedColumn = new TextColumn() { - @Override - public String getValue(RaceDTO raceDTO) { - if (raceDTO.isTracked == true) - return stringMessages.tracked(); - - return ""; - } - }; - - TextColumn hasWindDataColumn = new TextColumn() { - @Override - public String getValue(RaceDTO raceDTO) { - if (raceDTO.trackedRace != null && raceDTO.trackedRace.hasWindData == true) - return stringMessages.yes(); - else - return stringMessages.no(); - } - }; - - TextColumn hasGPSDataColumn = new TextColumn() { - @Override - public String getValue(RaceDTO raceDTO) { - if (raceDTO.trackedRace != null && raceDTO.trackedRace.hasGPSData == true) { - return stringMessages.yes(); - } else { - return stringMessages.no(); - } - } - }; - - TextColumn raceLiveDelayColumn = new TextColumn() { - @Override - public String getValue(RaceDTO raceDTO) { - if (raceDTO.isTracked && raceDTO.trackedRace != null && raceDTO.trackedRace.delayToLiveInMs > 0) { - return "" + raceDTO.trackedRace.delayToLiveInMs / 1000; - } - return ""; - } - }; - - raceTable.addColumn(regattaNameColumn, stringMessages.regatta()); - raceTable.addColumn(boatClassNameColumn, stringMessages.boatClass()); - raceTable.addColumn(raceNameColumn, stringMessages.race()); - raceTable.addColumn(raceStartColumn, stringMessages.startTime()); - raceTable.addColumn(raceTrackedColumn, stringMessages.tracked()); - raceTable.addColumn(hasWindDataColumn, "Wind data"); - raceTable.addColumn(hasGPSDataColumn, "GPS data"); - - raceTable.addColumn(raceLiveDelayColumn, stringMessages.delayInSeconds()); - raceTable.setWidth("300px"); - raceTable.setSelectionModel(selectionModel); - raceTable.setVisible(false); - panel.add(raceTable); - raceList.addDataDisplay(raceTable); - raceTable.addColumnSortHandler(columnSortHandler); - raceTable.getSelectionModel().addSelectionChangeHandler(new Handler() { - @Override - public void onSelectionChange(SelectionChangeEvent event) { - List selectedRaces = getSelectedRaces(); - if (selectedRaces.isEmpty()) { - btnRemoveRace.setEnabled(false); - btnUntrack.setEnabled(false); - } else { - btnRemoveRace.setEnabled(true); - btnUntrack.setEnabled(true); - } - if (dontFireNextSelectionChangeEvent) { - dontFireNextSelectionChangeEvent = false; - } else { - List selectedRaceIdentifiers = new ArrayList(); - for (RaceDTO selectedRace : selectedRaces) { - selectedRaceIdentifiers.add(selectedRace.getRaceIdentifier()); + private void removeAndUntrackRace(final RaceDTO race) { + final RegattaNameAndRaceName regattaNameAndRaceName = (RegattaNameAndRaceName) race.getRaceIdentifier(); + sailingService.removeAndUntrackRace(regattaNameAndRaceName, + new AsyncCallback() { + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError("Exception trying to stop tracking race " + race.name + "in regatta " + + race.getRegattaName() + ": " + caught.getMessage()); } - TrackedRacesListComposite.this.raceSelectionProvider.setSelection(selectedRaceIdentifiers, - TrackedRacesListComposite.this); - } - } - }); - HorizontalPanel trackedRacesButtonPanel = new HorizontalPanel(); - trackedRacesButtonPanel.setSpacing(10); - panel.add(trackedRacesButtonPanel); + + @Override + public void onSuccess(Void result) { + regattaRefresher.fillRegattas(); + for (TrackedRaceChangedListener listener : raceIsTrackedRaceChangeListener) { + listener.changeTrackingRace(regattaNameAndRaceName, false); + } + } + }); + } + + @Override + protected void addControlButtons(HorizontalPanel trackedRacesButtonPanel) { btnRemoveRace = new Button(stringMessages.remove()); btnRemoveRace.ensureDebugId("RemoveRave"); btnRemoveRace.addClickHandler(new ClickHandler() { @@ -395,16 +125,7 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< btnUntrack.setEnabled(false); trackedRacesButtonPanel.add(btnUntrack); - btnRefresh = new Button(stringMessages.refresh()); - btnRefresh.ensureDebugId("Refresh"); - btnRefresh.addClickHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - regattaRefresher.fillRegattas(); - } - }); - trackedRacesButtonPanel.add(btnRefresh); - + btnSetDelayToLive = new Button(stringMessages.setDelayToLive() + "..."); btnSetDelayToLive.ensureDebugId("SetDelayToLive"); btnSetDelayToLive.addClickHandler(new ClickHandler() { @@ -416,258 +137,31 @@ public class TrackedRacesListComposite extends SimplePanel implements Component< trackedRacesButtonPanel.add(btnSetDelayToLive); } - private void showSetDelayToLiveDialog() { - TrackedRacesSettings settings = new TrackedRacesSettings(); - settings.setDelayToLiveInSeconds(DEFAULT_LIVE_DELAY_IN_MILLISECONDS); - - SettingsDialog settingsDialog = new SettingsDialog(this, - stringMessages); - settingsDialog.show(); - } - - public RaceDTO getRaceByIdentifier(RaceIdentifier raceIdentifier) { - RaceDTO result = null; - if (raceList != null) { - for (RaceDTO race : raceList.getList()) { - if (race.getRaceIdentifier().equals(raceIdentifier)) { - result = race; - break; - } - } - } - return result; - } - - private List getSelectedRaces() { - List result = new ArrayList(); - if (raceList != null) { - for (RaceDTO race : raceList.getList()) { - if (selectionModel.isSelected(race)) { - result.add(race); - } - } - } - return result; - } - - public void selectRaceByIdentifier(RegattaAndRaceIdentifier raceIdentifier) { - if (raceList != null) { - for (RaceDTO race : raceList.getList()) { - String regattaName = race.getRegattaName(); - if (regattaName.equals(raceIdentifier.getRegattaName()) - && race.name.equals(raceIdentifier.getRaceName())) { - dontFireNextSelectionChangeEvent = true; - selectionModel.setSelected(race, true); - break; - } - } - } - } - - public void clearSelection() { - List emptySelection = Collections.emptyList(); - raceSelectionProvider.setSelection(emptySelection, /* listenersNotToNotify */ - this); - if (raceList != null) { - for (RaceDTO race : raceList.getList()) { - selectionModel.setSelected(race, false); - } + @Override + protected void makeControlsReactToSelectionChange(List selectedRaces) { + if (selectedRaces.isEmpty()) { + btnRemoveRace.setEnabled(false); + btnUntrack.setEnabled(false); + } else { + btnRemoveRace.setEnabled(true); + btnUntrack.setEnabled(true); } } @Override - public void fillRegattas(List regattas) { - setUiElementVisibilty(regattas); - List newAllRaces = new ArrayList(); - List newAllRegattas = new ArrayList(); - List newAllRaceIdentifiers = new ArrayList(); - for (RegattaDTO regatta : regattas) { - newAllRegattas.add(regatta); - for (RaceDTO race : regatta.races) { - if (race != null) { - if (raceCompliesToFilter(race)) { - newAllRaces.add(race); - newAllRaceIdentifiers.add(race.getRaceIdentifier()); - } - } - } - } - allRaces = newAllRaces; - fillRaceListFromAvailableRacesApplyingFilter(); - raceSelectionProvider.setAllRaces(newAllRaceIdentifiers); // have this - // object be - // notified; - // triggers - // onRaceSelectionChange - } - - /** - * Allows subclasses to add a racefilter, so that only races with specific characteristics are displayed. - * @param race - * @return - */ - protected boolean raceCompliesToFilter(RaceDTO race) { - return true; - } - - private void setUiElementVisibilty(List regattas) { + protected void makeControlsReactToFillRegattas(List regattas) { if (regattas.isEmpty()) { - raceTable.setVisible(false); btnUntrack.setVisible(false); btnRemoveRace.setVisible(false); btnSetDelayToLive.setVisible(false); - noTrackedRacesLabel.setVisible(true); } else { - raceTable.setVisible(true); btnUntrack.setVisible(true); btnUntrack.setEnabled(false); btnRemoveRace.setVisible(true); btnRemoveRace.setEnabled(false); - noTrackedRacesLabel.setVisible(false); btnSetDelayToLive.setVisible(true); } } - public void addRaceSelectionChangeListener(RaceSelectionChangeListener listener) { - this.raceSelectionProvider.addRaceSelectionChangeListener(listener); - } - - public void addTrackedRaceChangeListener(TrackedRaceChangedListener listener) { - this.raceIsTrackedRaceChangeListener.add(listener); - } - - private void stopTrackingRace(final RaceDTO race) { - final RegattaAndRaceIdentifier regattaAndRaceIdentifier = race.getRaceIdentifier(); - sailingService.stopTrackingRace(regattaAndRaceIdentifier, new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - errorReporter.reportError("Exception trying to stop tracking race " + race.name + "in event " - + race.getRegattaName() + ": " + caught.getMessage()); - } - - @Override - public void onSuccess(Void result) { - regattaRefresher.fillRegattas(); - for (TrackedRaceChangedListener listener : raceIsTrackedRaceChangeListener) { - listener.changeTrackingRace(regattaAndRaceIdentifier, false); - } - } - }); - } - - private void removeAndUntrackRace(final RaceDTO race) { - final RegattaNameAndRaceName regattaNameAndRaceName = (RegattaNameAndRaceName) race.getRaceIdentifier(); - sailingService.removeAndUntrackRace(regattaNameAndRaceName, new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - errorReporter.reportError("Exception trying to stop tracking race " + race.name + "in regatta " - + race.getRegattaName() + ": " + caught.getMessage()); - } - - @Override - public void onSuccess(Void result) { - regattaRefresher.fillRegattas(); - for (TrackedRaceChangedListener listener : raceIsTrackedRaceChangeListener) { - listener.changeTrackingRace(regattaNameAndRaceName, false); - } - } - }); - } - - private void fillRaceListFromAvailableRacesApplyingFilter() { - String text = filterRacesTextbox.getText(); - List wordsToFilter = Arrays.asList(text.split(" ")); - raceList.getList().clear(); - if (text != null && !text.isEmpty()) { - for (RaceDTO raceDTO : getAllRaces()) { - boolean failed = false; - for (String word : wordsToFilter) { - String textAsUppercase = word.toUpperCase().trim(); - if (!raceDTO.getRegattaName().toUpperCase().contains(textAsUppercase) - && !raceDTO.boatClass.toUpperCase().contains(textAsUppercase) - && !raceDTO.name.toUpperCase().contains(textAsUppercase)) { - failed = true; - break; - } - } - if (!failed) { - raceList.getList().add(raceDTO); - } - } - } else { - for (RaceDTO raceFromAllRaces : getAllRaces()) { - raceList.getList().add(raceFromAllRaces); - } - } - // now sort again according to selected criterion - ColumnSortEvent.fire(raceTable, raceTable.getColumnSortList()); - onRaceSelectionChange(raceSelectionProvider.getSelectedRaces()); // update - // selection - // based - // on - // underlying - // domain - // race - // selection - // model - } - - @Override - public void onRaceSelectionChange(List selectedRaces) { - for (RaceDTO raceFromAllRaces : raceList.getList()) { - selectionModel.setSelected(raceFromAllRaces, selectedRaces.contains(raceFromAllRaces.getRaceIdentifier())); - } - } - - private Iterable getAllRaces() { - return allRaces; - } - - @Override - public boolean hasSettings() { - return true; - } - - @Override - public SettingsDialogComponent getSettingsDialogComponent() { - return new TrackedRacesSettingsDialogComponent(settings, stringMessages); - } - - @Override - public void updateSettings(TrackedRacesSettings newSettings) { - settings.setDelayToLiveInSeconds(newSettings.getDelayToLiveInSeconds()); - - // set the new delay to all selected races - List raceIdentifiersToUpdate = new ArrayList(); - for (RaceDTO raceDTO : getSelectedRaces()) { - raceIdentifiersToUpdate.add(raceDTO.getRaceIdentifier()); - } - - if (raceIdentifiersToUpdate != null && !raceIdentifiersToUpdate.isEmpty()) { - sailingService.updateRacesDelayToLive(raceIdentifiersToUpdate, settings.getDelayToLiveInSeconds() * 1000l, - new AsyncCallback() { - @Override - public void onFailure(Throwable caught) { - errorReporter - .reportError("Exception trying to set the delay to live for the selected tracked races: " - + caught.getMessage()); - } - - @Override - public void onSuccess(Void result) { - regattaRefresher.fillRegattas(); - } - }); - } - } - - @Override - public String getLocalizedShortName() { - return "Tracked races"; - } - - @Override - public Widget getEntryWidget() { - return this; - } + } From 4272c96ee6409130302d04918215c5268712fa06 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Wed, 23 Jan 2013 10:18:45 +0100 Subject: [PATCH 04/37] Changed FilteredTrackedRacesList to implement new abstract class it now implements the freshly created AbstractTrackedRacesComposite class --- .../polarsheets/FilteredTrackedRacesList.java | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java index 2e92d734c92..0ed1365d7c6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java @@ -1,14 +1,18 @@ package com.sap.sailing.gwt.ui.polarsheets; -import com.sap.sailing.gwt.ui.adminconsole.TrackedRacesListComposite; +import java.util.List; + +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.sap.sailing.gwt.ui.adminconsole.AbstractTrackedRacesListComposite; import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.RaceSelectionProvider; import com.sap.sailing.gwt.ui.client.RegattaRefresher; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.shared.RaceDTO; +import com.sap.sailing.gwt.ui.shared.RegattaDTO; -public class FilteredTrackedRacesList extends TrackedRacesListComposite { +public class FilteredTrackedRacesList extends AbstractTrackedRacesListComposite { private RaceFilter filter; @@ -20,13 +24,31 @@ public class FilteredTrackedRacesList extends TrackedRacesListComposite { } @Override - protected boolean raceCompliesToFilter(RaceDTO race) { + protected boolean raceIsToBeAddedToList(RaceDTO race) { if (filter!=null) { return filter.compliesToFilter(race); } return true; } + @Override + protected void makeControlsReactToSelectionChange(List selectedRaces) { + // TODO Auto-generated method stub + + } + + @Override + protected void addControlButtons(HorizontalPanel trackedRacesButtonPanel) { + // TODO Auto-generated method stub + + } + + @Override + protected void makeControlsReactToFillRegattas(List regattas) { + // TODO Auto-generated method stub + + } + } From a27340e3d4ad7f1db27cfbdd545855feb025aa17 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Wed, 23 Jan 2013 10:30:17 +0100 Subject: [PATCH 05/37] Added advanced settings for the gwt compiler extended by three new modules --- .../.settings/com.google.gwt.eclipse.core.prefs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs b/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs index 9869601107d..4e750c36bc5 100755 --- a/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs +++ b/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs @@ -1,4 +1,4 @@ eclipse.preferences.version=1 entryPointModules= filesCopiedToWebInfLib=gwt-servlet.jar -gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDEwMjRtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5BZG1pbkNvbnNvbGU8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmRFZGl0aW5nPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlJhY2VCb2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVHZWaWV3PC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\= +gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDEwMjRtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5BZG1pbkNvbnNvbGU8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmRFZGl0aW5nPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlJhY2VCb2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVHZWaWV3PC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlBvbGFyU2hlZXRzPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlZpZGVvUG9wdXA8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuWW91dHViZVBvcHVwPC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\= From 30b4f04ac7a59ed4315051d8c3ce54caa60eaf39 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Wed, 23 Jan 2013 10:51:53 +0100 Subject: [PATCH 06/37] Added polar sheet generation button to the PolarSheetPanel --- .../sailing/gwt/ui/client/StringMessages.java | 2 + .../gwt/ui/client/StringMessages.properties | 3 +- .../ui/client/StringMessages_de.properties | 3 +- ... => AbstractFilteredTrackedRacesList.java} | 23 +-------- .../gwt/ui/polarsheets/PolarSheetsPanel.java | 23 +++++---- .../PolarSheetsTrackedRacesList.java | 51 +++++++++++++++++++ 6 files changed, 72 insertions(+), 33 deletions(-) rename java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/{FilteredTrackedRacesList.java => AbstractFilteredTrackedRacesList.java} (64%) create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index 8a0b71a1e1d..71a5f090f11 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -1,6 +1,7 @@ package com.sap.sailing.gwt.ui.client; import com.google.gwt.i18n.client.Messages; +import com.google.gwt.safehtml.shared.SafeHtml; public interface StringMessages extends Messages { String helloWorld(); @@ -476,4 +477,5 @@ public interface StringMessages extends Messages { String totalTimeSailedReachingInSecondsTooltip(); String totalTimeSailedUpwindInSecondsTooltip(); String windwardDistanceToGoInMetersTooltip(); + String generatePolarSheet(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index f2d891156a3..a03700bfd37 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -476,4 +476,5 @@ gapChangeSinceLegStartInSeconds=Gap Change sideToWhichMarkAtLegStartWasRounded=Mark rounded to raceIsLive=Race {0} is live racesAreLive=Races {0} are live -knotsUnit=kts \ No newline at end of file +knotsUnit=kts +generatePolarSheet=Generate Polar Sheet \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index 2a4732accd2..44f818cd605 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -477,4 +477,5 @@ gapChangeSinceLegStartInSeconds=Gap Änderung sideToWhichMarkAtLegStartWasRounded=Tonne gerundet an raceIsLive=Rennen {0} ist live racesAreLive=Rennen {0} sind live -knotsUnit=kn \ No newline at end of file +knotsUnit=kn +generatePolarSheet=Polardiagramm erstellen \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/AbstractFilteredTrackedRacesList.java similarity index 64% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/AbstractFilteredTrackedRacesList.java index 0ed1365d7c6..e280cb6a124 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/FilteredTrackedRacesList.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/AbstractFilteredTrackedRacesList.java @@ -12,11 +12,11 @@ import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.shared.RaceDTO; import com.sap.sailing.gwt.ui.shared.RegattaDTO; -public class FilteredTrackedRacesList extends AbstractTrackedRacesListComposite { +public abstract class AbstractFilteredTrackedRacesList extends AbstractTrackedRacesListComposite { private RaceFilter filter; - public FilteredTrackedRacesList(SailingServiceAsync sailingService, ErrorReporter errorReporter, + public AbstractFilteredTrackedRacesList(SailingServiceAsync sailingService, ErrorReporter errorReporter, RegattaRefresher regattaRefresher, RaceSelectionProvider raceSelectionProvider, StringMessages stringMessages, boolean hasMultiSelection, RaceFilter filter) { super(sailingService, errorReporter, regattaRefresher, raceSelectionProvider, stringMessages, hasMultiSelection); @@ -30,25 +30,6 @@ public class FilteredTrackedRacesList extends AbstractTrackedRacesListComposite } return true; } - - @Override - protected void makeControlsReactToSelectionChange(List selectedRaces) { - // TODO Auto-generated method stub - - } - - @Override - protected void addControlButtons(HorizontalPanel trackedRacesButtonPanel) { - // TODO Auto-generated method stub - - } - - @Override - protected void makeControlsReactToFillRegattas(List regattas) { - // TODO Auto-generated method stub - - } - } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index 1abb6f18297..4abd1eb70b5 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -25,7 +25,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi private FlowPanel mainPanel; private SailingServiceAsync sailingService; - private FilteredTrackedRacesList filteredTrackedRacesList; + private PolarSheetsTrackedRacesList polarSheetsTrackedRacesList; private ErrorReporter errorReporter; private StringMessages stringMessages; private RaceSelectionModel raceSelectionProvider; @@ -50,30 +50,33 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi trackedRacesPanel.setWidth("100%"); createFilteredTrackedList(); - trackedRacesPanel.add(filteredTrackedRacesList); + trackedRacesPanel.add(polarSheetsTrackedRacesList); - Button polarSheetGenerationStartButton = createPolarSheetCalculationStartButton(); - trackedRacesPanel.add(polarSheetGenerationStartButton); mainPanel.add(trackedRacesPanel); } private Button createPolarSheetCalculationStartButton() { - Button polarSheetGenerationStartButton = new Button("Generate Polar Sheet"); + Button polarSheetGenerationStartButton = new Button(stringMessages.generatePolarSheet()); + polarSheetGenerationStartButton.ensureDebugId("PolarSheetGeneration"); polarSheetGenerationStartButton.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent arg0) { - // TODO Auto-generated method stub - + startPolarSheetGeneration(); } }); return polarSheetGenerationStartButton; } + protected void startPolarSheetGeneration() { + // TODO Auto-generated method stub + + } + private void createFilteredTrackedList() { raceSelectionProvider = new RaceSelectionModel(); - filteredTrackedRacesList = new FilteredTrackedRacesList(sailingService, errorReporter, polarSheetsEntryPoint, - raceSelectionProvider, stringMessages, true, new RaceFilter(true, true)); + polarSheetsTrackedRacesList = new PolarSheetsTrackedRacesList(sailingService, errorReporter, polarSheetsEntryPoint, + raceSelectionProvider, stringMessages, true, new RaceFilter(true, true), createPolarSheetCalculationStartButton()); raceSelectionProvider.addRaceSelectionChangeListener(this); } @@ -84,7 +87,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi @Override public void fillRegattas(List regattas) { - filteredTrackedRacesList.fillRegattas(regattas); + polarSheetsTrackedRacesList.fillRegattas(regattas); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java new file mode 100644 index 00000000000..dcd0cc76629 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java @@ -0,0 +1,51 @@ +package com.sap.sailing.gwt.ui.polarsheets; + +import java.util.List; + +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.HorizontalPanel; +import com.sap.sailing.gwt.ui.client.ErrorReporter; +import com.sap.sailing.gwt.ui.client.RaceSelectionProvider; +import com.sap.sailing.gwt.ui.client.RegattaRefresher; +import com.sap.sailing.gwt.ui.client.SailingServiceAsync; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sailing.gwt.ui.shared.RaceDTO; +import com.sap.sailing.gwt.ui.shared.RegattaDTO; + +public class PolarSheetsTrackedRacesList extends AbstractFilteredTrackedRacesList { + + private Button btnPolarSheetGeneration; + + public PolarSheetsTrackedRacesList(SailingServiceAsync sailingService, ErrorReporter errorReporter, + RegattaRefresher regattaRefresher, RaceSelectionProvider raceSelectionProvider, + StringMessages stringMessages, boolean hasMultiSelection, RaceFilter filter, Button btnPolarSheetGeneration) { + super(sailingService, errorReporter, regattaRefresher, raceSelectionProvider, stringMessages, hasMultiSelection, filter); + this.btnPolarSheetGeneration = btnPolarSheetGeneration; + } + + @Override + protected void addControlButtons(HorizontalPanel trackedRacesButtonPanel) { + trackedRacesButtonPanel.add(btnPolarSheetGeneration); + } + + + @Override + protected void makeControlsReactToSelectionChange(List selectedRaces) { + if (selectedRaces.isEmpty()) { + btnPolarSheetGeneration.setEnabled(false); + } else { + btnPolarSheetGeneration.setEnabled(true); + } + } + + @Override + protected void makeControlsReactToFillRegattas(List regattas) { + if (regattas.isEmpty()) { + btnPolarSheetGeneration.setVisible(false); + } else { + btnPolarSheetGeneration.setVisible(true); + btnPolarSheetGeneration.setEnabled(false); + } + } + +} From 0367fbcf6a22ae2719faae1a703cbc0ba9192513 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Wed, 23 Jan 2013 11:24:54 +0100 Subject: [PATCH 07/37] Refactored polar sheets panel and its components --- .../AbstractTrackedRacesListComposite.java | 18 ++++---- .../sailing/gwt/ui/client/StringMessages.java | 1 - .../AbstractFilteredTrackedRacesList.java | 4 -- .../gwt/ui/polarsheets/PolarSheetsPanel.java | 42 ++++++++----------- .../PolarSheetsTrackedRacesList.java | 20 +++++---- 5 files changed, 39 insertions(+), 46 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractTrackedRacesListComposite.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractTrackedRacesListComposite.java index 30bd49c7519..c6d3211c122 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractTrackedRacesListComposite.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractTrackedRacesListComposite.java @@ -22,9 +22,9 @@ import com.google.gwt.text.client.DateTimeFormatRenderer; import com.google.gwt.user.cellview.client.CellTable; import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.cellview.client.ColumnSortEvent; +import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler; import com.google.gwt.user.cellview.client.ColumnSortList; import com.google.gwt.user.cellview.client.TextColumn; -import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; @@ -38,9 +38,9 @@ import com.google.gwt.user.client.ui.Widget; import com.google.gwt.view.client.ListDataProvider; import com.google.gwt.view.client.MultiSelectionModel; import com.google.gwt.view.client.SelectionChangeEvent; +import com.google.gwt.view.client.SelectionChangeEvent.Handler; import com.google.gwt.view.client.SelectionModel; import com.google.gwt.view.client.SingleSelectionModel; -import com.google.gwt.view.client.SelectionChangeEvent.Handler; import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.RegattaNameAndRaceName; @@ -151,13 +151,13 @@ public abstract class AbstractTrackedRacesListComposite extends SimplePanel impl AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class); raceTable = new CellTable(/* pageSize */10000, tableRes); raceTable.ensureDebugId("TrackedRaces"); - ListHandler columnSortHandler = setupTableColumns(stringMessages); + setupTableColumns(stringMessages); raceTable.setWidth("300px"); raceTable.setSelectionModel(selectionModel); raceTable.setVisible(false); panel.add(raceTable); raceList.addDataDisplay(raceTable); - raceTable.addColumnSortHandler(columnSortHandler); + raceTable.getSelectionModel().addSelectionChangeHandler(new Handler() { @Override public void onSelectionChange(SelectionChangeEvent event) { @@ -197,7 +197,7 @@ public abstract class AbstractTrackedRacesListComposite extends SimplePanel impl abstract protected void addControlButtons(HorizontalPanel trackedRacesButtonPanel); - private ListHandler setupTableColumns(final StringMessages stringMessages) { + private void setupTableColumns(final StringMessages stringMessages) { ListHandler columnSortHandler = new ListHandler(raceList.getList()); TextColumn regattaNameColumn = new TextColumn() { @Override @@ -371,7 +371,8 @@ public abstract class AbstractTrackedRacesListComposite extends SimplePanel impl raceTable.addColumn(hasGPSDataColumn, "GPS data"); raceTable.addColumn(raceLiveDelayColumn, stringMessages.delayInSeconds()); - return columnSortHandler; + + raceTable.addColumnSortHandler(columnSortHandler); } private void fillRaceListFromAvailableRacesApplyingFilter() { @@ -548,8 +549,9 @@ public abstract class AbstractTrackedRacesListComposite extends SimplePanel impl } /** - * Allows applying some sort of filter to the process of adding races. - * Defaults to true in standard implementation. Override for custom behavior + * Allows applying some sort of filter to the process of adding races. Defaults to true in standard implementation. + * Override for custom behavior + * * @param race * @return */ diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index 71a5f090f11..2bc6f1419a5 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -1,7 +1,6 @@ package com.sap.sailing.gwt.ui.client; import com.google.gwt.i18n.client.Messages; -import com.google.gwt.safehtml.shared.SafeHtml; public interface StringMessages extends Messages { String helloWorld(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/AbstractFilteredTrackedRacesList.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/AbstractFilteredTrackedRacesList.java index e280cb6a124..2c1d3bcd6f6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/AbstractFilteredTrackedRacesList.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/AbstractFilteredTrackedRacesList.java @@ -1,8 +1,5 @@ package com.sap.sailing.gwt.ui.polarsheets; -import java.util.List; - -import com.google.gwt.user.client.ui.HorizontalPanel; import com.sap.sailing.gwt.ui.adminconsole.AbstractTrackedRacesListComposite; import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.RaceSelectionProvider; @@ -10,7 +7,6 @@ import com.sap.sailing.gwt.ui.client.RegattaRefresher; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.shared.RaceDTO; -import com.sap.sailing.gwt.ui.shared.RegattaDTO; public abstract class AbstractFilteredTrackedRacesList extends AbstractTrackedRacesListComposite { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index 4abd1eb70b5..fabe52fb15b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -4,7 +4,6 @@ import java.util.List; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.VerticalPanel; @@ -17,8 +16,7 @@ import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.shared.RegattaDTO; -public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeListener, - RegattaDisplayer { +public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeListener, RegattaDisplayer { // TODO UI stuff public static final String POLARSHEETS_STYLE = "polarSheets"; @@ -48,38 +46,32 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi private void addFilteredTrackedRacesList() { VerticalPanel trackedRacesPanel = new VerticalPanel(); trackedRacesPanel.setWidth("100%"); - + createFilteredTrackedList(); trackedRacesPanel.add(polarSheetsTrackedRacesList); - + mainPanel.add(trackedRacesPanel); } - private Button createPolarSheetCalculationStartButton() { - Button polarSheetGenerationStartButton = new Button(stringMessages.generatePolarSheet()); - polarSheetGenerationStartButton.ensureDebugId("PolarSheetGeneration"); - polarSheetGenerationStartButton.addClickHandler(new ClickHandler() { - - @Override - public void onClick(ClickEvent arg0) { - startPolarSheetGeneration(); - } - }); - return polarSheetGenerationStartButton; - } - - protected void startPolarSheetGeneration() { - // TODO Auto-generated method stub - - } - private void createFilteredTrackedList() { raceSelectionProvider = new RaceSelectionModel(); - polarSheetsTrackedRacesList = new PolarSheetsTrackedRacesList(sailingService, errorReporter, polarSheetsEntryPoint, - raceSelectionProvider, stringMessages, true, new RaceFilter(true, true), createPolarSheetCalculationStartButton()); + ClickHandler polarSheetsGenerationButtonClickHandler = new ClickHandler() { + + @Override + public void onClick(ClickEvent arg0) { + startPolarSheetGeneration(); + } + }; + polarSheetsTrackedRacesList = new PolarSheetsTrackedRacesList(sailingService, errorReporter, + polarSheetsEntryPoint, raceSelectionProvider, stringMessages, true, new RaceFilter(true, true), + polarSheetsGenerationButtonClickHandler); raceSelectionProvider.addRaceSelectionChangeListener(this); } + protected void startPolarSheetGeneration() { + // TODO Auto-generated method stub + } + @Override public void onRaceSelectionChange(List selectedRaces) { this.selectedRaces = selectedRaces; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java index dcd0cc76629..233bb8ca3c3 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java @@ -2,6 +2,7 @@ package com.sap.sailing.gwt.ui.polarsheets; import java.util.List; +import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.HorizontalPanel; import com.sap.sailing.gwt.ui.client.ErrorReporter; @@ -18,16 +19,19 @@ public class PolarSheetsTrackedRacesList extends AbstractFilteredTrackedRacesLis public PolarSheetsTrackedRacesList(SailingServiceAsync sailingService, ErrorReporter errorReporter, RegattaRefresher regattaRefresher, RaceSelectionProvider raceSelectionProvider, - StringMessages stringMessages, boolean hasMultiSelection, RaceFilter filter, Button btnPolarSheetGeneration) { - super(sailingService, errorReporter, regattaRefresher, raceSelectionProvider, stringMessages, hasMultiSelection, filter); - this.btnPolarSheetGeneration = btnPolarSheetGeneration; - } - - @Override - protected void addControlButtons(HorizontalPanel trackedRacesButtonPanel) { - trackedRacesButtonPanel.add(btnPolarSheetGeneration); + StringMessages stringMessages, boolean hasMultiSelection, RaceFilter filter, + ClickHandler polarSheetsGenerationButtonClickedHandler) { + super(sailingService, errorReporter, regattaRefresher, raceSelectionProvider, stringMessages, + hasMultiSelection, filter); + btnPolarSheetGeneration.addClickHandler(polarSheetsGenerationButtonClickedHandler); } + @Override + protected void addControlButtons(HorizontalPanel trackedRacesButtonPanel) { + btnPolarSheetGeneration = new Button(stringMessages.generatePolarSheet()); + btnPolarSheetGeneration.ensureDebugId("PolarSheetGeneration"); + trackedRacesButtonPanel.add(btnPolarSheetGeneration); + } @Override protected void makeControlsReactToSelectionChange(List selectedRaces) { From 7611b096e9b0c8cd490c1660fb4b975d6b5899b5 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Wed, 23 Jan 2013 16:56:12 +0100 Subject: [PATCH 08/37] Removed unused highcharts lib from gwt.ui bundle we include the source code in the project --- .../lib/org.moxieapps.gwt.highcharts-1.1.3.jar | Bin 309619 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 java/com.sap.sailing.gwt.ui/WEB-INF/lib/org.moxieapps.gwt.highcharts-1.1.3.jar diff --git a/java/com.sap.sailing.gwt.ui/WEB-INF/lib/org.moxieapps.gwt.highcharts-1.1.3.jar b/java/com.sap.sailing.gwt.ui/WEB-INF/lib/org.moxieapps.gwt.highcharts-1.1.3.jar deleted file mode 100755 index cbf2faaf83df1f5b8724361623da6cc034202a97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 309619 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

L(i8BO|X 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%0DsV*~yk5&_+u+xiAU8@r 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 From 7a73c7a3681a9602aad9b078e7f86e276ec47d59 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Wed, 23 Jan 2013 16:57:11 +0100 Subject: [PATCH 09/37] Added PolarSheetsChartPanel not a lot of functionality yet --- .../sailing/gwt/ui/client/StringMessages.java | 1 + .../gwt/ui/client/StringMessages.properties | 1 + .../ui/client/StringMessages_de.properties | 1 + .../ui/polarsheets/PolarSheetsChartPanel.java | 35 +++++++++++++++++++ .../gwt/ui/polarsheets/PolarSheetsPanel.java | 25 +++++++++---- 5 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index 27046f82901..564ae6e62af 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -483,4 +483,5 @@ public interface StringMessages extends Messages { String velocityMadeGoodInKnotsTooltip(); String sideToWhichMarkAtLegStartWasRoundedTooltip(); String generatePolarSheet(); + String polarSheetChart(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index cab5e7ee8e8..7712e6bca80 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -486,3 +486,4 @@ knotsUnit=kts scoringSchemeHighPointFirstGetsTen=High Point, winner gets 10 points knotsUnit=kts generatePolarSheet=Generate Polar Sheet +polarSheetChart=Polar Sheet: diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index 5d6d9815c18..eb5c4a05cbc 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -486,3 +486,4 @@ racesAreLive=Rennen {0} sind live scoringSchemeHighPointFirstGetsTen=High Point System, Gewinner erhält 10 Punkte knotsUnit=kn generatePolarSheet=Polardiagramm erstellen +polarSheetChart=Polardiagramm: diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java new file mode 100644 index 00000000000..2a4e9624917 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java @@ -0,0 +1,35 @@ +package com.sap.sailing.gwt.ui.polarsheets; + +import org.moxieapps.gwt.highcharts.client.Chart; +import org.moxieapps.gwt.highcharts.client.Series; + +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.SimplePanel; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.ui.client.StringMessages; + +public class PolarSheetsChartPanel extends SimplePanel { + + private VerticalPanel mainPanel; + private StringMessages stringMessages; + + public PolarSheetsChartPanel(StringMessages stringMessages) { + this.stringMessages = stringMessages; + mainPanel = new VerticalPanel(); + mainPanel.setSize("100%", "100%"); + setWidget(mainPanel); + Label polarSheetsChartLabel = new Label(stringMessages.polarSheetChart()); + mainPanel.add(polarSheetsChartLabel); + mainPanel.add(createPolarSheetChart()); + } + + private Widget createPolarSheetChart() { + Chart polarSheetChart = new Chart(); + polarSheetChart.setType(Series.Type.LINE); + polarSheetChart.setOption("/chart/polar", true); + + return polarSheetChart; + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index fabe52fb15b..b26f3e26832 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -6,6 +6,7 @@ import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FormPanel; +import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.gwt.ui.client.ErrorReporter; @@ -40,20 +41,31 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi this.mainPanel = new FlowPanel(); mainPanel.setSize("100%", "100%"); setWidget(mainPanel); - addFilteredTrackedRacesList(); + HorizontalPanel splitPanel = createSplitPanel(); + addFilteredTrackedRacesList(splitPanel); + addPolarSheetsChartPanel(splitPanel); } - private void addFilteredTrackedRacesList() { + private void addPolarSheetsChartPanel(HorizontalPanel splitPanel) { + + } + + private HorizontalPanel createSplitPanel() { + HorizontalPanel splitPanel = new HorizontalPanel(); + splitPanel.setSize("100%", "100%"); + return splitPanel; + } + + private void addFilteredTrackedRacesList(HorizontalPanel splitPanel) { VerticalPanel trackedRacesPanel = new VerticalPanel(); trackedRacesPanel.setWidth("100%"); - createFilteredTrackedList(); - trackedRacesPanel.add(polarSheetsTrackedRacesList); + trackedRacesPanel.add(createPolarSheetsTrackedRacesList()); - mainPanel.add(trackedRacesPanel); + splitPanel.add(trackedRacesPanel); } - private void createFilteredTrackedList() { + private PolarSheetsTrackedRacesList createPolarSheetsTrackedRacesList() { raceSelectionProvider = new RaceSelectionModel(); ClickHandler polarSheetsGenerationButtonClickHandler = new ClickHandler() { @@ -66,6 +78,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi polarSheetsEntryPoint, raceSelectionProvider, stringMessages, true, new RaceFilter(true, true), polarSheetsGenerationButtonClickHandler); raceSelectionProvider.addRaceSelectionChangeListener(this); + return polarSheetsTrackedRacesList; } protected void startPolarSheetGeneration() { From d0e9ebd793b891a8fb4b98940cefd4734522d959 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Thu, 24 Jan 2013 10:22:52 +0100 Subject: [PATCH 10/37] Initial highcharts upgrade new gwt version: 1.5.0 new js lib version: 2.3.5 --- .../com.google.gwt.eclipse.core.prefs | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../WEB-INF/lib/Highcharts-2.1.9.zip | Bin 234888 -> 0 bytes .../WEB-INF/lib/Highcharts-2.3.5.zip | Bin 0 -> 410981 bytes java/com.sap.sailing.gwt.ui/pom.xml | 2 +- .../META-INF/MANIFEST.MF | 10 +- java/org.moxieapps.gwt.highcharts/pom.xml | 2 +- .../moxieapps/gwt/highcharts/client/Axis.java | 18 +- .../gwt/highcharts/client/BaseChart.java | 222 +++++++++---- .../gwt/highcharts/client/Chart.java | 36 ++- .../client/DateTimeLabelFormats.java | 14 + .../gwt/highcharts/client/Global.java | 58 ++++ .../gwt/highcharts/client/Highcharts.java | 82 +++++ .../moxieapps/gwt/highcharts/client/Lang.java | 291 ++++++++++++++++- .../gwt/highcharts/client/Navigator.java | 214 +++++++++++++ .../moxieapps/gwt/highcharts/client/Pane.java | 49 +++ .../gwt/highcharts/client/Point.java | 170 +++++++++- .../gwt/highcharts/client/RangeSelector.java | 163 +++++++++- .../gwt/highcharts/client/Series.java | 294 ++++++++++++------ .../gwt/highcharts/client/StockChart.java | 38 +++ .../gwt/highcharts/client/ToolTip.java | 109 +++++++ .../gwt/highcharts/client/ToolTipData.java | 10 +- .../highcharts/client/events/AxisEvent.java | 14 +- .../highcharts/client/events/MouseEvent.java | 12 + .../client/labels/AxisLabelsData.java | 11 + .../client/labels/DataLabelsData.java | 26 ++ .../client/labels/LegendLabelsData.java | 11 + .../client/labels/StackLabelsData.java | 11 + .../client/labels/StackLabelsFormatter.java | 7 +- .../client/plotOptions/AreaPlotOptions.java | 102 +----- .../plotOptions/AreaRangePlotOptions.java | 43 +++ .../plotOptions/AreaSplinePlotOptions.java | 101 +----- .../AreaSplineRangePlotOptions.java | 44 +++ .../plotOptions/BaseAreaPlotOptions.java | 118 +++++++ .../BaseAreaSplinePlotOptions.java | 119 +++++++ .../plotOptions/BaseColumnPlotOptions.java | 164 ++++++++++ .../client/plotOptions/ColumnPlotOptions.java | 150 +-------- .../plotOptions/ColumnRangePlotOptions.java | 44 +++ .../client/plotOptions/OHLCPlotOptions.java | 40 +++ .../client/plotOptions/PlotOptions.java | 18 +- 40 files changed, 2273 insertions(+), 548 deletions(-) delete mode 100755 java/com.sap.sailing.gwt.ui/WEB-INF/lib/Highcharts-2.1.9.zip create mode 100644 java/com.sap.sailing.gwt.ui/WEB-INF/lib/Highcharts-2.3.5.zip create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Global.java create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Highcharts.java create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Navigator.java create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Pane.java create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/plotOptions/AreaRangePlotOptions.java create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/plotOptions/AreaSplineRangePlotOptions.java create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/plotOptions/BaseAreaPlotOptions.java create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/plotOptions/BaseAreaSplinePlotOptions.java create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/plotOptions/BaseColumnPlotOptions.java create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/plotOptions/ColumnRangePlotOptions.java create mode 100644 java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/plotOptions/OHLCPlotOptions.java diff --git a/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs b/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs index 9869601107d..4e750c36bc5 100755 --- a/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs +++ b/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs @@ -1,4 +1,4 @@ eclipse.preferences.version=1 entryPointModules= filesCopiedToWebInfLib=gwt-servlet.jar -gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDEwMjRtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5BZG1pbkNvbnNvbGU8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmRFZGl0aW5nPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlJhY2VCb2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVHZWaWV3PC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\= +gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDEwMjRtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5BZG1pbkNvbnNvbGU8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmRFZGl0aW5nPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlJhY2VCb2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVHZWaWV3PC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlBvbGFyU2hlZXRzPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlZpZGVvUG9wdXA8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuWW91dHViZVBvcHVwPC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\= diff --git a/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF b/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF index 19b550edacd..b4ff0228da0 100755 --- a/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF @@ -17,7 +17,7 @@ Require-Bundle: com.sap.sailing.domain, com.sap.sailing.domain.tractracadapter.persistence, com.google.gwt.osgi;bundle-version="2.4.0", com.sap.sailing.domain.common, - org.moxieapps.gwt.highcharts;bundle-version="1.1.4", + org.moxieapps.gwt.highcharts;bundle-version="1.5.0", com.sap.sailing.geocoding, com.sap.sailing.server.replication, com.googlecode.java-diff-utils;bundle-version="1.3.0", diff --git a/java/com.sap.sailing.gwt.ui/WEB-INF/lib/Highcharts-2.1.9.zip b/java/com.sap.sailing.gwt.ui/WEB-INF/lib/Highcharts-2.1.9.zip deleted file mode 100755 index 7a0c97888294bd75ad13cf4e52a139d17dac459b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 234888 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 diff --git a/java/com.sap.sailing.gwt.ui/WEB-INF/lib/Highcharts-2.3.5.zip b/java/com.sap.sailing.gwt.ui/WEB-INF/lib/Highcharts-2.3.5.zip new file mode 100644 index 0000000000000000000000000000000000000000..49d2320068b84bd938b59f4fe610f391898d05ea GIT binary patch literal 410981 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

vwj*Z`*O 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

NrezIT1GU$3A1J0SmRw@HmxVO3 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%0D|`9V0jgE2QF;v5 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⋘JSW`704+Atmv5;ub{v?3Vu`E+s(NLi|#v<>0@; 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 cTiN{g%WN9T org.moxieapps.gwt org.moxieapps.gwt.highcharts - 1.3.0-SNAPSHOT + 1.5.0-SNAPSHOT sources diff --git a/java/org.moxieapps.gwt.highcharts/META-INF/MANIFEST.MF b/java/org.moxieapps.gwt.highcharts/META-INF/MANIFEST.MF index ce4ada46312..03ebffac9cd 100755 --- a/java/org.moxieapps.gwt.highcharts/META-INF/MANIFEST.MF +++ b/java/org.moxieapps.gwt.highcharts/META-INF/MANIFEST.MF @@ -2,21 +2,21 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Moxie Apps GWT Highcharts Bundle-SymbolicName: org.moxieapps.gwt.highcharts -Bundle-Version: 1.3.0.qualifier +Bundle-Version: 1.5.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: org.moxieapps.gwt.highcharts.client.plotOptions;uses:="o rg.moxieapps.gwt.highcharts.client,com.google.gwt.json.client,org.moxie apps.gwt.highcharts.client.events,org.moxieapps.gwt.highcharts.client.l - abels";version="1.3.0",org.moxieapps.gwt.highcharts;version="1.3.0",org + abels";version="1.5.0",org.moxieapps.gwt.highcharts;version="1.5.0",org .moxieapps.gwt.highcharts.client;uses:="com.google.gwt.core.client,com. google.gwt.dom.client,com.google.gwt.json.client,org.moxieapps.gwt.high charts.client.plotOptions,com.google.gwt.user.client,org.moxieapps.gwt. highcharts.client.events,org.moxieapps.gwt.highcharts.client.labels,com - .google.gwt.user.client.ui";version="1.3.0",org.moxieapps.gwt.highchart + .google.gwt.user.client.ui";version="1.5.0",org.moxieapps.gwt.highchart s.client.events;uses:="com.google.gwt.core.client,com.google.gwt.dom.cl - ient,org.moxieapps.gwt.highcharts.client";version="1.3.0",org.moxieapps + ient,org.moxieapps.gwt.highcharts.client";version="1.5.0",org.moxieapps .gwt.highcharts.client.labels;uses:="com.google.gwt.core.client,org.mox - ieapps.gwt.highcharts.client,com.google.gwt.json.client";version="1.3.0 + ieapps.gwt.highcharts.client,com.google.gwt.json.client";version="1.5.0 " Import-Package: com.google.gwt.core.client,com.google.gwt.dom.client,com .google.gwt.json.client,com.google.gwt.user.client,com.google.gwt.user. diff --git a/java/org.moxieapps.gwt.highcharts/pom.xml b/java/org.moxieapps.gwt.highcharts/pom.xml index 22ec700e7eb..c1f737eed42 100755 --- a/java/org.moxieapps.gwt.highcharts/pom.xml +++ b/java/org.moxieapps.gwt.highcharts/pom.xml @@ -9,7 +9,7 @@ org.moxieapps.gwt.highcharts org.moxieapps.gwt - 1.3.0-SNAPSHOT + 1.5.0-SNAPSHOT eclipse-plugin diff --git a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Axis.java b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Axis.java index 4d9174a0a4e..f4e83f3e6da 100755 --- a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Axis.java +++ b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Axis.java @@ -390,8 +390,20 @@ public abstract class Axis extends Configurable { return extremes; } - protected JavaScriptObject getNativeAxis() { - return chart.get(this.id); + /** + * Returns a pointer to the native Highchart's Axis instance that this GWT Axis instance + * is associated with. Note that this method will only return a non-null value if it + * is called after the chart has been rendered. For advanced use-cases only. + * + * @return The native Highcharts axis instance that this Axis is associated with, or + * null if the chart has not yet been rendered. + * @since 1.4.0 + */ + public JavaScriptObject getNativeAxis() { + if(chart != null) { + return chart.get(this.id); + } + return null; } /* package */ String getId() { @@ -401,7 +413,7 @@ public abstract class Axis extends Configurable { // Save some typing in the getExtremes() method private Number getNumberFromJSONObject(JSONObject jsonObject, String key) { JSONValue jsonValue = jsonObject.get(key); - if (jsonValue.isNumber() != null) { + if (jsonValue != null && jsonValue.isNumber() != null) { return jsonValue.isNumber().doubleValue(); } return null; diff --git a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/BaseChart.java b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/BaseChart.java index 43f3e1654c6..d4ae1bf7135 100644 --- a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/BaseChart.java +++ b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/BaseChart.java @@ -42,7 +42,7 @@ import java.util.Iterator; * @see Chart * @see StockChart * @since 1.0.0 - */ +*/ public abstract class BaseChart extends Widget { /** @@ -1145,15 +1145,21 @@ public abstract class BaseChart extends Widget { // We need to maintain a local reference to the plot options in order to handle the potential callback formatter functions private AreaPlotOptions areaPlotOptions; + private AreaRangePlotOptions areaRangePlotOptions; private AreaSplinePlotOptions areaSplinePlotOptions; + private AreaSplineRangePlotOptions areaSplineRangePlotOptions; private BarPlotOptions barPlotOptions; private ColumnPlotOptions columnPlotOptions; + private ColumnRangePlotOptions columnRangePlotOptions; private LinePlotOptions linePlotOptions; private PiePlotOptions piePlotOptions; private SeriesPlotOptions seriesPlotOptions; private ScatterPlotOptions scatterPlotOptions; private SplinePlotOptions splinePlotOptions; + // The OHLC plot options are managed by the StockChart sub class, but the reference is managed here for rendering + protected OHLCPlotOptions ohlcPlotOptions; + /** * Updates the options that all area type series within the chart will use by default. The settings can then * be overridden for each individual series via the {@link Series#setPlotOptions(PlotOptions)} method. @@ -1172,7 +1178,27 @@ public abstract class BaseChart extends Widget { this.setOption("/plotOptions/area", areaPlotOptions.getOptions()) : returnThis(); } - + + /** + * Updates the options that all area range type series within the chart will use by default. The settings can then + * be overridden for each individual series via the {@link Series#setPlotOptions(PlotOptions)} method. + *

+ * Note that changing the plot options on a chart that has already been rendered will only affect + * series that are subsequently added to the chart (and will not impact any of the series that are already + * rendered in the chart.) + *

+ * Note that the highcharts-more.js script must be included in your GWT module to use AreaRange charts. + * + * @param areaRangePlotOptions The options to set on the chart as the default settings for all area range type series + * that are part of this chart. + * @return A reference to this {@link BaseChart} instance for convenient method chaining. + */ + public T setAreaRangePlotOptions(AreaRangePlotOptions areaRangePlotOptions) { + this.areaRangePlotOptions = areaRangePlotOptions; + return areaRangePlotOptions != null && areaRangePlotOptions.getOptions() != null ? + this.setOption("/plotOptions/arearange", areaRangePlotOptions.getOptions()) : + returnThis(); + } /** * Updates the options that all area spline type series within the chart will use by default. The settings can then @@ -1192,6 +1218,27 @@ public abstract class BaseChart extends Widget { this.setOption("/plotOptions/areaspline", areaSplinePlotOptions.getOptions()) : returnThis(); } + + /** + * Updates the options that all area spline range type series within the chart will use by default. The settings can then + * be overridden for each individual series via the {@link Series#setPlotOptions(org.moxieapps.gwt.highcharts.client.plotOptions.PlotOptions)} method. + *

+ * Note that changing the plot options on a chart that has already been rendered will only affect + * series that are subsequently added to the chart (and will not impact any of the series that are already + * rendered in the chart.) + *

+ * Note that the highcharts-more.js script must be included in your GWT module to use AreaSplineRange charts. + * + * @param areaSplineRangePlotOptions The options to set on the chart as the default settings for all area spline range type series + * that are part of this chart. + * @return A reference to this {@link BaseChart} instance for convenient method chaining. + */ + public T setAreaSplineRangePlotOptions(AreaSplineRangePlotOptions areaSplineRangePlotOptions) { + this.areaSplineRangePlotOptions = areaSplineRangePlotOptions; + return areaSplineRangePlotOptions != null && areaSplineRangePlotOptions.getOptions() != null ? + this.setOption("/plotOptions/areasplinerange", areaSplineRangePlotOptions.getOptions()) : + returnThis(); + } /** * Updates the options that all bar type series within the chart will use by default. The settings can then @@ -1231,6 +1278,25 @@ public abstract class BaseChart extends Widget { returnThis(); } + /** + * Updates the options that all column range type series within the chart will use by default. The settings can then + * be overridden for each individual series via the {@link Series#setPlotOptions(PlotOptions)} method. + *

+ * Note that changing the plot options on a chart that has already been rendered will only affect + * series that are subsequently added to the chart (and will not impact any of the series that are already + * rendered in the chart.) + * + * @param columnRangePlotOptions The options to set on the chart as the default settings for all column type series + * that are part of this chart. + * @return A reference to this {@link BaseChart} instance for convenient method chaining. + */ + public T setColumnRangePlotOptions(ColumnRangePlotOptions columnRangePlotOptions) { + this.columnRangePlotOptions = columnRangePlotOptions; + return columnRangePlotOptions != null && columnRangePlotOptions.getOptions() != null ? + this.setOption("/plotOptions/columnrange", columnRangePlotOptions.getOptions()) : + returnThis(); + } + /** * Updates the options that all line type series within the chart will use by default. The settings can then * be overridden for each individual series via the {@link Series#setPlotOptions(PlotOptions)} method. @@ -1800,6 +1866,19 @@ public abstract class BaseChart extends Widget { return null; } + /** + * Returns a pointer to the native Highcharts or Highstock chart instance that this GWT BaseChart + * instance is associated with. Note that this method will only return a non-null value if it + * is called after the chart has been rendered. For advanced use-cases only. + * + * @return The native Highcharts or Highstock JS chart instance that this BaseChart is associated with, or + * null if the chart has not yet been rendered. + * @since 1.4.0 + */ + public JavaScriptObject getNativeChart() { + return chart; + } + /** * Redraw the chart after changes have been done to the data or axis extremes. All methods for * updating axes, series or points have a parameter for redrawing the chart. This is true by default. @@ -1864,11 +1943,15 @@ public abstract class BaseChart extends Widget { // Build a similar object for dealing with all of the data label formatters that may be set on the plot options JSONObject plotOptionsLabelFormatters = new JSONObject(); plotOptionsLabelFormatters.put("area", hasDataLabelsFormatter(areaPlotOptions)); + plotOptionsLabelFormatters.put("arearange", hasDataLabelsFormatter(areaRangePlotOptions)); plotOptionsLabelFormatters.put("areaspline", hasDataLabelsFormatter(areaSplinePlotOptions)); + plotOptionsLabelFormatters.put("areasplinerange", hasDataLabelsFormatter(areaSplineRangePlotOptions)); plotOptionsLabelFormatters.put("bar", hasDataLabelsFormatter(barPlotOptions)); plotOptionsLabelFormatters.put("column", hasDataLabelsFormatter(columnPlotOptions)); + plotOptionsLabelFormatters.put("columnrange", hasDataLabelsFormatter(columnRangePlotOptions)); plotOptionsLabelFormatters.put("line", hasDataLabelsFormatter(linePlotOptions)); plotOptionsLabelFormatters.put("pie", hasDataLabelsFormatter(piePlotOptions)); + plotOptionsLabelFormatters.put("ohlc", hasDataLabelsFormatter(ohlcPlotOptions)); plotOptionsLabelFormatters.put("series", hasDataLabelsFormatter(seriesPlotOptions)); plotOptionsLabelFormatters.put("scatter", hasDataLabelsFormatter(scatterPlotOptions)); plotOptionsLabelFormatters.put("spline", hasDataLabelsFormatter(splinePlotOptions)); @@ -2012,7 +2095,7 @@ public abstract class BaseChart extends Widget { } private JavaScriptObject createNativeOptions() { - JSONObject options = configurable.getOptions(); + JSONObject options = getOptions(); if (options == null) { options = new JSONObject(); } @@ -2112,26 +2195,30 @@ public abstract class BaseChart extends Widget { options = new JSONObject(); addPointScalarValues(point, options); return addPointId(point, options); - } else if (point.getX() != null) { - JSONArray jsonArray = new JSONArray(); - jsonArray.set(0, new JSONNumber(point.getX().doubleValue())); - if (point.getY() != null) { - jsonArray.set(1, new JSONNumber(point.getY().doubleValue())); - } else { - if (point.getOpen() != null && point.getHigh() != null && point.getLow() != null && point.getClose() != null) { - jsonArray.set(1, new JSONNumber(point.getOpen().doubleValue())); - jsonArray.set(2, new JSONNumber(point.getHigh().doubleValue())); - jsonArray.set(3, new JSONNumber(point.getLow().doubleValue())); - jsonArray.set(4, new JSONNumber(point.getClose().doubleValue())); - } else { - jsonArray.set(1, JSONNull.getInstance()); - } - } - return jsonArray; - } else if (point.getY() != null) { - return new JSONNumber(point.getY().doubleValue()); - } else { - return JSONNull.getInstance(); + } + + JSONArray jsonArray = new JSONArray(); + switch (point.getType()) { + case Y: return convertNumberToJSONValue(point.getY()); + case X_Y : + jsonArray.set(0, convertNumberToJSONValue(point.getX())); + jsonArray.set(1, convertNumberToJSONValue(point.getY())); + return jsonArray; + case X_LOW_HIGH : + jsonArray.set(0, convertNumberToJSONValue(point.getX())); + jsonArray.set(1, convertNumberToJSONValue(point.getLow())); + jsonArray.set(2, convertNumberToJSONValue(point.getHigh())); + return jsonArray; + case X_OPEN_HIGH_LOW_CLOSE : + jsonArray.set(0, convertNumberToJSONValue(point.getX())); + jsonArray.set(1, convertNumberToJSONValue(point.getOpen())); + jsonArray.set(2, convertNumberToJSONValue(point.getHigh())); + jsonArray.set(3, convertNumberToJSONValue(point.getLow())); + jsonArray.set(4, convertNumberToJSONValue(point.getClose())); + return jsonArray; + default: + // Should not reach this statement based on the structure of the Point class constructors + throw new IllegalArgumentException("Unable to convert point to JSON due to an invalid type"); } } @@ -2150,29 +2237,38 @@ public abstract class BaseChart extends Widget { // Purposefully package scope static JSONValue addPointScalarValues(Point point, JSONObject options) { - if (point.getX() != null) { - options.put("x", new JSONNumber(point.getX().doubleValue())); - } - if (point.getY() != null) { - options.put("y", new JSONNumber(point.getY().doubleValue())); - } else { - options.put("y", JSONNull.getInstance()); - } - if (point.getOpen() != null) { - options.put("open", new JSONNumber(point.getOpen().doubleValue())); - } - if (point.getHigh() != null) { - options.put("high", new JSONNumber(point.getHigh().doubleValue())); - } - if (point.getLow() != null) { - options.put("low", new JSONNumber(point.getLow().doubleValue())); - } - if (point.getClose() != null) { - options.put("close", new JSONNumber(point.getClose().doubleValue())); - } + Point.Type type = point.getType(); + + if (type != Point.Type.Y) { + options.put("x", convertNumberToJSONValue(point.getX())); + } + + if (type == Point.Type.Y || type == Point.Type.X_Y) { + options.put("y", convertNumberToJSONValue(point.getY())); + } + + if (type == Point.Type.X_LOW_HIGH || type == Point.Type.X_OPEN_HIGH_LOW_CLOSE) { + options.put("high", convertNumberToJSONValue(point.getHigh())); + options.put("low", convertNumberToJSONValue(point.getLow())); + + if (type == Point.Type.X_OPEN_HIGH_LOW_CLOSE) { + options.put("open", convertNumberToJSONValue(point.getOpen())); + options.put("close", convertNumberToJSONValue(point.getClose())); + } + } + return options; } + // Purposefully package scope + static JSONValue convertNumberToJSONValue(Number number) { + if (number != null) { + return new JSONNumber(number.doubleValue()); + } else { + return JSONNull.getInstance(); + } + } + // Purposefully constrained to package scope JavaScriptObject get(String id) { if (isRendered()) { @@ -2460,10 +2556,14 @@ public abstract class BaseChart extends Widget { private String plotOptionsLabelsFormatterCallback(JavaScriptObject nativeData, String type) { PlotOptions plotOptions = null; if ("area".equals(type)) plotOptions = areaPlotOptions; + if ("arearange".equals(type)) plotOptions = areaRangePlotOptions; if ("areaspline".equals(type)) plotOptions = areaSplinePlotOptions; + if ("areasplinerange".equals(type)) plotOptions = areaSplineRangePlotOptions; if ("bar".equals(type)) plotOptions = barPlotOptions; if ("column".equals(type)) plotOptions = columnPlotOptions; + if ("columnrange".equals(type)) plotOptions = columnRangePlotOptions; if ("line".equals(type)) plotOptions = linePlotOptions; + if ("ohlc".equals(type)) plotOptions = ohlcPlotOptions; if ("pie".equals(type)) plotOptions = piePlotOptions; if ("scatter".equals(type)) plotOptions = scatterPlotOptions; if ("series".equals(type)) plotOptions = seriesPlotOptions; @@ -2486,24 +2586,6 @@ public abstract class BaseChart extends Widget { return seriesList.get(seriesIndex).getPlotOptions().getDataLabels().getFormatter().format(new DataLabelsData(nativeData)); } - /** - * Fixing a bug currently in the base Highcharts implementation regarding the placement of the checkbox in the legend. - * Requires the symbol padding (see {@link Legend#setSymbolPadding(Number)}) to be set to 25. Invoked - * whenever the chart is rendered.

- * - * The implementation moves the checkbox between the legend symbol and the legend item, using the space made by setting the symbol - * padding to 25px. - */ - private static native JavaScriptObject nativeAdjustCheckboxPosition(JavaScriptObject chart) /*-{ - var series = chart.series; - for(var i= 0; i extends Widget { private static native void nativeSetTitle(JavaScriptObject chart, JavaScriptObject title, JavaScriptObject subTitle) /*-{ chart.setTitle(title, subTitle); }-*/; + + /** + * Fixing a bug currently in the base Highcharts implementation regarding the placement of the checkbox in the legend. + * Requires the symbol padding (see {@link Legend#setSymbolPadding(Number)}) to be set to 25. Invoked + * whenever the chart is rendered.

+ * + * The implementation moves the checkbox between the legend symbol and the legend item, using the space made by setting the symbol + * padding to 25px. + */ + private static native JavaScriptObject nativeAdjustCheckboxPosition(JavaScriptObject chart) /*-{ + var series = chart.series; + for(var i= 0; i { super(); } + /** + * Convenience method for setting the 'pane' options of the chart, which represents + * a collection of options that apply only to polar charts and angular gauges. + *

+ * Note: mane of the pane options are only available if the highcharts-more.js script is included in your GWT module. E.g.: + *

+ * <script type="text/javascript" src="js/highcharts-more.js"></script> + * + * @param pane The pane options to apply to the chart. + * @return A reference to this {@link Chart} instance for convenient method chaining. + * @since 1.5.0 + */ + public Chart setPane(Pane pane) { + return this.setOption("/pane", pane != null ? pane.getOptions() : null); + } + + /** + * Convenience method for setting the 'polar' option of the chart. Equivalent to: + *

+     *     chart.setOption("/chart/polar", true);
+     * 
+ * When true, cartesian charts like line, spline, area and column are transformed + * into the polar coordinate system. Defaults to false. + *

+ * Note: this option is only available if the highcharts-more.js script is included in your GWT module. + *

+ * + * @param polar The value to set as the 'polar' option on the chart. + * @return A reference to this {@link Chart} instance for convenient method chaining. + * @since 1.5.0 + */ + public Chart setPolar(boolean polar) { + return this.setOption("/chart/polar", polar); + } + /** * Sets which dimensions the user can zoom by dragging the mouse. * Can be one of {@link Chart.ZoomType#X}, {@link Chart.ZoomType#Y} or @@ -125,7 +160,6 @@ public class Chart extends BaseChart { return this.setOption("/chart/zoomType", zoomType != null ? zoomType.toString() : null); } - @Override protected String getChartTypeName() { return "Chart"; diff --git a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/DateTimeLabelFormats.java b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/DateTimeLabelFormats.java index 5e5a95c4ab4..4b939cded45 100755 --- a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/DateTimeLabelFormats.java +++ b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/DateTimeLabelFormats.java @@ -71,6 +71,20 @@ package org.moxieapps.gwt.highcharts.client; */ public class DateTimeLabelFormats extends Configurable { + /** + * Convenience method for setting the 'millisecond' format. Equivalent to: + *

+     *     dateTimeLabelFormats.setOption("millisecond", "%H:%M:%S.%L");
+     * 
+ * + * @param millisecond The format to use when displaying labels in units of milliseconds. + * @return A reference to this {@link DateTimeLabelFormats} instance for convenient method chaining. + * @since 1.5.0 + */ + public DateTimeLabelFormats setMillisecond(String millisecond){ + return this.setOption("millisecond", millisecond); + } + /** * Convenience method for setting the 'second' format. Equivalent to: *

diff --git a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Global.java b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Global.java
new file mode 100644
index 00000000000..34f22df0333
--- /dev/null
+++ b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Global.java
@@ -0,0 +1,58 @@
+package org.moxieapps.gwt.highcharts.client;
+
+/**
+ * A configurable class that can be used to globally configure options for Highcharts.
+ * These options should be configured prior to the initialization of any chart instance.
+ * 

+ * Example usage: + *

+ *   Highcharts.setOptions(
+ *     new Highcharts.Options().setGlobal(
+ *         new Global()
+ *           .setUseUTC(false)
+ *   ));
+ * 
+ * + * @author myersj@gmail.com (Jeff Myers) + * @since 1.4.0 + */ +public class Global extends Configurable { + + /** + * Convenience method for setting the 'canvasToolsURL' global option. Equivalent to: + *

+     *     global.setOption("canvasToolsURL", "http://localhost/js/canvas-tools.js");
+     * 
+ * The URL to the additional file to lazy load for Android 2.x devices. These devices + * don't support SVG, so we download a helper file that contains canvg, its dependency + * rbcolor, and our own CanVG Renderer class. To avoid hot linking to the highcharts + * web site, you can install canvas-tools.js on your own server and change this option + * accordingly. + * Defaults to "http://www.highcharts.com/js/canvas-tools.js". + * + * @param canvasToolsURL URL of the canvas tools library + * @return A reference to this {@link org.moxieapps.gwt.highcharts.client.Global} instance for convenient method chaining. + */ + public Global setCanvasToolsURL(String canvasToolsURL) { + return this.setOption("canvasToolsURL", canvasToolsURL); + } + + /** + * Convenience method for setting the 'useUTC' global option. Equivalent to: + *

+     *     global.setOption("useUTC", false);
+     * 
+ * Whether to use UTC time for axis scaling, tickmark placement and time display in + * Highcharts.dateFormat. Advantages of using UTC is that the time displays equally + * regardless of the user agent's time zone settings. Local time can be used when the + * data is loaded in real time or when correct Daylight Saving Time transitions are + * required. Defaults to true. + * + * @param useUTC Flag to indicate whether time displays using UTC or not + * @return A reference to this {@link org.moxieapps.gwt.highcharts.client.Global} instance for convenient method chaining. + */ + public Global setUseUTC(boolean useUTC) { + return this.setOption("useUTC", useUTC); + } + +} diff --git a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Highcharts.java b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Highcharts.java new file mode 100644 index 00000000000..adf575768be --- /dev/null +++ b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Highcharts.java @@ -0,0 +1,82 @@ +package org.moxieapps.gwt.highcharts.client; + +import com.google.gwt.core.client.JavaScriptObject; + +/** + * A utility class that can be used to globally configure options for Highcharts. + * These options should be configured prior to the initialization of any chart instance. + *

+ * Example usage: + *

+ *   Highcharts.setOptions(
+ *     new Highcharts.Options().setGlobal(
+ *         new Global()
+ *           .setUseUTC(false)
+ *   ));
+ * 
+ * + * @author myersj@gmail.com (Jeff Myers) + * @since 1.4.0 + */ +public class Highcharts { + + /** + * A configurable class that can be used to globally configure options for Highcharts. + * These options should be configured prior to the initialization of any chart instance. + *

+ * Example usage: + *

+     *   Highcharts.setOptions(
+     *     new Highcharts.Options().setGlobal(
+     *         new Global()
+     *           .setUseUTC(false)
+     *   ));
+     * 
+ * + * @author myersj@gmail.com (Jeff Myers) + * @since 1.4.0 + */ + public static class Options extends Configurable { + + /** + * Set the global options to use on all Highchart instances. + * + * @param global the global configuration options + * @return A reference to this {@link org.moxieapps.gwt.highcharts.client.Highcharts.Options} instance for convenient method chaining. + */ + public Options setGlobal(Global global) { + return this.setOption("/global", global); + } + + /** + * Set the language options to use on all Highchart instances. + * + * @param lang the language configuration options + * @return A reference to this {@link org.moxieapps.gwt.highcharts.client.Highcharts.Options} instance for convenient method chaining. + */ + public Options setLang(Lang lang) { + return this.setOption("/lang", lang); + } + } + + /** + * Sets the options globally for all charts created after this has been called. + * + * @param options the global options to use + */ + public static void setOptions(Options options) { + nativeSetOptions(options.getOptions().getJavaScriptObject()); + } + + private native static JavaScriptObject nativeSetOptions(JavaScriptObject options) /*-{ + $wnd.Highcharts.setOptions(options); + }-*/; + + /** + * Private constructor to prevent instantiation. + */ + private Highcharts() { + // Do nothing + } + +} diff --git a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Lang.java b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Lang.java index 4525f6ccd41..52dcb2ca8b8 100755 --- a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Lang.java +++ b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Lang.java @@ -1,13 +1,294 @@ package org.moxieapps.gwt.highcharts.client; /** - * TODO + * A configurable class that can be used to globally configure the messages displayed by Highcharts. + * These options should be configured prior to the initialization of any chart instance. + *

+ * Example usage: + *

+ *   Highcharts.setOptions(
+ *     new Highcharts.Options().setLang(
+ *         new Lang()
+ *           .setMonths(new String[] { 'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin',
+ *             'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre' })
+ *           .setWeekdays(new String[] {'Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'})
+ *   ));
+ * 
* - * @author squinn@moxiegroup.com (Shawn Quinn) - * @since 1.0.0 + * @author myersj@gmail.com (Jeff Myers) + * @since 1.4.0 */ -public class Lang { +public class Lang extends Configurable { - // TODO + /** + * Expected array length of the months and shortMonths parameters. + */ + private static final int MONTH_PARAM_LENGTH = 12; + /** + * Expected array length of the weekdays parameter. + */ + private static final int WEEKDAYS_PARAM_LENGTH = 7; + + /** + * Convenience method for setting the 'decimalPoint' lang option. Equivalent to: + *

+     *     lang.setOption("decimalPoint", ",");
+     * 
+ * The default decimal point used in the Highcharts.numberFormat method unless otherwise + * specified in the function arguments. Defaults to ".". + * + * @param decimalPoint value to used as the decimal point by default when formatting numbers + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setDecimalPoint(String decimalPoint) { + return this.setOption("decimalPoint", decimalPoint); + } + + /** + * Convenience method for setting the 'downloadPNG' lang option. Equivalent to: + *

+     *     lang.setOption("downloadPNG", "PNG");
+     * 
+ * Exporting module only. The text for the PNG download menu item. Defaults to "Download PNG image". + * + * @param downloadPNG text for the PNG download menu item + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setDownloadPNG(String downloadPNG) { + return this.setOption("downloadPNG", downloadPNG); + } + + /** + * Convenience method for setting the 'downloadJPEG' lang option. Equivalent to: + *

+     *     lang.setOption("downloadJPEG", "JPEG");
+     * 
+ * Exporting module only. The text for the JPEG download menu item. Defaults to "Download JPEG image". + * + * @param downloadJPEG text for the JPEG download menu item + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setDownloadJPEG(String downloadJPEG) { + return this.setOption("downloadJPEG", downloadJPEG); + } + + /** + * Convenience method for setting the 'downloadPDF' lang option. Equivalent to: + *

+     *     lang.setOption("downloadPDF", "PDF");
+     * 
+ * Exporting module only. The text for the PDF download menu item. Defaults to "Download PDF document". + * + * @param downloadPDF text for the PDF download menu item + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setDownloadPDF(String downloadPDF) { + return this.setOption("downloadPDF", downloadPDF); + } + + /** + * Convenience method for setting the 'downloadSVG' lang option. Equivalent to: + *

+     *     lang.setOption("downloadSVG", "SVG");
+     * 
+ * Exporting module only. The text for the SVG download menu item. Defaults to "Download SVG vector image". + * + * @param downloadSVG text for the SVG download menu item + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setDownloadSVG(String downloadSVG) { + return this.setOption("downloadSVG", downloadSVG); + } + + /** + * Convenience method for setting the 'exportButtonTitle' lang option. Equivalent to: + *

+     *     lang.setOption("exportButtonTitle", "Export");
+     * 
+ * Exporting module only. The tooltip text for the export button. Defaults to "Export to raster or vector image". + * + * @param exportButtonTitle tooltip text for the export button + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setExportButtonTitle(String exportButtonTitle) { + return this.setOption("exportButtonTitle", exportButtonTitle); + } + + /** + * Convenience method for setting the 'loading' lang option. Equivalent to: + *

+     *     lang.setOption("loading", "Loading");
+     * 
+ * The loading text that appears when the chart is set into the loading state following a + * call to chart.showLoading. Defaults to "Loading...". + * + * @param loading loading text message + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setLoading(String loading) { + return this.setOption("loading", loading); + } + + /** + * Convenience method for setting the 'months' lang option. Equivalent to: + *

+     *     lang.setOption("months", months);
+     * 
+ * An array containing the months names. Defaults to ['January', 'February', 'March', + * 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']. + * + * @param months array containing the months names + * @return A reference to this {@link Lang} instance for convenient method chaining. + * @throws IllegalArgumentException if months param is null or not exactly 12 items. + */ + public Lang setMonths(String[] months) { + if (months == null || months.length != MONTH_PARAM_LENGTH) { + throw new IllegalArgumentException("Month values incomplete"); + } + + return this.setOption("months", months); + } + + /** + * Convenience method for setting the 'shortMonths' lang option. Equivalent to: + *

+     *     lang.setOption("shortMonths", shortMonths);
+     * 
+ * An array containing the months names in abbreviated form. Corresponds to the %b + * format in Highcharts.dateFormat(). Defaults to ['Jan', 'Feb', 'Mar', 'Apr', 'May', + * 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']. + * + * @param shortMonths array containing the months names in abbreviated form + * @return A reference to this {@link Lang} instance for convenient method chaining. + * @throws IllegalArgumentException if shortMonths param is null or not exactly 12 items. + */ + public Lang setShortMonths(String[] shortMonths) { + if (shortMonths == null || shortMonths.length != MONTH_PARAM_LENGTH) { + throw new IllegalArgumentException("Short Month values incomplete"); + } + + return this.setOption("shortMonths", shortMonths); + } + + /** + * Convenience method for setting the 'printButtonTitle' lang option. Equivalent to: + *

+     *     lang.setOption("printButtonTitle", "Print");
+     * 
+ * Exporting module only. The tooltip text for the print button. Defaults to "Print the chart". + * + * @param printButtonTitle tooltip text for the print button + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setPrintButtonTitle(String printButtonTitle) { + return this.setOption("printButtonTitle", printButtonTitle); + } + + /** + * Convenience method for setting the 'rangeSelectorFrom' lang option. Equivalent to: + *

+     *     lang.setOption("rangeSelectorFrom", "Start");
+     * 
+ * StockChart only. The text for the label for the "from" input box in the range selector. + * Defaults to "From". + * + * @param rangeSelectorFrom text for the label for the "from" input box + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setRangeSelectorFrom(String rangeSelectorFrom) { + return this.setOption("rangeSelectorFrom", rangeSelectorFrom); + } + + /** + * Convenience method for setting the 'rangeSelectorTo' lang option. Equivalent to: + *

+     *     lang.setOption("rangeSelectorTo", "End");
+     * 
+ * StockChart only. The text for the label for the "to" input box in the range selector. + * Defaults to "To". + * + * @param rangeSelectorTo text for the label for the "to" input box + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setRangeSelectorTo(String rangeSelectorTo) { + return this.setOption("rangeSelectorTo", rangeSelectorTo); + } + + /** + * Convenience method for setting the 'rangeSelectorZoom' lang option. Equivalent to: + *

+     *     lang.setOption("rangeSelectorZoom", "zoom");
+     * 
+ * StockChart only. The text for the label for the range selector buttons. Defaults to "Zoom". + * + * @param rangeSelectorZoom text for the label for the range selector buttons + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setRangeSelectorZoom(String rangeSelectorZoom) { + return this.setOption("rangeSelectorZoom", rangeSelectorZoom); + } + + /** + * Convenience method for setting the 'resetZoom' lang option. Equivalent to: + *

+     *     lang.setOption("resetZoom", "Reset");
+     * 
+ * The text for the label appearing when a chart is zoomed. Defaults to "Reset zoom". + * + * @param resetZoom text for the label appearing when a chart is zoomed + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setResetZoom(String resetZoom) { + return this.setOption("resetZoom", resetZoom); + } + + /** + * Convenience method for setting the 'resetZoomTitle' lang option. Equivalent to: + *

+     *     lang.setOption("resetZoomTitle", "Reset");
+     * 
+ * The tooltip title for the label appearing when a chart is zoomed. Defaults to "Reset zoom level 1:1." + * + * @param resetZoomTitle tooltip title for the label appearing when a chart is zoomed + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setResetZoomTitle(String resetZoomTitle) { + return this.setOption("resetZoomTitle", resetZoomTitle); + } + + /** + * Convenience method for setting the 'thousandsSep' lang option. Equivalent to: + *

+     *     lang.setOption("thousandsSep", ".");
+     * 
+ * The default thousands separator used in the Highcharts.numberFormat method unless + * otherwise specified in the function arguments. Defaults to ",". + * + * @param thousandsSep value to used as the thousands separator by default when formatting numbers + * @return A reference to this {@link Lang} instance for convenient method chaining. + */ + public Lang setThousandsSep(String thousandsSep) { + return this.setOption("thousandsSep", thousandsSep); + } + + /** + * Convenience method for setting the 'weekdays' lang option. Equivalent to: + *

+     *     lang.setOption("weekdays", weekdays);
+     * 
+ * An array containing the weekday names. Defaults to ['Sunday', 'Monday', 'Tuesday', + * 'Wednesday', 'Thursday', 'Friday', 'Saturday']. + * + * @param weekdays array containing the weekday names + * @return A reference to this {@link Lang} instance for convenient method chaining. + * @throws IllegalArgumentException if weekdays param is null or not exactly 7 items. + */ + public Lang setWeekdays(String[] weekdays) { + if (weekdays == null || weekdays.length != WEEKDAYS_PARAM_LENGTH) { + throw new IllegalArgumentException("Weekdays values incomplete"); + } + + return this.setOption("weekdays", weekdays); + } } diff --git a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Navigator.java b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Navigator.java new file mode 100644 index 00000000000..e34b86533c1 --- /dev/null +++ b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Navigator.java @@ -0,0 +1,214 @@ +/* + * Copyright 2011 Moxie Group + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.moxieapps.gwt.highcharts.client; + +import com.google.gwt.json.client.JSONObject; + +/** + * The navigator is a small series below the main series, displaying a view of the entire data set. It provides tools + * to zoom in and out on parts of the data as well as panning across the dataset. Applies only to {@link org.moxieapps.gwt.highcharts.client.StockChart}. + * + * @author myersj@gmail.com (Jeff Myers) + * @since 1.5.0 + */ +public class Navigator extends Configurable { + + private final Series series; + private final XAxis xAxis; + private final YAxis yAxis; + + /** + * Use the {@link org.moxieapps.gwt.highcharts.client.StockChart#getNavigator()} method to get access to the Navigator of the chart. + * + * @param stockChart The chart instance that this navigator is being created within. + * @param series The chart series used for the navigator display + */ + Navigator(StockChart stockChart, Series series) { + this.series = series; + this.xAxis = new XAxis(stockChart); + this.yAxis = new YAxis(stockChart); + + // Link the internal configurable instances to be part of this configurable instance + setOption("series", this.series); + setOption("xAxis", this.xAxis); + setOption("yAxis", this.yAxis); + } + + /** + * Access the navigator series, to allow for customization via the {@link Series#setPlotOptions(org.moxieapps.gwt.highcharts.client.plotOptions.PlotOptions)} + * method. + *

+     * stockChart.getNavigator().getSeries()
+     *   .setType(Series.Type.LINE)
+     *   .setPlotOptions(new LinePlotOptions()
+     *      .setColor("#0000ff")
+     *      .setLineWidth(2));
+     * 
+ * + * @return the navigator series. + */ + public Series getSeries() { + return series; + } + + /** + * Access the navigator X axis, to allow for customization. + *

+     * stockChart.getNavigator().getXAxis()
+     *    .setOpposite(true)
+     *    .setTickWidth(1)
+     *    .setTickColor("#eeeeee");
+     * 
+ * + * @return the navigator X axis. + */ + public XAxis getXAxis() { + return xAxis; + } + + /** + * Access the navigator Y axis, to allow for customization. + *

+     * stockChart.getNavigator().getYAxis()
+     *    .setOpposite(true)
+     *    .setTickWidth(1)
+     *    .setTickColor("#eeeeee");
+     * 
+ * + * @return the navigator Y axis. + */ + public YAxis getYAxis() { + return yAxis; + } + + /** + * When this option is true, the navigator will redraw and reposition when data is updated in the main + * chart. When loading data asynchronously from the server depending on zoomed range, this option + * must be set to false in order to prevent looping. Defaults to true. + * + * @param adaptToUpdatedData true to redraw and reposition on data update, false to disable. + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setAdaptToUpdatedData(boolean adaptToUpdatedData) { + return this.setOption("adaptToUpdatedData", adaptToUpdatedData); + } + + /** + * Specify the index of the base series for the navigator. The base series will be used to provide + * data for the navigator. Defaults to 0. + * + * @param seriesIndex index of the base series + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setBaseSeries(Number seriesIndex) { + return this.setOption("baseSeries", seriesIndex); + } + + /** + * Specify the ID of the base series for the navigator. The base series will be used to provide + * data for the navigator. + * + * @param seriesId ID of the base series + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setBaseSeries(String seriesId) { + return this.setOption("baseSeries", seriesId); + } + + /** + * Enable or disable the navigator. Defaults to true. + * + * @param enabled true to enable the range selector, false to disable. + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setEnabled(boolean enabled) { + return this.setOption("enabled", enabled); + } + + /** + * Set the background color of the navigator handles. + * + * @param color the background color to set + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setHandlesBackgroundColor(String color) { + return this.setOption("handles/backgroundColor", color); + } + + /** + * Set the border color of the navigator handles. + * + * @param color the border color to set + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setHandlesBorderColor(String color) { + return this.setOption("handles/borderColor", color); + } + + /** + * Set the height of the navigator. Defaults to 40. + * + * @param height the height value to set (in pixels) + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setHeight(Number height) { + return this.setOption("height", height); + } + + /** + * Set the distance from the nearest element, the X axis or X axis labels. Defaults to 10. + * + * @param margin the margin distance value to set (in pixels) + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setMargin(Number margin) { + return this.setOption("margin", margin); + } + + /** + * Set the color mask covering the areas of the navigator series that are currently not visible in the + * main series. The default color is white with an opacity of 0.75 to see the series below. Defaults to + * "rgba(255, 255, 255, 0.75)" + * + * @param maskFillColor the color of the mask fill to set + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setMaskFill(String maskFillColor) { + return this.setOption("maskFill", maskFillColor); + } + + /** + * Set the color of the line marking the currently zoomed area in the navigator. Defaults to #444. + * + * @param outlineColor the outline color to set + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setOutlineColor(String outlineColor) { + return this.setOption("outlineColor", outlineColor); + } + + /** + * Set the width of the line marking the currently zoomed area in the navigator. Defaults to 2. + * + * @param outlineWidth the outlineWidth value to set (in pixels) + * @return A reference to this {@link Navigator} instance for convenient method chaining. + */ + public Navigator setOutlineWidth(Number outlineWidth) { + return this.setOption("outlineWidth", outlineWidth); + } + +} \ No newline at end of file diff --git a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Pane.java b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Pane.java new file mode 100644 index 00000000000..dcb734b821a --- /dev/null +++ b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Pane.java @@ -0,0 +1,49 @@ +package org.moxieapps.gwt.highcharts.client; + +/** + * A configurable class that will allow you to control the pane options of the charts, which + * applies only to polar charts and angular gauges. This configuration object holds general + * options for the combined X and Y axes set. Each xAxis or yAxis can reference the pane by index. + * An instance of this class can be constructed and then + * set on the chart via the {@link org.moxieapps.gwt.highcharts.client.Chart#setPane(Pane)} method. + *

+ * Note: mane of the pane options are only available if the highcharts-more.js script is included in your GWT module. E.g.: + *

+ * <script type="text/javascript" src="js/highcharts-more.js"></script> + * + * @author squinn@moxiegroup.com (Shawn Quinn) + * @since 1.5.0 + */ +public class Pane extends Configurable { + + /** + * Convenience method for setting the 'startAngle' option of the pane. Equivalent to: + *

+     *     pane.setOption("startAngle", 90);
+     * 
+ * The start angle of the polar X axis or gauge axis, given in degrees where 0 is north. Defaults to 0. + * + * @param startAngle The start angle fo the polar X axis of the chart. + * @return A reference to this {@link Pane} instance for convenient method chaining. + */ + public Pane setStartAngle(Number startAngle) { + return this.setOption("startAngle", startAngle); + } + + /** + * Convenience method for setting the 'endAngle' option of the pane. Equivalent to: + *

+     *     pane.setOption("endAngle", 180);
+     * 
+ * The end angle of the polar X axis or gauge value axis, given in degrees where 0 is north. Defaults to startAngle + 360. + * + * @param endAngle The end angle of the polar X axis or gauge value axis. + * @return A reference to this {@link Pane} instance for convenient method chaining. + */ + public Pane setEndAngle(Number endAngle) { + return this.setOption("endAngle", endAngle); + } + + // TODO: Add 'background' and 'center' configuration methods + +} diff --git a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Point.java b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Point.java index 28bf6d67aab..75465f9db0f 100644 --- a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Point.java +++ b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/Point.java @@ -61,6 +61,36 @@ import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; * @since 1.0.0 */ public class Point extends Configurable { + + /** + * An enumeration describing the type of data contained within the Point. Retrievable via + * {@link Point#getType()}. (The type is purposefully restricted to package scope to hide + * this as an implementation detail since an equivalent concept doesn't exist in the core + * Highcharts API, but exposing this enum could be reconsidered if a use case was identified.) + */ + static enum Type { + /** + * Indicates the point contains only a Y value + */ + Y, + + /** + * Indicates the point contains an X and Y value + */ + X_Y, + + /** + * Indicates the point contains an X, Low and High values + */ + X_LOW_HIGH, + + /** + * Indicates the point contains an X, Open, High, Low, and Close values + */ + X_OPEN_HIGH_LOW_CLOSE + } + + private final Type type; private Number y; private Number x; @@ -77,6 +107,7 @@ public class Point extends Configurable { */ public Point(Number y) { this.y = y; + this.type = Type.Y; } /** @@ -89,6 +120,23 @@ public class Point extends Configurable { public Point(Number x, Number y) { this.x = x; this.y = y; + this.type = Type.X_Y; + } + + /** + * Create a new point for an area range / area range spline chart, setting the x and low / high y values. + * + * @param x The X value that the point should be rendered at within the series. + * @param low The "low" Y value that the point should be rendered at within the series. + * @param high The "high" Y value that the point should be rendered at within the series. + * + * @since 1.5.0 + */ + public Point(Number x, Number low, Number high) { + this.x = x; + this.low = low; + this.high = high; + this.type = Type.X_LOW_HIGH; } /** @@ -107,11 +155,13 @@ public class Point extends Configurable { this.high = high; this.low = low; this.close = close; + this.type = Type.X_OPEN_HIGH_LOW_CLOSE; } /** * Create a new point, setting the Y axis value that the point should be - * rendered at within the series as well as the "name" property of the point. + * rendered at within the series as well as the "name" property of the point + * (which is often the case for pie charts.) * * @param name The value to set as the "property" of the point. * @param y The Y value that the point should be rendered at within the series. @@ -119,6 +169,7 @@ public class Point extends Configurable { public Point(String name, Number y) { setName(name); this.y = y; + this.type = Type.Y; } @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) @@ -132,6 +183,20 @@ public class Point extends Configurable { */ public Point(JavaScriptObject nativePoint) { this.nativePoint = nativePoint; + this.type = determineType(nativePoint); + } + + /** + * Retrieve the type of data stored within this Point instance (purposefully restricted to + * package scope to hide this as an implementation detail since the concept doesn't exist + * in the core Highcharts API, but exposing this properly could be reconsidered if a + * use case was identified.) + * + * @return The point's type + * @since 1.5.0 + */ + Type getType() { + return type; } /** @@ -369,7 +434,6 @@ public class Point extends Configurable { * Also note that when using persistent chart's, you'll normally want to use the * {@link Series#removePoint(Point)} method instead of this one. * - * * @return A reference to this {@link Point} instance for convenient method chaining. * @since 1.1.0 */ @@ -600,6 +664,20 @@ public class Point extends Configurable { public Point update(Number x, Number y) { return this.update(new Point(x, y)); } + + /** + * Update the point with the new values, automatically redrawing + * the chart with the default animation options. + * + * @param x The new x value for the point. + * @param low The new low value for the point. + * @param high The new high value for the point. + * @return A reference to this {@link Point} instance for convenient method chaining. + * @since 1.5.0 + */ + public Point update(Number x, Number low, Number high) { + return this.update(new Point(x, low, high)); + } /** * Update the point with the new values, specifying whether or not the chart should be automatically @@ -631,6 +709,23 @@ public class Point extends Configurable { public Point update(Number x, Number y, boolean redraw) { return this.update(new Point(x, y), redraw, true); } + + /** + * Update the point with the new values, specifying whether or not the chart should be automatically + * redrawn with the new values. + * + * @param x The new x value for the point. + * @param low The new low value for the point. + * @param high The new high value for the point. + * @param redraw Whether to redraw the chart after the point is updated. When updating more than one + * point, it is highly recommended that the redraw option be set to false, and instead + * {@link Chart#redraw()} is explicitly called after the updating of points is finished. + * @return A reference to this {@link Point} instance for convenient method chaining. + * @since 1.5.0 + */ + public Point update(Number x, Number low, Number high, boolean redraw) { + return this.update(new Point(x, low, high), redraw, true); + } /** * Update the point with the new values and options from the given point, automatically redrawing @@ -745,7 +840,7 @@ public class Point extends Configurable { // Internal method purposefully package scope String getId() { - if(this.nativePoint != null) { + if (this.nativePoint != null) { return nativeGetString(this.nativePoint, "id"); } else { return this.id; @@ -755,14 +850,79 @@ public class Point extends Configurable { private static JavaScriptObject convertPointToJavaScriptObject(Point point) { final JSONObject options = point.getOptions() != null ? point.getOptions() : new JSONObject(); Chart.addPointScalarValues(point, options); - if(point.hasNativeProperties()) { + if (point.hasNativeProperties()) { Point.addPointNativeProperties(point, options); } return options.getJavaScriptObject(); } + private static Type determineType(JavaScriptObject nativePoint) { + boolean hasX = nativeContainsKey(nativePoint, "x"); + boolean hasY = nativeContainsKey(nativePoint, "y"); + boolean hasLow = nativeContainsKey(nativePoint, "low"); + boolean hasHigh = nativeContainsKey(nativePoint, "high"); + boolean hasOpen = nativeContainsKey(nativePoint, "open"); + boolean hasClose = nativeContainsKey(nativePoint, "close"); + + if (hasX && hasOpen && hasHigh && hasLow && hasClose) { + return Type.X_OPEN_HIGH_LOW_CLOSE; + } + if (hasX && hasLow && hasHigh) { + return Type.X_LOW_HIGH; + } + if (hasX && hasY) { + return Type.X_Y; + } + if (hasY) { + return Type.Y; + } + + // Fall back on determining based on data array length + int dataLength = nativeGetDataLength(nativePoint); + switch (dataLength) { + case 1: + return Type.Y; + case 2: + return Type.X_Y; + case 3: + return Type.X_LOW_HIGH; + case 5: + return Type.X_OPEN_HIGH_LOW_CLOSE; + default: + // Assuming the most basic case if the value is null + return Type.Y; + } + } + + /** + * Returns a pointer to the native Highchart's JS point instance + * that this GWT Point instance is associated with. Note that this method will only return + * a non-null value if it is called on a Point instance that was retrieved from the chart + * after the chart has been rendered, such as via a {@link org.moxieapps.gwt.highcharts.client.events.PointEvent} + * or {@link org.moxieapps.gwt.highcharts.client.Series#getPoints()}. For advanced use-cases only. + * + * @return The native Highcharts JS point instance that this point is associated with, or + * null if the Point instance was not retrieved dynamically from a rendered chart. + * @since 1.4.0 + */ + public JavaScriptObject getNativePoint() { + return this.nativePoint; + } + private static native boolean nativeContainsKey(JavaScriptObject point, String key) /*-{ - return point[key] != undefined; + return (typeof key !== "undefined" && point != null && point[key] != null); + }-*/; + + private static native int nativeGetDataLength(JavaScriptObject point) /*-{ + if(point == null){ + return -1; + } + + if (typeof point.data === "undefined" || typeof point.data.length === "undefined") { + return -1; + } else { + return point.data.length; + } }-*/; private static native double nativeGetNumber(JavaScriptObject point, String key) /*-{ diff --git a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/RangeSelector.java b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/RangeSelector.java index de01edf858f..c95287e298e 100755 --- a/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/RangeSelector.java +++ b/java/org.moxieapps.gwt.highcharts/src/org/moxieapps/gwt/highcharts/client/RangeSelector.java @@ -17,20 +17,165 @@ package org.moxieapps.gwt.highcharts.client; /** - * TODO: This is a place holder class which will be formalized once the Highstock - * library is released. + * The range selector is a tool for selecting ranges to display within a {@link org.moxieapps.gwt.highcharts.client.StockChart}. It provides buttons to select + * preconfigured ranges in the chart, like 1 day, 1 week, 1 month, etc. It also provides input boxes where min + * and max dates can be manually input. + * Basic usage is as follows: + *

+ * stockChart.setRangeSelector(new RangeSelector()
+ *    .setButtons(
+ *       new RangeSelector.Button()
+ *          .setButtonType(RangeSelector.ButtonType.DAY)
+ *          .setCount(1)
+ *          .setText("1d"),
+ *       new RangeSelector.Button()
+ *          .setButtonType(RangeSelector.ButtonType.WEEK)
+ *          .setCount(2)
+ *          .setText("2w"),
+ *       new RangeSelector.Button()
+ *          .setButtonType(RangeSelector.ButtonType.MONTH)
+ *          .setCount(3)
+ *          .setText("2m")
+ *    )
+ *    .setSelected(1)
+ *    .setButtonSpacing(10));
+ * 
* - * @author squinn@moxiegroup.com (Shawn Quinn) - * @since 1.0.0 + * @author myersj@gmail.com (Jeff Myers) + * @since 1.5.0 */ public class RangeSelector extends Configurable { - - public RangeSelector setSelected(Number selected) { - return this.setOption("selected", selected); + + /** + * An enumeration of supported range selector button types, which can be used with the {@link RangeSelector.Button#setType(RangeSelector.ButtonType)} method. + */ + public static enum ButtonType { + MILLISECOND("millisecond"), + SECOND("second"), + MINUTE("minute"), + DAY("day"), + WEEK("week"), + MONTH("month"), + YTD("ytd"), + YEAR("year"), + ALL("all"); + + private final String optionName; + + private ButtonType(String optionName) { + this.optionName = optionName; + } + + @Override + public String toString() { + return optionName; + } } - + + /** + * Manages the options for configuring the buttons to show within the {@link RangeSelector} of + * a {@link org.moxieapps.gwt.highcharts.client.StockChart}. For example, to create a button to display a 6 month time selection: + *

+     *    new RangeSelector.Button()
+     *       .setType(RangeSelector.ButtonType.MONTH)
+     *       .setCount(6)
+     *       .setText("6m");
+     * 
+ * + * @see RangeSelector#setButtons(RangeSelector.Button...) + */ + public static class Button extends Configurable
') - .insertBefore($container) - .click(function () { - if (origChartWidth === UNDEFINED) { - origChartWidth = chartWidth; - origChartHeight = chartHeight; - } - chart.resize(chartWidth *= 1.1, chartHeight *= 1.1); - }); - $('') - .insertBefore($container) - .click(function () { - if (origChartWidth === UNDEFINED) { - origChartWidth = chartWidth; - origChartHeight = chartHeight; - } - chart.resize(chartWidth *= 0.9, chartHeight *= 0.9); - }); - $('') - .insertBefore($container) - .click(function () { - if (origChartWidth === UNDEFINED) { - origChartWidth = chartWidth; - origChartHeight = chartHeight; - } - chart.resize(origChartWidth, origChartHeight); - }); - } - }) - */ - - - - - firstRender(); - - -} // end Chart +}; // end Chart // Hook for exporting module Chart.prototype.callbacks = []; @@ -10092,11 +11198,7 @@ Point.prototype = { if (series.options.colorByPoint) { defaultColors = series.chart.options.colors; - if (!point.options) { - point.options = {}; - } - point.color = point.options.color = point.color || defaultColors[counters.color++]; - + point.color = point.color || defaultColors[counters.color++]; // loop back to zero counters.wrapColor(defaultColors.length); } @@ -10133,6 +11235,11 @@ Point.prototype = { if (options.dataLabels) { series._hasPointLabels = true; } + + // Same approach as above for markers + if (options.marker) { + series._hasPointMarkers = true; + } } else if (typeof options[0] === 'string') { // categorized data with name in first position point.name = options[0]; point.y = options[1]; @@ -10147,8 +11254,6 @@ Point.prototype = { point.x = x === UNDEFINED ? series.autoIncrement() : x; } - - }, /** @@ -10197,7 +11302,7 @@ Point.prototype = { */ destroyElements: function () { var point = this, - props = ['graphic', 'tracker', 'dataLabel', 'group', 'connector', 'shadowGroup'], + props = ['graphic', 'tracker', 'dataLabel', 'dataLabelUpper', 'group', 'connector', 'shadowGroup'], prop, i = 6; while (i--) { @@ -10281,11 +11386,15 @@ Point.prototype = { }, onMouseOut: function () { - var point = this; - point.firePointEvent('mouseOut'); - - point.setState(); - point.series.chart.hoverPoint = null; + var chart = this.series.chart, + hoverPoints = chart.hoverPoints; + + if (!hoverPoints || inArray(this, hoverPoints) === -1) { // #887 + this.firePointEvent('mouseOut'); + + this.setState(); + chart.hoverPoint = null; + } }, /** @@ -10297,16 +11406,29 @@ Point.prototype = { var point = this, series = point.series, seriesTooltipOptions = series.tooltipOptions, - split = String(point.y).split('.'), - originalDecimals = split[1] ? split[1].length : 0, match = pointFormat.match(/\{(series|point)\.[a-zA-Z]+\}/g), splitter = /[{\.}]/, obj, key, replacement, + repOptionKey, parts, prop, - i; + i, + cfg = { + y: 0, // 0: use 'value' for repOptionKey + open: 0, + high: 0, + low: 0, + close: 0, + percentage: 1, // 1: use the self name for repOptionKey + total: 1 + }; + + // Backwards compatibility to y naming in early Highstock + seriesTooltipOptions.valuePrefix = seriesTooltipOptions.valuePrefix || seriesTooltipOptions.yPrefix; + seriesTooltipOptions.valueDecimals = pick(seriesTooltipOptions.valueDecimals, seriesTooltipOptions.yDecimals); // #1248 + seriesTooltipOptions.valueSuffix = seriesTooltipOptions.valueSuffix || seriesTooltipOptions.ySuffix; // loop over the variables defined on the form {series.name}, {point.y} etc for (i in match) { @@ -10319,11 +11441,11 @@ Point.prototype = { prop = parts[2]; // Add some preformatting - if (obj === point && (prop === 'y' || prop === 'open' || prop === 'high' || - prop === 'low' || prop === 'close')) { - replacement = (seriesTooltipOptions.valuePrefix || seriesTooltipOptions.yPrefix || '') + - numberFormat(point[prop], pick(seriesTooltipOptions.valueDecimals, seriesTooltipOptions.yDecimals, originalDecimals)) + - (seriesTooltipOptions.valueSuffix || seriesTooltipOptions.ySuffix || ''); + if (obj === point && cfg.hasOwnProperty(prop)) { + repOptionKey = cfg[prop] ? prop : 'value'; + replacement = (seriesTooltipOptions[repOptionKey + 'Prefix'] || '') + + numberFormat(point[prop], pick(seriesTooltipOptions[repOptionKey + 'Decimals'], -1)) + + (seriesTooltipOptions[repOptionKey + 'Suffix'] || ''); // Automatic replacement } else { @@ -10374,7 +11496,7 @@ Point.prototype = { for (i = 0; i < dataLength; i++) { if (data[i] === point) { series.xData[i] = point.x; - series.yData[i] = point.y; + series.yData[i] = point.toYData ? point.toYData() : point.y; series.options.data[i] = options; break; } @@ -10535,28 +11657,29 @@ Point.prototype = { } else { // if a graphic is not applied to each point in the normal state, create a shared // graphic for the hover state - if (state) { - if (!stateMarkerGraphic) { - radius = markerOptions.radius; + if (state && markerStateOptions) { + radius = markerStateOptions.radius; + if (!stateMarkerGraphic) { // add series.stateMarkerGraphic = stateMarkerGraphic = chart.renderer.symbol( series.symbol, - -radius, - -radius, + plotX - radius, + plotY - radius, 2 * radius, 2 * radius ) .attr(pointAttr[state]) - .add(series.group); + .add(series.markerGroup); + + } else { // update + stateMarkerGraphic.attr({ // #1054 + x: plotX - radius, + y: plotY - radius + }); } - - stateMarkerGraphic.translate( - plotX, - plotY - ); } if (stateMarkerGraphic) { - stateMarkerGraphic[state ? 'show' : 'hide'](); + stateMarkerGraphic[state && chart.isInsidePlot(plotX, plotY) ? 'show' : 'hide'](); } } @@ -10591,6 +11714,7 @@ Series.prototype = { type: 'line', pointClass: Point, sorted: true, // requires the data to be sorted + requireSorting: true, pointAttrToOptions: { // mapping between SVG attributes and the corresponding options stroke: 'lineColor', 'stroke-width': 'lineWidth', @@ -10600,9 +11724,7 @@ Series.prototype = { init: function (chart, options) { var series = this, eventType, - events, - //pointEvent, - index = chart.series.length; + events; series.chart = chart; series.options = options = series.setOptions(options); // merge with plotOptions @@ -10612,8 +11734,7 @@ Series.prototype = { // set some variables extend(series, { - index: index, - name: options.name || 'Series ' + (index + 1), + name: options.name, state: NORMAL_STATE, pointAttr: {}, visible: options.visible !== false, // true by default @@ -10643,11 +11764,25 @@ Series.prototype = { // set the data series.setData(options.data, false); + + // Mark cartesian + if (series.isCartesian) { + chart.hasCartesianSeries = true; + } + // Register it in the chart + chart.series.push(series); + + // Sort series according to index option (#248, #1123) + stableSort(chart.series, function (a, b) { + return (a.options.index || 0) - (b.options.index || 0); + }); + each(chart.series, function (series, i) { + series.index = i; + series.name = series.name || 'Series ' + (i + 1); + }); }, - - /** * Set the xAxis and yAxis properties of cartesian series, and register the series * in the axis.series array @@ -10752,17 +11887,17 @@ Series.prototype = { * @param {Object} itemOptions */ setOptions: function (itemOptions) { - var series = this, - chart = series.chart, + var chart = this.chart, chartOptions = chart.options, plotOptions = chartOptions.plotOptions, + typeOptions = plotOptions[this.type], data = itemOptions.data, options; itemOptions.data = null; // remove from merge to prevent looping over the data set options = merge( - plotOptions[this.type], + typeOptions, plotOptions.series, itemOptions ); @@ -10771,7 +11906,12 @@ Series.prototype = { options.data = itemOptions.data = data; // the tooltip options are merged between global and series specific options - series.tooltipOptions = merge(chartOptions.tooltip, options.tooltip); + this.tooltipOptions = merge(chartOptions.tooltip, options.tooltip); + + // Delte marker object if not allowed (#1125) + if (typeOptions.marker === null) { + delete options.marker; + } return options; @@ -10780,9 +11920,11 @@ Series.prototype = { * Get the series' color */ getColor: function () { - var defaultColors = this.chart.options.colors, + var options = this.options, + defaultColors = this.chart.options.colors, counters = this.chart.counters; - this.color = this.options.color || defaultColors[counters.color++] || '#0000ff'; + this.color = options.color || + (!options.colorByPoint && defaultColors[counters.color++]) || 'gray'; counters.wrapColor(defaultColors.length); }, /** @@ -10803,6 +11945,59 @@ Series.prototype = { counters.wrapSymbol(defaultSymbols.length); }, + /** + * Get the series' symbol in the legend. This method should be overridable to create custom + * symbols through Highcharts.seriesTypes[type].prototype.drawLegendSymbols. + * + * @param {Object} legend The legend object + */ + drawLegendSymbol: function (legend) { + + var options = this.options, + markerOptions = options.marker, + radius, + legendOptions = legend.options, + legendSymbol, + symbolWidth = legendOptions.symbolWidth, + renderer = this.chart.renderer, + legendItemGroup = this.legendGroup, + baseline = legend.baseline, + attr; + + // Draw the line + if (options.lineWidth) { + attr = { + 'stroke-width': options.lineWidth + }; + if (options.dashStyle) { + attr.dashstyle = options.dashStyle; + } + this.legendLine = renderer.path([ + M, + 0, + baseline - 4, + L, + symbolWidth, + baseline - 4 + ]) + .attr(attr) + .add(legendItemGroup); + } + + // Draw the marker + if (markerOptions && markerOptions.enabled) { + radius = markerOptions.radius; + this.legendSymbol = legendSymbol = renderer.symbol( + this.symbol, + (symbolWidth / 2) - radius, + baseline - 4 - radius, + 2 * radius, + 2 * radius + ) + .add(legendItemGroup); + } + }, + /** * Add a point dynamically after chart load time * @param {Object} options Point options as given in series.data @@ -10814,6 +12009,7 @@ Series.prototype = { */ addPoint: function (options, redraw, shift, animation) { var series = this, + seriesOptions = series.options, data = series.data, graph = series.graph, area = series.area, @@ -10821,9 +12017,9 @@ Series.prototype = { xData = series.xData, yData = series.yData, currentShift = (graph && graph.shift) || 0, - dataOptions = series.options.data, - point; - //point = (new series.pointClass()).init(series, options); + dataOptions = seriesOptions.data, + point, + proto = series.pointClass.prototype; setAnimation(animation, chart); @@ -10844,11 +12040,15 @@ Series.prototype = { // Get options and push the point to xData, yData and series.options. In series.generatePoints // the Point instance will be created on demand and pushed to the series.data array. point = { series: series }; - series.pointClass.prototype.applyOptions.apply(point, [options]); + proto.applyOptions.apply(point, [options]); xData.push(point.x); - yData.push(series.valueCount === 4 ? [point.open, point.high, point.low, point.close] : point.y); + yData.push(proto.toYData ? proto.toYData.call(point) : point.y); dataOptions.push(options); + // Generate points to be added to the legend (#1329) + if (seriesOptions.legendType === 'point') { + series.generatePoints(); + } // Shift the first point off the parallel arrays // todo: consider series.removePoint(i) method @@ -10885,12 +12085,13 @@ Series.prototype = { chart = series.chart, firstPoint = null, xAxis = series.xAxis, - i; + i, + pointProto = series.pointClass.prototype; // reset properties series.xIncrement = null; - series.pointRange = (xAxis && xAxis.categories && 1) || options.pointRange; - + series.pointRange = xAxis && xAxis.categories ? 1 : options.pointRange; + if (defined(initialColor)) { // reset colors for pie chart.counters.color = initialColor; } @@ -10901,7 +12102,8 @@ Series.prototype = { dataLength = data ? data.length : [], turboThreshold = options.turboThreshold || 1000, pt, - ohlc = series.valueCount === 4; + pointArrayMap = series.pointArrayMap, + valueCount = pointArrayMap && pointArrayMap.length; // In turbo mode, only one- or twodimensional arrays of numbers are allowed. The // first value is tested, and we assume that all the rest are defined the same @@ -10928,11 +12130,11 @@ Series.prototype = { } series.xIncrement = x; } else if (isArray(firstPoint)) { // assume all points are arrays - if (ohlc) { // [x, o, h, l, c] + if (valueCount) { // [x, low, high] or [x, o, h, l, c] for (i = 0; i < dataLength; i++) { pt = data[i]; xData[i] = pt[0]; - yData[i] = pt.slice(1, 5); + yData[i] = pt.slice(1, valueCount + 1); } } else { // [x, y] for (i = 0; i < dataLength; i++) { @@ -10947,11 +12149,22 @@ Series.prototype = { } else { for (i = 0; i < dataLength; i++) { pt = { series: series }; - series.pointClass.prototype.applyOptions.apply(pt, [data[i]]); + pointProto.applyOptions.apply(pt, [data[i]]); xData[i] = pt.x; - yData[i] = ohlc ? [pt.open, pt.high, pt.low, pt.close] : pt.y; + yData[i] = pointProto.toYData ? pointProto.toYData.call(pt) : pt.y; } } + + // Unsorted data is not supported by the line tooltip as well as data grouping and + // navigation in Stock charts (#725) + if (series.requireSorting && xData.length > 1 && xData[1] < xData[0]) { + error(15); + } + + // Forgetting to cast strings to numbers is a common caveat when handling CSV or JSON + if (isString(yData[0])) { + error(14, true); + } series.data = []; series.options.data = data; @@ -10965,12 +12178,10 @@ Series.prototype = { oldData[i].destroy(); } } - + // reset minRange (#878) - // TODO: In protofy, run this code instead: - // if (xAxis) xAxis.minRange = UNDEFINED; - if (xAxis && xAxis.setMinRange) { - xAxis.setMinRange(); // to undefined + if (xAxis) { + xAxis.minRange = xAxis.userMinRange; } // redraw @@ -11131,7 +12342,7 @@ Series.prototype = { if (!hasGroupedData) { if (data[cursor]) { point = data[cursor]; - } else { + } else if (dataOptions[cursor] !== UNDEFINED) { // #970 data[cursor] = point = (new pointClass()).init(series, dataOptions[cursor], processedXData[i]); } points[i] = point; @@ -11150,6 +12361,7 @@ Series.prototype = { } if (data[i]) { data[i].destroyElements(); + data[i].plotX = UNDEFINED; // #1003 } } } @@ -11177,15 +12389,17 @@ Series.prototype = { points = series.points, dataLength = points.length, hasModifyValue = !!series.modifyValue, - isLastSeries, + isBottomSeries, allStackSeries = yAxis.series, - i = allStackSeries.length; + i = allStackSeries.length, + placeBetween = options.pointPlacement === 'between'; + //nextSeriesDown; // Is it the last visible series? while (i--) { if (allStackSeries[i].visible) { - if (i === series.index) { - isLastSeries = true; + if (allStackSeries[i] === series) { // #809 + isBottomSeries = true; } break; } @@ -11202,7 +12416,8 @@ Series.prototype = { pointStackTotal; // get the plotX translation - point.plotX = mathRound(xAxis.translate(xValue, 0, 0, 0, 1) * 10) / 10; // Math.round fixes #591 + //point.plotX = mathRound(xAxis.translate(xValue, 0, 0, 0, 1) * 10) / 10; // Math.round fixes #591 + point.plotX = xAxis.translate(xValue, 0, 0, 0, 1, placeBetween); // Math.round fixes #591 // calculate the bottom y value for stacked series if (stacking && series.visible && stack && stack[xValue]) { @@ -11211,8 +12426,12 @@ Series.prototype = { pointStack.cum = yBottom = pointStack.cum - yValue; // start from top yValue = yBottom + yValue; - if (isLastSeries) { - yBottom = options.threshold; + if (isBottomSeries) { + yBottom = pick(options.threshold, yAxis.min); + } + + if (yAxis.isLog && yBottom <= 0) { // #1200, #1232 + yBottom = null; } if (stacking === 'percent') { @@ -11221,7 +12440,7 @@ Series.prototype = { } point.percentage = pointStackTotal ? point.y * 100 / pointStackTotal : 0; - point.stackTotal = pointStackTotal; + point.total = point.stackTotal = pointStackTotal; point.stackY = yValue; } @@ -11239,7 +12458,7 @@ Series.prototype = { point.plotY = (typeof yValue === 'number') ? mathRound(yAxis.translate(yValue, 0, 1, 0, 1) * 10) / 10 : // Math.round fixes #591 UNDEFINED; - + // set client related positions for mouse tracking point.clientX = chart.inverted ? chart.plotHeight - point.plotX : @@ -11260,13 +12479,13 @@ Series.prototype = { */ setTooltipPoints: function (renew) { var series = this, - chart = series.chart, points = [], pointsLength, - plotSize = chart.plotSizeX, low, high, xAxis = series.xAxis, + axisLength = xAxis ? (xAxis.tooltipLen || xAxis.len) : series.chart.plotSizeX, // tooltipLen and tooltipPosName used in polar + plotX = (xAxis && xAxis.tooltipPosName) || 'plotX', point, i, tooltipPoints = []; // a lookup array for each pixel in the x dimension @@ -11286,8 +12505,7 @@ Series.prototype = { points = points.concat(segment); }); - // loop the concatenated points and apply each point to all the closest - // pixel positions + // Reverse the points in case the X axis is reversed if (xAxis && xAxis.reversed) { points = points.reverse(); } @@ -11296,12 +12514,14 @@ Series.prototype = { pointsLength = points.length; for (i = 0; i < pointsLength; i++) { point = points[i]; - low = points[i - 1] ? points[i - 1]._high + 1 : 0; - high = point._high = points[i + 1] ? - (mathFloor((point.plotX + (points[i + 1] ? points[i + 1].plotX : plotSize)) / 2)) : - plotSize; + // Set this range's low to the last range's high plus one + low = points[i - 1] ? high + 1 : 0; + // Now find the new high + high = points[i + 1] ? + mathMax(0, mathFloor((point[plotX] + (points[i + 1] ? points[i + 1][plotX] : axisLength)) / 2)) : + axisLength; - while (low <= high) { + while (low >= 0 && low <= high) { tooltipPoints[low++] = point; } } @@ -11314,12 +12534,23 @@ Series.prototype = { tooltipHeaderFormatter: function (key) { var series = this, tooltipOptions = series.tooltipOptions, - xDateFormat = tooltipOptions.xDateFormat || '%A, %b %e, %Y', + xDateFormat = tooltipOptions.xDateFormat, xAxis = series.xAxis, - isDateTime = xAxis && xAxis.options.type === 'datetime'; + isDateTime = xAxis && xAxis.options.type === 'datetime', + n; + + // Guess the best date format based on the closest point distance (#568) + if (isDateTime && !xDateFormat) { + for (n in timeUnits) { + if (timeUnits[n] >= xAxis.closestPointRange) { + xDateFormat = tooltipOptions.dateTimeLabelFormats[n]; + break; + } + } + } return tooltipOptions.headerFormat - .replace('{point.key}', isDateTime ? dateFormat(xDateFormat, key) : key) + .replace('{point.key}', isDateTime && isNumber(key) ? dateFormat(xDateFormat, key) : key) .replace('{series.name}', series.name) .replace('{series.color}', series.color); }, @@ -11332,10 +12563,6 @@ Series.prototype = { chart = series.chart, hoverSeries = chart.hoverSeries; - if (!hasTouch && chart.mouseIsDown) { - return; - } - // set normal state to previous series if (hoverSeries && hoverSeries !== series) { hoverSeries.onMouseOut(); @@ -11390,29 +12617,90 @@ Series.prototype = { animate: function (init) { var series = this, chart = series.chart, - clipRect = series.clipRect, - animation = series.options.animation; + renderer = chart.renderer, + clipRect, + markerClipRect, + animation = series.options.animation, + clipBox = chart.clipBox, + inverted = chart.inverted, + sharedClipKey; + // Animation option is set to true if (animation && !isObject(animation)) { - animation = {}; + animation = defaultPlotOptions[series.type].animation; } + sharedClipKey = '_sharedClip' + animation.duration + animation.easing; - if (init) { // initialize the animation - if (!clipRect.isAnimating) { // apply it only for one of the series - clipRect.attr('width', 0); - clipRect.isAnimating = true; + // Initialize the animation. Set up the clipping rectangle. + if (init) { + + // If a clipping rectangle with the same properties is currently present in the chart, use that. + clipRect = chart[sharedClipKey]; + markerClipRect = chart[sharedClipKey + 'm']; + if (!clipRect) { + chart[sharedClipKey] = clipRect = renderer.clipRect( + extend(clipBox, { width: 0 }) + ); + + chart[sharedClipKey + 'm'] = markerClipRect = renderer.clipRect( + -99, // include the width of the first marker + inverted ? -chart.plotLeft : -chart.plotTop, + 99, + inverted ? chart.chartWidth : chart.chartHeight + ); + } + series.group.clip(clipRect); + series.markerGroup.clip(markerClipRect); + series.sharedClipKey = sharedClipKey; + + // Run the animation + } else { + clipRect = chart[sharedClipKey]; + if (clipRect) { + clipRect.animate({ + width: chart.plotSizeX + }, animation); + chart[sharedClipKey + 'm'].animate({ + width: chart.plotSizeX + 99 + }, animation); } - } else { // run the animation - clipRect.animate({ - width: chart.plotSizeX - }, animation); - - // delete this function to allow it only once - this.animate = null; + // Delete this function to allow it only once + series.animate = null; + + // Call the afterAnimate function on animation complete (but don't overwrite the animation.complete option + // which should be available to the user). + series.animationTimeout = setTimeout(function () { + series.afterAnimate(); + }, animation.duration); } }, - + + /** + * This runs after animation to land on the final plot clipping + */ + afterAnimate: function () { + var chart = this.chart, + sharedClipKey = this.sharedClipKey, + group = this.group, + trackerGroup = this.trackerGroup; + + if (group && this.options.clip !== false) { + group.clip(chart.clipRect); + if (trackerGroup) { + trackerGroup.clip(chart.clipRect); // #484 + } + this.markerGroup.clip(); // no clip + } + + // Remove the shared clipping rectancgle when all series are shown + setTimeout(function () { + if (sharedClipKey && chart[sharedClipKey]) { + chart[sharedClipKey] = chart[sharedClipKey].destroy(); + chart[sharedClipKey + 'm'] = chart[sharedClipKey + 'm'].destroy(); + } + }, 100); + }, /** * Draw the markers @@ -11429,35 +12717,49 @@ Series.prototype = { radius, symbol, isImage, - graphic; + graphic, + options = series.options, + seriesMarkerOptions = options.marker, + pointMarkerOptions, + enabled, + isInside, + markerGroup = series.markerGroup; - if (series.options.marker.enabled) { + if (seriesMarkerOptions.enabled || series._hasPointMarkers) { + i = points.length; while (i--) { point = points[i]; plotX = point.plotX; plotY = point.plotY; graphic = point.graphic; - + pointMarkerOptions = point.marker || {}; + enabled = (seriesMarkerOptions.enabled && pointMarkerOptions.enabled === UNDEFINED) || pointMarkerOptions.enabled; + isInside = chart.isInsidePlot(plotX, plotY, chart.inverted); + // only draw the point if y is defined - if (plotY !== UNDEFINED && !isNaN(plotY)) { + if (enabled && plotY !== UNDEFINED && !isNaN(plotY)) { // shortcuts pointAttr = point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE]; radius = pointAttr.r; - symbol = pick(point.marker && point.marker.symbol, series.symbol); + symbol = pick(pointMarkerOptions.symbol, series.symbol); isImage = symbol.indexOf('url') === 0; if (graphic) { // update - graphic.animate(extend({ - x: plotX - radius, - y: plotY - radius - }, graphic.symbolName ? { // don't apply to image symbols #507 - width: 2 * radius, - height: 2 * radius - } : {})); - } else if (radius > 0 || isImage) { - point.graphic = chart.renderer.symbol( + graphic + .attr({ // Since the marker group isn't clipped, each individual marker must be toggled + visibility: isInside ? (hasSVG ? 'inherit' : VISIBLE) : HIDDEN + }) + .animate(extend({ + x: plotX - radius, + y: plotY - radius + }, graphic.symbolName ? { // don't apply to image symbols #507 + width: 2 * radius, + height: 2 * radius + } : {})); + } else if (isInside && (radius > 0 || isImage)) { + point.graphic = graphic = chart.renderer.symbol( symbol, plotX - radius, plotY - radius, @@ -11465,8 +12767,11 @@ Series.prototype = { 2 * radius ) .attr(pointAttr) - .add(series.group); + .add(markerGroup); } + + } else if (graphic) { + point.graphic = graphic.destroy(); // #1269 } } } @@ -11516,7 +12821,7 @@ Series.prototype = { stroke: seriesColor, fill: seriesColor }, - points = series.points, + points = series.points || [], // #927 i, point, seriesPointAttr = [], @@ -11563,8 +12868,8 @@ Series.prototype = { if (normalOptions && normalOptions.enabled === false) { normalOptions.radius = 0; } - hasPointSpecificOptions = false; - + hasPointSpecificOptions = series.options.colorByPoint; // #868 + // check if the point has specific visual options if (point.options) { for (key in pointAttrToOptions) { @@ -11579,22 +12884,25 @@ Series.prototype = { // a specific marker config object is defined for the individual point: // create it's own attribute collection if (hasPointSpecificOptions) { - + normalOptions = normalOptions || {}; pointAttr = []; stateOptions = normalOptions.states || {}; // reassign for individual point pointStateOptionsHover = stateOptions[HOVER_STATE] = stateOptions[HOVER_STATE] || {}; - // if no hover color is given, brighten the normal color + // Handle colors for column and pies if (!series.options.marker) { // column, bar, point + // if no hover color is given, brighten the normal color pointStateOptionsHover.color = - Color(pointStateOptionsHover.color || point.options.color) + Color(pointStateOptionsHover.color || point.color) .brighten(pointStateOptionsHover.brightness || stateOptionsHover.brightness).get(); } // normal point state inherits series wide normal state - pointAttr[NORMAL_STATE] = series.convertAttribs(normalOptions, seriesPointAttr[NORMAL_STATE]); + pointAttr[NORMAL_STATE] = series.convertAttribs(extend({ + color: point.color // #868 + }, normalOptions), seriesPointAttr[NORMAL_STATE]); // inherit from point normal and series hover pointAttr[HOVER_STATE] = series.convertAttribs( @@ -11630,7 +12938,6 @@ Series.prototype = { destroy: function () { var series = this, chart = series.chart, - seriesClipRect = series.clipRect, issue134 = /AppleWebKit\/533/.test(userAgent), destroy, i, @@ -11669,14 +12976,11 @@ Series.prototype = { } series.points = null; - // If this series clipRect is not the global one (which is removed on chart.destroy) we - // destroy it here. - if (seriesClipRect && seriesClipRect !== chart.clipRect) { - series.clipRect = seriesClipRect.destroy(); - } + // Clear the animation timeout if we are destroying the series during initial animation + clearTimeout(series.animationTimeout); // destroy all SVGElements associated to the series - each(['area', 'graph', 'dataLabelsGroup', 'group', 'tracker'], function (prop) { + each(['area', 'graph', 'dataLabelsGroup', 'group', 'markerGroup', 'tracker', 'trackerGroup'], function (prop) { if (series[prop]) { // issue 134 workaround @@ -11707,133 +13011,61 @@ Series.prototype = { var series = this, seriesOptions = series.options, - options = seriesOptions.dataLabels; + options = seriesOptions.dataLabels, + points = series.points, + pointOptions, + generalOptions, + str, + dataLabelsGroup; if (options.enabled || series._hasPointLabels) { - var x, - y, - points = series.points, - pointOptions, - generalOptions, - str, - dataLabelsGroup = series.dataLabelsGroup, - chart = series.chart, - xAxis = series.xAxis, - groupLeft = xAxis ? xAxis.left : chart.plotLeft, - yAxis = series.yAxis, - groupTop = yAxis ? yAxis.top : chart.plotTop, - renderer = chart.renderer, - inverted = chart.inverted, - seriesType = series.type, - stacking = seriesOptions.stacking, - isBarLike = seriesType === 'column' || seriesType === 'bar', - vAlignIsNull = options.verticalAlign === null, - yIsNull = options.y === null, - fontMetrics = renderer.fontMetrics(options.style.fontSize), // height and baseline - fontLineHeight = fontMetrics.h, - fontBaseline = fontMetrics.b, - dataLabel, - enabled; - - if (isBarLike) { - var defaultYs = { - top: fontBaseline, - middle: fontBaseline - fontLineHeight / 2, - bottom: -fontLineHeight + fontBaseline - }; - if (stacking) { - // In stacked series the default label placement is inside the bars - if (vAlignIsNull) { - options = merge(options, {verticalAlign: 'middle'}); - } - - // If no y delta is specified, try to create a good default - if (yIsNull) { - options = merge(options, { y: defaultYs[options.verticalAlign]}); - } - } else { - // In non stacked series the default label placement is on top of the bars - if (vAlignIsNull) { - options = merge(options, {verticalAlign: 'top'}); - - // If no y delta is specified, try to create a good default (like default bar) - } else if (yIsNull) { - options = merge(options, { y: defaultYs[options.verticalAlign]}); - } - - } + + // Process default alignment of data labels for columns + if (series.dlProcessOptions) { + series.dlProcessOptions(options); } - - // create a separate group for the data labels to avoid rotation - if (!dataLabelsGroup) { - dataLabelsGroup = series.dataLabelsGroup = - renderer.g('data-labels') - .attr({ - visibility: series.visible ? VISIBLE : HIDDEN, - zIndex: 6 - }) - .translate(groupLeft, groupTop) - .add(); - } else { - dataLabelsGroup.translate(groupLeft, groupTop); - } + // Create a separate group for the data labels to avoid rotation + dataLabelsGroup = series.plotGroup( + 'dataLabelsGroup', + 'data-labels', + series.visible ? VISIBLE : HIDDEN, + options.zIndex || 6 + ); - // make the labels for each point + // Make the labels for each point generalOptions = options; each(points, function (point) { - dataLabel = point.dataLabel; + var enabled, + dataLabel = point.dataLabel, + attr, + name, + rotation, + isNew = true; - // Merge in individual options from point - options = generalOptions; // reset changes from previous points - pointOptions = point.options; - if (pointOptions && pointOptions.dataLabels) { - options = merge(options, pointOptions.dataLabels); - } - enabled = options.enabled; + // Determine if each data label is enabled + pointOptions = point.options && point.options.dataLabels; + enabled = generalOptions.enabled || (pointOptions && pointOptions.enabled); - // Get the positions - if (enabled) { - var plotX = (point.barX && point.barX + point.barW / 2) || pick(point.plotX, -999), - plotY = pick(point.plotY, -999), - - // if options.y is null, which happens by default on column charts, set the position - // above or below the column depending on the threshold - individualYDelta = options.y === null ? - (point.y >= seriesOptions.threshold ? - -fontLineHeight + fontBaseline : // below the threshold - fontBaseline) : // above the threshold - options.y; - - x = (inverted ? chart.plotWidth - plotY : plotX) + options.x; - y = mathRound((inverted ? chart.plotHeight - plotX : plotY) + individualYDelta); - - } // If the point is outside the plot area, destroy it. #678, #820 - if (dataLabel && series.isCartesian && (!chart.isInsidePlot(x, y) || !enabled)) { + if (dataLabel && !enabled) { point.dataLabel = dataLabel.destroy(); // Individual labels are disabled if the are explicitly disabled // in the point options, or if they fall outside the plot area. } else if (enabled) { - var align = options.align; + rotation = options.rotation; + + // Create individual options structure that can be extended without + // affecting others + options = merge(generalOptions, pointOptions); // Get the string str = options.formatter.call(point.getLabelConfig(), options); - // in columns, align the string to the column - if (seriesType === 'column') { - x += { left: -1, right: 1 }[align] * point.barW / 2 || 0; - } - - if (!stacking && inverted && point.y < 0) { - align = 'right'; - x -= 10; - } - // Determine the color options.style.color = pick(options.color, options.style.color, series.color, 'black'); @@ -11844,182 +13076,201 @@ Series.prototype = { dataLabel .attr({ text: str - }).animate({ - x: x, - y: y }); + isNew = false; // create new label } else if (defined(str)) { - dataLabel = point.dataLabel = renderer[options.rotation ? 'text' : 'label']( // labels don't support rotation - str, - x, - y, - null, - null, - null, - options.useHTML, - true // baseline for backwards compat - ) - .attr({ - align: align, + attr = { + //align: align, fill: options.backgroundColor, stroke: options.borderColor, 'stroke-width': options.borderWidth, r: options.borderRadius || 0, - rotation: options.rotation, + rotation: rotation, padding: options.padding, zIndex: 1 - }) + }; + // Remove unused attributes (#947) + for (name in attr) { + if (attr[name] === UNDEFINED) { + delete attr[name]; + } + } + + dataLabel = point.dataLabel = series.chart.renderer[rotation ? 'text' : 'label']( // labels don't support rotation + str, + 0, + -999, + null, + null, + null, + options.useHTML + ) + .attr(attr) .css(options.style) .add(dataLabelsGroup) .shadow(options.shadow); - } - - if (isBarLike && seriesOptions.stacking && dataLabel) { - var barX = point.barX, - barY = point.barY, - barW = point.barW, - barH = point.barH; - - dataLabel.align(options, null, - { - x: inverted ? chart.plotWidth - barY - barH : barX, - y: inverted ? chart.plotHeight - barX - barW : barY, - width: inverted ? barH : barW, - height: inverted ? barW : barH - }); + } - + // Now the data label is created and placed at 0,0, so we need to align it + if (dataLabel) { + series.alignDataLabel(point, dataLabel, options, null, isNew); + } } }); } }, - + /** - * Draw the actual graph + * Align each individual data label */ - drawGraph: function () { + alignDataLabel: function (point, dataLabel, options, alignTo, isNew) { + var chart = this.chart, + inverted = chart.inverted, + plotX = pick(point.plotX, -999), + plotY = pick(point.plotY, -999), + bBox = dataLabel.getBBox(), + alignAttr; // the final position; + + // The alignment box is a singular point + alignTo = extend({ + x: inverted ? chart.plotWidth - plotY : plotX, + y: mathRound(inverted ? chart.plotHeight - plotX : plotY), + width: 0, + height: 0 + }, alignTo); + + // Add the text size for alignment calculation + extend(options, { + width: bBox.width, + height: bBox.height + }); + + // Allow a hook for changing alignment in the last moment, then do the alignment + if (options.rotation) { // Fancy box alignment isn't supported for rotated text + alignAttr = { + align: options.align, + x: alignTo.x + options.x + alignTo.width / 2, + y: alignTo.y + options.y + alignTo.height / 2 + }; + dataLabel[isNew ? 'attr' : 'animate'](alignAttr); + } else { + dataLabel.align(options, null, alignTo); + alignAttr = dataLabel.alignAttr; + } + + // Show or hide based on the final aligned position + dataLabel.attr({ + visibility: options.crop === false || chart.isInsidePlot(alignAttr.x, alignAttr.y) || chart.isInsidePlot(plotX, plotY, inverted) ? + (chart.renderer.isSVG ? 'inherit' : VISIBLE) : + HIDDEN + }); + + }, + + /** + * Return the graph path of a segment + */ + getSegmentPath: function (segment) { var series = this, - options = series.options, - chart = series.chart, - graph = series.graph, - graphPath = [], - fillColor, - area = series.area, - group = series.group, - color = options.lineColor || series.color, - lineWidth = options.lineWidth, - dashStyle = options.dashStyle, - segmentPath, - renderer = chart.renderer, - translatedThreshold = series.yAxis.getThreshold(options.threshold), - useArea = /^area/.test(series.type), - singlePoints = [], // used in drawTracker - areaPath = [], - attribs; + segmentPath = [], + step = series.options.step; + + // build the segment line + each(segment, function (point, i) { + + var plotX = point.plotX, + plotY = point.plotY, + lastPoint; + if (series.getPointSpline) { // generate the spline as defined in the SplineSeries object + segmentPath.push.apply(segmentPath, series.getPointSpline(segment, point, i)); - // divide into segments and build graph and area paths - each(series.segments, function (segment) { - segmentPath = []; + } else { - // build the segment line - each(segment, function (point, i) { + // moveTo or lineTo + segmentPath.push(i ? L : M); - if (series.getPointSpline) { // generate the spline as defined in the SplineSeries object - segmentPath.push.apply(segmentPath, series.getPointSpline(segment, point, i)); - - } else { - - // moveTo or lineTo - segmentPath.push(i ? L : M); - - // step line? - if (i && options.step) { - var lastPoint = segment[i - 1]; + // step line? + if (step && i) { + lastPoint = segment[i - 1]; + if (step === 'right') { segmentPath.push( - point.plotX, + lastPoint.plotX, + plotY + ); + + } else if (step === 'center') { + segmentPath.push( + (lastPoint.plotX + plotX) / 2, + lastPoint.plotY, + (lastPoint.plotX + plotX) / 2, + plotY + ); + + } else { + segmentPath.push( + plotX, lastPoint.plotY ); } - - // normal line to next point - segmentPath.push( - point.plotX, - point.plotY - ); } - }); + // normal line to next point + segmentPath.push( + point.plotX, + point.plotY + ); + } + }); + + return segmentPath; + }, + + /** + * Get the graph path + */ + getGraphPath: function () { + var series = this, + graphPath = [], + segmentPath, + singlePoints = []; // used in drawTracker + + // Divide into segments and build graph and area paths + each(series.segments, function (segment) { + + segmentPath = series.getSegmentPath(segment); + // add the segment to the graph, or a single point for tracking if (segment.length > 1) { graphPath = graphPath.concat(segmentPath); } else { singlePoints.push(segment[0]); } - - // build the area - if (useArea) { - var areaSegmentPath = [], - i, - segLength = segmentPath.length; - for (i = 0; i < segLength; i++) { - areaSegmentPath.push(segmentPath[i]); - } - if (segLength === 3) { // for animation from 1 to two points - areaSegmentPath.push(L, segmentPath[1], segmentPath[2]); - } - if (options.stacking && series.type !== 'areaspline') { - - // Follow stack back. Todo: implement areaspline. A general solution could be to - // reverse the entire graphPath of the previous series, though may be hard with - // splines and with series with different extremes - for (i = segment.length - 1; i >= 0; i--) { - - // step line? - if (i < segment.length - 1 && options.step) { - areaSegmentPath.push(segment[i + 1].plotX, segment[i].yBottom); - } - - areaSegmentPath.push(segment[i].plotX, segment[i].yBottom); - } - - } else { // follow zero line back - areaSegmentPath.push( - L, - segment[segment.length - 1].plotX, - translatedThreshold, - L, - segment[0].plotX, - translatedThreshold - ); - } - areaPath = areaPath.concat(areaSegmentPath); - } }); - // used in drawTracker: - series.graphPath = graphPath; + // Record it for use in drawGraph and drawTracker, and return graphPath series.singlePoints = singlePoints; - - // draw the area if area series or areaspline - if (useArea) { - fillColor = pick( - options.fillColor, - Color(series.color).setOpacity(options.fillOpacity || 0.75).get() - ); - if (area) { - area.animate({ d: areaPath }); - - } else { - // draw the area - series.area = series.chart.renderer.path(areaPath) - .attr({ - fill: fillColor - }).add(group); - } - } + series.graphPath = graphPath; + + return graphPath; + + }, + + /** + * Draw the actual graph + */ + drawGraph: function () { + var options = this.options, + graph = this.graph, + group = this.group, + color = options.lineColor || this.color, + lineWidth = options.lineWidth, + dashStyle = options.dashStyle, + attribs, + graphPath = this.getGraphPath(); + // draw the graph if (graph) { @@ -12029,14 +13280,15 @@ Series.prototype = { } else { if (lineWidth) { attribs = { - 'stroke': color, - 'stroke-width': lineWidth + stroke: color, + 'stroke-width': lineWidth, + zIndex: 1 // #1069 }; if (dashStyle) { attribs.dashstyle = dashStyle; } - series.graph = renderer.path(graphPath) + this.graph = this.chart.renderer.path(graphPath) .attr(attribs).add(group).shadow(options.shadow); } } @@ -12047,8 +13299,6 @@ Series.prototype = { */ invertGroups: function () { var series = this, - group = series.group, - trackerGroup = series.trackerGroup, chart = series.chart; // A fixed size is needed for inversion to work @@ -12058,13 +13308,11 @@ Series.prototype = { height: series.xAxis.len }; - // Set the series.group size - group.attr(size).invert(); - - // Set the tracker group size - if (trackerGroup) { - trackerGroup.attr(size).invert(); - } + each(['group', 'trackerGroup', 'markerGroup'], function (groupName) { + if (series[groupName]) { + series[groupName].attr(size).invert(); + } + }); } addEvent(chart, 'resize', setInvert); // do it on resize @@ -12078,7 +13326,36 @@ Series.prototype = { // On subsequent render and redraw, just do setInvert without setting up events again series.invertGroups = setInvert; }, - + + /** + * General abstraction for creating plot groups like series.group, series.trackerGroup, series.dataLabelsGroup and + * series.markerGroup. On subsequent calls, the group will only be adjusted to the updated plot size. + */ + plotGroup: function (prop, name, visibility, zIndex, parent) { + var group = this[prop], + chart = this.chart, + xAxis = this.xAxis, + yAxis = this.yAxis; + + // Generate it on first call + if (!group) { + this[prop] = group = chart.renderer.g(name) + .attr({ + visibility: visibility, + zIndex: zIndex || 0.1 // IE8 needs this + }) + .add(parent); + } + // Place it on first and subsequent (redraw) calls + group.translate( + xAxis ? xAxis.left : chart.plotLeft, + yAxis ? yAxis.top : chart.plotTop + ); + + return group; + + }, + /** * Render the graph and markers */ @@ -12087,44 +13364,30 @@ Series.prototype = { chart = series.chart, group, options = series.options, - doClip = options.clip !== false, animation = options.animation, - doAnimation = animation && series.animate, - duration = doAnimation ? (animation && animation.duration) || 500 : 0, - clipRect = series.clipRect, - renderer = chart.renderer; - - - // Add plot area clipping rectangle. If this is before chart.hasRendered, - // create one shared clipRect. - - // Todo: since creating the clip property, the clipRect is created but - // never used when clip is false. A better way would be that the animation - // would run, then the clipRect destroyed. - if (!clipRect) { - clipRect = series.clipRect = !chart.hasRendered && chart.clipRect ? - chart.clipRect : - renderer.clipRect(0, 0, chart.plotSizeX, chart.plotSizeY + 1); - if (!chart.clipRect) { - chart.clipRect = clipRect; - } - } + doAnimation = animation && !!series.animate, + visibility = series.visible ? VISIBLE : HIDDEN, + zIndex = options.zIndex, + hasRendered = series.hasRendered, + chartSeriesGroup = chart.seriesGroup; - // the group - if (!series.group) { - group = series.group = renderer.g('series'); - - group.attr({ - visibility: series.visible ? VISIBLE : HIDDEN, - zIndex: options.zIndex - }) - .translate(series.xAxis.left, series.yAxis.top) - .add(chart.seriesGroup); - } - - series.drawDataLabels(); - + group = series.plotGroup( + 'group', + 'series', + visibility, + zIndex, + chartSeriesGroup + ); + + series.markerGroup = series.plotGroup( + 'markerGroup', + 'markers', + visibility, + zIndex, + chartSeriesGroup + ); + // initiate the animation if (doAnimation) { series.animate(true); @@ -12133,6 +13396,9 @@ Series.prototype = { // cache attributes for shapes series.getAttribs(); + // SVGRenderer needs to know this before drawing elements (#1089) + group.inverted = chart.inverted; + // draw the graph if any if (series.drawGraph) { series.drawGraph(); @@ -12140,6 +13406,10 @@ Series.prototype = { // draw the points series.drawPoints(); + + // draw the data labels + series.drawDataLabels(); + // draw the mouse tracking area if (series.options.enableMouseTracking !== false) { @@ -12151,37 +13421,26 @@ Series.prototype = { series.invertGroups(); } - // Do the initial clipping. This must be done after inverting for VML. - if (doClip && !series.hasRendered) { - group.clip(clipRect); - if (series.trackerGroup) { - series.trackerGroup.clip(chart.clipRect); + // Initial clipping, must be defined after inverting groups for VML + if (options.clip !== false && !series.sharedClipKey && !hasRendered) { + group.clip(chart.clipRect); + if (this.trackerGroup) { + this.trackerGroup.clip(chart.clipRect); } } - - // run the animation + // Run the animation if (doAnimation) { series.animate(); + } else if (!hasRendered) { + series.afterAnimate(); } - // finish the individual clipRect - setTimeout(function () { - clipRect.isAnimating = false; - group = series.group; // can be destroyed during the timeout - if (group && clipRect !== chart.clipRect && clipRect.renderer) { - if (doClip) { - group.clip((series.clipRect = chart.clipRect)); - } - clipRect.destroy(); - } - }, duration); - series.isDirty = series.isDirtyData = false; // means data is in accordance with what you see // (See #322) series.isDirty = series.isDirtyData = false; // means data is in accordance with what you see series.hasRendered = true; }, - + /** * Redraw the series after an update in the axes. */ @@ -12259,6 +13518,7 @@ Series.prototype = { seriesGroup = series.group, seriesTracker = series.tracker, dataLabelsGroup = series.dataLabelsGroup, + markerGroup = series.markerGroup, showOrHide, i, points = series.points, @@ -12274,6 +13534,9 @@ Series.prototype = { if (seriesGroup) { // pies don't have one seriesGroup[showOrHide](); } + if (markerGroup) { + markerGroup[showOrHide](); + } // show or hide trackers if (seriesTracker) { @@ -12287,6 +13550,11 @@ Series.prototype = { } } } + + // hide tooltip (#1361) + if (chart.hoverSeries === series) { + series.onMouseOut(); + } if (dataLabelsGroup) { @@ -12352,33 +13620,6 @@ Series.prototype = { fireEvent(series, selected ? 'select' : 'unselect'); }, - /** - * Create a group that holds the tracking object or objects. This allows for - * individual clipping and placement of each series tracker. - */ - drawTrackerGroup: function () { - var trackerGroup = this.trackerGroup, - chart = this.chart; - - if (this.isCartesian) { - - // Generate it on first call - if (!trackerGroup) { - this.trackerGroup = trackerGroup = chart.renderer.g() - .attr({ - zIndex: this.options.zIndex || 1 - }) - .add(chart.trackerGroup); - - } - // Place it on first and subsequent (redraw) calls - trackerGroup.translate(this.xAxis.left, this.yAxis.top); - - } - - return trackerGroup; - }, - /** * Draw the tracker object that sits above all data labels and markers to * track mouse events on the graph or points. For the line type charts @@ -12388,7 +13629,8 @@ Series.prototype = { drawTracker: function () { var series = this, options = series.options, - trackerPath = [].concat(series.graphPath), + trackByArea = options.trackByArea, + trackerPath = [].concat(trackByArea ? series.areaPath : series.graphPath), trackerPathLength = trackerPath.length, chart = series.chart, renderer = chart.renderer, @@ -12397,13 +13639,23 @@ Series.prototype = { cursor = options.cursor, css = cursor && { cursor: cursor }, singlePoints = series.singlePoints, - trackerGroup = series.drawTrackerGroup(), + trackerGroup = this.isCartesian && this.plotGroup('trackerGroup', null, VISIBLE, options.zIndex || 1, chart.trackerGroup), singlePoint, - i; + i, + onMouseOver = function () { + if (chart.hoverSeries !== series) { + series.onMouseOver(); + } + }, + onMouseOut = function () { + if (!options.stickyTracking) { + series.onMouseOut(); + } + }; // Extend end points. A better way would be to use round linecaps, // but those are not clickable in VML. - if (trackerPathLength) { + if (trackerPathLength && !trackByArea) { i = trackerPathLength + 1; while (i--) { if (trackerPath[i] === M) { // extend left side @@ -12430,27 +13682,23 @@ Series.prototype = { } else { // create - series.tracker = renderer.path(trackerPath) + series.tracker = tracker = renderer.path(trackerPath) .attr({ isTracker: true, + 'stroke-linejoin': 'round', // #1225 + visibility: series.visible ? VISIBLE : HIDDEN, stroke: TRACKER_FILL, - fill: NONE, - 'stroke-linejoin': 'bevel', - 'stroke-width' : options.lineWidth + 2 * snap, - visibility: series.visible ? VISIBLE : HIDDEN - }) - .on(hasTouch ? 'touchstart' : 'mouseover', function () { - if (chart.hoverSeries !== series) { - series.onMouseOver(); - } - }) - .on('mouseout', function () { - if (!options.stickyTracking) { - series.onMouseOut(); - } + fill: trackByArea ? TRACKER_FILL : NONE, + 'stroke-width' : options.lineWidth + (trackByArea ? 0 : 2 * snap) }) + .on('mouseover', onMouseOver) + .on('mouseout', onMouseOut) .css(css) .add(trackerGroup); + + if (hasTouch) { + tracker.on('touchstart', onMouseOver); + } } } @@ -12464,16 +13712,136 @@ Series.prototype = { var LineSeries = extendClass(Series); seriesTypes.line = LineSeries; +/** + * Set the default options for area + */ +defaultPlotOptions.area = merge(defaultSeriesOptions, { + threshold: 0 + // trackByArea: false, + // lineColor: null, // overrides color, but lets fillColor be unaltered + // fillOpacity: 0.75, + // fillColor: null +}); + /** * AreaSeries object */ var AreaSeries = extendClass(Series, { - type: 'area' + type: 'area', + + /** + * Extend the base Series getSegmentPath method by adding the path for the area. + * This path is pushed to the series.areaPath property. + */ + getSegmentPath: function (segment) { + + var segmentPath = Series.prototype.getSegmentPath.call(this, segment), // call base method + areaSegmentPath = [].concat(segmentPath), // work on a copy for the area path + i, + options = this.options, + segLength = segmentPath.length; + + if (segLength === 3) { // for animation from 1 to two points + areaSegmentPath.push(L, segmentPath[1], segmentPath[2]); + } + if (options.stacking && !this.closedStacks) { + + // Follow stack back. Todo: implement areaspline. A general solution could be to + // reverse the entire graphPath of the previous series, though may be hard with + // splines and with series with different extremes + for (i = segment.length - 1; i >= 0; i--) { + + // step line? + if (i < segment.length - 1 && options.step) { + areaSegmentPath.push(segment[i + 1].plotX, segment[i].yBottom); + } + + areaSegmentPath.push(segment[i].plotX, segment[i].yBottom); + } + + } else { // follow zero line back + this.closeSegment(areaSegmentPath, segment); + } + this.areaPath = this.areaPath.concat(areaSegmentPath); + + return segmentPath; + }, + + /** + * Extendable method to close the segment path of an area. This is overridden in polar + * charts. + */ + closeSegment: function (path, segment) { + var translatedThreshold = this.yAxis.getThreshold(this.options.threshold); + path.push( + L, + segment[segment.length - 1].plotX, + translatedThreshold, + L, + segment[0].plotX, + translatedThreshold + ); + }, + + /** + * Draw the graph and the underlying area. This method calls the Series base + * function and adds the area. The areaPath is calculated in the getSegmentPath + * method called from Series.prototype.drawGraph. + */ + drawGraph: function () { + + // Define or reset areaPath + this.areaPath = []; + + // Call the base method + Series.prototype.drawGraph.apply(this); + + // Define local variables + var areaPath = this.areaPath, + options = this.options, + area = this.area; + + // Create or update the area + if (area) { // update + area.animate({ d: areaPath }); + + } else { // create + this.area = this.chart.renderer.path(areaPath) + .attr({ + fill: pick( + options.fillColor, + Color(this.color).setOpacity(options.fillOpacity || 0.75).get() + ), + zIndex: 0 // #1069 + }).add(this.group); + } + }, + + /** + * Get the series' symbol in the legend + * + * @param {Object} legend The legend object + * @param {Object} item The series (this) or point + */ + drawLegendSymbol: function (legend, item) { + + item.legendSymbol = this.chart.renderer.rect( + 0, + legend.baseline - 11, + legend.options.symbolWidth, + 12, + 2 + ).attr({ + zIndex: 3 + }).add(item.legendGroup); + + } }); -seriesTypes.area = AreaSeries; - - +seriesTypes.area = AreaSeries;/** + * Set the default options for spline + */ +defaultPlotOptions.spline = merge(defaultSeriesOptions); /** * SplineSeries object @@ -12482,7 +13850,7 @@ var SplineSeries = extendClass(Series, { type: 'spline', /** - * Draw the actual graph + * Get the spline segment from a given point's previous neighbour to the given point */ getPointSpline: function (segment, point, i) { var smoothing = 1.5, // 1 means control points midway between points, 2 means 1/3 from the point, 3 is 1/4 etc @@ -12498,7 +13866,8 @@ var SplineSeries = extendClass(Series, { ret; // find control points - if (i && i < segment.length - 1) { + if (lastPoint && nextPoint) { + var lastX = lastPoint.plotX, lastY = lastPoint.plotY, nextX = nextPoint.plotX, @@ -12539,6 +13908,40 @@ var SplineSeries = extendClass(Series, { point.rightContY = rightContY; } + + // Visualize control points for debugging + /* + if (leftContX) { + this.chart.renderer.circle(leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop, 2) + .attr({ + stroke: 'red', + 'stroke-width': 1, + fill: 'none' + }) + .add(); + this.chart.renderer.path(['M', leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop, + 'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop]) + .attr({ + stroke: 'red', + 'stroke-width': 1 + }) + .add(); + this.chart.renderer.circle(rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop, 2) + .attr({ + stroke: 'green', + 'stroke-width': 1, + fill: 'none' + }) + .add(); + this.chart.renderer.path(['M', rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop, + 'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop]) + .attr({ + stroke: 'green', + 'stroke-width': 1 + }) + .add(); + } + // */ // moveTo or lineTo if (!i) { @@ -12560,16 +13963,61 @@ var SplineSeries = extendClass(Series, { }); seriesTypes.spline = SplineSeries; - +/** + * Set the default options for areaspline + */ +defaultPlotOptions.areaspline = merge(defaultPlotOptions.area); /** * AreaSplineSeries object */ -var AreaSplineSeries = extendClass(SplineSeries, { - type: 'areaspline' -}); +var areaProto = AreaSeries.prototype, + AreaSplineSeries = extendClass(SplineSeries, { + type: 'areaspline', + closedStacks: true, // instead of following the previous graph back, follow the threshold back + + // Mix in methods from the area series + getSegmentPath: areaProto.getSegmentPath, + closeSegment: areaProto.closeSegment, + drawGraph: areaProto.drawGraph + }); seriesTypes.areaspline = AreaSplineSeries; +/** + * Set the default options for column + */ +defaultPlotOptions.column = merge(defaultSeriesOptions, { + borderColor: '#FFFFFF', + borderWidth: 1, + borderRadius: 0, + //colorByPoint: undefined, + groupPadding: 0.2, + //grouping: true, + marker: null, // point options are specified in the base options + pointPadding: 0.1, + //pointWidth: null, + minPointLength: 0, + cropThreshold: 50, // when there are more points, they will not animate out of the chart on xAxis.setExtremes + pointRange: null, // null means auto, meaning 1 in a categorized axis and least distance between points if not categories + states: { + hover: { + brightness: 0.1, + shadow: false + }, + select: { + color: '#C0C0C0', + borderColor: '#000000', + shadow: false + } + }, + dataLabels: { + align: null, // auto + verticalAlign: null, // auto + y: null + }, + threshold: 0 +}); + /** * ColumnSeries object */ @@ -12582,6 +14030,10 @@ var ColumnSeries = extendClass(Series, { fill: 'color', r: 'borderRadius' }, + + /** + * Initialize the series + */ init: function () { Series.prototype.init.apply(this, arguments); @@ -12610,6 +14062,7 @@ var ColumnSeries = extendClass(Series, { borderWidth = options.borderWidth, columnCount = 0, xAxis = series.xAxis, + yAxis = series.yAxis, reversedXAxis = xAxis.reversed, stackGroups = {}, stackKey, @@ -12620,56 +14073,63 @@ var ColumnSeries = extendClass(Series, { // Get the total number of column type series. // This is called on every series. Consider moving this logic to a // chart.orderStacks() function and call it on init, addSeries and removeSeries - each(chart.series, function (otherSeries) { - if (otherSeries.type === series.type && otherSeries.visible && - series.options.group === otherSeries.options.group) { // used in Stock charts navigator series - if (otherSeries.options.stacking) { - stackKey = otherSeries.stackKey; - if (stackGroups[stackKey] === UNDEFINED) { - stackGroups[stackKey] = columnCount++; + if (options.grouping === false) { + columnCount = 1; + } else { + each(chart.series, function (otherSeries) { + var otherOptions = otherSeries.options; + if (otherSeries.type === series.type && otherSeries.visible && + series.options.group === otherOptions.group) { // used in Stock charts navigator series + if (otherOptions.stacking) { + stackKey = otherSeries.stackKey; + if (stackGroups[stackKey] === UNDEFINED) { + stackGroups[stackKey] = columnCount++; + } + columnIndex = stackGroups[stackKey]; + } else if (otherOptions.grouping !== false) { // #1162 + columnIndex = columnCount++; } - columnIndex = stackGroups[stackKey]; - } else { - columnIndex = columnCount++; + otherSeries.columnIndex = columnIndex; } - otherSeries.columnIndex = columnIndex; - } - }); + }); + } // calculate the width and position of each column based on // the number of column series in the plot, the groupPadding // and the pointPadding options var points = series.points, - categoryWidth = mathAbs(xAxis.translationSlope) * (xAxis.ordinalSlope || xAxis.closestPointRange || 1), + categoryWidth = mathAbs(xAxis.transA) * (xAxis.ordinalSlope || options.pointRange || xAxis.closestPointRange || 1), groupPadding = categoryWidth * options.groupPadding, groupWidth = categoryWidth - 2 * groupPadding, pointOffsetWidth = groupWidth / columnCount, optionPointWidth = options.pointWidth, pointPadding = defined(optionPointWidth) ? (pointOffsetWidth - optionPointWidth) / 2 : pointOffsetWidth * options.pointPadding, - pointWidth = mathCeil(mathMax(pick(optionPointWidth, pointOffsetWidth - 2 * pointPadding), 1 + 2 * borderWidth)), - colIndex = (reversedXAxis ? columnCount - - series.columnIndex : series.columnIndex) || 0, + pointWidth = pick(optionPointWidth, pointOffsetWidth - 2 * pointPadding), // exact point width, used in polar charts + barW = mathCeil(mathMax(pointWidth, 1 + 2 * borderWidth)), // rounded and postprocessed for border width + colIndex = (reversedXAxis ? + columnCount - (series.columnIndex || 0) : // #1251 + series.columnIndex) || 0, pointXOffset = pointPadding + (groupPadding + colIndex * pointOffsetWidth - (categoryWidth / 2)) * (reversedXAxis ? -1 : 1), threshold = options.threshold, - translatedThreshold = series.yAxis.getThreshold(threshold), + translatedThreshold = series.translatedThreshold = yAxis.getThreshold(threshold), minPointLength = pick(options.minPointLength, 5); // record the new values each(points, function (point) { - var plotY = point.plotY, + var plotY = mathMin(mathMax(-999, point.plotY), yAxis.len + 999), // Don't draw too far outside plot area (#1303) yBottom = pick(point.yBottom, translatedThreshold), barX = point.plotX + pointXOffset, barY = mathCeil(mathMin(plotY, yBottom)), barH = mathCeil(mathMax(plotY, yBottom) - barY), - stack = series.yAxis.stacks[(point.y < 0 ? '-' : '') + series.stackKey], + stack = yAxis.stacks[(point.y < 0 ? '-' : '') + series.stackKey], shapeArgs; // Record the offset'ed position and width of the bar to be able to align the stacking total correctly if (stacking && series.visible && stack && stack[point.x]) { - stack[point.x].setOffset(pointXOffset, pointWidth); + stack[point.x].setOffset(pointXOffset, barW); } // handle options.minPointLength @@ -12683,29 +14143,17 @@ var ColumnSeries = extendClass(Series, { } } - extend(point, { - barX: barX, - barY: barY, - barW: pointWidth, - barH: barH - }); + point.barX = barX; + point.pointWidth = pointWidth; // create shape type and shape args that are reused in drawPoints and drawTracker point.shapeType = 'rect'; - shapeArgs = { - x: barX, - y: barY, - width: pointWidth, - height: barH, - r: options.borderRadius, - strokeWidth: borderWidth - }; + point.shapeArgs = shapeArgs = chart.renderer.Element.prototype.crisp.call(0, borderWidth, barX, barY, barW, barH); if (borderWidth % 2) { // correct for shorting in crisp method, visible in stacked columns with 1px border shapeArgs.y -= 1; shapeArgs.height += 1; } - point.shapeArgs = shapeArgs; // make small columns responsive to mouse point.trackerArgs = mathAbs(barH) < 3 && merge(point.shapeArgs, { @@ -12716,13 +14164,18 @@ var ColumnSeries = extendClass(Series, { }, - getSymbol: function () { - }, - + getSymbol: noop, + + /** + * Use a solid rectangle like the area series types + */ + drawLegendSymbol: AreaSeries.prototype.drawLegendSymbol, + + /** * Columns have no graph */ - drawGraph: function () {}, + drawGraph: noop, /** * Draw the columns. For bars, the series.group is rotated, so the same coordinates @@ -12733,40 +14186,34 @@ var ColumnSeries = extendClass(Series, { var series = this, options = series.options, renderer = series.chart.renderer, - graphic, shapeArgs; // draw the columns each(series.points, function (point) { - var plotY = point.plotY; - if (plotY !== UNDEFINED && !isNaN(plotY) && point.y !== null) { + var plotY = point.plotY, graphic = point.graphic; + if (plotY !== UNDEFINED && !isNaN(plotY) && point.y !== null) { shapeArgs = point.shapeArgs; if (graphic) { // update stop(graphic); - graphic.animate(renderer.Element.prototype.crisp.apply({}, [ - shapeArgs.strokeWidth, - shapeArgs.x, - shapeArgs.y, - shapeArgs.width, - shapeArgs.height - ])); + graphic.animate(merge(shapeArgs)); } else { point.graphic = graphic = renderer[point.shapeType](shapeArgs) .attr(point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE]) .add(series.group) - .shadow(options.shadow); - + .shadow(options.shadow, null, options.stacking && !options.borderRadius); } + } else if (graphic) { + point.graphic = graphic.destroy(); // #1269 } }); }, /** * Draw the individual tracker elements. - * This method is inherited by scatter and pie charts too. + * This method is inherited by pie charts too. */ drawTracker: function () { var series = this, @@ -12778,12 +14225,31 @@ var ColumnSeries = extendClass(Series, { options = series.options, cursor = options.cursor, css = cursor && { cursor: cursor }, - trackerGroup = series.drawTrackerGroup(), + trackerGroup = series.isCartesian && series.plotGroup('trackerGroup', null, VISIBLE, options.zIndex || 1, chart.trackerGroup), rel, plotY, - validPlotY; + validPlotY, + points = series.points, + point, + i = points.length, + onMouseOver = function (event) { + rel = event.relatedTarget || event.fromElement; + if (chart.hoverSeries !== series && attr(rel, 'isTracker') !== trackerLabel) { + series.onMouseOver(); + } + points[event.target._i].onMouseOver(); + }, + onMouseOut = function (event) { + if (!options.stickyTracking) { + rel = event.relatedTarget || event.toElement; + if (attr(rel, 'isTracker') !== trackerLabel) { + series.onMouseOut(); + } + } + }; - each(series.points, function (point) { + while (i--) { + point = points[i]; tracker = point.tracker; shapeArgs = point.trackerArgs || point.shapeArgs; plotY = point.plotY; @@ -12794,34 +14260,73 @@ var ColumnSeries = extendClass(Series, { tracker.attr(shapeArgs); } else { - point.tracker = + point.tracker = tracker = renderer[point.shapeType](shapeArgs) .attr({ isTracker: trackerLabel, fill: TRACKER_FILL, visibility: series.visible ? VISIBLE : HIDDEN }) - .on(hasTouch ? 'touchstart' : 'mouseover', function (event) { - rel = event.relatedTarget || event.fromElement; - if (chart.hoverSeries !== series && attr(rel, 'isTracker') !== trackerLabel) { - series.onMouseOver(); - } - point.onMouseOver(); - - }) - .on('mouseout', function (event) { - if (!options.stickyTracking) { - rel = event.relatedTarget || event.toElement; - if (attr(rel, 'isTracker') !== trackerLabel) { - series.onMouseOut(); - } - } - }) + .on('mouseover', onMouseOver) + .on('mouseout', onMouseOut) .css(css) .add(point.group || trackerGroup); // pies have point group - see issue #118 + + if (hasTouch) { + tracker.on('touchstart', onMouseOver); + } + } + tracker.element._i = i; + } + } + }, + + /** + * Override the basic data label alignment by adjusting for the position of the column + */ + alignDataLabel: function (point, dataLabel, options, alignTo, isNew) { + var chart = this.chart, + inverted = chart.inverted, + below = point.below || (point.plotY > pick(this.translatedThreshold, chart.plotSizeY)), + inside = (this.options.stacking || options.inside); // draw it inside the box? + + // Align to the column itself, or the top of it + if (point.shapeArgs) { // Area range uses this method but not alignTo + alignTo = merge(point.shapeArgs); + if (inverted) { + alignTo = { + x: chart.plotWidth - alignTo.y - alignTo.height, + y: chart.plotHeight - alignTo.x - alignTo.width, + width: alignTo.height, + height: alignTo.width + }; + } + + // Compute the alignment box + if (!inside) { + if (inverted) { + alignTo.x += below ? 0 : alignTo.width; + alignTo.width = 0; + } else { + alignTo.y += below ? alignTo.height : 0; + alignTo.height = 0; } } - }); + } + + // When alignment is undefined (typically columns and bars), display the individual + // point below or above the point depending on the threshold + options.align = pick( + options.align, + !inverted || inside ? 'center' : below ? 'right' : 'left' + ); + options.verticalAlign = pick( + options.verticalAlign, + inverted || inside ? 'middle' : below ? 'top' : 'bottom' + ); + + // Call the parent method + Series.prototype.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew); }, @@ -12872,6 +14377,7 @@ var ColumnSeries = extendClass(Series, { } }, + /** * Remove this series from the chart */ @@ -12893,22 +14399,42 @@ var ColumnSeries = extendClass(Series, { } }); seriesTypes.column = ColumnSeries; - +/** + * Set the default options for bar + */ +defaultPlotOptions.bar = merge(defaultPlotOptions.column); +/** + * The Bar series class + */ var BarSeries = extendClass(ColumnSeries, { type: 'bar', - init: function () { - this.inverted = true; - ColumnSeries.prototype.init.apply(this, arguments); - } + inverted: true }); seriesTypes.bar = BarSeries; +/** + * Set the default options for scatter + */ +defaultPlotOptions.scatter = merge(defaultSeriesOptions, { + lineWidth: 0, + states: { + hover: { + lineWidth: 0 + } + }, + tooltip: { + headerFormat: '{series.name}
', + pointFormat: 'x: {point.x}
y: {point.y}
' + } +}); + /** * The scatter series class */ var ScatterSeries = extendClass(Series, { type: 'scatter', sorted: false, + requireSorting: false, /** * Extend the base Series' translate method by adding shape type and * arguments for the point trackers @@ -12938,7 +14464,19 @@ var ScatterSeries = extendClass(Series, { css = cursor && { cursor: cursor }, points = series.points, i = points.length, - graphic; + graphic, + markerGroup = series.markerGroup, + onMouseOver = function (e) { + series.onMouseOver(); + if (e.target._i !== UNDEFINED) { // undefined on graph in scatterchart + points[e.target._i].onMouseOver(); + } + }, + onMouseOut = function () { + if (!series.options.stickyTracking) { + series.onMouseOut(); + } + }; // Set an expando property for the point index, used below while (i--) { @@ -12950,30 +14488,61 @@ var ScatterSeries = extendClass(Series, { // Add the event listeners, we need to do this only once if (!series._hasTracking) { - series.group + markerGroup .attr({ isTracker: true }) - .on(hasTouch ? 'touchstart' : 'mouseover', function (e) { - series.onMouseOver(); - if (e.target._i !== UNDEFINED) { // undefined on graph in scatterchart - points[e.target._i].onMouseOver(); - } - }) - .on('mouseout', function () { - if (!series.options.stickyTracking) { - series.onMouseOut(); - } - }) + .on('mouseover', onMouseOver) + .on('mouseout', onMouseOut) .css(css); + if (hasTouch) { + markerGroup.on('touchstart', onMouseOver); + } + } else { series._hasTracking = true; } - - } + }, + + setTooltipPoints: noop }); seriesTypes.scatter = ScatterSeries; +/** + * Set the default options for pie + */ +defaultPlotOptions.pie = merge(defaultSeriesOptions, { + borderColor: '#FFFFFF', + borderWidth: 1, + center: ['50%', '50%'], + colorByPoint: true, // always true for pies + dataLabels: { + // align: null, + // connectorWidth: 1, + // connectorColor: point.color, + // connectorPadding: 5, + distance: 30, + enabled: true, + formatter: function () { + return this.point.name; + } + // softConnector: true, + //y: 0 + }, + //innerSize: 0, + legendType: 'point', + marker: null, // point options are specified in the base options + size: '75%', + showInLegend: false, + slicedOffset: 10, + states: { + hover: { + brightness: 0.1, + shadow: false + } + } +}); + /** * Extended point object for pies */ @@ -13011,7 +14580,8 @@ var PiePoint = extendClass(Point, { */ setVisible: function (vis) { var point = this, - chart = point.series.chart, + series = point.series, + chart = series.chart, tracker = point.tracker, dataLabel = point.dataLabel, connector = point.connector, @@ -13039,6 +14609,12 @@ var PiePoint = extendClass(Point, { if (point.legendItem) { chart.legend.colorizeItem(point, vis); } + + // Handle ignore hidden slices + if (!series.isDirty && series.options.ignoreHiddenPoint) { + series.isDirty = true; + chart.redraw(); + } }, /** @@ -13076,10 +14652,11 @@ var PiePoint = extendClass(Point, { /** * The Pie series class */ -var PieSeries = extendClass(Series, { +var PieSeries = { type: 'pie', isCartesian: false, pointClass: PiePoint, + requireSorting: false, pointAttrToOptions: { // mapping between SVG attributes and the corresponding options stroke: 'borderColor', 'stroke-width': 'borderWidth', @@ -13095,23 +14672,23 @@ var PieSeries = extendClass(Series, { }, /** - * Animate the column heights one by one from zero + * Animate the pies in */ animate: function () { var series = this, - points = series.points; + points = series.points, + startAngleRad = series.startAngleRad; each(points, function (point) { var graphic = point.graphic, - args = point.shapeArgs, - up = -mathPI / 2; + args = point.shapeArgs; if (graphic) { // start values graphic.attr({ - r: 0, - start: up, - end: up + r: series.center[3] / 2, // animate from inner radius (#779) + start: startAngleRad, + end: startAngleRad }); // animate @@ -13140,37 +14717,22 @@ var PieSeries = extendClass(Series, { this.chart.redraw(); } }, + /** - * Do translation for pie slices + * Get the center of the pie based on the size and center options relative to the + * plot area. Borrowed by the polar and gauge series types. */ - translate: function () { - this.generatePoints(); + getCenter: function () { - var total = 0, - series = this, - cumulative = -0.25, // start at top - precision = 1000, // issue #172 - options = series.options, - slicedOffset = options.slicedOffset, - connectorOffset = slicedOffset + options.borderWidth, - positions = options.center.concat([options.size, options.innerSize || 0]), - chart = series.chart, + var options = this.options, + chart = this.chart, plotWidth = chart.plotWidth, plotHeight = chart.plotHeight, - start, - end, - angle, - points = series.points, - circ = 2 * mathPI, - fraction, + positions = options.center.concat([options.size, options.innerSize || 0]), smallestSize = mathMin(plotWidth, plotHeight), - isPercent, - radiusX, // the x component of the radius vector for a given point - radiusY, - labelDistance = options.dataLabels.distance; - - // get positions - either an integer or a percentage string must be given - positions = map(positions, function (length, i) { + isPercent; + + return map(positions, function (length, i) { isPercent = /%$/.test(length); return isPercent ? @@ -13182,6 +14744,40 @@ var PieSeries = extendClass(Series, { pInt(length) / 100 : length; }); + }, + + /** + * Do translation for pie slices + */ + translate: function () { + this.generatePoints(); + + var total = 0, + series = this, + cumulative = 0, + precision = 1000, // issue #172 + options = series.options, + slicedOffset = options.slicedOffset, + connectorOffset = slicedOffset + options.borderWidth, + positions, + chart = series.chart, + start, + end, + angle, + startAngleRad = series.startAngleRad = mathPI / 180 * ((options.startAngle || 0) % 360 - 90), + points = series.points, + circ = 2 * mathPI, + fraction, + radiusX, // the x component of the radius vector for a given point + radiusY, + labelDistance = options.dataLabels.distance, + ignoreHiddenPoint = options.ignoreHiddenPoint, + i, + len = points.length, + point; + + // get positions - either an integer or a percentage string must be given + series.center = positions = series.getCenter(); // utility for getting the x value from a given y, used for anticollision logic in data labels series.getX = function (y, left) { @@ -13193,20 +14789,24 @@ var PieSeries = extendClass(Series, { (mathCos(angle) * (positions[2] / 2 + labelDistance)); }; - // set center for later use - series.center = positions; - // get the total sum - each(points, function (point) { - total += point.y; - }); + for (i = 0; i < len; i++) { + point = points[i]; + total += (ignoreHiddenPoint && !point.visible) ? 0 : point.y; + } - each(points, function (point) { + // Calculate the geometry for each point + for (i = 0; i < len; i++) { + + point = points[i]; + // set start and end angle fraction = total ? point.y / total : 0; - start = mathRound(cumulative * circ * precision) / precision; - cumulative += fraction; - end = mathRound(cumulative * circ * precision) / precision; + start = mathRound((startAngleRad + (cumulative * circ)) * precision) / precision; + if (!ignoreHiddenPoint || point.visible) { + cumulative += fraction; + } + end = mathRound((startAngleRad + (cumulative * circ)) * precision) / precision; // set the shape point.shapeType = 'arc'; @@ -13221,6 +14821,9 @@ var PieSeries = extendClass(Series, { // center for the sliced out slice angle = (end + start) / 2; + if (angle > 0.75 * circ) { + angle -= 2 * mathPI; + } point.slicedTranslation = map([ mathCos(angle) * slicedOffset + chart.plotLeft, mathSin(angle) * slicedOffset + chart.plotTop @@ -13233,6 +14836,9 @@ var PieSeries = extendClass(Series, { positions[0] + radiusX * 0.7, positions[1] + radiusY * 0.7 ]; + + point.half = angle < circ / 4 ? 0 : 1; + point.angle = angle; // set the anchor point for data labels point.labelPos = [ @@ -13244,7 +14850,7 @@ var PieSeries = extendClass(Series, { positions[1] + radiusY, // a/a labelDistance < 0 ? // alignment 'center' : - angle < circ / 4 ? 'left' : 'right', // alignment + point.half ? 'right' : 'left', // alignment angle // center angle ]; @@ -13252,7 +14858,7 @@ var PieSeries = extendClass(Series, { point.percentage = fraction * 100; point.total = total; - }); + } this.setTooltipPoints(); @@ -13331,14 +14937,15 @@ var PieSeries = extendClass(Series, { if (graphic) { graphic.animate(shapeArgs); } else { - point.graphic = - renderer.arc(shapeArgs) + point.graphic = graphic = renderer.arc(shapeArgs) + .setRadialReference(series.center) .attr(extend( point.pointAttr[NORMAL_STATE], { 'stroke-linejoin': 'round' } )) .add(point.group) .shadow(shadow, shadowGroup); + } // detect point specific visibility @@ -13380,12 +14987,19 @@ var PieSeries = extendClass(Series, { y, visibility, rankArr, - sort, i = 2, - j; + j, + sort = function (a, b) { + return b.y - a.y; + }, + sortByAngle = function (points, sign) { + points.sort(function (a, b) { + return (b.angle - a.angle) * sign; + }); + }; // get out if not enabled - if (!options.enabled) { + if (!options.enabled && !series._hasPointLabels) { return; } @@ -13395,20 +15009,12 @@ var PieSeries = extendClass(Series, { // arrange points for detection collision each(data, function (point) { if (point.dataLabel) { // it may have been cancelled in the base method (#407) - halves[ - point.labelPos[7] < mathPI / 2 ? 0 : 1 - ].push(point); + halves[point.half].push(point); } }); - halves[1].reverse(); - - // define the sorting algorithm - sort = function (a, b) { - return b.y - a.y; - }; // assume equal label heights - labelHeight = halves[0][0] && halves[0][0].dataLabel && halves[0][0].dataLabel.getBBox().height; + labelHeight = halves[0][0] && halves[0][0].dataLabel && (halves[0][0].dataLabel.getBBox().height || 21); // 21 is for #968 /* Loop over the points in each half, starting from the top and bottom * of the pie to detect overlapping labels. @@ -13422,6 +15028,9 @@ var PieSeries = extendClass(Series, { pos, length = points.length, slotIndex; + + // Sort by angle + sortByAngle(points, i - 0.5); // Only do anti-collision when we are outside the pie and have connectors (#856) if (distanceOption > 0) { @@ -13552,7 +15161,7 @@ var PieSeries = extendClass(Series, { })[dataLabel.moved ? 'animate' : 'attr']({ x: x + options.x + ({ left: connectorPadding, right: -connectorPadding }[labelPos[6]] || 0), - y: y + options.y + y: y + options.y - 10 // 10 is for the baseline (label vs text) }); dataLabel.moved = true; @@ -13596,40 +15205,59 @@ var PieSeries = extendClass(Series, { } } }, + + alignDataLabel: noop, /** * Draw point specific tracker objects. Inherit directly from column series. */ drawTracker: ColumnSeries.prototype.drawTracker, + /** + * Use a simple symbol from column prototype + */ + drawLegendSymbol: AreaSeries.prototype.drawLegendSymbol, + /** * Pies don't have point marker symbols */ getSymbol: function () {} -}); +}; +PieSeries = extendClass(Series, PieSeries); seriesTypes.pie = PieSeries; // global variables extend(Highcharts, { + + // Constructors + Axis: Axis, + CanVGRenderer: CanVGRenderer, Chart: Chart, + Color: Color, + Legend: Legend, + MouseTracker: MouseTracker, + Point: Point, + Tick: Tick, + Tooltip: Tooltip, + Renderer: Renderer, + Series: Series, + SVGRenderer: SVGRenderer, + VMLRenderer: VMLRenderer, + + // Various + arrayMin: arrayMin, + arrayMax: arrayMax, + charts: charts, dateFormat: dateFormat, pathAnim: pathAnim, getOptions: getOptions, hasBidiBug: hasBidiBug, + isTouchDevice: isTouchDevice, numberFormat: numberFormat, - Point: Point, - Color: Color, - Renderer: Renderer, - SVGRenderer: SVGRenderer, - VMLRenderer: VMLRenderer, - CanVGRenderer: CanVGRenderer, seriesTypes: seriesTypes, setOptions: setOptions, - Series: Series, - - // Expose utility funcitons for modules addEvent: addEvent, removeEvent: removeEvent, createElement: createElement, @@ -13642,8 +15270,12 @@ extend(Highcharts, { pick: pick, splat: splat, extendClass: extendClass, - placeBox: placeBox, + pInt: pInt, + wrap: wrap, + svg: hasSVG, + canvas: useCanVG, + vml: !hasSVG && !useCanVG, product: 'Highcharts', - version: '2.2.3' + version: '2.3.5' }); }()); diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.js index 5274a3d5bb9..3425fc7ea3b 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.js @@ -11,10 +11,10 @@ Requires: rgbcolor.js - http://www.phpied.com/rgb-color-parser-in-javascript/ - Highcharts JS v2.2.3 (2012-05-07) + Highcharts JS v2.3.5 (2012-12-19) CanVGRenderer Extension module - (c) 2011-2012 Torstein H?nsi, Erik Olsson + (c) 2011-2012 Torstein Hønsi, Erik Olsson License: www.highcharts.com/license */ @@ -25,7 +25,7 @@ lightslateblue:"8470ff",lightslategray:"778899",lightsteelblue:"b0c4de",lightyel oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"d87093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",red:"ff0000",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd", slategray:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",violetred:"d02090",wheat:"f5deb3",white:"ffffff",whitesmoke:"f5f5f5",yellow:"ffff00",yellowgreen:"9acd32"},c;for(c in a)m==c&&(m=a[c]);var d=[{re:/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,example:["rgb(123, 234, 45)","rgb(255,234,245)"],process:function(b){return[parseInt(b[1]),parseInt(b[2]),parseInt(b[3])]}},{re:/^(\w{2})(\w{2})(\w{2})$/, example:["#00ff00","336699"],process:function(b){return[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)]}},{re:/^(\w{1})(\w{1})(\w{1})$/,example:["#fb0","f0f"],process:function(b){return[parseInt(b[1]+b[1],16),parseInt(b[2]+b[2],16),parseInt(b[3]+b[3],16)]}}];for(c=0;c255?255:this.r;this.g=this.g<0||isNaN(this.g)?0: -this.g>255?255:this.g;this.b=this.b<0||isNaN(this.b)?0:this.b>255?255:this.b;this.toRGB=function(){return"rgb("+this.r+", "+this.g+", "+this.b+")"};this.toHex=function(){var b=this.r.toString(16),a=this.g.toString(16),d=this.b.toString(16);b.length==1&&(b="0"+b);a.length==1&&(a="0"+a);d.length==1&&(d="0"+d);return"#"+b+a+d};this.getHelpXML=function(){for(var b=[],k=0;k255?255:this.g;this.b=this.b<0||isNaN(this.b)?0:this.b>255?255:this.b;this.toRGB=function(){return"rgb("+this.r+", "+this.g+", "+this.b+")"};this.toHex=function(){var b=this.r.toString(16),a=this.g.toString(16),d=this.b.toString(16);b.length==1&&(b="0"+b);a.length==1&&(a="0"+a);d.length==1&&(d="0"+d);return"#"+b+a+d};this.getHelpXML=function(){for(var b=[],k=0;k "+o.toRGB()+" -> "+o.toHex());l.appendChild(n);l.appendChild(q);c.appendChild(l)}catch(p){}return c}} if(!window.console)window.console={},window.console.log=function(){},window.console.dir=function(){};if(!Array.prototype.indexOf)Array.prototype.indexOf=function(m){for(var a=0;athis.x2)this.x2=b}if(a!=null){if(isNaN(this.y1)||isNaN(this.y2))this.y2=this.y1=a;if(athis.y2)this.y2=a}};this.addX=function(b){this.addPoint(b,null)};this.addY=function(b){this.addPoint(null,b)};this.addBoundingBox=function(b){this.addPoint(b.x1,b.y1);this.addPoint(b.x2,b.y2)};this.addQuadraticCurve=function(b,a,d,c,k,l){d=b+2/3*(d-b);c=a+2/3*(c- -a);this.addBezierCurve(b,a,d,d+1/3*(k-b),c,c+1/3*(l-a),k,l)};this.addBezierCurve=function(b,a,d,c,k,l,o,n){var q=[b,a],p=[d,c],s=[k,l],m=[o,n];this.addPoint(q[0],q[1]);this.addPoint(m[0],m[1]);for(i=0;i<=1;i++)b=function(b){return Math.pow(1-b,3)*q[i]+3*Math.pow(1-b,2)*b*p[i]+3*(1-b)*Math.pow(b,2)*s[i]+Math.pow(b,3)*m[i]},a=6*q[i]-12*p[i]+6*s[i],d=-3*q[i]+9*p[i]-9*s[i]+3*m[i],c=3*p[i]-3*q[i],d==0?a!=0&&(a=-c/a,01&&(j*=Math.sqrt(q),l*=Math.sqrt(q));o=(o==h?-1:1)*Math.sqrt((Math.pow(j,2)*Math.pow(l,2)-Math.pow(j,2)*Math.pow(n.y,2)-Math.pow(l,2)*Math.pow(n.x,2))/(Math.pow(j,2)*Math.pow(n.y,2)+Math.pow(l,2)*Math.pow(n.x,2)));isNaN(o)&&(o=0);var p=new a.Point(o*j*n.y/l,o*-l*n.x/j),g=new a.Point((g.x+e.x)/2+Math.cos(f)* -p.x-Math.sin(f)*p.y,(g.y+e.y)/2+Math.sin(f)*p.x+Math.cos(f)*p.y),m=function(b,a){return(b[0]*a[0]+b[1]*a[1])/(Math.sqrt(Math.pow(b[0],2)+Math.pow(b[1],2))*Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)))},t=function(b,a){return(b[0]*a[1]=1&&(n=0);h==0&&n>0&&(n-=2*Math.PI);h==1&&n<0&&(n+=2*Math.PI);q=new a.Point(g.x-j*Math.cos((o+n)/ -2),g.y-l*Math.sin((o+n)/2));b.addMarkerAngle(q,(o+n)/2+(h==0?1:-1)*Math.PI/2);b.addMarkerAngle(e,n+(h==0?1:-1)*Math.PI/2);c.addPoint(e.x,e.y);d!=null&&(m=j>l?j:l,e=j>l?1:j/l,j=j>l?l/j:1,d.translate(g.x,g.y),d.rotate(f),d.scale(e,j),d.arc(0,0,m,o,o+n,1-h),d.scale(1/e,1/j),d.rotate(-f),d.translate(-g.x,-g.y))}break;case "Z":d!=null&&d.closePath(),b.current=b.start}return c};this.getMarkers=function(){for(var a=this.PathParser.getMarkerPoints(),b=this.PathParser.getMarkerAngles(),c=[],e=0;e1&&(h*=Math.sqrt(q),l*=Math.sqrt(q));o=(o==j?-1:1)*Math.sqrt((Math.pow(h,2)*Math.pow(l,2)-Math.pow(h,2)*Math.pow(n.y,2)-Math.pow(l,2)*Math.pow(n.x,2))/(Math.pow(h,2)*Math.pow(n.y,2)+Math.pow(l,2)*Math.pow(n.x,2)));isNaN(o)&&(o=0);var p=new a.Point(o*h*n.y/l,o*-l*n.x/h),g=new a.Point((g.x+e.x)/2+Math.cos(f)* +p.x-Math.sin(f)*p.y,(g.y+e.y)/2+Math.sin(f)*p.x+Math.cos(f)*p.y),m=function(b,a){return(b[0]*a[0]+b[1]*a[1])/(Math.sqrt(Math.pow(b[0],2)+Math.pow(b[1],2))*Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)))},s=function(b,a){return(b[0]*a[1]=1&&(n=0);j==0&&n>0&&(n-=2*Math.PI);j==1&&n<0&&(n+=2*Math.PI);q=new a.Point(g.x-h*Math.cos((o+n)/ +2),g.y-l*Math.sin((o+n)/2));b.addMarkerAngle(q,(o+n)/2+(j==0?1:-1)*Math.PI/2);b.addMarkerAngle(e,n+(j==0?1:-1)*Math.PI/2);c.addPoint(e.x,e.y);d!=null&&(m=h>l?h:l,e=h>l?1:h/l,h=h>l?l/h:1,d.translate(g.x,g.y),d.rotate(f),d.scale(e,h),d.arc(0,0,m,o,o+n,1-j),d.scale(1/e,1/h),d.rotate(-f),d.translate(-g.x,-g.y))}break;case "Z":d!=null&&d.closePath(),b.current=b.start}return c};this.getMarkers=function(){for(var a=this.PathParser.getMarkerPoints(),b=this.PathParser.getMarkerAngles(),c=[],e=0;ethis.maxDuration)if(this.attribute("repeatCount").value=="indefinite")this.duration=0;else return this.attribute("fill").valueOrDefault("remove")=="remove"&&!this.removed?(this.removed=!0,this.getProperty().value=this.initialValue,!0):!1;this.duration+=a;a=!1;if(this.begin0&&b[c-1]!=" "&&c0&&b[c-1]!=" "&&(c==b.length-1||b[c+1]==" "))g="initial";typeof a.glyphs[e]!="undefined"&&(f=a.glyphs[e][g],f==null&&a.glyphs[e].type=="glyph"&&(f=a.glyphs[e]))}else f=a.glyphs[e];if(f==null)f=a.missingGlyph;return f};this.renderChildren=function(c){var b=this.parent.style("font-family").Definition.getDefinition();if(b!=null){var k=this.parent.style("font-size").numValueOrDefault(a.Font.Parse(a.ctx.font).fontSize), -e=this.parent.style("font-style").valueOrDefault(a.Font.Parse(a.ctx.font).fontStyle),f=this.getText();b.isRTL&&(f=f.split("").reverse().join(""));for(var g=a.ToNumberArray(this.parent.attribute("dx").value),h=0;h0?c.childNodes[0].nodeValue:c.text;this.getText=function(){return this.text}};a.Element.tspan.prototype=new a.Element.TextElementBase;a.Element.tref=function(c){this.base=a.Element.TextElementBase;this.base(c);this.getText=function(){var a=this.attribute("xlink:href").Definition.getDefinition();if(a!=null)return a.children[0].getText()}};a.Element.tref.prototype=new a.Element.TextElementBase; a.Element.a=function(c){this.base=a.Element.TextElementBase;this.base(c);this.hasText=!0;for(var d=0;d1?c.childNodes[1].nodeValue: -""),c=c.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(^[\s]*\/\/.*)/gm,""),c=a.compressSpaces(c),c=c.split("}"),d=0;d0){l=g[h].indexOf("url");j=g[h].indexOf(")",l);l=g[h].substr(l+5,j-l-6);l=a.parseXml(a.ajax(l)).getElementsByTagName("font");for(j=0;j0){l=g[j].indexOf("url");h=g[j].indexOf(")",l);l=g[j].substr(l+5,h-l-6);l=a.parseXml(a.ajax(l)).getElementsByTagName("font");for(h=0;h=c&&k<=g){var e=b.split(a.itemDelimiter||",");l(e,function(a,b){b>=f&&b<=j&&(d[b-f]||(d[b-f]=[]),d[b-f][k-c]=a)})}}),this.dataFound())},parseTable:function(){var a=this.options,b=a.table,d=this.columns,c=a.startRow||0,g=a.endRow||Number.MAX_VALUE,f=a.startColumn||0,j=a.endColumn||Number.MAX_VALUE,i;b&&(typeof b==="string"&&(b=document.getElementById(b)),l(b.getElementsByTagName("tr"),function(a,b){i= +0;b>=c&&b<=g&&l(a.childNodes,function(a){if((a.tagName==="TD"||a.tagName==="TH")&&i>=f&&i<=j)d[i]||(d[i]=[]),d[i][b-c]=a.innerHTML,i+=1})}),this.dataFound())},parseGoogleSpreadsheet:function(){var a=this,b=this.options,d=b.googleSpreadsheetKey,c=this.columns;d&&jQuery.getJSON("https://spreadsheets.google.com/feeds/cells/"+d+"/"+(b.googleSpreadsheetWorksheet||"od6")+"/public/values?alt=json-in-script&callback=?",function(b){var b=b.feed.entry,d,j=b.length,i=0,k=0,e;for(e=0;e31536E6?a[b].isDatetime=!0:a[b].isNumeric= +!0):(c=this.parseDate(c),b===0&&typeof c==="number"&&!isNaN(c)?(a[b][d]=c,a[b].isDatetime=!0):a[b][d]=f)},dateFormats:{"YYYY-mm-dd":{regex:"^([0-9]{4})-([0-9]{2})-([0-9]{2})$",parser:function(a){return Date.UTC(+a[1],a[2]-1,+a[3])}}},parseDate:function(a){var b=this.options.parseDate,d,c,g;b&&(d=b);if(typeof a==="string")for(c in this.dateFormats)b=this.dateFormats[c],(g=a.match(b.regex))&&(d=b.parser(g));return d},rowsToColumns:function(a){var b,d,c,g,f;if(a){f=[];d=a.length;for(b=0;b1&&(c=a.shift(),this.headerRow===0&&c.shift(),(b=c.isNumeric||c.isDatetime)||(d=c),c.isDatetime&&(g="datetime"));j=[];for(e=0;e> + * A two-dimensional array representing the input data on tabular form. This input can + * be used when the data is already parsed, for example from a grid view component. + * Each cell can be a string or number. If not switchRowsAndColumns is set, the columns + * are interpreted as series. See also the rows option. + * + * - complete : Function(chartOptions) + * The callback that is evaluated when the data is finished loading, optionally from an + * external source, and parsed. The first argument passed is a finished chart options + * object, containing series and an xAxis with categories if applicable. Thise options + * can be extended with additional options and passed directly to the chart constructor. + * + * - csv : String + * A comma delimited string to be parsed. Related options are startRow, endRow, startColumn + * and endColumn to delimit what part of the table is used. The lineDelimiter and + * itemDelimiter options define the CSV delimiter formats. + * + * - endColumn : Integer + * In tabular input data, the first row (indexed by 0) to use. Defaults to the last + * column containing data. + * + * - endRow : Integer + * In tabular input data, the last row (indexed by 0) to use. Defaults to the last row + * containing data. + * + * - googleSpreadsheetKey : String + * A Google Spreadsheet key. See https://developers.google.com/gdata/samples/spreadsheet_sample + * for general information on GS. + * + * - googleSpreadsheetKey : String + * The Google Spreadsheet worksheet. The available id's can be read from + * https://spreadsheets.google.com/feeds/worksheets/{key}/public/basic + * + * - itemDilimiter : String + * Item or cell delimiter for parsing CSV. Defaults to ",". + * + * - lineDilimiter : String + * Line delimiter for parsing CSV. Defaults to "\n". + * + * - parsed : Function + * A callback function to access the parsed columns, the two-dimentional input data + * array directly, before they are interpreted into series data and categories. + * + * - parseDate : Function + * A callback function to parse string representations of dates into JavaScript timestamps. + * Return an integer on success. + * + * - rows : Array> + * The same as the columns input option, but defining rows intead of columns. + * + * - startColumn : Integer + * In tabular input data, the first column (indexed by 0) to use. + * + * - startRow : Integer + * In tabular input data, the first row (indexed by 0) to use. + * + * - table : String|HTMLElement + * A HTML table or the id of such to be parsed as input data. Related options ara startRow, + * endRow, startColumn and endColumn to delimit what part of the table is used. + */ + +/*global jQuery */ +(function (Highcharts) { + + // Utilities + var each = Highcharts.each; + + + // The Data constructor + var Data = function (options) { + this.init(options); + }; + + // Set the prototype properties + Highcharts.extend(Data.prototype, { + + /** + * Initialize the Data object with the given options + */ + init: function (options) { + this.options = options; + this.columns = options.columns || this.rowsToColumns(options.rows) || []; + + // No need to parse or interpret anything + if (this.columns.length) { + this.dataFound(); + + // Parse and interpret + } else { + + // Parse a CSV string if options.csv is given + this.parseCSV(); + + // Parse a HTML table if options.table is given + this.parseTable(); + + // Parse a Google Spreadsheet + this.parseGoogleSpreadsheet(); + } + + }, + + dataFound: function () { + + // Interpret the values into right types + this.parseTypes(); + + // Use first row for series names? + this.findHeaderRow(); + + // Handle columns if a handleColumns callback is given + this.parsed(); + + // Complete if a complete callback is given + this.complete(); + + }, + + /** + * Parse a CSV input string + */ + parseCSV: function () { + var options = this.options, + csv = options.csv, + columns = this.columns, + startRow = options.startRow || 0, + endRow = options.endRow || Number.MAX_VALUE, + startColumn = options.startColumn || 0, + endColumn = options.endColumn || Number.MAX_VALUE, + lines; + + if (csv) { + + lines = csv + .replace(/\r\n/g, "\n") // Unix + .replace(/\r/g, "\n") // Mac + .split(options.lineDelimiter || "\n"); + + each(lines, function (line, rowNo) { + if (rowNo >= startRow && rowNo <= endRow) { + var items = line.split(options.itemDelimiter || ','); + each(items, function (item, colNo) { + if (colNo >= startColumn && colNo <= endColumn) { + if (!columns[colNo - startColumn]) { + columns[colNo - startColumn] = []; + } + + columns[colNo - startColumn][rowNo - startRow] = item; + } + }); + } + }); + this.dataFound(); + } + }, + + /** + * Parse a HTML table + */ + parseTable: function () { + var options = this.options, + table = options.table, + columns = this.columns, + startRow = options.startRow || 0, + endRow = options.endRow || Number.MAX_VALUE, + startColumn = options.startColumn || 0, + endColumn = options.endColumn || Number.MAX_VALUE, + colNo; + + if (table) { + + if (typeof table === 'string') { + table = document.getElementById(table); + } + + each(table.getElementsByTagName('tr'), function (tr, rowNo) { + colNo = 0; + if (rowNo >= startRow && rowNo <= endRow) { + each(tr.childNodes, function (item) { + if ((item.tagName === 'TD' || item.tagName === 'TH') && colNo >= startColumn && colNo <= endColumn) { + if (!columns[colNo]) { + columns[colNo] = []; + } + columns[colNo][rowNo - startRow] = item.innerHTML; + + colNo += 1; + } + }); + } + }); + + this.dataFound(); // continue + } + }, + + /** + * TODO: + * - switchRowsAndColumns + * - startRow, endRow etc. + */ + parseGoogleSpreadsheet: function () { + var self = this, + options = this.options, + googleSpreadsheetKey = options.googleSpreadsheetKey, + columns = this.columns; + + if (googleSpreadsheetKey) { + jQuery.getJSON('https://spreadsheets.google.com/feeds/cells/' + + googleSpreadsheetKey + '/' + (options.googleSpreadsheetWorksheet || 'od6') + + '/public/values?alt=json-in-script&callback=?', + function (json) { + + // Prepare the data from the spreadsheat + var cells = json.feed.entry, + cell, + cellCount = cells.length, + colCount = 0, + rowCount = 0, + i; + + // First, find the total number of columns and rows that + // are actually filled with data + for (i = 0; i < cellCount; i++) { + cell = cells[i]; + colCount = Math.max(colCount, cell.gs$cell.col); + rowCount = Math.max(rowCount, cell.gs$cell.row); + } + + // Set up arrays containing the column data + for (i = 0; i < colCount; i++) { + columns[i] = new Array(rowCount); + } + + // Loop over the cells and assign the value to the right + // place in the column arrays + for (i = 0; i < cellCount; i++) { + cell = cells[i]; + columns[cell.gs$cell.col - 1][cell.gs$cell.row - 1] = + cell.content.$t; + } + self.dataFound(); + }); + } + }, + + /** + * Find the header row. For now, we just check whether the first row contains + * numbers or strings. Later we could loop down and find the first row with + * numbers. + */ + findHeaderRow: function () { + var headerRow = 0; + each(this.columns, function (column) { + if (typeof column[0] !== 'string') { + headerRow = null; + } + }); + this.headerRow = 0; + }, + + /** + * Trim a string from whitespace + */ + trim: function (str) { + //return typeof str === 'number' ? str : str.replace(/^\s+|\s+$/g, ''); // fails with spreadsheet + return typeof str === 'string' ? str.replace(/^\s+|\s+$/g, '') : str; + }, + + /** + * Parse numeric cells in to number types and date types in to true dates. + * @param {Object} columns + */ + parseTypes: function () { + var columns = this.columns, + col = columns.length, + row, + val, + floatVal, + trimVal, + dateVal; + + while (col--) { + row = columns[col].length; + while (row--) { + val = columns[col][row]; + floatVal = parseFloat(val); + trimVal = this.trim(val); + /*jslint eqeq: true*/ + if (trimVal == floatVal) { // is numeric + /*jslint eqeq: false*/ + columns[col][row] = floatVal; + + // If the number is greater than milliseconds in a year, assume datetime + if (floatVal > 365 * 24 * 3600 * 1000) { + columns[col].isDatetime = true; + } else { + columns[col].isNumeric = true; + } + + } else { // string, continue to determine if it is a date string or really a string + dateVal = this.parseDate(val); + + if (col === 0 && typeof dateVal === 'number' && !isNaN(dateVal)) { // is date + columns[col][row] = dateVal; + columns[col].isDatetime = true; + + } else { // string + columns[col][row] = trimVal; + } + } + + } + } + }, + //* + dateFormats: { + 'YYYY-mm-dd': { + regex: '^([0-9]{4})-([0-9]{2})-([0-9]{2})$', + parser: function (match) { + return Date.UTC(+match[1], match[2] - 1, +match[3]); + } + } + }, + // */ + /** + * Parse a date and return it as a number. Overridable through options.parseDate. + */ + parseDate: function (val) { + var parseDate = this.options.parseDate, + ret, + key, + format, + match; + + if (parseDate) { + ret = parseDate; + } + + if (typeof val === 'string') { + for (key in this.dateFormats) { + format = this.dateFormats[key]; + match = val.match(format.regex); + if (match) { + ret = format.parser(match); + } + } + } + return ret; + }, + + /** + * Reorganize rows into columns + */ + rowsToColumns: function (rows) { + var row, + rowsLength, + col, + colsLength, + columns; + + if (rows) { + columns = []; + rowsLength = rows.length; + for (row = 0; row < rowsLength; row++) { + colsLength = rows[row].length; + for (col = 0; col < colsLength; col++) { + if (!columns[col]) { + columns[col] = []; + } + columns[col][row] = rows[row][col]; + } + } + } + return columns; + }, + + /** + * A hook for working directly on the parsed columns + */ + parsed: function () { + if (this.options.parsed) { + this.options.parsed.call(this, this.columns); + } + }, + + /** + * If a complete callback function is provided in the options, interpret the + * columns into a Highcharts options object. + */ + complete: function () { + + var columns = this.columns, + hasXData, + categories, + firstCol, + type, + options = this.options, + series, + data, + name, + i, + j; + + + if (options.complete) { + + // Use first column for X data or categories? + if (columns.length > 1) { + firstCol = columns.shift(); + if (this.headerRow === 0) { + firstCol.shift(); // remove the first cell + } + + // Use the first column for categories or X values + hasXData = firstCol.isNumeric || firstCol.isDatetime; + if (!hasXData) { // means type is neither datetime nor linear + categories = firstCol; + } + + if (firstCol.isDatetime) { + type = 'datetime'; + } + } + + // Use the next columns for series + series = []; + for (i = 0; i < columns.length; i++) { + if (this.headerRow === 0) { + name = columns[i].shift(); + } + data = []; + for (j = 0; j < columns[i].length; j++) { + data[j] = columns[i][j] !== undefined ? + (hasXData ? + [firstCol[j], columns[i][j]] : + columns[i][j] + ) : + null; + } + series[i] = { + name: name, + data: data + }; + } + + // Do the callback + options.complete({ + xAxis: { + categories: categories, + type: type + }, + series: series + }); + } + } + }); + + // Register the Data prototype and data function on Highcharts + Highcharts.Data = Data; + Highcharts.data = function (options) { + return new Data(options); + }; + + // Extend Chart.init so that the Chart constructor accepts a new configuration + // option group, data. + Highcharts.wrap(Highcharts.Chart.prototype, 'init', function (proceed, userOptions, callback) { + var chart = this; + + if (userOptions && userOptions.data) { + Highcharts.data(Highcharts.extend(userOptions.data, { + complete: function (dataOptions) { + var datasets = []; + + // Don't merge the data arrays themselves + each(dataOptions.series, function (series, i) { + datasets[i] = series.data; + series.data = null; + }); + + // Do the merge + userOptions = Highcharts.merge(dataOptions, userOptions); + + // Re-insert the data + each(datasets, function (data, i) { + userOptions.series[i].data = data; + }); + proceed.call(chart, userOptions, callback); + } + })); + } else { + proceed.call(chart, userOptions, callback); + } + }); + +}(Highcharts)); diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.js index 990557b6168..5c0d0e5c61c 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.js @@ -1,23 +1,23 @@ /* - Highcharts JS v2.2.3 (2012-05-07) + Highcharts JS v2.3.5 (2012-12-19) Exporting module - (c) 2010-2011 Torstein H?nsi + (c) 2010-2011 Torstein Hønsi License: www.highcharts.com/license */ -(function(){function x(a){for(var b=a.length;b--;)typeof a[b]==="number"&&(a[b]=Math.round(a[b])-0.5);return a}var f=Highcharts,y=f.Chart,z=f.addEvent,B=f.removeEvent,r=f.createElement,u=f.discardElement,t=f.css,s=f.merge,k=f.each,n=f.extend,C=Math.max,h=document,D=window,A=h.documentElement.ontouchstart!==void 0,v=f.getOptions();n(v.lang,{downloadPNG:"Download PNG image",downloadJPEG:"Download JPEG image",downloadPDF:"Download PDF document",downloadSVG:"Download SVG vector image",exportButtonTitle:"Export to raster or vector image", -printButtonTitle:"Print the chart"});v.navigation={menuStyle:{border:"1px solid #A0A0A0",background:"#FFFFFF"},menuItemStyle:{padding:"0 5px",background:"none",color:"#303030",fontSize:A?"14px":"11px"},menuItemHoverStyle:{background:"#4572A5",color:"#FFFFFF"},buttonOptions:{align:"right",backgroundColor:{linearGradient:[0,0,0,20],stops:[[0.4,"#F7F7F7"],[0.6,"#E3E3E3"]]},borderColor:"#B0B0B0",borderRadius:3,borderWidth:1,height:20,hoverBorderColor:"#909090",hoverSymbolFill:"#81A7CF",hoverSymbolStroke:"#4572A5", -symbolFill:"#E0E0E0",symbolStroke:"#A0A0A0",symbolX:11.5,symbolY:10.5,verticalAlign:"top",width:24,y:10}};v.exporting={type:"image/png",url:"http://export.highcharts.com/",width:800,buttons:{exportButton:{symbol:"exportIcon",x:-10,symbolFill:"#A8BF77",hoverSymbolFill:"#768F3E",_id:"exportButton",_titleKey:"exportButtonTitle",menuItems:[{textKey:"downloadPNG",onclick:function(){this.exportChart()}},{textKey:"downloadJPEG",onclick:function(){this.exportChart({type:"image/jpeg"})}},{textKey:"downloadPDF", -onclick:function(){this.exportChart({type:"application/pdf"})}},{textKey:"downloadSVG",onclick:function(){this.exportChart({type:"image/svg+xml"})}}]},printButton:{symbol:"printIcon",x:-36,symbolFill:"#B5C9DF",hoverSymbolFill:"#779ABF",_id:"printButton",_titleKey:"printButtonTitle",onclick:function(){this.print()}}}};n(y.prototype,{getSVG:function(a){var b=this,c,d,e,g=s(b.options,a);if(!h.createElementNS)h.createElementNS=function(a,b){var c=h.createElement(b);c.getBBox=function(){return f.Renderer.prototype.Element.prototype.getBBox.apply({element:c})}; -return c};a=r("div",null,{position:"absolute",top:"-9999em",width:b.chartWidth+"px",height:b.chartHeight+"px"},h.body);n(g.chart,{renderTo:a,forExport:!0});g.exporting.enabled=!1;g.chart.plotBackgroundImage=null;g.series=[];k(b.series,function(a){e=s(a.options,{animation:!1,showCheckbox:!1,visible:a.visible});if(!e.isInternal){if(e&&e.marker&&/^url\(/.test(e.marker.symbol))e.marker.symbol="circle";g.series.push(e)}});c=new Highcharts.Chart(g);k(["xAxis","yAxis"],function(a){k(b[a],function(b,d){var e= -c[a][d],g=b.getExtremes(),f=g.userMin,g=g.userMax;(f!==void 0||g!==void 0)&&e.setExtremes(f,g,!0,!1)})});d=c.container.innerHTML;g=null;c.destroy();u(a);d=d.replace(/zIndex="[^"]+"/g,"").replace(/isShadow="[^"]+"/g,"").replace(/symbolName="[^"]+"/g,"").replace(/jQuery[0-9]+="[^"]+"/g,"").replace(/isTracker="[^"]+"/g,"").replace(/url\([^#]+#/g,"url(#").replace(/.*?$/,"").replace(/ /g, -"\u00a0").replace(/­/g,"\u00ad").replace(//g,'xlink:href="$1"/>').replace(/id=([^" >]+)/g,'id="$1"').replace(/class=([^" ]+)/g,'class="$1"').replace(/ transform /g," ").replace(/:(path|rect)/g,"$1").replace(/style="([^"]+)"/g,function(a){return a.toLowerCase()});d=d.replace(/(url\(#highcharts-[0-9]+)"/g,"$1").replace(/"/g,"'");d.match(/ xmlns="/g).length=== -2&&(d=d.replace(/xmlns="[^"]+"/,""));return d},exportChart:function(a,b){var c,d=this.getSVG(s(this.options.exporting.chartOptions,b)),a=s(this.options.exporting,a);c=r("form",{method:"post",action:a.url,enctype:"multipart/form-data"},{display:"none"},h.body);k(["filename","type","width","svg"],function(b){r("input",{type:"hidden",name:b,value:{filename:a.filename||"chart",type:a.type,width:a.width,svg:d}[b]},null,c)});c.submit();u(c)},print:function(){var a=this,b=a.container,c=[],d=b.parentNode, -e=h.body,g=e.childNodes;if(!a.isPrinting)a.isPrinting=!0,k(g,function(a,b){if(a.nodeType===1)c[b]=a.style.display,a.style.display="none"}),e.appendChild(b),D.print(),setTimeout(function(){d.appendChild(b);k(g,function(a,b){if(a.nodeType===1)a.style.display=c[b]});a.isPrinting=!1},1E3)},contextMenu:function(a,b,c,d,e,g){var i=this,f=i.options.navigation,h=f.menuItemStyle,o=i.chartWidth,p=i.chartHeight,q="cache-"+a,j=i[q],l=C(e,g),m,w;if(!j)i[q]=j=r("div",{className:"highcharts-"+a},{position:"absolute", -zIndex:1E3,padding:l+"px"},i.container),m=r("div",null,n({MozBoxShadow:"3px 3px 10px #888",WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"},f.menuStyle),j),w=function(){t(j,{display:"none"})},z(j,"mouseleave",w),k(b,function(a){if(a){var b=r("div",{onmouseover:function(){t(this,f.menuItemHoverStyle)},onmouseout:function(){t(this,h)},innerHTML:a.text||i.options.lang[a.textKey]},n({cursor:"pointer"},h),m);b[A?"ontouchstart":"onclick"]=function(){w();a.onclick.apply(i,arguments)};i.exportDivElements.push(b)}}), -i.exportDivElements.push(m,j),i.exportMenuWidth=j.offsetWidth,i.exportMenuHeight=j.offsetHeight;a={display:"block"};c+i.exportMenuWidth>o?a.right=o-c-e-l+"px":a.left=c-l+"px";d+g+i.exportMenuHeight>p?a.bottom=p-d-l+"px":a.top=d+g-l+"px";t(j,a)},addButton:function(a){function b(){p.attr(l);o.attr(j)}var c=this,d=c.renderer,e=s(c.options.navigation.buttonOptions,a),g=e.onclick,f=e.menuItems,h=e.width,k=e.height,o,p,q,a=e.borderWidth,j={stroke:e.borderColor},l={stroke:e.symbolStroke,fill:e.symbolFill}, -m=e.symbolSize||12;if(!c.exportDivElements)c.exportDivElements=[],c.exportSVGElements=[];e.enabled!==!1&&(o=d.rect(0,0,h,k,e.borderRadius,a).align(e,!0).attr(n({fill:e.backgroundColor,"stroke-width":a,zIndex:19},j)).add(),q=d.rect(0,0,h,k,0).align(e).attr({id:e._id,fill:"rgba(255, 255, 255, 0.001)",title:c.options.lang[e._titleKey],zIndex:21}).css({cursor:"pointer"}).on("mouseover",function(){p.attr({stroke:e.hoverSymbolStroke,fill:e.hoverSymbolFill});o.attr({stroke:e.hoverBorderColor})}).on("mouseout", -b).on("click",b).add(),f&&(g=function(){b();var a=q.getBBox();c.contextMenu("export-menu",f,a.x,a.y,h,k)}),q.on("click",function(){g.apply(c,arguments)}),p=d.symbol(e.symbol,e.symbolX-m/2,e.symbolY-m/2,m,m).align(e,!0).attr(n(l,{"stroke-width":e.symbolStrokeWidth||1,zIndex:20})).add(),c.exportSVGElements.push(o,q,p))},destroyExport:function(){var a,b;for(a=0;a.*?$/,"").replace(/ /g," ").replace(/­/g,"­").replace(//g,'xlink:href="$1"/>').replace(/id=([^" >]+)/g,'id="$1"').replace(/class=([^" ]+)/g,'class="$1"').replace(/ transform /g," ").replace(/:(path|rect)/g,"$1").replace(/style="([^"]+)"/g,function(a){return a.toLowerCase()});d=d.replace(/(url\(#highcharts-[0-9]+)"/g, +"$1").replace(/"/g,"'");d.match(/ xmlns="/g).length===2&&(d=d.replace(/xmlns="[^"]+"/,""));return d},exportChart:function(a,b){var c=this.options.exporting,d=this.getSVG(l(c.chartOptions,b)),a=l(c,a);e.post(a.url,{filename:a.filename||"chart",type:a.type,width:a.width,scale:a.scale||2,svg:d})},print:function(){var a=this,b=a.container,c=[],d=b.parentNode,f=i.body,g=f.childNodes;if(!a.isPrinting)a.isPrinting=!0,k(g,function(a,b){if(a.nodeType===1)c[b]=a.style.display,a.style.display="none"}), +f.appendChild(b),D.print(),setTimeout(function(){d.appendChild(b);k(g,function(a,b){if(a.nodeType===1)a.style.display=c[b]});a.isPrinting=!1},1E3)},contextMenu:function(a,b,c,d,f,g){var e=this,p=e.options.navigation,i=p.menuItemStyle,q=e.chartWidth,r=e.chartHeight,s="cache-"+a,h=e[s],m=C(f,g),x,n,l;if(!h)e[s]=h=j("div",{className:"highcharts-"+a},{position:"absolute",zIndex:1E3,padding:m+"px"},e.container),x=j("div",null,o({MozBoxShadow:"3px 3px 10px #888",WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"}, +p.menuStyle),h),n=function(){t(h,{display:"none"})},u(h,"mouseleave",function(){l=setTimeout(n,500)}),u(h,"mouseenter",function(){clearTimeout(l)}),k(b,function(a){if(a){var b=j("div",{onmouseover:function(){t(this,p.menuItemHoverStyle)},onmouseout:function(){t(this,i)},innerHTML:a.text||e.options.lang[a.textKey]},o({cursor:"pointer"},i),x);b.onclick=function(){n();a.onclick.apply(e,arguments)};e.exportDivElements.push(b)}}),e.exportDivElements.push(x,h),e.exportMenuWidth=h.offsetWidth,e.exportMenuHeight= +h.offsetHeight;a={display:"block"};c+e.exportMenuWidth>q?a.right=q-c-f-m+"px":a.left=c-m+"px";d+g+e.exportMenuHeight>r?a.bottom=r-d-m+"px":a.top=d+g-m+"px";t(h,a)},addButton:function(a){function b(){r.attr(k);q.attr(m)}var c=this,d=c.renderer,f=l(c.options.navigation.buttonOptions,a),e=f.onclick,i=f.menuItems,p=f.width,j=f.height,q,r,s,h,a=f.borderWidth,m={stroke:f.borderColor},k={stroke:f.symbolStroke,fill:f.symbolFill},n=f.symbolSize||12;if(!c.btnCount)c.btnCount=0;h=c.btnCount++;if(!c.exportDivElements)c.exportDivElements= +[],c.exportSVGElements=[];f.enabled!==!1&&(q=d.rect(0,0,p,j,f.borderRadius,a).align(f,!0).attr(o({fill:f.backgroundColor,"stroke-width":a,zIndex:19},m)).add(),s=d.rect(0,0,p,j,0).align(f).attr({id:f._id,fill:"rgba(255, 255, 255, 0.001)",title:c.options.lang[f._titleKey],zIndex:21}).css({cursor:"pointer"}).on("mouseover",function(){r.attr({stroke:f.hoverSymbolStroke,fill:f.hoverSymbolFill});q.attr({stroke:f.hoverBorderColor})}).on("mouseout",b).on("click",b).add(),i&&(e=function(){b();var a=s.getBBox(); +c.contextMenu("menu"+h,i,a.x,a.y,p,j)}),s.on("click",function(){e.apply(c,arguments)}),r=d.symbol(f.symbol,f.symbolX-n/2,f.symbolY-n/2,n,n).align(f,!0).attr(o(k,{"stroke-width":f.symbolStrokeWidth||1,zIndex:20})).add(),c.exportSVGElements.push(q,s,r))},destroyExport:function(){var a,b;for(a=0;a Date: Thu, 24 Jan 2013 15:53:01 +0100 Subject: [PATCH 12/37] Added method in sailing service for polar sheet generation also added some functionality to the polarsheetchartpanel --- .../META-INF/MANIFEST.MF | 1 + .../PolarSheetGenerationWorker.java | 20 + java/com.sap.sailing.gwt.ui/PolarSheets.html | 1 + .../sailing/gwt/ui/client/SailingService.java | 146 +-- .../gwt/ui/client/SailingServiceAsync.java | 223 ++-- .../ui/polarsheets/PolarSheetsChartPanel.java | 63 +- .../gwt/ui/polarsheets/PolarSheetsPanel.java | 31 +- .../gwt/ui/server/SailingServiceImpl.java | 1000 ++++++++++------- 8 files changed, 890 insertions(+), 595 deletions(-) create mode 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java diff --git a/java/com.sap.sailing.domain/META-INF/MANIFEST.MF b/java/com.sap.sailing.domain/META-INF/MANIFEST.MF index bc76fb9fd21..0231cb99102 100755 --- a/java/com.sap.sailing.domain/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.domain/META-INF/MANIFEST.MF @@ -13,6 +13,7 @@ Export-Package: com.sap.sailing.domain.base, com.sap.sailing.domain.leaderboard, com.sap.sailing.domain.leaderboard.impl, com.sap.sailing.domain.leaderboard.meta, + com.sap.sailing.domain.polarsheets, com.sap.sailing.domain.tracking, com.sap.sailing.domain.tracking.impl, com.sap.sailing.util, diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java new file mode 100644 index 00000000000..671711d1ec6 --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java @@ -0,0 +1,20 @@ +package com.sap.sailing.domain.polarsheets; + +import java.util.List; + +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; + +public class PolarSheetGenerationWorker { + + private final List selectedRaces; + + public PolarSheetGenerationWorker(List selectedRaces) { + this.selectedRaces = selectedRaces; + } + + public void startPolarSheetGeneration() { + // TODO Auto-generated method stub + + } + +} diff --git a/java/com.sap.sailing.gwt.ui/PolarSheets.html b/java/com.sap.sailing.gwt.ui/PolarSheets.html index 39cb1b74a67..ee8905e056c 100644 --- a/java/com.sap.sailing.gwt.ui/PolarSheets.html +++ b/java/com.sap.sailing.gwt.ui/PolarSheets.html @@ -13,6 +13,7 @@ + diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java index 5c85446effb..af791ee8b47 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java @@ -22,6 +22,7 @@ import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Triple; import com.sap.sailing.gwt.ui.shared.BulkScoreCorrectionDTO; import com.sap.sailing.gwt.ui.shared.CompetitorDTO; +import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO; import com.sap.sailing.gwt.ui.shared.ControlPointDTO; import com.sap.sailing.gwt.ui.shared.CourseDTO; import com.sap.sailing.gwt.ui.shared.EventDTO; @@ -29,10 +30,9 @@ import com.sap.sailing.gwt.ui.shared.GPSFixDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; import com.sap.sailing.gwt.ui.shared.ManeuverDTO; -import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO; import com.sap.sailing.gwt.ui.shared.QuickRankDTO; -import com.sap.sailing.gwt.ui.shared.RaceCourseMarksDTO; import com.sap.sailing.gwt.ui.shared.RaceColumnInSeriesDTO; +import com.sap.sailing.gwt.ui.shared.RaceCourseMarksDTO; import com.sap.sailing.gwt.ui.shared.RaceDTO; import com.sap.sailing.gwt.ui.shared.RaceMapDataDTO; import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO; @@ -42,9 +42,9 @@ import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO; import com.sap.sailing.gwt.ui.shared.ScoreCorrectionProviderDTO; import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationDTO; -import com.sap.sailing.gwt.ui.shared.SwissTimingReplayRaceDTO; import com.sap.sailing.gwt.ui.shared.SwissTimingConfigurationDTO; import com.sap.sailing.gwt.ui.shared.SwissTimingRaceRecordDTO; +import com.sap.sailing.gwt.ui.shared.SwissTimingReplayRaceDTO; import com.sap.sailing.gwt.ui.shared.TracTracConfigurationDTO; import com.sap.sailing.gwt.ui.shared.TracTracRaceRecordDTO; import com.sap.sailing.gwt.ui.shared.VenueDTO; @@ -52,13 +52,13 @@ import com.sap.sailing.gwt.ui.shared.WindDTO; import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO; /** - * The client side stub for the RPC service. Usually, when a null date is passed to - * the time-dependent service methods, an empty (non-null) result is returned. + * The client side stub for the RPC service. Usually, when a null date is passed to the time-dependent + * service methods, an empty (non-null) result is returned. */ @RemoteServiceRelativePath("sailing") public interface SailingService extends RemoteService { List getPreviousTracTracConfigurations() throws Exception; - + List getRegattas(); List getEvents(); @@ -66,42 +66,46 @@ public interface SailingService extends RemoteService { Pair> listTracTracRacesInEvent(String eventJsonURL) throws Exception; void trackWithTracTrac(RegattaIdentifier regattaToAddTo, TracTracRaceRecordDTO rr, String liveURI, - String storedURI, boolean trackWind, boolean correctWindByDeclination, boolean simulateWithStartTimeNow) throws Exception; + String storedURI, boolean trackWind, boolean correctWindByDeclination, boolean simulateWithStartTimeNow) + throws Exception; void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, SwissTimingRaceRecordDTO rr, String hostname, int port, boolean canSendRequests, boolean trackWind, boolean correctWindByDeclination) throws Exception; - - void storeTracTracConfiguration(String name, String jsonURL, String liveDataURI, String storedDataURI) throws Exception; + + void storeTracTracConfiguration(String name, String jsonURL, String liveDataURI, String storedDataURI) + throws Exception; void stopTrackingEvent(RegattaIdentifier eventIdentifier) throws Exception; void stopTrackingRace(RegattaAndRaceIdentifier regattaAndRaceIdentifier) throws Exception; - + void removeAndUntrackRace(RegattaAndRaceIdentifier regattaAndRaceidentifier) throws Exception; WindInfoForRaceDTO getRawWindFixes(RegattaAndRaceIdentifier raceIdentifier, Collection windSources); void setWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO wind); - WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth, - int numberOfFixes, Collection windSourceTypeNames) throws NoWindException; + WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, + long millisecondsStepWidth, int numberOfFixes, Collection windSourceTypeNames) + throws NoWindException; - WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, Date to, long resolutionInMilliseconds, - Collection windSourceTypeNames); + WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, Date to, + long resolutionInMilliseconds, Collection windSourceTypeNames); - WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth, - int numberOfFixes, double latDeg, double lngDeg, Collection windSources) throws NoWindException; + WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, + long millisecondsStepWidth, int numberOfFixes, double latDeg, double lngDeg, Collection windSources) + throws NoWindException; - RaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date, Map from, Map to, - boolean extrapolate) throws NoWindException; - - Map> getBoatPositions(RegattaAndRaceIdentifier raceIdentifier, Map from, + RaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date, Map from, Map to, boolean extrapolate) throws NoWindException; + Map> getBoatPositions(RegattaAndRaceIdentifier raceIdentifier, + Map from, Map to, boolean extrapolate) throws NoWindException; + RaceTimesInfoDTO getRaceTimesInfo(RegattaAndRaceIdentifier raceIdentifier); - + List getRaceTimesInfos(Collection raceIdentifiers); - + CourseDTO getCoursePositions(RegattaAndRaceIdentifier raceIdentifier, Date date); List getRaceCourse(RegattaAndRaceIdentifier raceIdentifier, Date date); @@ -111,17 +115,18 @@ public interface SailingService extends RemoteService { void removeWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO windDTO); public List getLeaderboardNames() throws Exception; - + LeaderboardDTO getLeaderboardByName(String leaderboardName, Date date, Collection namesOfRaceColumnsForWhichToLoadLegDetails) throws Exception; List getLeaderboards(); - + List getLeaderboardsByEvent(RegattaDTO regatta); - + void updateLeaderboard(String leaderboardName, String newLeaderboardName, int[] newDiscardingThreasholds); - StrippedLeaderboardDTO createFlexibleLeaderboard(String leaderboardName, int[] discardThresholds, ScoringSchemeType scoringSchemeType); + StrippedLeaderboardDTO createFlexibleLeaderboard(String leaderboardName, int[] discardThresholds, + ScoringSchemeType scoringSchemeType); StrippedLeaderboardDTO createRegattaLeaderboard(RegattaIdentifier regattaIdentifier, int[] discardThresholds); @@ -132,22 +137,26 @@ public interface SailingService extends RemoteService { void renameLeaderboardColumn(String leaderboardName, String oldColumnName, String newColumnName); void removeLeaderboardColumn(String leaderboardName, String columnName); - + void addColumnToLeaderboard(String columnName, String leaderboardName, boolean medalRace); - + void moveLeaderboardColumnUp(String leaderboardName, String columnName); - + void moveLeaderboardColumnDown(String leaderboardName, String columnName); - - RegattaDTO createRegatta(String regattaName, String boatClassName, + + RegattaDTO createRegatta( + String regattaName, + String boatClassName, LinkedHashMap>, Boolean>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal, boolean persistent, ScoringSchemeType scoringSchemeType); - - void removeRegatta(RegattaIdentifier regattaIdentifier); - - List addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName, List columnNames); - RaceColumnInSeriesDTO addRaceColumnToSeries(RegattaIdentifier regattaIdentifier, String seriesName, String columnName); + void removeRegatta(RegattaIdentifier regattaIdentifier); + + List addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName, + List columnNames); + + RaceColumnInSeriesDTO addRaceColumnToSeries(RegattaIdentifier regattaIdentifier, String seriesName, + String columnName); void removeRaceColumnsFromSeries(RegattaIdentifier regattaIdentifier, String seriesName, List columnNames); @@ -157,39 +166,44 @@ public interface SailingService extends RemoteService { void moveRaceColumnInSeriesDown(RegattaIdentifier regattaIdentifier, String seriesName, String columnName); - boolean connectTrackedRaceToLeaderboardColumn(String leaderboardName, String raceColumnName, - String fleetName, RegattaAndRaceIdentifier raceIdentifier); - + boolean connectTrackedRaceToLeaderboardColumn(String leaderboardName, String raceColumnName, String fleetName, + RegattaAndRaceIdentifier raceIdentifier); + void disconnectLeaderboardColumnFromTrackedRace(String leaderboardName, String raceColumnName, String fleetName); - - Map getRegattaAndRaceNameOfTrackedRaceConnectedToLeaderboardColumn(String leaderboardName, String raceColumnName); + + Map getRegattaAndRaceNameOfTrackedRaceConnectedToLeaderboardColumn( + String leaderboardName, String raceColumnName); void updateLeaderboardCarryValue(String leaderboardName, String competitorIdAsString, Double carriedPoints); /** * @return the new net points in {@link Pair#getA()} and the new total points in {@link Pair#getB()} for time point - * date after the max points reason has been updated to maxPointsReasonAsString. + * date after the max points reason has been updated to maxPointsReasonAsString. */ - Triple updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, - String raceColumnName, MaxPointsReason maxPointsReason, Date date) throws NoWindException; + Triple updateLeaderboardMaxPointsReason(String leaderboardName, + String competitorIdAsString, String raceColumnName, MaxPointsReason maxPointsReason, Date date) + throws NoWindException; - Triple updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString, - String columnName, Double correctedScore, Date date) throws NoWindException; + Triple updateLeaderboardScoreCorrection(String leaderboardName, + String competitorIdAsString, String columnName, Double correctedScore, Date date) throws NoWindException; + + void updateCompetitorDisplayNameInLeaderboard(String leaderboardName, String competitorIdAsString, + String displayName); - void updateCompetitorDisplayNameInLeaderboard(String leaderboardName, String competitorIdAsString, String displayName); - void updateIsMedalRace(String leaderboardName, String columnName, boolean isMedalRace); List getPreviousSwissTimingConfigurations(); - List listSwissTimingRaces(String hostname, int port, boolean canSendRequests) throws Exception; + List listSwissTimingRaces(String hostname, int port, boolean canSendRequests) + throws Exception; void storeSwissTimingConfiguration(String configName, String hostname, int port, boolean canSendRequests); - void sendSwissTimingDummyRace(String racMessage, String stlMesssage, String ccgMessage) throws IllegalArgumentException; + void sendSwissTimingDummyRace(String racMessage, String stlMesssage, String ccgMessage) + throws IllegalArgumentException; String[] getCountryCodes(); - + Map> getDouglasPoints(RegattaAndRaceIdentifier raceIdentifier, Map from, Map to, double meters) throws NoWindException; @@ -197,32 +211,33 @@ public interface SailingService extends RemoteService { Map from, Map to) throws NoWindException; List getLeaderboardsByRace(RaceDTO race); - + List getLeaderboardGroups(boolean withGeoLocationData); - + LeaderboardGroupDTO getLeaderboardGroupByName(String groupName, boolean withGeoLocationData); - + void renameLeaderboardGroup(String oldName, String newName); - + void removeLeaderboardGroup(String groupName); - + LeaderboardGroupDTO createLeaderboardGroup(String groupName, String description, boolean displayGroupsInReverseOrder, int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType); - + void updateLeaderboardGroup(String oldName, String newName, String description, List leaderboardNames, int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType); - CompetitorsRaceDataDTO getCompetitorsRaceData(RegattaAndRaceIdentifier race, List competitors, Date from, Date to, - long stepSizeInMs, DetailType detailType) throws NoWindException; + CompetitorsRaceDataDTO getCompetitorsRaceData(RegattaAndRaceIdentifier race, List competitors, + Date from, Date to, long stepSizeInMs, DetailType detailType) throws NoWindException; void setRaceIsKnownToStartUpwind(RegattaAndRaceIdentifier raceIdentifier, boolean raceIsKnownToStartUpwind); void setWindSourcesToExclude(RegattaAndRaceIdentifier raceIdentifier, Iterable windSourcesToExclude); - + ReplicationStateDTO getReplicaInfo(); - void startReplicatingFromMaster(String masterName, String exchangeName, int servletPort, int messagingPort) throws Exception; + void startReplicatingFromMaster(String masterName, String exchangeName, int servletPort, int messagingPort) + throws Exception; void updateRaceDelayToLive(RegattaAndRaceIdentifier regattaAndRaceIdentifier, long delayToLiveInMs); @@ -241,8 +256,8 @@ public interface SailingService extends RemoteService { Iterable getScoreCorrectionProviderDTOs() throws Exception; - RegattaScoreCorrectionDTO getScoreCorrections(String scoreCorrectionProviderName, String eventName, String boatClassName, - Date timePointWhenResultPublished) throws Exception; + RegattaScoreCorrectionDTO getScoreCorrections(String scoreCorrectionProviderName, String eventName, + String boatClassName, Date timePointWhenResultPublished) throws Exception; void updateLeaderboardScoreCorrectionsAndMaxPointsReasons(BulkScoreCorrectionDTO updates) throws NoWindException; @@ -276,11 +291,14 @@ public interface SailingService extends RemoteService { void replaySwissTimingRace(RegattaIdentifier regattaIdentifier, SwissTimingReplayRaceDTO replayRace, boolean trackWind, boolean correctWindByDeclination, boolean simulateWithStartTimeNow); - List>> getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(String leaderboardName, Date date) throws NoWindException; + List>> getRankedCompetitorsFromBestToWorstAfterEachRaceColumn( + String leaderboardName, Date date) throws NoWindException; List getOverallLeaderboardNamesContaining(String leaderboardName); List getPreviousSwissTimingArchiveConfigurations(); void storeSwissTimingArchiveConfiguration(String swissTimingUrl); + + String generatePolarSheetForRaces(List selectedRaces); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java index e7736279b42..45a189f7144 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java @@ -11,40 +11,40 @@ import java.util.Set; import com.google.gwt.user.client.rpc.AsyncCallback; import com.sap.sailing.domain.common.Color; import com.sap.sailing.domain.common.DetailType; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.domain.common.RegattaIdentifier; import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.RaceIdentifier; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.domain.common.RegattaIdentifier; import com.sap.sailing.domain.common.ScoringSchemeType; import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Triple; -import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationDTO; import com.sap.sailing.gwt.ui.shared.BulkScoreCorrectionDTO; import com.sap.sailing.gwt.ui.shared.CompetitorDTO; +import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO; import com.sap.sailing.gwt.ui.shared.ControlPointDTO; import com.sap.sailing.gwt.ui.shared.CourseDTO; import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sailing.gwt.ui.shared.RaceCourseMarksDTO; -import com.sap.sailing.gwt.ui.shared.RaceColumnInSeriesDTO; -import com.sap.sailing.gwt.ui.shared.RegattaDTO; import com.sap.sailing.gwt.ui.shared.GPSFixDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardEntryDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; import com.sap.sailing.gwt.ui.shared.ManeuverDTO; -import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO; import com.sap.sailing.gwt.ui.shared.QuickRankDTO; +import com.sap.sailing.gwt.ui.shared.RaceColumnInSeriesDTO; +import com.sap.sailing.gwt.ui.shared.RaceCourseMarksDTO; import com.sap.sailing.gwt.ui.shared.RaceDTO; import com.sap.sailing.gwt.ui.shared.RaceMapDataDTO; import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO; -import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO; +import com.sap.sailing.gwt.ui.shared.RegattaDTO; import com.sap.sailing.gwt.ui.shared.RegattaScoreCorrectionDTO; +import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO; import com.sap.sailing.gwt.ui.shared.ScoreCorrectionProviderDTO; import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; -import com.sap.sailing.gwt.ui.shared.SwissTimingReplayRaceDTO; +import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationDTO; import com.sap.sailing.gwt.ui.shared.SwissTimingConfigurationDTO; import com.sap.sailing.gwt.ui.shared.SwissTimingRaceRecordDTO; +import com.sap.sailing.gwt.ui.shared.SwissTimingReplayRaceDTO; import com.sap.sailing.gwt.ui.shared.TracTracConfigurationDTO; import com.sap.sailing.gwt.ui.shared.TracTracRaceRecordDTO; import com.sap.sailing.gwt.ui.shared.VenueDTO; @@ -55,7 +55,7 @@ import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO; * The async counterpart of {@link SailingService} */ public interface SailingServiceAsync { - + void getRegattas(AsyncCallback> callback); /** @@ -76,15 +76,15 @@ public interface SailingServiceAsync { * @param simulateWithStartTimeNow * if true, the connector will adjust the time stamps of all events received such that the * first mark passing for the first waypoint will be set to "now." It will delay the forwarding of all - * events received such that they seem to be sent in "real-time." So, more or less the time points attached - * to the events sent to the receivers will again approximate the wall time. + * events received such that they seem to be sent in "real-time." So, more or less the time points + * attached to the events sent to the receivers will again approximate the wall time. * @param storedURImay * be null or the empty string in which case the server will use the * {@link TracTracRaceRecordDTO#storedURI} from the rr race record. */ - void trackWithTracTrac(RegattaIdentifier regattaToAddTo, - TracTracRaceRecordDTO rr, String liveURI, String storedURI, boolean trackWind, boolean correctWindByDeclination, - boolean simulateWithStartTimeNow, AsyncCallback callback); + void trackWithTracTrac(RegattaIdentifier regattaToAddTo, TracTracRaceRecordDTO rr, String liveURI, + String storedURI, boolean trackWind, boolean correctWindByDeclination, boolean simulateWithStartTimeNow, + AsyncCallback callback); void getPreviousTracTracConfigurations(AsyncCallback> callback); @@ -94,33 +94,40 @@ public interface SailingServiceAsync { void stopTrackingEvent(RegattaIdentifier eventIdentifier, AsyncCallback callback); void stopTrackingRace(RegattaAndRaceIdentifier raceIdentifier, AsyncCallback asyncCallback); - + /** * Untracks the race and removes it from the regatta. It will also be removed in all leaderboards - * @param regattaAndRaceidentifier The identifier for the regatta name, and the race name to remove + * + * @param regattaAndRaceidentifier + * The identifier for the regatta name, and the race name to remove */ void removeAndUntrackRace(RegattaAndRaceIdentifier regattaAndRaceidentifier, AsyncCallback callback); - void getRawWindFixes(RegattaAndRaceIdentifier raceIdentifier, Collection windSources, AsyncCallback callback); + void getRawWindFixes(RegattaAndRaceIdentifier raceIdentifier, Collection windSources, + AsyncCallback callback); /** - * @param from if null, the tracked race's start of tracking is used - * @param to if null, the tracked race's time point of newest event is used + * @param from + * if null, the tracked race's start of tracking is used + * @param to + * if null, the tracked race's time point of newest event is used */ - void getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, Date to, long resolutionInMilliseconds, - Collection windSourceTypeNames, AsyncCallback callback); + void getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, Date to, + long resolutionInMilliseconds, Collection windSourceTypeNames, + AsyncCallback callback); /** * @param windSourceTypeNames * if null, data from all available wind sources will be returned, otherwise only from those * whose {@link WindSource} name is contained in the windSources collection. */ - void getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth, int numberOfFixes, - double latDeg, double lngDeg, Collection windSourceTypeNames, + void getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth, + int numberOfFixes, double latDeg, double lngDeg, Collection windSourceTypeNames, AsyncCallback callback); /** - * Same as {@link #getWindInfo(RegattaAndRaceIdentifier, Date, long, int, double, double, Collection, AsyncCallback)}, only + * Same as + * {@link #getWindInfo(RegattaAndRaceIdentifier, Date, long, int, double, double, Collection, AsyncCallback)}, only * that the wind is not requested for a specific position, but instead the wind sources associated with the tracked * race identified by raceIdentifier are requested to deliver their original position. This will in * particular preserve the positions of actual measurements and will deliver the averaged positions for averaged / @@ -132,11 +139,11 @@ public interface SailingServiceAsync { * no matter how great this value is chosen, never returns data beyond the newest event recorded in the * race */ - void getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth, int numberOfFixes, - Collection windSourceTypeNames, AsyncCallback callback); + void getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth, + int numberOfFixes, Collection windSourceTypeNames, AsyncCallback callback); void setWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO wind, AsyncCallback callback); - + void removeWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO windDTO, AsyncCallback callback); /** @@ -154,13 +161,14 @@ public interface SailingServiceAsync { * @return a map where for each competitor participating in the race the list of GPS fixes in increasing * chronological order is provided. The last one is the last position at or before date. */ - void getBoatPositions(RegattaAndRaceIdentifier raceIdentifier, - Map from, Map to, - boolean extrapolate, AsyncCallback>> callback); + void getBoatPositions(RegattaAndRaceIdentifier raceIdentifier, Map from, + Map to, boolean extrapolate, + AsyncCallback>> callback); void getRaceTimesInfo(RegattaAndRaceIdentifier raceIdentifier, AsyncCallback callback); - - void getRaceTimesInfos(Collection raceIdentifiers, AsyncCallback> callback); + + void getRaceTimesInfos(Collection raceIdentifiers, + AsyncCallback> callback); void getCoursePositions(RegattaAndRaceIdentifier raceIdentifier, Date date, AsyncCallback asyncCallback); @@ -179,39 +187,40 @@ public interface SailingServiceAsync { * if null, no {@link LeaderboardEntryDTO#legDetails leg details} will be present in the * result ({@link LeaderboardEntryDTO#legDetails} will be null for all * {@link LeaderboardEntryDTO} objects contained). Otherwise, the {@link LeaderboardEntryDTO#legDetails} - * list will contain one entry per leg of the race {@link com.sap.sailing.domain.base.Course} for those race columns whose - * {@link com.sap.sailing.domain.base.RaceColumn#getType() name} is contained in namesOfRacesForWhichToLoadLegDetails. - * For all other columns, {@link LeaderboardEntryDTO#legDetails} is null. + * list will contain one entry per leg of the race {@link com.sap.sailing.domain.base.Course} for those + * race columns whose {@link com.sap.sailing.domain.base.RaceColumn#getType() name} is contained in + * namesOfRacesForWhichToLoadLegDetails. For all other columns, + * {@link LeaderboardEntryDTO#legDetails} is null. */ void getLeaderboardByName(String leaderboardName, Date date, - Collection namesOfRaceColumnsForWhichToLoadLegDetails, - AsyncCallback callback); + Collection namesOfRaceColumnsForWhichToLoadLegDetails, AsyncCallback callback); void getLeaderboardNames(AsyncCallback> callback); void getLeaderboards(AsyncCallback> callback); - + void getLeaderboardsByEvent(RegattaDTO regatta, AsyncCallback> callback); - + void getLeaderboardsByRace(RaceDTO race, AsyncCallback> callback); - + void updateLeaderboard(String leaderboardName, String newLeaderboardName, int[] newDiscardingThreasholds, AsyncCallback callback); - void createFlexibleLeaderboard(String leaderboardName, int[] discardThresholds, ScoringSchemeType scoringSchemeType, - AsyncCallback asyncCallback); + void createFlexibleLeaderboard(String leaderboardName, int[] discardThresholds, + ScoringSchemeType scoringSchemeType, AsyncCallback asyncCallback); void createRegattaLeaderboard(RegattaIdentifier regattaIdentifier, int[] discardThresholds, AsyncCallback asyncCallback); void removeLeaderboard(String leaderboardName, AsyncCallback asyncCallback); - + void renameLeaderboard(String leaderboardName, String newLeaderboardName, AsyncCallback asyncCallback); void addColumnToLeaderboard(String columnName, String leaderboardName, boolean medalRace, AsyncCallback callback); - void renameLeaderboardColumn(String leaderboardName, String oldColumnName, String newColumnName, AsyncCallback callback); + void renameLeaderboardColumn(String leaderboardName, String oldColumnName, String newColumnName, + AsyncCallback callback); void removeLeaderboardColumn(String leaderboardName, String columnName, AsyncCallback callback); @@ -222,7 +231,8 @@ public interface SailingServiceAsync { * The key set of the map returned contains all fleets of the race column identified by the combination of * leaderboardName and raceColumnName. If a value is null, there is no * tracked race currently linked to the fleet in the race column; otherwise, the value is the {@link RaceIdentifier} - * of the tracked race currently connected for the fleet whose name is the key. The map returned is never null. + * of the tracked race currently connected for the fleet whose name is the key. The map returned is never + * null. */ void getRegattaAndRaceNameOfTrackedRaceConnectedToLeaderboardColumn(String leaderboardName, String raceColumnName, AsyncCallback> callback); @@ -230,7 +240,8 @@ public interface SailingServiceAsync { void disconnectLeaderboardColumnFromTrackedRace(String leaderboardName, String raceColumnName, String fleetName, AsyncCallback callback); - void updateLeaderboardCarryValue(String leaderboardName, String competitorIdAsString, Double carriedPoints, AsyncCallback callback); + void updateLeaderboardCarryValue(String leaderboardName, String competitorIdAsString, Double carriedPoints, + AsyncCallback callback); void updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, String raceColumnName, MaxPointsReason maxPointsReason, Date date, AsyncCallback> asyncCallback); @@ -253,16 +264,19 @@ public interface SailingServiceAsync { void updateIsMedalRace(String leaderboardName, String columnName, boolean isMedalRace, AsyncCallback callback); - void updateRaceDelayToLive(RegattaAndRaceIdentifier regattaAndRaceIdentifier, long delayToLiveInMs, AsyncCallback callback); + void updateRaceDelayToLive(RegattaAndRaceIdentifier regattaAndRaceIdentifier, long delayToLiveInMs, + AsyncCallback callback); - void updateRacesDelayToLive(List regattaAndRaceIdentifiers, long delayToLiveInMs, AsyncCallback callback); + void updateRacesDelayToLive(List regattaAndRaceIdentifiers, long delayToLiveInMs, + AsyncCallback callback); void getPreviousSwissTimingConfigurations(AsyncCallback> asyncCallback); void listSwissTimingRaces(String hostname, int port, boolean canSendRequests, AsyncCallback> asyncCallback); - void storeSwissTimingConfiguration(String configName, String hostname, int port, boolean canSendRequests, AsyncCallback asyncCallback); + void storeSwissTimingConfiguration(String configName, String hostname, int port, boolean canSendRequests, + AsyncCallback asyncCallback); /** * @param regattaToAddTo @@ -277,51 +291,58 @@ public interface SailingServiceAsync { AsyncCallback asyncCallback); void sendSwissTimingDummyRace(String racMessage, String stlMesssage, String ccgMessage, AsyncCallback callback); - - void getCountryCodes(AsyncCallback callback); - - void getDouglasPoints(RegattaAndRaceIdentifier raceIdentifier, Map from, Map to, - double meters, AsyncCallback>> callback); - void getManeuvers(RegattaAndRaceIdentifier raceIdentifier, Map from, Map to, - AsyncCallback>> callback); + void getCountryCodes(AsyncCallback callback); + + void getDouglasPoints(RegattaAndRaceIdentifier raceIdentifier, Map from, + Map to, double meters, AsyncCallback>> callback); + + void getManeuvers(RegattaAndRaceIdentifier raceIdentifier, Map from, + Map to, AsyncCallback>> callback); void getLeaderboardGroups(boolean withGeoLocationData, AsyncCallback> callback); void getLeaderboardGroupByName(String groupName, boolean withGeoLocationData, AsyncCallback callback); - + /** - * Renames the group with the name oldName to the newName.
- * If there's no group with the name oldName or there's already a group with the name - * newName a {@link IllegalArgumentException} is thrown. - */ + * Renames the group with the name oldName to the newName.
+ * If there's no group with the name oldName or there's already a group with the name + * newName a {@link IllegalArgumentException} is thrown. + */ void renameLeaderboardGroup(String oldName, String newName, AsyncCallback callback); - + /** * Removes the leaderboard group with the name groupName from the service and the persistant store. */ void removeLeaderboardGroup(String groupName, AsyncCallback callback); - + /** - * Creates a new group with the name groupname, the description description and an empty list of leaderboards.
- * @param displayGroupsInReverseOrder TODO + * Creates a new group with the name groupname, the description description and an empty + * list of leaderboards.
+ * + * @param displayGroupsInReverseOrder + * TODO */ - void createLeaderboardGroup(String groupName, String description, - boolean displayGroupsInReverseOrder, int[] overallLeaderboardDiscardThresholds, - ScoringSchemeType overallLeaderboardScoringSchemeType, AsyncCallback callback); - + void createLeaderboardGroup(String groupName, String description, boolean displayGroupsInReverseOrder, + int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType, + AsyncCallback callback); + /** * Updates the data of the group with the name oldName. * - * @param oldName The old name of the group - * @param newName The new name of the group - * @param description The new description of the group - * @param leaderboardNames The list of names of the new leaderboards of the group + * @param oldName + * The old name of the group + * @param newName + * The new name of the group + * @param description + * The new description of the group + * @param leaderboardNames + * The list of names of the new leaderboards of the group */ - void updateLeaderboardGroup(String oldName, String newName, String description, - List leaderboardNames, int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType, AsyncCallback callback); - + void updateLeaderboardGroup(String oldName, String newName, String description, List leaderboardNames, + int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType, + AsyncCallback callback); void setRaceIsKnownToStartUpwind(RegattaAndRaceIdentifier raceIdentifier, boolean raceIsKnownToStartUpwind, AsyncCallback callback); @@ -340,26 +361,27 @@ public interface SailingServiceAsync { void getEvents(AsyncCallback> callback); /** - * Creates a {@link EventDTO} for the {@link com.sap.sailing.domain.base.Event} with the name eventName, which contains the - * name, the description and a list with {@link RegattaDTO RegattaDTOs} contained in the event.
+ * Creates a {@link EventDTO} for the {@link com.sap.sailing.domain.base.Event} with the name eventName + * , which contains the name, the description and a list with {@link RegattaDTO RegattaDTOs} contained in the event.
* If no event with the name eventName is known, an {@link IllegalArgumentException} is thrown. */ void getEventByName(String eventName, AsyncCallback callback); - + /** - * Renames the event with the name oldName to the newName.
- * If there's no event with the name oldName or there's already a event with the name - * newName a {@link IllegalArgumentException} is thrown. - */ + * Renames the event with the name oldName to the newName.
+ * If there's no event with the name oldName or there's already a event with the name + * newName a {@link IllegalArgumentException} is thrown. + */ void renameEvent(String oldName, String newName, AsyncCallback callback); - + /** * Removes the event with the name eventName from the service and the persistence store. */ void removeEvent(String eventName, AsyncCallback callback); - - void createEvent(String eventName, String description, String publicationUrl, boolean isPublic, AsyncCallback callback); - + + void createEvent(String eventName, String description, String publicationUrl, boolean isPublic, + AsyncCallback callback); + void updateEvent(String eventName, Serializable id, VenueDTO venue, String publicationUrl, boolean isPublic, List regattaNames, AsyncCallback callback); @@ -371,13 +393,15 @@ public interface SailingServiceAsync { void removeRaceColumnFromSeries(RegattaIdentifier regattaIdentifier, String seriesName, String columnName, AsyncCallback callback); - void moveRaceColumnInSeriesUp(RegattaIdentifier regattaIdentifier, String seriesName, String columnName, + void moveRaceColumnInSeriesUp(RegattaIdentifier regattaIdentifier, String seriesName, String columnName, AsyncCallback callback); void moveRaceColumnInSeriesDown(RegattaIdentifier regattaIdentifier, String seriesName, String columnName, AsyncCallback callback); - void createRegatta(String regattaName, String boatClassName, + void createRegatta( + String regattaName, + String boatClassName, LinkedHashMap>, Boolean>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal, boolean persistent, ScoringSchemeType scoringSchemeType, AsyncCallback callback); @@ -396,7 +420,8 @@ public interface SailingServiceAsync { void getRaceCourse(RegattaAndRaceIdentifier raceIdentifier, Date date, AsyncCallback> callback); - void updateRaceCourse(RegattaAndRaceIdentifier raceIdentifier, List controlPoints, AsyncCallback callback); + void updateRaceCourse(RegattaAndRaceIdentifier raceIdentifier, List controlPoints, + AsyncCallback callback); void getFregResultUrls(AsyncCallback> asyncCallback); @@ -404,7 +429,8 @@ public interface SailingServiceAsync { void addFragUrl(String result, AsyncCallback asyncCallback); - void getRaceCourseMarks(RegattaAndRaceIdentifier raceIdentifier, Date date, AsyncCallback callback); + void getRaceCourseMarks(RegattaAndRaceIdentifier raceIdentifier, Date date, + AsyncCallback callback); void addColumnsToLeaderboard(String leaderboardName, List> columnsToAdd, AsyncCallback callback); @@ -413,7 +439,8 @@ public interface SailingServiceAsync { void getLeaderboard(String leaderboardName, AsyncCallback callback); - void suppressCompetitorInLeaderboard(String leaderboardName, String competitorIdAsString, boolean suppressed, AsyncCallback asyncCallback); + void suppressCompetitorInLeaderboard(String leaderboardName, String competitorIdAsString, boolean suppressed, + AsyncCallback asyncCallback); void updateLeaderboardColumnFactor(String leaderboardName, String columnName, Double newFactor, AsyncCallback callback); @@ -431,10 +458,10 @@ public interface SailingServiceAsync { long stepSize, DetailType detailType, AsyncCallback callback); /** - * Finds out the names of all {@link com.sap.sailing.domain.leaderboard.MetaLeaderboard}s managed by this server that - * {@link com.sap.sailing.domain.leaderboard.MetaLeaderboard#getLeaderboards() contain} the leaderboard identified by leaderboardName. The - * names of those meta-leaderboards are returned. The list returned is never null but may be empty if no such - * leaderboard is found. + * Finds out the names of all {@link com.sap.sailing.domain.leaderboard.MetaLeaderboard}s managed by this server + * that {@link com.sap.sailing.domain.leaderboard.MetaLeaderboard#getLeaderboards() contain} the leaderboard + * identified by leaderboardName. The names of those meta-leaderboards are returned. The list returned + * is never null but may be empty if no such leaderboard is found. */ void getOverallLeaderboardNamesContaining(String leaderboardName, AsyncCallback> asyncCallback); @@ -442,4 +469,6 @@ public interface SailingServiceAsync { AsyncCallback> asyncCallback); void storeSwissTimingArchiveConfiguration(String swissTimingUrl, AsyncCallback asyncCallback); + + void generatePolarSheetForRaces(List selectedRaces, AsyncCallback asyncCallback); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java index 2a4e9624917..baa58f44c5e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java @@ -1,35 +1,68 @@ package com.sap.sailing.gwt.ui.polarsheets; +import java.util.Map; + import org.moxieapps.gwt.highcharts.client.Chart; import org.moxieapps.gwt.highcharts.client.Series; -import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.VerticalPanel; -import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.ui.client.StringMessages; public class PolarSheetsChartPanel extends SimplePanel { - private VerticalPanel mainPanel; private StringMessages stringMessages; + private Chart chart; + private Map seriesMap; public PolarSheetsChartPanel(StringMessages stringMessages) { this.stringMessages = stringMessages; - mainPanel = new VerticalPanel(); - mainPanel.setSize("100%", "100%"); - setWidget(mainPanel); - Label polarSheetsChartLabel = new Label(stringMessages.polarSheetChart()); - mainPanel.add(polarSheetsChartLabel); - mainPanel.add(createPolarSheetChart()); + setSize("100%", "100%"); + chart = createPolarSheetChart(); + setWidget(chart); } - private Widget createPolarSheetChart() { - Chart polarSheetChart = new Chart(); - polarSheetChart.setType(Series.Type.LINE); - polarSheetChart.setOption("/chart/polar", true); - + private Chart createPolarSheetChart() { + Chart polarSheetChart = new Chart().setType(Series.Type.LINE).setZoomType(Chart.ZoomType.X_AND_Y) + .setPolar(true).setSize(700, 700); + polarSheetChart.setChartTitleText(stringMessages.polarSheetChart()); return polarSheetChart; } + public void newSeries(String name) { + if (!seriesMap.containsKey(name)) { + Number[] forEachDeg = initializeDataForNewSeries(); + Series newSeries = chart.createSeries().setPoints(forEachDeg); + newSeries.setName(name); + chart.addSeries(newSeries); + seriesMap.put(name, newSeries); + } else { + // TODO exception handling + } + } + + private Number[] initializeDataForNewSeries() { + Number[] forEachDeg = new Number[360]; + return forEachDeg; + } + + public void addDataToSeries(String seriesName, int deg, double value) { + if (seriesMap.containsKey(seriesName)) { + Series series = seriesMap.get(seriesName); + series.addPoint(deg, value); + } + } + + public void removeSeries(String seriesName) { + if (seriesMap.containsKey(seriesName)) { + Series series = seriesMap.get(seriesName); + chart.removeSeries(series); + seriesMap.remove(seriesName); + } + } + + public void removeAllSeries() { + chart.removeAllSeries(); + seriesMap.clear(); + } + } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index b26f3e26832..899d86994f2 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -4,6 +4,7 @@ import java.util.List; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.HorizontalPanel; @@ -30,6 +31,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi private RaceSelectionModel raceSelectionProvider; private PolarSheetsEntryPoint polarSheetsEntryPoint; private List selectedRaces; + private PolarSheetsChartPanel chartPanel; public PolarSheetsPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter, StringMessages stringMessages, PolarSheetsEntryPoint polarSheetsEntryPoint) { @@ -39,15 +41,20 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi this.stringMessages = stringMessages; this.mainPanel = new FlowPanel(); + setSize("100%", "100%"); + mainPanel.setSize("100%", "100%"); setWidget(mainPanel); HorizontalPanel splitPanel = createSplitPanel(); addFilteredTrackedRacesList(splitPanel); addPolarSheetsChartPanel(splitPanel); + mainPanel.add(splitPanel); } private void addPolarSheetsChartPanel(HorizontalPanel splitPanel) { - + chartPanel = new PolarSheetsChartPanel(stringMessages); + splitPanel.add(chartPanel); + splitPanel.setCellWidth(chartPanel, "50%"); } private HorizontalPanel createSplitPanel() { @@ -60,12 +67,14 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi VerticalPanel trackedRacesPanel = new VerticalPanel(); trackedRacesPanel.setWidth("100%"); - trackedRacesPanel.add(createPolarSheetsTrackedRacesList()); + createPolarSheetsTrackedRacesList(); + trackedRacesPanel.add(polarSheetsTrackedRacesList); splitPanel.add(trackedRacesPanel); + splitPanel.setCellWidth(trackedRacesPanel, "50%"); } - private PolarSheetsTrackedRacesList createPolarSheetsTrackedRacesList() { + private void createPolarSheetsTrackedRacesList() { raceSelectionProvider = new RaceSelectionModel(); ClickHandler polarSheetsGenerationButtonClickHandler = new ClickHandler() { @@ -78,11 +87,23 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi polarSheetsEntryPoint, raceSelectionProvider, stringMessages, true, new RaceFilter(true, true), polarSheetsGenerationButtonClickHandler); raceSelectionProvider.addRaceSelectionChangeListener(this); - return polarSheetsTrackedRacesList; } protected void startPolarSheetGeneration() { - // TODO Auto-generated method stub + sailingService.generatePolarSheetForRaces(selectedRaces, new AsyncCallback() { + + @Override + public void onSuccess(String result) { + // TODO Auto-generated method stub + + } + + @Override + public void onFailure(Throwable caught) { + // TODO Auto-generated method stub + + } + }); } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index bdf85d865ab..67f9b817ed2 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -106,6 +106,7 @@ import com.sap.sailing.domain.persistence.DomainObjectFactory; import com.sap.sailing.domain.persistence.MongoFactory; import com.sap.sailing.domain.persistence.MongoObjectFactory; import com.sap.sailing.domain.persistence.MongoWindStoreFactory; +import com.sap.sailing.domain.polarsheets.PolarSheetGenerationWorker; import com.sap.sailing.domain.swisstimingadapter.SwissTimingArchiveConfiguration; import com.sap.sailing.domain.swisstimingadapter.SwissTimingConfiguration; import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory; @@ -241,33 +242,34 @@ import com.sap.sailing.server.replication.ReplicationService; /** * The server side implementation of the RPC service. */ -public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements SailingService, RaceFetcher, RegattaFetcher { +public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements SailingService, RaceFetcher, + RegattaFetcher { private static final Logger logger = Logger.getLogger(SailingServiceImpl.class.getName()); - + private static final long serialVersionUID = 9031688830194537489L; private final ServiceTracker racingEventServiceTracker; - + private final ServiceTracker replicationServiceTracker; - + private final ServiceTracker scoreCorrectionProviderServiceTracker; private final MongoObjectFactory mongoObjectFactory; - + private final SwissTimingAdapterPersistence swissTimingAdapterPersistence; - + private final com.sap.sailing.domain.tractracadapter.persistence.MongoObjectFactory tractracMongoObjectFactory; private final DomainObjectFactory domainObjectFactory; - + private final SwissTimingFactory swissTimingFactory; private final com.sap.sailing.domain.tractracadapter.persistence.DomainObjectFactory tractracDomainObjectFactory; - + private final com.sap.sailing.domain.common.CountryCodeFactory countryCodeFactory; - + private final Executor executor; - + /** * {@link #getLeaderboardByName(String, Date, Collection)} is the application's bottleneck. When two clients ask the * same data for the same leaderboard with their waitForLatestAnalyses parameters set to @@ -276,12 +278,12 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S * Results are cached in this LRU-based evicting cache. */ private final Map leaderboardByNameLiveUpdaters; - + /** - * This executor needs to be a different one than {@link #executor} because the tasks run by {@link #executor} - * can depend on the results of the tasks run by {@link #raceDetailsExecutor}, and an {@link Executor} doesn't - * move a task that is blocked by waiting for another {@link FutureTask} to the side but blocks permanently, - * ending in a deadlock (one that cannot easily be detected by the Eclipse debugger either). + * This executor needs to be a different one than {@link #executor} because the tasks run by {@link #executor} can + * depend on the results of the tasks run by {@link #raceDetailsExecutor}, and an {@link Executor} doesn't move a + * task that is blocked by waiting for another {@link FutureTask} to the side but blocks permanently, ending in a + * deadlock (one that cannot easily be detected by the Eclipse debugger either). */ private final Executor raceDetailsExecutor; @@ -293,13 +295,15 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S * Used to remove all these listeners from their tracked races when this servlet is {@link #destroy() destroyed}. */ private final Set cacheInvalidationListeners; - + private final LeaderboardDTOCache leaderboardDTOCacheWaitingForLatestAnalysis; - + private final DomainFactory tractracDomainFactory; - + private final com.sap.sailing.domain.base.DomainFactory baseDomainFactory; + private final Map polarSheetGenerationWorkers; + public SailingServiceImpl() { BundleContext context = Activator.getDefault(); tractracDomainFactory = DomainFactory.INSTANCE; @@ -320,13 +324,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); raceDetailsExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); leaderboardByNameLiveUpdaters = new HashMap(); - leaderboardDTOCacheWaitingForLatestAnalysis = new LeaderboardDTOCache(this, /* waitForLatestAnalyses */ true); + leaderboardDTOCacheWaitingForLatestAnalysis = new LeaderboardDTOCache(this, /* waitForLatestAnalyses */true); + polarSheetGenerationWorkers = new HashMap(); } - + private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); } - + public void destroy() { super.destroy(); for (CacheInvalidationListener cacheInvalidationListener : cacheInvalidationListeners) { @@ -341,19 +346,19 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S result.open(); return result; } - + /** * Asks the OSGi system for registered score correction provider services */ private ServiceTracker createAndOpenScoreCorrectionProviderServiceTracker( BundleContext bundleContext) { - ServiceTracker tracker = new ServiceTracker(bundleContext, - ScoreCorrectionProvider.class.getName(), + ServiceTracker tracker = new ServiceTracker( + bundleContext, ScoreCorrectionProvider.class.getName(), /* customizer */null); tracker.open(); return tracker; } - + @Override public Iterable getScoreCorrectionProviderDTOs() throws Exception { List result = new ArrayList(); @@ -374,10 +379,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } return result; } - + private ScoreCorrectionProviderDTO createScoreCorrectionProviderDTO(ScoreCorrectionProvider scoreCorrectionProvider) throws Exception { - Map>> hasResultsForBoatClassFromDateByEventName = new HashMap>>(); + Map>> hasResultsForBoatClassFromDateByEventName = new HashMap>>(); for (Map.Entry>> e : scoreCorrectionProvider .getHasResultsForBoatClassFromDateByEventName().entrySet()) { Set> set = new HashSet>(); @@ -386,7 +391,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } hasResultsForBoatClassFromDateByEventName.put(e.getKey(), set); } - return new ScoreCorrectionProviderDTO(scoreCorrectionProvider.getName(), hasResultsForBoatClassFromDateByEventName); + return new ScoreCorrectionProviderDTO(scoreCorrectionProvider.getName(), + hasResultsForBoatClassFromDateByEventName); } protected ServiceTracker createAndOpenReplicationServiceTracker( @@ -396,7 +402,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S result.open(); return result; } - + /** * If date is null, the {@link LiveLeaderboardUpdater} for the * leaderboardName requested is obtained or created if it doesn't exist yet. The request is then passed @@ -411,8 +417,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S */ @Override public LeaderboardDTO getLeaderboardByName(final String leaderboardName, final Date date, - final Collection namesOfRaceColumnsForWhichToLoadLegDetails) - throws NoWindException, InterruptedException, ExecutionException { + final Collection namesOfRaceColumnsForWhichToLoadLegDetails) throws NoWindException, + InterruptedException, ExecutionException { long startOfRequestHandling = System.currentTimeMillis(); LeaderboardDTO result = null; TimePoint timePoint; @@ -421,8 +427,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S if (leaderboard != null) { if (date == null) { // date==null means live mode; however, if we're after the end of all races and after all score - // corrections, don't use the live leaderboard updater which would keep re-calculating over and over again, but map - // this to a usual non-live call which uses the regular LeaderboardDTOCache which is invalidated properly + // corrections, don't use the live leaderboard updater which would keep re-calculating over and over + // again, but map + // this to a usual non-live call which uses the regular LeaderboardDTOCache which is invalidated + // properly // when the tracked race associations or score corrections or tracked race contents changes: // TODO see bug 929: use lock instead of synchronized to increase concurrency synchronized (leaderboardByNameLiveUpdaters) { @@ -464,10 +472,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S long startOfRequestHandling = System.currentTimeMillis(); LeaderboardDTO result = null; if (leaderboard != null) { - result = new LeaderboardDTO(leaderboard.getScoreCorrection().getTimePointOfLastCorrectionsValidity()==null ? - null : leaderboard.getScoreCorrection().getTimePointOfLastCorrectionsValidity().asDate(), - leaderboard.getScoreCorrection()==null?null:leaderboard.getScoreCorrection().getComment(), - leaderboard.getScoringScheme().isHigherBetter()); + result = new LeaderboardDTO( + leaderboard.getScoreCorrection().getTimePointOfLastCorrectionsValidity() == null ? null + : leaderboard.getScoreCorrection().getTimePointOfLastCorrectionsValidity().asDate(), + leaderboard.getScoreCorrection() == null ? null : leaderboard.getScoreCorrection().getComment(), + leaderboard.getScoringScheme().isHigherBetter()); result.competitors = new ArrayList(); result.name = leaderboard.getName(); result.competitorDisplayNames = new HashMap(); @@ -475,7 +484,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S result.setSuppressed(convertToCompetitorDTO(suppressedCompetitor), true); } for (RaceColumn raceColumn : leaderboard.getRaceColumns()) { - RaceColumnDTO raceColumnDTO = result.createEmptyRaceColumn(raceColumn.getName(), raceColumn.isMedalRace(), + RaceColumnDTO raceColumnDTO = result.createEmptyRaceColumn(raceColumn.getName(), + raceColumn.isMedalRace(), leaderboard.getScoringScheme().isValidInTotalScore(leaderboard, raceColumn, timePoint)); for (Fleet fleet : raceColumn.getFleets()) { TimePoint latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive = null; @@ -494,29 +504,36 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive = liveTimePointForTrackedRace; } } - // Note: the RaceColumnDTO won't be created by the following addRace call because it has been created + // Note: the RaceColumnDTO won't be created by the following addRace call because it has been + // created // above by the result.createEmptyRaceColumn call result.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), fleetDTO, - raceColumn.isMedalRace(), raceIdentifier, /* StrippedRaceDTO */ null); + raceColumn.isMedalRace(), raceIdentifier, /* StrippedRaceDTO */null); if (latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive != null) { - raceColumnDTO.setWhenLastTrackedRaceWasLive(fleetDTO, latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive.asDate()); + raceColumnDTO.setWhenLastTrackedRaceWasLive(fleetDTO, + latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive.asDate()); } } - result.setCompetitorsFromBestToWorst(raceColumnDTO, getCompetitorDTOList(leaderboard.getCompetitorsFromBestToWorst(raceColumn, timePoint))); + result.setCompetitorsFromBestToWorst(raceColumnDTO, + getCompetitorDTOList(leaderboard.getCompetitorsFromBestToWorst(raceColumn, timePoint))); } result.setDelayToLiveInMillisForLatestRace(leaderboard.getDelayToLiveInMillis()); result.rows = new HashMap(); result.hasCarriedPoints = leaderboard.hasCarriedPoints(); - result.discardThresholds = leaderboard.getResultDiscardingRule().getDiscardIndexResultsStartingWithHowManyRaces(); - // Computing the competitor leg ranks is expensive, especially in live mode, in case new events keep invalidating - // the ranks cache in TrackedLegImpl. Then problem then is that the sorting based on wind data is repeated for each - // competitor, leading to square effort. We therefore need to compute the leg ranks for those race where leg details + result.discardThresholds = leaderboard.getResultDiscardingRule() + .getDiscardIndexResultsStartingWithHowManyRaces(); + // Computing the competitor leg ranks is expensive, especially in live mode, in case new events keep + // invalidating + // the ranks cache in TrackedLegImpl. Then problem then is that the sorting based on wind data is repeated + // for each + // competitor, leading to square effort. We therefore need to compute the leg ranks for those race where leg + // details // are requested only once and pass them into getLeaderboardEntryDTO - final Map> legRanksCache = new HashMap>(); + final Map> legRanksCache = new HashMap>(); for (final RaceColumn raceColumn : leaderboard.getRaceColumns()) { // if details for the column are requested, cache the leg's ranks if (namesOfRaceColumnsForWhichToLoadLegDetails != null - && namesOfRaceColumnsForWhichToLoadLegDetails.contains(raceColumn.getName())) { + && namesOfRaceColumnsForWhichToLoadLegDetails.contains(raceColumn.getName())) { for (Fleet fleet : raceColumn.getFleets()) { TrackedRace trackedRace = raceColumn.getTrackedRace(fleet); if (trackedRace != null) { @@ -537,34 +554,45 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S LeaderboardRowDTO row = new LeaderboardRowDTO(); row.competitor = competitorDTO; row.fieldsByRaceColumnName = new HashMap(); - row.carriedPoints = leaderboard.hasCarriedPoints(competitor) ? leaderboard.getCarriedPoints(competitor) : null; + row.carriedPoints = leaderboard.hasCarriedPoints(competitor) ? leaderboard.getCarriedPoints(competitor) + : null; addOverallDetailsToRow(leaderboard, timePoint, competitor, row); result.competitors.add(competitorDTO); Map> futuresForColumnName = new HashMap>(); for (final RaceColumn raceColumn : leaderboard.getRaceColumns()) { - RunnableFuture future = new FutureTask(new Callable() { - @Override - public LeaderboardEntryDTO call() { - try { - Entry entry = leaderboard.getEntry(competitor, raceColumn, timePoint); - return getLeaderboardEntryDTO(entry, raceColumn.getTrackedRace(competitor), competitor, timePoint, - namesOfRaceColumnsForWhichToLoadLegDetails != null - && namesOfRaceColumnsForWhichToLoadLegDetails.contains(raceColumn.getName()), - waitForLatestAnalyses, legRanksCache); - } catch (NoWindException e) { - logger.info("Exception trying to compute leaderboard entry for competitor "+competitor.getName()+ - " in race column "+raceColumn.getName()+": "+e.getMessage()); - logger.throwing(SailingServiceImpl.class.getName(), "computeLeaderboardByName.future.call()", e); - throw new NoWindError(e); - } - } - }); + RunnableFuture future = new FutureTask( + new Callable() { + @Override + public LeaderboardEntryDTO call() { + try { + Entry entry = leaderboard.getEntry(competitor, raceColumn, timePoint); + return getLeaderboardEntryDTO( + entry, + raceColumn.getTrackedRace(competitor), + competitor, + timePoint, + namesOfRaceColumnsForWhichToLoadLegDetails != null + && namesOfRaceColumnsForWhichToLoadLegDetails + .contains(raceColumn.getName()), waitForLatestAnalyses, + legRanksCache); + } catch (NoWindException e) { + logger.info("Exception trying to compute leaderboard entry for competitor " + + competitor.getName() + " in race column " + raceColumn.getName() + + ": " + e.getMessage()); + logger.throwing(SailingServiceImpl.class.getName(), + "computeLeaderboardByName.future.call()", e); + throw new NoWindError(e); + } + } + }); executor.execute(future); futuresForColumnName.put(raceColumn.getName(), future); } - for (Map.Entry> raceColumnNameAndFuture : futuresForColumnName.entrySet()) { + for (Map.Entry> raceColumnNameAndFuture : futuresForColumnName + .entrySet()) { try { - row.fieldsByRaceColumnName.put(raceColumnNameAndFuture.getKey(), raceColumnNameAndFuture.getValue().get()); + row.fieldsByRaceColumnName.put(raceColumnNameAndFuture.getKey(), raceColumnNameAndFuture + .getValue().get()); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { @@ -578,28 +606,37 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } } } - logger.fine("computeLeaderboardByName("+leaderboard.getName()+", "+timePoint+", "+namesOfRaceColumnsForWhichToLoadLegDetails+") took "+ - (System.currentTimeMillis()-startOfRequestHandling)+"ms"); + logger.fine("computeLeaderboardByName(" + leaderboard.getName() + ", " + timePoint + ", " + + namesOfRaceColumnsForWhichToLoadLegDetails + ") took " + + (System.currentTimeMillis() - startOfRequestHandling) + "ms"); return result; } private void addOverallDetailsToRow(final Leaderboard leaderboard, final TimePoint timePoint, final Competitor competitor, LeaderboardRowDTO row) throws NoWindException { - final Pair maximumSpeedOverGround = leaderboard.getMaximumSpeedOverGround(competitor, timePoint); + final Pair maximumSpeedOverGround = leaderboard.getMaximumSpeedOverGround(competitor, + timePoint); if (maximumSpeedOverGround != null && maximumSpeedOverGround.getB() != null) { row.maximumSpeedOverGroundInKnots = maximumSpeedOverGround.getB().getKnots(); row.whenMaximumSpeedOverGroundWasAchieved = maximumSpeedOverGround.getA().getTimePoint().asDate(); } - final Long totalTimeSailedDownwindInMilliseconds = leaderboard.getTotalTimeSailedInLegTypeInMilliseconds(competitor, LegType.DOWNWIND, timePoint); - row.totalTimeSailedDownwindInSeconds = totalTimeSailedDownwindInMilliseconds==null?null:1./1000.*totalTimeSailedDownwindInMilliseconds; - final Long totalTimeSailedUpwindInMilliseconds = leaderboard.getTotalTimeSailedInLegTypeInMilliseconds(competitor, LegType.UPWIND, timePoint); - row.totalTimeSailedUpwindInSeconds = totalTimeSailedUpwindInMilliseconds==null?null:1./1000.*totalTimeSailedUpwindInMilliseconds; - final Long totalTimeSailedReachingInMilliseconds = leaderboard.getTotalTimeSailedInLegTypeInMilliseconds(competitor, LegType.REACHING, timePoint); - row.totalTimeSailedReachingInSeconds = totalTimeSailedReachingInMilliseconds==null?null:1./1000.*totalTimeSailedReachingInMilliseconds; + final Long totalTimeSailedDownwindInMilliseconds = leaderboard.getTotalTimeSailedInLegTypeInMilliseconds( + competitor, LegType.DOWNWIND, timePoint); + row.totalTimeSailedDownwindInSeconds = totalTimeSailedDownwindInMilliseconds == null ? null + : 1. / 1000. * totalTimeSailedDownwindInMilliseconds; + final Long totalTimeSailedUpwindInMilliseconds = leaderboard.getTotalTimeSailedInLegTypeInMilliseconds( + competitor, LegType.UPWIND, timePoint); + row.totalTimeSailedUpwindInSeconds = totalTimeSailedUpwindInMilliseconds == null ? null + : 1. / 1000. * totalTimeSailedUpwindInMilliseconds; + final Long totalTimeSailedReachingInMilliseconds = leaderboard.getTotalTimeSailedInLegTypeInMilliseconds( + competitor, LegType.REACHING, timePoint); + row.totalTimeSailedReachingInSeconds = totalTimeSailedReachingInMilliseconds == null ? null + : 1. / 1000. * totalTimeSailedReachingInMilliseconds; final Long totalTimeSailedInMilliseconds = leaderboard.getTotalTimeSailedInMilliseconds(competitor, timePoint); - row.totalTimeSailedInSeconds = totalTimeSailedInMilliseconds==null?null:1./1000.*totalTimeSailedInMilliseconds; + row.totalTimeSailedInSeconds = totalTimeSailedInMilliseconds == null ? null + : 1. / 1000. * totalTimeSailedInMilliseconds; } - + private List getCompetitorDTOList(List competitors) { List result = new ArrayList(); for (Competitor competitor : competitors) { @@ -626,7 +663,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S entryDTO.discarded = entry.isDiscarded(); if (addLegDetails && trackedRace != null) { try { - RaceDetails raceDetails = getRaceDetails(trackedRace, competitor, timePoint, waitForLatestAnalyses, legRanksCache); + RaceDetails raceDetails = getRaceDetails(trackedRace, competitor, timePoint, waitForLatestAnalyses, + legRanksCache); entryDTO.legDetails = raceDetails.getLegDetails(); entryDTO.windwardDistanceToOverallLeaderInMeters = raceDetails.getWindwardDistanceToOverallLeader() == null ? null : raceDetails.getWindwardDistanceToOverallLeader().getMeters(); @@ -635,18 +673,20 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { - throw new RuntimeException(e); // the future used to calculate the leg details was interrupted; escalate as runtime exception + throw new RuntimeException(e); // the future used to calculate the leg details was interrupted; escalate + // as runtime exception } } final Fleet fleet = entry.getFleet(); entryDTO.fleet = fleet == null ? null : convertToFleetDTO(fleet); return entryDTO; } - + private static class RaceDetails { private final List legDetails; private final Distance windwardDistanceToOverallLeader; private final Distance averageCrossTrackError; + public RaceDetails(List legDetails, Distance windwardDistanceToOverallLeader, Distance averageCrossTrackError) { super(); @@ -654,12 +694,15 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S this.windwardDistanceToOverallLeader = windwardDistanceToOverallLeader; this.averageCrossTrackError = averageCrossTrackError; } + public List getLegDetails() { return legDetails; } + public Distance getWindwardDistanceToOverallLeader() { return windwardDistanceToOverallLeader; } + public Distance getAverageCrossTrackError() { return averageCrossTrackError; } @@ -671,16 +714,19 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S * way equals the end of the tracking time, the query results will be looked up in a cache first and if not found, * they will be stored to the cache after calculating them. A cache invalidation {@link RaceChangeListener listener} * will be registered with the race which will be triggered for any event received by the race. + * * @param waitForLatestAnalyses * if false, this method is allowed to read the maneuver analysis results from a cache that * may not reflect all data already received; otherwise, the method will always block for the latest * cache updates to have happened before returning. */ private RaceDetails getRaceDetails(TrackedRace trackedRace, Competitor competitor, TimePoint timePoint, - boolean waitForLatestAnalyses, Map> legRanksCache) throws NoWindException, InterruptedException, ExecutionException { + boolean waitForLatestAnalyses, Map> legRanksCache) + throws NoWindException, InterruptedException, ExecutionException { RaceDetails raceDetails; if (trackedRace.getEndOfTracking() != null && trackedRace.getEndOfTracking().compareTo(timePoint) < 0) { - raceDetails = getRaceDetailsForEndOfTrackingFromCacheOrCalculateAndCache(trackedRace, competitor, legRanksCache); + raceDetails = getRaceDetailsForEndOfTrackingFromCacheOrCalculateAndCache(trackedRace, competitor, + legRanksCache); } else { raceDetails = calculateRaceDetails(trackedRace, competitor, timePoint, waitForLatestAnalyses, legRanksCache); } @@ -689,7 +735,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S private RaceDetails getRaceDetailsForEndOfTrackingFromCacheOrCalculateAndCache(final TrackedRace trackedRace, final Competitor competitor, final Map> legRanksCache) - throws NoWindException, InterruptedException, ExecutionException { + throws NoWindException, InterruptedException, ExecutionException { final Pair key = new Pair(trackedRace, competitor); RunnableFuture raceDetails; synchronized (raceDetailsAtEndOfTrackingCache) { @@ -703,7 +749,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S end = trackedRace.getEndOfTracking(); } return calculateRaceDetails(trackedRace, competitor, end, - /* waitForLatestManeuverAnalysis */ true /* because this is done only once after end of tracking */, legRanksCache); + /* waitForLatestManeuverAnalysis */true /* + * because this is done only once after end of tracking + */, legRanksCache); } }); raceDetailsExecutor.execute(raceDetails); @@ -716,18 +764,18 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } return raceDetails.get(); } - + /** - * Handles the invalidation of the {@link SailingServiceImpl#raceDetailsAtEndOfTrackingCache} entries if the tracked race - * changes in any way. + * Handles the invalidation of the {@link SailingServiceImpl#raceDetailsAtEndOfTrackingCache} entries if the tracked + * race changes in any way. * * @author Axel Uhl (D043530) - * + * */ private class CacheInvalidationListener implements RaceChangeListener { private final TrackedRace trackedRace; private final Competitor competitor; - + public CacheInvalidationListener(TrackedRace trackedRace, Competitor competitor) { this.trackedRace = trackedRace; this.competitor = competitor; @@ -797,7 +845,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } private RaceDetails calculateRaceDetails(TrackedRace trackedRace, Competitor competitor, TimePoint timePoint, - boolean waitForLatestAnalyses, Map> legRanksCache) throws NoWindException { + boolean waitForLatestAnalyses, Map> legRanksCache) + throws NoWindException { List legDetails; legDetails = new ArrayList(); final Course course = trackedRace.getRace().getCourse(); @@ -827,18 +876,22 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } private LegEntryDTO createLegEntry(TrackedLegOfCompetitor trackedLeg, TimePoint timePoint, - boolean waitForLatestAnalyses, Map> legRanksCache) throws NoWindException { + boolean waitForLatestAnalyses, Map> legRanksCache) + throws NoWindException { LegEntryDTO result; if (trackedLeg == null) { result = null; } else { result = new LegEntryDTO(); final Speed averageSpeedOverGround = trackedLeg.getAverageSpeedOverGround(timePoint); - result.averageSpeedOverGroundInKnots = averageSpeedOverGround == null ? null : averageSpeedOverGround.getKnots(); - final Distance averageCrossTrackError = trackedLeg.getAverageCrossTrackError(timePoint, waitForLatestAnalyses); - result.averageCrossTrackErrorInMeters = averageCrossTrackError == null ? null : averageCrossTrackError.getMeters(); + result.averageSpeedOverGroundInKnots = averageSpeedOverGround == null ? null : averageSpeedOverGround + .getKnots(); + final Distance averageCrossTrackError = trackedLeg.getAverageCrossTrackError(timePoint, + waitForLatestAnalyses); + result.averageCrossTrackErrorInMeters = averageCrossTrackError == null ? null : averageCrossTrackError + .getMeters(); Double speedOverGroundInKnots; - if (trackedLeg.hasFinishedLeg(timePoint)) { + if (trackedLeg.hasFinishedLeg(timePoint)) { speedOverGroundInKnots = averageSpeedOverGround == null ? null : averageSpeedOverGround.getKnots(); } else { final SpeedWithBearing speedOverGround = trackedLeg.getSpeedOverGround(timePoint); @@ -853,12 +906,15 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S result.gapToLeaderInSeconds = trackedLeg.getGapToLeaderInSeconds(timePoint, legRanksCache.get(trackedLeg.getLeg()).entrySet().iterator().next().getKey()); if (result.gapToLeaderInSeconds != null) { - // FIXME problem: asking just after the beginning of the leg yields very different values from asking for the end of the previous leg. - // This is because for the previous leg it's decided based on the mark passings; for the next (current) leg it's decided based on + // FIXME problem: asking just after the beginning of the leg yields very different values from asking + // for the end of the previous leg. + // This is because for the previous leg it's decided based on the mark passings; for the next (current) + // leg it's decided based on // windward distance and VMG Double gapAtEndOfPreviousLegInSeconds = getGapAtEndOfPreviousLegInSeconds(trackedLeg); if (gapAtEndOfPreviousLegInSeconds != null) { - result.gapChangeSinceLegStartInSeconds = result.gapToLeaderInSeconds - gapAtEndOfPreviousLegInSeconds; + result.gapChangeSinceLegStartInSeconds = result.gapToLeaderInSeconds + - gapAtEndOfPreviousLegInSeconds; } } LinkedHashMap legRanks = legRanksCache.get(trackedLeg.getLeg()); @@ -880,8 +936,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S .getMeters(); final TimePoint startOfRace = trackedLeg.getTrackedLeg().getTrackedRace().getStartOfRace(); if (startOfRace != null && trackedLeg.hasStartedLeg(timePoint)) { - // not using trackedLeg.getManeuvers(...) because it may not catch the mark passing maneuver starting this leg - // because that may have been detected as slightly before the mark passing time, hence associated with the previous leg + // not using trackedLeg.getManeuvers(...) because it may not catch the mark passing maneuver starting + // this leg + // because that may have been detected as slightly before the mark passing time, hence associated with + // the previous leg List maneuvers = trackedLeg.getTrackedLeg().getTrackedRace() .getManeuvers(trackedLeg.getCompetitor(), startOfRace, timePoint, waitForLatestAnalyses); if (maneuvers != null) { @@ -900,8 +958,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S case TACK: case JIBE: case PENALTY_CIRCLE: - if (!maneuver.getTimePoint().before(startOfLeg) && (!trackedLeg.hasFinishedLeg(timePoint) || - maneuver.getTimePoint().before(trackedLeg.getFinishTime()))) { + if (!maneuver.getTimePoint().before(startOfLeg) + && (!trackedLeg.hasFinishedLeg(timePoint) || maneuver.getTimePoint().before( + trackedLeg.getFinishTime()))) { if (maneuver.getManeuverLoss() != null) { result.numberOfManeuvers.put(maneuver.getType(), result.numberOfManeuvers.get(maneuver.getType()) + 1); @@ -912,17 +971,20 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } break; case MARK_PASSING: - // analyze all mark passings, not only those after this leg's start, to catch the mark passing - // maneuver starting this leg, even if its time point is slightly before the mark passing starting this leg + // analyze all mark passings, not only those after this leg's start, to catch the mark + // passing + // maneuver starting this leg, even if its time point is slightly before the mark passing + // starting this leg MarkPassingManeuver mpm = (MarkPassingManeuver) maneuver; if (mpm.getWaypointPassed() == trackedLeg.getLeg().getFrom()) { result.sideToWhichMarkAtLegStartWasRounded = mpm.getSide(); } break; - default: - /* Do nothing here. - * Throwing an exception destroys the toggling (and maybe other behaviour) of the leaderboard. - */ + default: + /* + * Do nothing here. Throwing an exception destroys the toggling (and maybe other behaviour) + * of the leaderboard. + */ } } result.averageManeuverLossInMeters = new HashMap(); @@ -949,7 +1011,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S int indexOfStartWaypoint = course.getIndexOfWaypoint(trackedLeg.getLeg().getFrom()); if (indexOfStartWaypoint == 0) { // trackedLeg was the first leg; gap is determined by gap of start line passing time points - Iterable markPassingsForLegStart = trackedLeg.getTrackedLeg().getTrackedRace().getMarkPassingsInOrder(trackedLeg.getLeg().getFrom()); + Iterable markPassingsForLegStart = trackedLeg.getTrackedLeg().getTrackedRace() + .getMarkPassingsInOrder(trackedLeg.getLeg().getFrom()); trackedLeg.getTrackedLeg().getTrackedRace().lockForRead(markPassingsForLegStart); try { final Iterator markPassingsIter = markPassingsForLegStart.iterator(); @@ -970,9 +1033,12 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S trackedLeg.getTrackedLeg().getTrackedRace().unlockAfterRead(markPassingsForLegStart); } } else { - TrackedLeg previousTrackedLeg = trackedLeg.getTrackedLeg().getTrackedRace().getTrackedLeg(course.getLegs().get(indexOfStartWaypoint-1)); - TrackedLegOfCompetitor previousTrackedLegOfCompetitor = previousTrackedLeg.getTrackedLeg(trackedLeg.getCompetitor()); - result = previousTrackedLegOfCompetitor.getGapToLeaderInSeconds(previousTrackedLegOfCompetitor.getFinishTime()); + TrackedLeg previousTrackedLeg = trackedLeg.getTrackedLeg().getTrackedRace() + .getTrackedLeg(course.getLegs().get(indexOfStartWaypoint - 1)); + TrackedLegOfCompetitor previousTrackedLegOfCompetitor = previousTrackedLeg.getTrackedLeg(trackedLeg + .getCompetitor()); + result = previousTrackedLegOfCompetitor.getGapToLeaderInSeconds(previousTrackedLegOfCompetitor + .getFinishTime()); } return result; } finally { @@ -1025,7 +1091,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } List raceColumns = new ArrayList(); for (RaceColumnInSeries raceColumn : series.getRaceColumns()) { - RaceColumnDTO raceColumnDTO = new RaceColumnDTO(/* isValidInTotalScore not relevant here because no scores conveyed */ null); + RaceColumnDTO raceColumnDTO = new RaceColumnDTO(/* + * isValidInTotalScore not relevant here because no scores + * conveyed + */null); raceColumnDTO.name = raceColumn.getName(); raceColumnDTO.setMedalRace(raceColumn.isMedalRace()); raceColumnDTO.setExplicitFactor(raceColumn.getExplicitFactor()); @@ -1044,23 +1113,27 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S for (RaceDefinition r : regatta.getAllRaces()) { RegattaAndRaceIdentifier raceIdentifier = new RegattaNameAndRaceName(regatta.getName(), r.getName()); TrackedRace trackedRace = getService().getExistingTrackedRace(raceIdentifier); - TrackedRaceDTO trackedRaceDTO = null; + TrackedRaceDTO trackedRaceDTO = null; if (trackedRace != null) { trackedRaceDTO = new TrackedRaceDTO(); trackedRaceDTO.hasWindData = trackedRace.hasWindData(); trackedRaceDTO.hasGPSData = trackedRace.hasGPSData(); - trackedRaceDTO.startOfTracking = trackedRace.getStartOfTracking() == null ? null : trackedRace.getStartOfTracking().asDate(); - trackedRaceDTO.endOfTracking = trackedRace.getEndOfTracking() == null ? null : trackedRace.getEndOfTracking().asDate(); - trackedRaceDTO.timePointOfNewestEvent = trackedRace.getTimePointOfNewestEvent() == null ? null : trackedRace.getTimePointOfNewestEvent().asDate(); - trackedRaceDTO.delayToLiveInMs = trackedRace.getDelayToLiveInMillis(); + trackedRaceDTO.startOfTracking = trackedRace.getStartOfTracking() == null ? null : trackedRace + .getStartOfTracking().asDate(); + trackedRaceDTO.endOfTracking = trackedRace.getEndOfTracking() == null ? null : trackedRace + .getEndOfTracking().asDate(); + trackedRaceDTO.timePointOfNewestEvent = trackedRace.getTimePointOfNewestEvent() == null ? null + : trackedRace.getTimePointOfNewestEvent().asDate(); + trackedRaceDTO.delayToLiveInMs = trackedRace.getDelayToLiveInMillis(); } - RaceWithCompetitorsDTO raceDTO = new RaceWithCompetitorsDTO(raceIdentifier, convertToCompetitorDTOs(r.getCompetitors()), - trackedRaceDTO, getService().isRaceBeingTracked(r)); + RaceWithCompetitorsDTO raceDTO = new RaceWithCompetitorsDTO(raceIdentifier, + convertToCompetitorDTOs(r.getCompetitors()), trackedRaceDTO, getService().isRaceBeingTracked(r)); if (trackedRace != null) { - raceDTO.startOfRace = trackedRace.getStartOfRace() == null ? null : trackedRace.getStartOfRace().asDate(); + raceDTO.startOfRace = trackedRace.getStartOfRace() == null ? null : trackedRace.getStartOfRace() + .asDate(); raceDTO.endOfRace = trackedRace.getEndOfRace() == null ? null : trackedRace.getEndOfRace().asDate(); } - raceDTO.boatClass = regatta.getBoatClass() == null ? null : regatta.getBoatClass().getName(); + raceDTO.boatClass = regatta.getBoatClass() == null ? null : regatta.getBoatClass().getName(); result.add(raceDTO); } return result; @@ -1079,35 +1152,37 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S CompetitorDTO competitorDTO = weakCompetitorDTOCache.get(c); if (competitorDTO == null) { CountryCode countryCode = c.getTeam().getNationality().getCountryCode(); - competitorDTO = new CompetitorDTO(c.getName(), countryCode == null ? "" - : countryCode.getTwoLetterISOCode(), - countryCode == null ? "" : countryCode.getThreeLetterIOCCode(), countryCode == null ? "" - : countryCode.getName(), c.getBoat().getSailID(), c.getId().toString(), - new BoatClassDTO(c.getBoat().getBoatClass().getName(), c.getBoat().getBoatClass().getHullLength() - .getMeters())); + competitorDTO = new CompetitorDTO(c.getName(), + countryCode == null ? "" : countryCode.getTwoLetterISOCode(), countryCode == null ? "" + : countryCode.getThreeLetterIOCCode(), countryCode == null ? "" : countryCode.getName(), c + .getBoat().getSailID(), c.getId().toString(), new BoatClassDTO(c.getBoat().getBoatClass() + .getName(), c.getBoat().getBoatClass().getHullLength().getMeters())); weakCompetitorDTOCache.put(c, competitorDTO); } return competitorDTO; } @Override - public Pair> listTracTracRacesInEvent(String eventJsonURL) throws MalformedURLException, IOException, - ParseException, org.json.simple.parser.ParseException, URISyntaxException { - com.sap.sailing.domain.common.impl.Util.Pair> raceRecords; + public Pair> listTracTracRacesInEvent(String eventJsonURL) + throws MalformedURLException, IOException, ParseException, org.json.simple.parser.ParseException, + URISyntaxException { + com.sap.sailing.domain.common.impl.Util.Pair> raceRecords; raceRecords = getService().getTracTracRaceRecords(new URL(eventJsonURL)); List result = new ArrayList(); for (RaceRecord raceRecord : raceRecords.getB()) { result.add(new TracTracRaceRecordDTO(raceRecord.getID(), raceRecord.getEventName(), raceRecord.getName(), raceRecord.getParamURL().toString(), raceRecord.getReplayURL(), raceRecord.getLiveURI().toString(), raceRecord.getStoredURI().toString(), raceRecord.getTrackingStartTime().asDate(), raceRecord - .getTrackingEndTime().asDate(), raceRecord.getRaceStartTime().asDate(), raceRecord.getBoatClassNames())); + .getTrackingEndTime().asDate(), raceRecord.getRaceStartTime().asDate(), raceRecord + .getBoatClassNames())); } return new Pair>(raceRecords.getA(), result); } @Override - public void trackWithTracTrac(RegattaIdentifier regattaToAddTo, TracTracRaceRecordDTO rr, String liveURI, String storedURI, - boolean trackWind, final boolean correctWindByDeclination, final boolean simulateWithStartTimeNow) throws Exception { + public void trackWithTracTrac(RegattaIdentifier regattaToAddTo, TracTracRaceRecordDTO rr, String liveURI, + String storedURI, boolean trackWind, final boolean correctWindByDeclination, + final boolean simulateWithStartTimeNow) throws Exception { if (liveURI == null || liveURI.trim().length() == 0) { liveURI = rr.liveURI; } @@ -1120,10 +1195,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S MongoWindStoreFactory.INSTANCE.getMongoWindStore(mongoObjectFactory, domainObjectFactory), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, simulateWithStartTimeNow); if (trackWind) { - new Thread("Wind tracking starter for race "+rr.regattaName+"/"+rr.name) { + new Thread("Wind tracking starter for race " + rr.regattaName + "/" + rr.name) { public void run() { try { - startTrackingWind(raceHandle, correctWindByDeclination, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS); + startTrackingWind(raceHandle, correctWindByDeclination, + RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS); } catch (Exception e) { throw new RuntimeException(e); } @@ -1137,17 +1213,19 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S Iterable configs = tractracDomainObjectFactory.getTracTracConfigurations(); List result = new ArrayList(); for (TracTracConfiguration ttConfig : configs) { - result.add(new TracTracConfigurationDTO(ttConfig.getName(), ttConfig.getJSONURL().toString(), - ttConfig.getLiveDataURI().toString(), ttConfig.getStoredDataURI().toString())); + result.add(new TracTracConfigurationDTO(ttConfig.getName(), ttConfig.getJSONURL().toString(), ttConfig + .getLiveDataURI().toString(), ttConfig.getStoredDataURI().toString())); } return result; } @Override - public void storeTracTracConfiguration(String name, String jsonURL, String liveDataURI, String storedDataURI) throws Exception { - tractracMongoObjectFactory.storeTracTracConfiguration(tractracDomainFactory.createTracTracConfiguration(name, jsonURL, liveDataURI, storedDataURI)); + public void storeTracTracConfiguration(String name, String jsonURL, String liveDataURI, String storedDataURI) + throws Exception { + tractracMongoObjectFactory.storeTracTracConfiguration(tractracDomainFactory.createTracTracConfiguration(name, + jsonURL, liveDataURI, storedDataURI)); } - + @Override public void stopTrackingEvent(RegattaIdentifier regattaIdentifier) throws Exception { getService().apply(new StopTrackingRegatta(regattaIdentifier)); @@ -1160,23 +1238,25 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S return null; } } - + @Override public void stopTrackingRace(RegattaAndRaceIdentifier regattaAndRaceIdentifier) throws Exception { getService().apply(new StopTrackingRace(regattaAndRaceIdentifier)); } - + @Override public void removeAndUntrackRace(RegattaAndRaceIdentifier regattatAndRaceidentifier) { getService().apply(new RemoveAndUntrackRace(regattatAndRaceidentifier)); } - + /** - * @param timeoutInMilliseconds eventually passed to {@link RacesHandle#getRaces(long)}. If the race definition - * can be obtained within this timeout, wind for the race will be tracked; otherwise, the method returns without - * taking any effect. + * @param timeoutInMilliseconds + * eventually passed to {@link RacesHandle#getRaces(long)}. If the race definition can be obtained within + * this timeout, wind for the race will be tracked; otherwise, the method returns without taking any + * effect. */ - private void startTrackingWind(RacesHandle raceHandle, boolean correctByDeclination, long timeoutInMilliseconds) throws Exception { + private void startTrackingWind(RacesHandle raceHandle, boolean correctByDeclination, long timeoutInMilliseconds) + throws Exception { Regatta regatta = raceHandle.getRegatta(); if (regatta != null) { for (RaceDefinition race : raceHandle.getRaces(timeoutInMilliseconds)) { @@ -1191,7 +1271,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public WindInfoForRaceDTO getRawWindFixes(RegattaAndRaceIdentifier raceIdentifier, Collection windSources) { + public WindInfoForRaceDTO getRawWindFixes(RegattaAndRaceIdentifier raceIdentifier, + Collection windSources) { WindInfoForRaceDTO result = null; TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier); if (trackedRace != null) { @@ -1208,17 +1289,17 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S windSourcesToDeliver.add(new WindSourceImpl(WindSourceType.WEB)); } for (WindSource windSource : windSourcesToDeliver) { - if(windSource.getType() == WindSourceType.WEB) { + if (windSource.getType() == WindSourceType.WEB) { WindTrackInfoDTO windTrackInfoDTO = new WindTrackInfoDTO(); windTrackInfoDTO.windFixes = new ArrayList(); WindTrack windTrack = trackedRace.getOrCreateWindTrack(windSource); - + windTrack.lockForRead(); try { Iterator windIter = windTrack.getRawFixes().iterator(); while (windIter.hasNext()) { Wind wind = windIter.next(); - if(wind != null) { + if (wind != null) { WindDTO windDTO = createWindDTO(wind, windTrack); windTrackInfoDTO.windFixes.add(windDTO); } @@ -1226,7 +1307,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } finally { windTrack.unlockAfterRead(); } - + windTrackInfoDTOs.put(windSource, windTrackInfoDTO); } } @@ -1241,13 +1322,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S windDTO.trueWindSpeedInKnots = wind.getKnots(); windDTO.trueWindSpeedInMetersPerSecond = wind.getMetersPerSecond(); if (wind.getPosition() != null) { - windDTO.position = new PositionDTO(wind.getPosition().getLatDeg(), wind.getPosition() - .getLngDeg()); + windDTO.position = new PositionDTO(wind.getPosition().getLatDeg(), wind.getPosition().getLngDeg()); } if (wind.getTimePoint() != null) { windDTO.measureTimepoint = wind.getTimePoint().asMillis(); - Wind estimatedWind = windTrack - .getAveragedWind(wind.getPosition(), wind.getTimePoint()); + Wind estimatedWind = windTrack.getAveragedWind(wind.getPosition(), wind.getTimePoint()); if (estimatedWind != null) { windDTO.dampenedTrueWindBearingDeg = estimatedWind.getBearing().getDegrees(); windDTO.dampenedTrueWindFromDeg = estimatedWind.getBearing().reverse().getDegrees(); @@ -1257,7 +1336,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } return windDTO; } - + /** * Uses wind for both, the non-dampened and dampened fields of the {@link WindDTO} object returned */ @@ -1273,23 +1352,22 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S windDTO.dampenedTrueWindSpeedInKnots = wind.getKnots(); windDTO.dampenedTrueWindSpeedInMetersPerSecond = wind.getMetersPerSecond(); if (wind.getPosition() != null) { - windDTO.position = new PositionDTO(wind.getPosition().getLatDeg(), wind.getPosition() - .getLngDeg()); + windDTO.position = new PositionDTO(wind.getPosition().getLatDeg(), wind.getPosition().getLngDeg()); } if (wind.getTimePoint() != null) { windDTO.measureTimepoint = wind.getTimePoint().asMillis(); } return windDTO; } - + /** - * Fetches the {@link WindTrack#getAveragedWind(Position, TimePoint) average wind} from all wind tracks or those identified - * by windSourceTypeNames + * Fetches the {@link WindTrack#getAveragedWind(Position, TimePoint) average wind} from all wind tracks or those + * identified by windSourceTypeNames */ - //@Override - public WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth, - int numberOfFixes, double latDeg, double lngDeg, Collection windSourceTypeNames) - throws NoWindException { + // @Override + public WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, + long millisecondsStepWidth, int numberOfFixes, double latDeg, double lngDeg, + Collection windSourceTypeNames) throws NoWindException { Position position = new DegreePosition(latDeg, lngDeg); WindInfoForRaceDTO result = null; TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier); @@ -1305,7 +1383,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S result.windTrackInfoByWindSource = windTrackInfoDTOs; List windSourcesToDeliver = new ArrayList(); Util.addAll(trackedRace.getWindSources(), windSourcesToDeliver); - // TODO bug #375: add the combined wind; currently, CombinedWindTrackImpl just takes too long to return results... + // TODO bug #375: add the combined wind; currently, CombinedWindTrackImpl just takes too long to return + // results... windSourcesToDeliver.add(new WindSourceImpl(WindSourceType.COMBINED)); for (WindSource windSource : windSourcesToDeliver) { if (windSourceTypeNames == null || windSourceTypeNames.contains(windSource.getType().name())) { @@ -1320,39 +1399,41 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S Double minWindConfidence = 2.0; Double maxWindConfidence = -1.0; for (int i = 0; i < numberOfFixes; i++) { - WindWithConfidence> averagedWindWithConfidence = windTrack.getAveragedWindWithConfidence(position, timePoint); - + WindWithConfidence> averagedWindWithConfidence = windTrack + .getAveragedWindWithConfidence(position, timePoint); + if (averagedWindWithConfidence != null) { - WindDTO windDTO = createWindDTOFromAlreadyAveraged(averagedWindWithConfidence.getObject(), windTrack, timePoint); + WindDTO windDTO = createWindDTOFromAlreadyAveraged(averagedWindWithConfidence.getObject(), + windTrack, timePoint); double confidence = averagedWindWithConfidence.getConfidence(); windDTO.confidence = confidence; windTrackInfoDTO.windFixes.add(windDTO); - if(confidence < minWindConfidence) { + if (confidence < minWindConfidence) { minWindConfidence = confidence; } - if(confidence > maxWindConfidence) { + if (confidence > maxWindConfidence) { maxWindConfidence = confidence; } } timePoint = new MillisecondsTimePoint(timePoint.asMillis() + millisecondsStepWidth); } - windTrackInfoDTO.minWindConfidence = minWindConfidence; - windTrackInfoDTO.maxWindConfidence = maxWindConfidence; + windTrackInfoDTO.minWindConfidence = minWindConfidence; + windTrackInfoDTO.maxWindConfidence = maxWindConfidence; } } } return result; } - + @Override - public WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth, - int numberOfFixes, Collection windSourceTypeNames) + public WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, + long millisecondsStepWidth, int numberOfFixes, Collection windSourceTypeNames) throws NoWindException { assert from != null; TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier); - - WindInfoForRaceDTO result = getAveragedWindInfo(new MillisecondsTimePoint(from), millisecondsStepWidth, numberOfFixes, - windSourceTypeNames, trackedRace); + + WindInfoForRaceDTO result = getAveragedWindInfo(new MillisecondsTimePoint(from), millisecondsStepWidth, + numberOfFixes, windSourceTypeNames, trackedRace); return result; } @@ -1386,23 +1467,25 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S Double minWindConfidence = 2.0; Double maxWindConfidence = -1.0; for (int i = 0; i < numberOfFixes && newestEvent != null && timePoint.compareTo(newestEvent) < 0; i++) { - WindWithConfidence> averagedWindWithConfidence = windTrack.getAveragedWindWithConfidence(null, timePoint); + WindWithConfidence> averagedWindWithConfidence = windTrack + .getAveragedWindWithConfidence(null, timePoint); if (averagedWindWithConfidence != null) { double confidence = averagedWindWithConfidence.getConfidence(); - WindDTO windDTO = createWindDTOFromAlreadyAveraged(averagedWindWithConfidence.getObject(), windTrack, timePoint); + WindDTO windDTO = createWindDTOFromAlreadyAveraged(averagedWindWithConfidence.getObject(), + windTrack, timePoint); windDTO.confidence = confidence; windTrackInfoDTO.windFixes.add(windDTO); - if(confidence < minWindConfidence) { + if (confidence < minWindConfidence) { minWindConfidence = confidence; } - if(confidence > maxWindConfidence) { + if (confidence > maxWindConfidence) { maxWindConfidence = confidence; } } timePoint = new MillisecondsTimePoint(timePoint.asMillis() + millisecondsStepWidth); } - windTrackInfoDTO.minWindConfidence = minWindConfidence; - windTrackInfoDTO.maxWindConfidence = maxWindConfidence; + windTrackInfoDTO.minWindConfidence = minWindConfidence; + windTrackInfoDTO.maxWindConfidence = maxWindConfidence; } } } @@ -1417,9 +1500,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S if (trackedRace != null) { TimePoint fromTimePoint = from == null ? trackedRace.getStartOfTracking() : new MillisecondsTimePoint(from); TimePoint toTimePoint = to == null ? trackedRace.getEndOfRace() : new MillisecondsTimePoint(to); - if(fromTimePoint != null && toTimePoint != null) { - int numberOfFixes = (int) ((toTimePoint.asMillis() - fromTimePoint.asMillis())/resolutionInMilliseconds); - result = getAveragedWindInfo(fromTimePoint, resolutionInMilliseconds, numberOfFixes, windSourceTypeNames, trackedRace); + if (fromTimePoint != null && toTimePoint != null) { + int numberOfFixes = (int) ((toTimePoint.asMillis() - fromTimePoint.asMillis()) / resolutionInMilliseconds); + result = getAveragedWindInfo(fromTimePoint, resolutionInMilliseconds, numberOfFixes, + windSourceTypeNames, trackedRace); } } return result; @@ -1459,7 +1543,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } Wind wind = new WindImpl(p, at, speedWithBearing); Iterable webWindSources = trackedRace.getWindSources(WindSourceType.WEB); - if(Util.size(webWindSources) == 0) { + if (Util.size(webWindSources) == 0) { // create a new WEB wind source if not available trackedRace.recordWind(wind, new WindSourceImpl(WindSourceType.WEB)); } else { @@ -1470,21 +1554,19 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public RaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date, - Map from, Map to, - boolean extrapolate) throws NoWindException { + Map from, Map to, boolean extrapolate) throws NoWindException { RaceMapDataDTO raceMapDataDTO = new RaceMapDataDTO(); - + raceMapDataDTO.boatPositions = getBoatPositions(raceIdentifier, from, to, extrapolate); - raceMapDataDTO.coursePositions = getCoursePositions(raceIdentifier, date); + raceMapDataDTO.coursePositions = getCoursePositions(raceIdentifier, date); raceMapDataDTO.quickRanks = getQuickRanks(raceIdentifier, date); - + return raceMapDataDTO; - } - + } + @Override public Map> getBoatPositions(RegattaAndRaceIdentifier raceIdentifier, - Map from, Map to, - boolean extrapolate) throws NoWindException { + Map from, Map to, boolean extrapolate) throws NoWindException { Map> result = new HashMap>(); TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier); if (trackedRace != null) { @@ -1514,11 +1596,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S track.unlockAfterRead(); } if (fixes.isEmpty()) { - // then there was no (smoothened) fix between fromTimePoint and toTimePointExcluding; estimate... - TimePoint middle = new MillisecondsTimePoint((toTimePointExcluding.asMillis()+fromTimePoint.asMillis())/2); + // then there was no (smoothened) fix between fromTimePoint and toTimePointExcluding; + // estimate... + TimePoint middle = new MillisecondsTimePoint( + (toTimePointExcluding.asMillis() + fromTimePoint.asMillis()) / 2); Position estimatedPosition = track.getEstimatedPosition(middle, extrapolate); SpeedWithBearing estimatedSpeed = track.getEstimatedSpeed(middle); - if(estimatedPosition != null && estimatedSpeed != null) { + if (estimatedPosition != null && estimatedSpeed != null) { fixes.add(new GPSFixMovingImpl(estimatedPosition, middle, estimatedSpeed)); } } @@ -1526,15 +1610,17 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S if (fixIter.hasNext()) { final WindSource windSource = new WindSourceImpl(WindSourceType.COMBINED); GPSFixMoving fix = fixIter.next(); - while (fix != null && (fix.getTimePoint().compareTo(toTimePointExcluding) < 0 || - (fix.getTimePoint().equals(toTimePointExcluding) && toTimePointExcluding.equals(fromTimePoint)))) { + while (fix != null + && (fix.getTimePoint().compareTo(toTimePointExcluding) < 0 || (fix.getTimePoint() + .equals(toTimePointExcluding) && toTimePointExcluding.equals(fromTimePoint)))) { Tack tack = trackedRace.getTack(competitor, fix.getTimePoint()); TrackedLegOfCompetitor trackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, fix.getTimePoint()); LegType legType = trackedLegOfCompetitor == null ? null : trackedRace.getTrackedLeg( trackedLegOfCompetitor.getLeg()).getLegType(fix.getTimePoint()); - Wind wind = trackedRace.getWind(fix.getPosition(),toTimePointExcluding); - WindDTO windDTO = createWindDTOFromAlreadyAveraged(wind, trackedRace.getOrCreateWindTrack(windSource), toTimePointExcluding); + Wind wind = trackedRace.getWind(fix.getPosition(), toTimePointExcluding); + WindDTO windDTO = createWindDTOFromAlreadyAveraged(wind, + trackedRace.getOrCreateWindTrack(windSource), toTimePointExcluding); GPSFixDTO fixDTO = createGPSFixDTO(fix, fix.getSpeed(), windDTO, tack, legType, /* extrapolate */ false); fixesForCompetitor.add(fixDTO); @@ -1550,12 +1636,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S fix.getTimePoint()); SpeedWithBearing speedWithBearing = track.getEstimatedSpeed(toTimePointExcluding); Wind wind2 = trackedRace.getWind(position, toTimePointExcluding); - WindDTO windDTO2 = createWindDTOFromAlreadyAveraged(wind2, trackedRace.getOrCreateWindTrack(windSource), toTimePointExcluding); - GPSFixDTO extrapolated = new GPSFixDTO( - to.get(competitorDTO), - position==null?null:new PositionDTO(position.getLatDeg(), position.getLngDeg()), - speedWithBearing==null?null:createSpeedWithBearingDTO(speedWithBearing), windDTO2, - tack2, legType2, /* extrapolated */ true); + WindDTO windDTO2 = createWindDTOFromAlreadyAveraged(wind2, + trackedRace.getOrCreateWindTrack(windSource), toTimePointExcluding); + GPSFixDTO extrapolated = new GPSFixDTO(to.get(competitorDTO), + position == null ? null : new PositionDTO(position.getLatDeg(), position + .getLngDeg()), speedWithBearing == null ? null + : createSpeedWithBearingDTO(speedWithBearing), windDTO2, tack2, + legType2, /* extrapolated */true); fixesForCompetitor.add(extrapolated); } fix = null; @@ -1569,14 +1656,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } private SpeedWithBearingDTO createSpeedWithBearingDTO(SpeedWithBearing speedWithBearing) { - return new SpeedWithBearingDTO(speedWithBearing.getKnots(), speedWithBearing - .getBearing().getDegrees()); + return new SpeedWithBearingDTO(speedWithBearing.getKnots(), speedWithBearing.getBearing().getDegrees()); } - private GPSFixDTO createGPSFixDTO(GPSFix fix, SpeedWithBearing speedWithBearing, WindDTO windDTO, Tack tack, LegType legType, boolean extrapolated) { - return new GPSFixDTO(fix.getTimePoint().asDate(), fix.getPosition()==null?null:new PositionDTO(fix - .getPosition().getLatDeg(), fix.getPosition().getLngDeg()), - speedWithBearing==null?null:createSpeedWithBearingDTO(speedWithBearing), windDTO, tack, legType, extrapolated); + private GPSFixDTO createGPSFixDTO(GPSFix fix, SpeedWithBearing speedWithBearing, WindDTO windDTO, Tack tack, + LegType legType, boolean extrapolated) { + return new GPSFixDTO(fix.getTimePoint().asDate(), fix.getPosition() == null ? null : new PositionDTO(fix + .getPosition().getLatDeg(), fix.getPosition().getLngDeg()), speedWithBearing == null ? null + : createSpeedWithBearingDTO(speedWithBearing), windDTO, tack, legType, extrapolated); } @Override @@ -1591,10 +1678,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S List markPassingTimesDTOs = new ArrayList(); raceTimesInfo.setMarkPassingTimes(markPassingTimesDTOs); - raceTimesInfo.startOfRace = trackedRace.getStartOfRace() == null ? null : trackedRace.getStartOfRace().asDate(); - raceTimesInfo.startOfTracking = trackedRace.getStartOfTracking() == null ? null : trackedRace.getStartOfTracking().asDate(); - raceTimesInfo.newestTrackingEvent = trackedRace.getTimePointOfNewestEvent() == null ? null : trackedRace.getTimePointOfNewestEvent().asDate(); - raceTimesInfo.endOfTracking = trackedRace.getEndOfTracking() == null ? null : trackedRace.getEndOfTracking().asDate(); + raceTimesInfo.startOfRace = trackedRace.getStartOfRace() == null ? null : trackedRace.getStartOfRace() + .asDate(); + raceTimesInfo.startOfTracking = trackedRace.getStartOfTracking() == null ? null : trackedRace + .getStartOfTracking().asDate(); + raceTimesInfo.newestTrackingEvent = trackedRace.getTimePointOfNewestEvent() == null ? null : trackedRace + .getTimePointOfNewestEvent().asDate(); + raceTimesInfo.endOfTracking = trackedRace.getEndOfTracking() == null ? null : trackedRace + .getEndOfTracking().asDate(); raceTimesInfo.endOfRace = trackedRace.getEndOfRace() == null ? null : trackedRace.getEndOfRace().asDate(); raceTimesInfo.delayToLiveInMs = trackedRace.getDelayToLiveInMillis(); @@ -1643,10 +1734,10 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } finally { trackedRace.getRace().getCourse().unlockAfterRead(); } - } + } return raceTimesInfo; } - + @Override public List getRaceTimesInfos(Collection raceIdentifiers) { List raceTimesInfos = new ArrayList(); @@ -1670,10 +1761,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S result.waypointPositions = new ArrayList(); Set marks = new HashSet(); Course course = trackedRace.getRace().getCourse(); - for (Waypoint waypoint : course.getWaypoints()) { + for (Waypoint waypoint : course.getWaypoints()) { Position waypointPosition = trackedRace.getApproximatePosition(waypoint, dateAsTimePoint); if (waypointPosition != null) { - result.waypointPositions.add(new PositionDTO(waypointPosition.getLatDeg(), waypointPosition.getLngDeg())); + result.waypointPositions.add(new PositionDTO(waypointPosition.getLatDeg(), waypointPosition + .getLngDeg())); } for (Mark b : waypoint.getMarks()) { marks.add(b); @@ -1686,12 +1778,12 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S result.marks.add(convertToMarkDTO(mark, positionAtDate)); } } - + // set the positions of start and finish Waypoint firstWaypoint = course.getFirstWaypoint(); if (firstWaypoint != null) { result.startMarkPositions = getMarkPositionDTOs(dateAsTimePoint, trackedRace, firstWaypoint); - } + } Waypoint lastWaypoint = course.getLastWaypoint(); if (lastWaypoint != null) { result.finishMarkPositions = getMarkPositionDTOs(dateAsTimePoint, trackedRace, lastWaypoint); @@ -1719,7 +1811,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } return raceMarksDTO; } - + @Override public List getRaceCourse(RegattaAndRaceIdentifier raceIdentifier, Date date) { List result = new ArrayList(); @@ -1736,29 +1828,33 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S return result; } - private ControlPointDTO createControlPointDTO(ControlPoint controlPoint, TrackedRace trackedRace, TimePoint timePoint) { + private ControlPointDTO createControlPointDTO(ControlPoint controlPoint, TrackedRace trackedRace, + TimePoint timePoint) { ControlPointDTO result; if (controlPoint instanceof Gate) { final Mark left = ((Gate) controlPoint).getLeft(); - final Position leftPos = trackedRace.getOrCreateTrack(left).getEstimatedPosition(timePoint, /* extrapolate */ false); + final Position leftPos = trackedRace.getOrCreateTrack(left).getEstimatedPosition(timePoint, /* extrapolate */ + false); final Mark right = ((Gate) controlPoint).getRight(); - final Position rightPos = trackedRace.getOrCreateTrack(right).getEstimatedPosition(timePoint, /* extrapolate */ false); - result = new GateDTO(controlPoint.getName(), convertToMarkDTO(left, leftPos), convertToMarkDTO(right, rightPos)); + final Position rightPos = trackedRace.getOrCreateTrack(right).getEstimatedPosition(timePoint, /* extrapolate */ + false); + result = new GateDTO(controlPoint.getName(), convertToMarkDTO(left, leftPos), convertToMarkDTO(right, + rightPos)); } else { - final Position posOfFirst = trackedRace.getOrCreateTrack(controlPoint.getMarks().iterator().next()). - getEstimatedPosition(timePoint, /* extrapolate */ false); + final Position posOfFirst = trackedRace.getOrCreateTrack(controlPoint.getMarks().iterator().next()) + .getEstimatedPosition(timePoint, /* extrapolate */false); result = new MarkDTO(controlPoint.getName(), posOfFirst.getLatDeg(), posOfFirst.getLngDeg()); } return result; } /** - * For each {@link ControlPointDTO} in controlPoints tries to find the best-matching waypoint - * from the course that belongs to the race identified by raceIdentifier. If such a waypoint is - * found, its control point is added to the control point list for the new course. Otherwise, a new control - * point is created using the default {@link com.sap.sailing.domain.base.DomainFactory} instance. The resulting - * list of control points is then passed to {@link Course#update(List, com.sap.sailing.domain.base.DomainFactory)} for - * the course of the race identified by raceIdentifier. + * For each {@link ControlPointDTO} in controlPoints tries to find the best-matching waypoint from the + * course that belongs to the race identified by raceIdentifier. If such a waypoint is found, its + * control point is added to the control point list for the new course. Otherwise, a new control point is created + * using the default {@link com.sap.sailing.domain.base.DomainFactory} instance. The resulting list of control + * points is then passed to {@link Course#update(List, com.sap.sailing.domain.base.DomainFactory)} for the course of + * the race identified by raceIdentifier. */ @Override public void updateRaceCourse(RegattaAndRaceIdentifier raceIdentifier, List controlPoints) { @@ -1770,10 +1866,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S int lastMatchPosition = -1; for (ControlPointDTO controlPointDTO : controlPoints) { ControlPoint matchFromOldCourse = null; - for (int i=lastMatchPosition+1; matchFromOldCourse == null && i getMarkPositionDTOs(TimePoint timePoint, TrackedRace trackedRace, Waypoint waypoint) { List startMarkPositions = new ArrayList(); for (Mark startMark : waypoint.getMarks()) { - final Position estimatedMarkPosition = trackedRace.getOrCreateTrack(startMark) - .getEstimatedPosition(timePoint, /* extrapolate */false); + final Position estimatedMarkPosition = trackedRace.getOrCreateTrack(startMark).getEstimatedPosition( + timePoint, /* extrapolate */false); if (estimatedMarkPosition != null) { - startMarkPositions.add(new PositionDTO(estimatedMarkPosition.getLatDeg(), estimatedMarkPosition.getLngDeg())); + startMarkPositions.add(new PositionDTO(estimatedMarkPosition.getLatDeg(), estimatedMarkPosition + .getLngDeg())); } } return startMarkPositions; @@ -1839,7 +1937,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S TrackedLegOfCompetitor trackedLeg = trackedRace.getTrackedLeg(competitor, dateAsTimePoint); if (trackedLeg != null) { int legNumber = race.getCourse().getLegs().indexOf(trackedLeg.getLeg()) + 1; - QuickRankDTO quickRankDTO = new QuickRankDTO(convertToCompetitorDTO(competitor), rank, legNumber); + QuickRankDTO quickRankDTO = new QuickRankDTO(convertToCompetitorDTO(competitor), rank, + legNumber); result.add(quickRankDTO); } } @@ -1853,14 +1952,15 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } return result; } - + @Override public void setRaceIsKnownToStartUpwind(RegattaAndRaceIdentifier raceIdentifier, boolean raceIsKnownToStartUpwind) { getService().apply(new SetRaceIsKnownToStartUpwind(raceIdentifier, raceIsKnownToStartUpwind)); } - + @Override - public void setWindSourcesToExclude(RegattaAndRaceIdentifier raceIdentifier, Iterable windSourcesToExclude) { + public void setWindSourcesToExclude(RegattaAndRaceIdentifier raceIdentifier, + Iterable windSourcesToExclude) { getService().apply(new SetWindSourcesToExclude(raceIdentifier, windSourcesToExclude)); } @@ -1878,8 +1978,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S result.windSourcesToExclude = windSourcesToExclude; Map windTrackInfoDTOs = new HashMap(); result.windTrackInfoByWindSource = windTrackInfoDTOs; - - for(WindSource windSource: trackedRace.getWindSources()) { + + for (WindSource windSource : trackedRace.getWindSources()) { windTrackInfoDTOs.put(windSource, new WindTrackInfoDTO()); } windTrackInfoDTOs.put(new WindSourceImpl(WindSourceType.COMBINED), new WindTrackInfoDTO()); @@ -1922,7 +2022,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S Wind wind = new WindImpl(p, at, speedWithBearing); trackedRace.removeWind(wind, trackedRace.getWindSources(WindSourceType.WEB).iterator().next()); } - } + } protected RacingEventService getService() { return racingEventServiceTracker.getService(); // grab the service @@ -1938,21 +2038,25 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public StrippedLeaderboardDTO createFlexibleLeaderboard(String leaderboardName, int[] discardThresholds, ScoringSchemeType scoringSchemeType) { - return createStrippedLeaderboardDTO(getService().apply(new CreateFlexibleLeaderboard(leaderboardName, discardThresholds, - baseDomainFactory.createScoringScheme(scoringSchemeType))), false); + public StrippedLeaderboardDTO createFlexibleLeaderboard(String leaderboardName, int[] discardThresholds, + ScoringSchemeType scoringSchemeType) { + return createStrippedLeaderboardDTO( + getService().apply( + new CreateFlexibleLeaderboard(leaderboardName, discardThresholds, baseDomainFactory + .createScoringScheme(scoringSchemeType))), false); } @Override public StrippedLeaderboardDTO createRegattaLeaderboard(RegattaIdentifier regattaIdentifier, int[] discardThresholds) { - return createStrippedLeaderboardDTO(getService().apply(new CreateRegattaLeaderboard(regattaIdentifier, discardThresholds)), false); + return createStrippedLeaderboardDTO( + getService().apply(new CreateRegattaLeaderboard(regattaIdentifier, discardThresholds)), false); } @Override public List getLeaderboards() { Map leaderboards = getService().getLeaderboards(); List results = new ArrayList(); - for(Leaderboard leaderboard: leaderboards.values()) { + for (Leaderboard leaderboard : leaderboards.values()) { StrippedLeaderboardDTO dao = createStrippedLeaderboardDTO(leaderboard, false); results.add(dao); } @@ -1985,7 +2089,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S results.addAll(set); return results; } - + @Override public List getLeaderboardsByRace(RaceDTO race) { List results = new ArrayList(); @@ -2009,12 +2113,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } /** - * Creates a {@link LeaderboardDTO} for leaderboard and fills in the name, race master data - * in the form of {@link RaceColumnDTO}s, whether or not there are {@link LeaderboardDTO#hasCarriedPoints carried points} - * and the {@link LeaderboardDTO#discardThresholds discarding thresholds} for the leaderboard. No data about the points + * Creates a {@link LeaderboardDTO} for leaderboard and fills in the name, race master data in the form + * of {@link RaceColumnDTO}s, whether or not there are {@link LeaderboardDTO#hasCarriedPoints carried points} and + * the {@link LeaderboardDTO#discardThresholds discarding thresholds} for the leaderboard. No data about the points * is filled into the result object. No data about the competitor display names is filled in; instead, an empty map * is used for {@link LeaderboardDTO#competitorDisplayNames}.
- * If withGeoLocationData is true the geographical location of all races will be determined. + * If withGeoLocationData is true the geographical location of all races will be + * determined. */ private StrippedLeaderboardDTO createStrippedLeaderboardDTO(Leaderboard leaderboard, boolean withGeoLocationData) { StrippedLeaderboardDTO leaderboardDTO = new StrippedLeaderboardDTO(); @@ -2027,7 +2132,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S if (leaderboard instanceof RegattaLeaderboard) { RegattaLeaderboard regattaLeaderboard = (RegattaLeaderboard) leaderboard; Regatta regatta = regattaLeaderboard.getRegatta(); - leaderboardDTO.regattaName = regatta.getName(); + leaderboardDTO.regattaName = regatta.getName(); leaderboardDTO.isRegattaLeaderboard = true; leaderboardDTO.scoringScheme = regatta.getScoringScheme().getType(); } else { @@ -2036,7 +2141,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } leaderboardDTO.setDelayToLiveInMillisForLatestRace(delayToLiveInMillisForLatestRace); leaderboardDTO.hasCarriedPoints = leaderboard.hasCarriedPoints(); - leaderboardDTO.discardThresholds = leaderboard.getResultDiscardingRule().getDiscardIndexResultsStartingWithHowManyRaces(); + leaderboardDTO.discardThresholds = leaderboard.getResultDiscardingRule() + .getDiscardIndexResultsStartingWithHowManyRaces(); for (RaceColumn raceColumn : leaderboard.getRaceColumns()) { for (Fleet fleet : raceColumn.getFleets()) { TimePoint latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive = null; @@ -2044,20 +2150,26 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S RegattaAndRaceIdentifier raceIdentifier = null; TrackedRace trackedRace = raceColumn.getTrackedRace(fleet); if (trackedRace != null) { - if (startOfLatestRace == null || (trackedRace.getStartOfRace() != null && trackedRace.getStartOfRace().compareTo(startOfLatestRace) > 0)) { + if (startOfLatestRace == null + || (trackedRace.getStartOfRace() != null && trackedRace.getStartOfRace().compareTo( + startOfLatestRace) > 0)) { delayToLiveInMillisForLatestRace = trackedRace.getDelayToLiveInMillis(); } - raceIdentifier = new RegattaNameAndRaceName(trackedRace.getTrackedRegatta().getRegatta().getName(), trackedRace.getRace().getName()); + raceIdentifier = new RegattaNameAndRaceName(trackedRace.getTrackedRegatta().getRegatta().getName(), + trackedRace.getRace().getName()); // Optional: Getting the places of the race PlacemarkOrderDTO racePlaces = withGeoLocationData ? getRacePlaces(trackedRace) : null; TrackedRaceDTO trackedRaceDTO = new TrackedRaceDTO(); - trackedRaceDTO.startOfTracking = trackedRace.getStartOfTracking() == null ? null : trackedRace.getStartOfTracking().asDate(); + trackedRaceDTO.startOfTracking = trackedRace.getStartOfTracking() == null ? null : trackedRace + .getStartOfTracking().asDate(); trackedRaceDTO.hasWindData = trackedRace.hasWindData(); trackedRaceDTO.hasGPSData = trackedRace.hasGPSData(); - raceDTO = new RaceDTO(raceIdentifier, trackedRaceDTO, getService().isRaceBeingTracked(trackedRace.getRace())); + raceDTO = new RaceDTO(raceIdentifier, trackedRaceDTO, getService().isRaceBeingTracked( + trackedRace.getRace())); raceDTO.places = racePlaces; - raceDTO.startOfRace = trackedRace.getStartOfRace() == null ? null : trackedRace.getStartOfRace().asDate(); + raceDTO.startOfRace = trackedRace.getStartOfRace() == null ? null : trackedRace.getStartOfRace() + .asDate(); raceDTO.endOfRace = trackedRace.getEndOfRace() == null ? null : trackedRace.getEndOfRace().asDate(); if (trackedRace.hasStarted(now) && trackedRace.hasGPSData() && trackedRace.hasWindData()) { TimePoint liveTimePointForTrackedRace = now; @@ -2067,12 +2179,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive = liveTimePointForTrackedRace; } - } + } final FleetDTO fleetDTO = convertToFleetDTO(fleet); - RaceColumnDTO raceColumnDTO = leaderboardDTO.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), fleetDTO, - raceColumn.isMedalRace(), raceIdentifier, raceDTO); + RaceColumnDTO raceColumnDTO = leaderboardDTO.addRace(raceColumn.getName(), + raceColumn.getExplicitFactor(), fleetDTO, raceColumn.isMedalRace(), raceIdentifier, raceDTO); if (latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive != null) { - raceColumnDTO.setWhenLastTrackedRaceWasLive(fleetDTO, latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive.asDate()); + raceColumnDTO.setWhenLastTrackedRaceWasLive(fleetDTO, + latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive.asDate()); } } } @@ -2093,7 +2206,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } return racePlaces; } - + private Pair getStartFinishPlacemarksForTrackedRace(TrackedRace race) { double radiusCalculationFactor = 10.0; Placemark startBest = null; @@ -2149,7 +2262,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S Pair placemarks = new Pair(startBest, finishBest); return placemarks; } - + @Override public void updateLeaderboard(String leaderboardName, String newLeaderboardName, int[] newDiscardingThresholds) { getService().apply(new UpdateLeaderboard(leaderboardName, newLeaderboardName, newDiscardingThresholds)); @@ -2172,11 +2285,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public void addColumnsToLeaderboard(String leaderboardName, List> columnsToAdd) { - for(Pair columnToAdd: columnsToAdd) { + for (Pair columnToAdd : columnsToAdd) { getService().apply(new AddColumnToLeaderboard(columnToAdd.getA(), leaderboardName, columnToAdd.getB())); } } - + @Override public void removeLeaderboardColumns(String leaderboardName, List columnsToRemove) { for (String columnToRemove : columnsToRemove) { @@ -2188,12 +2301,12 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S public void removeLeaderboardColumn(String leaderboardName, String columnName) { getService().apply(new RemoveLeaderboardColumn(columnName, leaderboardName)); } - + @Override public void renameLeaderboardColumn(String leaderboardName, String oldColumnName, String newColumnName) { getService().apply(new RenameLeaderboardColumn(leaderboardName, oldColumnName, newColumnName)); } - + @Override public void updateLeaderboardColumnFactor(String leaderboardName, String columnName, Double newFactor) { getService().apply(new UpdateLeaderboardColumnFactor(leaderboardName, columnName, newFactor)); @@ -2201,17 +2314,20 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public void suppressCompetitorInLeaderboard(String leaderboardName, String competitorIdAsString, boolean suppressed) { - getService().apply(new SetSuppressedFlagForCompetitorInLeaderboard(leaderboardName, competitorIdAsString, suppressed)); + getService().apply( + new SetSuppressedFlagForCompetitorInLeaderboard(leaderboardName, competitorIdAsString, suppressed)); } @Override public boolean connectTrackedRaceToLeaderboardColumn(String leaderboardName, String raceColumnName, String fleetName, RegattaAndRaceIdentifier raceIdentifier) { - return getService().apply(new ConnectTrackedRaceToLeaderboardColumn(leaderboardName, raceColumnName, fleetName, raceIdentifier)); + return getService().apply( + new ConnectTrackedRaceToLeaderboardColumn(leaderboardName, raceColumnName, fleetName, raceIdentifier)); } @Override - public Map getRegattaAndRaceNameOfTrackedRaceConnectedToLeaderboardColumn(String leaderboardName, String raceColumnName) { + public Map getRegattaAndRaceNameOfTrackedRaceConnectedToLeaderboardColumn( + String leaderboardName, String raceColumnName) { Map result = new HashMap(); Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName); if (leaderboard != null) { @@ -2231,7 +2347,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public void disconnectLeaderboardColumnFromTrackedRace(String leaderboardName, String raceColumnName, String fleetName) { + public void disconnectLeaderboardColumnFromTrackedRace(String leaderboardName, String raceColumnName, + String fleetName) { getService().apply(new DisconnectLeaderboardColumnFromTrackedRace(leaderboardName, raceColumnName, fleetName)); } @@ -2241,8 +2358,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public Triple updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, String raceColumnName, - MaxPointsReason maxPointsReason, Date date) throws NoWindException { + public Triple updateLeaderboardMaxPointsReason(String leaderboardName, + String competitorIdAsString, String raceColumnName, MaxPointsReason maxPointsReason, Date date) + throws NoWindException { return getService().apply( new UpdateLeaderboardMaxPointsReason(leaderboardName, raceColumnName, competitorIdAsString, maxPointsReason, new MillisecondsTimePoint(date))); @@ -2255,35 +2373,43 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S new UpdateLeaderboardScoreCorrection(leaderboardName, columnName, competitorIdAsString, correctedScore, new MillisecondsTimePoint(date))); } - + @Override - public Void updateLeaderboardScoreCorrectionMetadata(String leaderboardName, Date timePointOfLastCorrectionValidity, String comment) { + public Void updateLeaderboardScoreCorrectionMetadata(String leaderboardName, + Date timePointOfLastCorrectionValidity, String comment) { return getService().apply( new UpdateLeaderboardScoreCorrectionMetadata(leaderboardName, - timePointOfLastCorrectionValidity == null ? null : new MillisecondsTimePoint(timePointOfLastCorrectionValidity), - comment)); + timePointOfLastCorrectionValidity == null ? null : new MillisecondsTimePoint( + timePointOfLastCorrectionValidity), comment)); } - + @Override - public void updateLeaderboardScoreCorrectionsAndMaxPointsReasons(BulkScoreCorrectionDTO updates) throws NoWindException { + public void updateLeaderboardScoreCorrectionsAndMaxPointsReasons(BulkScoreCorrectionDTO updates) + throws NoWindException { Date dateForResults = new Date(); // we don't care about the result date/time here; use current date as default - for (Map.Entry> e : updates.getScoreUpdatesForRaceColumnByCompetitorIdAsString().entrySet()) { + for (Map.Entry> e : updates.getScoreUpdatesForRaceColumnByCompetitorIdAsString() + .entrySet()) { for (Map.Entry raceColumnNameAndCorrectedScore : e.getValue().entrySet()) { updateLeaderboardScoreCorrection(updates.getLeaderboardName(), e.getKey(), - raceColumnNameAndCorrectedScore.getKey(), raceColumnNameAndCorrectedScore.getValue(), dateForResults); + raceColumnNameAndCorrectedScore.getKey(), raceColumnNameAndCorrectedScore.getValue(), + dateForResults); } } - for (Map.Entry> e : updates.getMaxPointsUpdatesForRaceColumnByCompetitorIdAsString().entrySet()) { + for (Map.Entry> e : updates + .getMaxPointsUpdatesForRaceColumnByCompetitorIdAsString().entrySet()) { for (Map.Entry raceColumnNameAndNewMaxPointsReason : e.getValue().entrySet()) { updateLeaderboardMaxPointsReason(updates.getLeaderboardName(), e.getKey(), - raceColumnNameAndNewMaxPointsReason.getKey(), raceColumnNameAndNewMaxPointsReason.getValue(), dateForResults); + raceColumnNameAndNewMaxPointsReason.getKey(), raceColumnNameAndNewMaxPointsReason.getValue(), + dateForResults); } } } - + @Override - public void updateCompetitorDisplayNameInLeaderboard(String leaderboardName, String competitorIdAsString, String displayName) { - getService().apply(new UpdateCompetitorDisplayNameInLeaderboard(leaderboardName, competitorIdAsString, displayName)); + public void updateCompetitorDisplayNameInLeaderboard(String leaderboardName, String competitorIdAsString, + String displayName) { + getService().apply( + new UpdateCompetitorDisplayNameInLeaderboard(leaderboardName, competitorIdAsString, displayName)); } @Override @@ -2318,16 +2444,18 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S Iterable configs = swissTimingAdapterPersistence.getSwissTimingConfigurations(); List result = new ArrayList(); for (SwissTimingConfiguration stConfig : configs) { - result.add(new SwissTimingConfigurationDTO(stConfig.getName(), stConfig.getHostname(), stConfig.getPort(), stConfig.canSendRequests())); + result.add(new SwissTimingConfigurationDTO(stConfig.getName(), stConfig.getHostname(), stConfig.getPort(), + stConfig.canSendRequests())); } return result; - } + } @Override - public List listSwissTimingRaces(String hostname, int port, boolean canSendRequests) - throws UnknownHostException, IOException, InterruptedException, ParseException { + public List listSwissTimingRaces(String hostname, int port, boolean canSendRequests) + throws UnknownHostException, IOException, InterruptedException, ParseException { List result = new ArrayList(); - for (com.sap.sailing.domain.swisstimingadapter.RaceRecord rr : getService().getSwissTimingRaceRecords(hostname, port, canSendRequests)) { + for (com.sap.sailing.domain.swisstimingadapter.RaceRecord rr : getService().getSwissTimingRaceRecords(hostname, + port, canSendRequests)) { result.add(new SwissTimingRaceRecordDTO(rr.getRaceID(), rr.getDescription(), rr.getStartTime())); } return result; @@ -2335,21 +2463,24 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public void storeSwissTimingConfiguration(String configName, String hostname, int port, boolean canSendRequests) { - swissTimingAdapterPersistence.storeSwissTimingConfiguration(swissTimingFactory.createSwissTimingConfiguration(configName, hostname, port, canSendRequests)); - } + swissTimingAdapterPersistence.storeSwissTimingConfiguration(swissTimingFactory.createSwissTimingConfiguration( + configName, hostname, port, canSendRequests)); + } @Override - public void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, SwissTimingRaceRecordDTO rr, String hostname, int port, - boolean canSendRequests, boolean trackWind, final boolean correctWindByDeclination) throws Exception { + public void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, SwissTimingRaceRecordDTO rr, String hostname, + int port, boolean canSendRequests, boolean trackWind, final boolean correctWindByDeclination) + throws Exception { final RacesHandle raceHandle = getService().addSwissTimingRace(regattaToAddTo, rr.ID, hostname, port, canSendRequests, MongoWindStoreFactory.INSTANCE.getMongoWindStore(mongoObjectFactory, domainObjectFactory), RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS); if (trackWind) { - new Thread("Wind tracking starter for race "+rr.ID+"/"+rr.description) { + new Thread("Wind tracking starter for race " + rr.ID + "/" + rr.description) { public void run() { try { - startTrackingWind(raceHandle, correctWindByDeclination, RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS); + startTrackingWind(raceHandle, correctWindByDeclination, + RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS); } catch (Exception e) { throw new RuntimeException(e); } @@ -2360,20 +2491,22 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public void sendSwissTimingDummyRace(String racMessage, String stlMesssage, String ccgMessage) { - getService().storeSwissTimingDummyRace(racMessage,stlMesssage,ccgMessage); + getService().storeSwissTimingDummyRace(racMessage, stlMesssage, ccgMessage); } @Override public List listSwissTiminigReplayRaces(String swissTimingUrl) { List replayRaces = SwissTimingReplayServiceFactory.INSTANCE .createSwissTimingReplayService().listReplayRaces(swissTimingUrl); - List result = new ArrayList(replayRaces.size()); + List result = new ArrayList(replayRaces.size()); for (SwissTimingReplayRace replayRace : replayRaces) { - result.add(new SwissTimingReplayRaceDTO(replayRace.getFlightNumber(), replayRace.getRaceId(), replayRace.getRsc(), replayRace.getName(), replayRace.getBoatClass(), replayRace.getStartTime(), replayRace.getLink())); + result.add(new SwissTimingReplayRaceDTO(replayRace.getFlightNumber(), replayRace.getRaceId(), replayRace + .getRsc(), replayRace.getName(), replayRace.getBoatClass(), replayRace.getStartTime(), replayRace + .getLink())); } return result; } - + @Override public void replaySwissTimingRace(RegattaIdentifier regattaIdentifier, SwissTimingReplayRaceDTO replayRaceDTO, boolean trackWind, boolean correctWindByDeclination, boolean simulateWithStartTimeNow) { @@ -2381,24 +2514,27 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S if (regattaIdentifier == null) { String boatClass = replayRaceDTO.boat_class; for (String genderIndicator : new String[] { "Man", "Woman", "Men", "Women", "M", "W" }) { - Pattern p = Pattern.compile("(( - )|-| )"+genderIndicator+"$"); + Pattern p = Pattern.compile("(( - )|-| )" + genderIndicator + "$"); Matcher m = p.matcher(boatClass.trim()); if (m.find()) { boatClass = boatClass.trim().substring(0, m.start(1)); break; } } - regatta = getService().createRegatta(replayRaceDTO.rsc, boatClass.trim(), + regatta = getService().createRegatta( + replayRaceDTO.rsc, + boatClass.trim(), RegattaImpl.getFullName(replayRaceDTO.rsc, replayRaceDTO.boat_class), Collections.singletonList(new SeriesImpl("Default", /* isMedal */false, Collections - .singletonList(new FleetImpl("Default")), /* race column names */new ArrayList(), - getService())), - false, baseDomainFactory.createScoringScheme(ScoringSchemeType.LOW_POINT)); + .singletonList(new FleetImpl("Default")), /* race column names */new ArrayList(), + getService())), false, baseDomainFactory.createScoringScheme(ScoringSchemeType.LOW_POINT)); } else { regatta = getService().getRegatta(regattaIdentifier); } - SwissTimingReplayService replayService = SwissTimingReplayServiceFactory.INSTANCE.createSwissTimingReplayService(); - replayService.loadRaceData(replayRaceDTO.link, getService().getSwissTimingDomainFactory(), regatta, getService()); + SwissTimingReplayService replayService = SwissTimingReplayServiceFactory.INSTANCE + .createSwissTimingReplayService(); + replayService.loadRaceData(replayRaceDTO.link, getService().getSwissTimingDomainFactory(), regatta, + getService()); } @Override @@ -2412,9 +2548,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S Collections.sort(countryCodes); return countryCodes.toArray(new String[0]); } - + /** - * Finds a competitor in a sequence of competitors that has an {@link Competitor#getId()} equal to id. + * Finds a competitor in a sequence of competitors that has an {@link Competitor#getId()} equal to id. */ private Competitor getCompetitorById(Iterable competitors, String id) { for (Competitor c : competitors) { @@ -2424,7 +2560,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } return null; } - + private Double getCompetitorRaceDataEntry(DetailType dataType, TrackedRace trackedRace, Competitor competitor, TimePoint timePoint) throws NoWindException { Double result = null; @@ -2456,8 +2592,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S case RACE_RANK: result = (double) trackedLeg.getRank(timePoint); break; - default: - throw new UnsupportedOperationException("Theres currently no support for the enum value '" + dataType + "' in this method."); + default: + throw new UnsupportedOperationException("Theres currently no support for the enum value '" + + dataType + "' in this method."); } } return result; @@ -2465,17 +2602,20 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S course.unlockAfterRead(); } } - + @Override - public CompetitorsRaceDataDTO getCompetitorsRaceData(RegattaAndRaceIdentifier race, List competitors, Date from, Date to, - long stepSizeInMs, DetailType detailType) throws NoWindException { + public CompetitorsRaceDataDTO getCompetitorsRaceData(RegattaAndRaceIdentifier race, + List competitors, Date from, Date to, long stepSizeInMs, DetailType detailType) + throws NoWindException { CompetitorsRaceDataDTO result = null; TrackedRace trackedRace = getExistingTrackedRace(race); if (trackedRace != null) { TimePoint newestEvent = trackedRace.getTimePointOfNewestEvent(); TimePoint startTime = from == null ? trackedRace.getStartOfTracking() : new MillisecondsTimePoint(from); - TimePoint endTime = (to == null || to.after(newestEvent.asDate())) ? newestEvent : new MillisecondsTimePoint(to); - result = new CompetitorsRaceDataDTO(detailType, startTime==null?null:startTime.asDate(), endTime==null?null:endTime.asDate()); + TimePoint endTime = (to == null || to.after(newestEvent.asDate())) ? newestEvent + : new MillisecondsTimePoint(to); + result = new CompetitorsRaceDataDTO(detailType, startTime == null ? null : startTime.asDate(), + endTime == null ? null : endTime.asDate()); for (CompetitorDTO competitorDTO : competitors) { Competitor competitor = getCompetitorById(trackedRace.getRace().getCompetitors(), competitorDTO.id); @@ -2487,7 +2627,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S trackedRace.lockForRead(competitorMarkPassings); try { for (MarkPassing markPassing : competitorMarkPassings) { - MillisecondsTimePoint time = new MillisecondsTimePoint(markPassing.getTimePoint().asMillis()); + MillisecondsTimePoint time = new MillisecondsTimePoint(markPassing.getTimePoint() + .asMillis()); markPassingsData.add(new Triple(markPassing.getWaypoint().getName(), time.asDate(), getCompetitorRaceDataEntry(detailType, trackedRace, competitor, time))); @@ -2499,20 +2640,20 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S if (startTime != null && endTime != null) { for (long i = startTime.asMillis(); i <= endTime.asMillis(); i += stepSizeInMs) { MillisecondsTimePoint time = new MillisecondsTimePoint(i); - raceData.add(new Pair(time.asDate(), getCompetitorRaceDataEntry(detailType, trackedRace, - competitor, time))); + raceData.add(new Pair(time.asDate(), getCompetitorRaceDataEntry(detailType, + trackedRace, competitor, time))); } } - result.setCompetitorData(competitorDTO, new CompetitorRaceDataDTO(competitorDTO, detailType, markPassingsData, raceData)); + result.setCompetitorData(competitorDTO, new CompetitorRaceDataDTO(competitorDTO, detailType, + markPassingsData, raceData)); } } return result; } - + @Override public Map> getDouglasPoints(RegattaAndRaceIdentifier raceIdentifier, - Map from, Map to, - double meters) throws NoWindException { + Map from, Map to, double meters) throws NoWindException { Map> result = new HashMap>(); TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier); if (trackedRace != null) { @@ -2542,12 +2683,15 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S speedWithBearing = gpsFixTrack.getEstimatedSpeed(fix.getTimePoint()); } Tack tack = trackedRace.getTack(competitor, fix.getTimePoint()); - TrackedLegOfCompetitor trackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, fix.getTimePoint()); + TrackedLegOfCompetitor trackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, + fix.getTimePoint()); LegType legType = trackedLegOfCompetitor == null ? null : trackedRace.getTrackedLeg( trackedLegOfCompetitor.getLeg()).getLegType(fix.getTimePoint()); Wind wind = trackedRace.getWind(fix.getPosition(), fix.getTimePoint()); - WindDTO windDTO = createWindDTOFromAlreadyAveraged(wind, trackedRace.getOrCreateWindTrack(windSource), fix.getTimePoint()); - GPSFixDTO fixDTO = createGPSFixDTO(fix, speedWithBearing, windDTO, tack, legType, /* extrapolated */false); + WindDTO windDTO = createWindDTOFromAlreadyAveraged(wind, + trackedRace.getOrCreateWindTrack(windSource), fix.getTimePoint()); + GPSFixDTO fixDTO = createGPSFixDTO(fix, speedWithBearing, windDTO, tack, legType, /* extrapolated */ + false); gpsFixDouglasList.add(fixDTO); } result.put(competitorDTO, gpsFixDouglasList); @@ -2576,7 +2720,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S List maneuversForCompetitor; try { maneuversForCompetitor = trackedRace.getManeuvers(competitor, timePointFrom, - timePointTo, /* waitForLatest */ true); + timePointTo, /* waitForLatest */true); } catch (NoWindException e) { throw new NoWindError(e); } @@ -2601,25 +2745,25 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S return result; } - private List createManeuverDTOsForCompetitor(List maneuvers, TrackedRace trackedRace, Competitor competitor) { + private List createManeuverDTOsForCompetitor(List maneuvers, TrackedRace trackedRace, + Competitor competitor) { List result = new ArrayList(); for (Maneuver maneuver : maneuvers) { final ManeuverDTO maneuverDTO; if (maneuver.getType() == ManeuverType.MARK_PASSING) { - maneuverDTO = new MarkpassingManeuverDTO(maneuver.getType(), maneuver.getNewTack(), - new PositionDTO(maneuver.getPosition().getLatDeg(), maneuver.getPosition().getLngDeg()), - maneuver.getTimePoint().asDate(), - createSpeedWithBearingDTO(maneuver.getSpeedWithBearingBefore()), - createSpeedWithBearingDTO(maneuver.getSpeedWithBearingAfter()), - maneuver.getDirectionChangeInDegrees(), maneuver.getManeuverLoss()==null?null:maneuver.getManeuverLoss().getMeters(), - ((MarkPassingManeuver) maneuver).getSide()); - } else { - maneuverDTO = new ManeuverDTO(maneuver.getType(), maneuver.getNewTack(), - new PositionDTO(maneuver.getPosition().getLatDeg(), maneuver.getPosition().getLngDeg()), - maneuver.getTimePoint().asDate(), - createSpeedWithBearingDTO(maneuver.getSpeedWithBearingBefore()), + maneuverDTO = new MarkpassingManeuverDTO(maneuver.getType(), maneuver.getNewTack(), new PositionDTO( + maneuver.getPosition().getLatDeg(), maneuver.getPosition().getLngDeg()), maneuver + .getTimePoint().asDate(), createSpeedWithBearingDTO(maneuver.getSpeedWithBearingBefore()), createSpeedWithBearingDTO(maneuver.getSpeedWithBearingAfter()), - maneuver.getDirectionChangeInDegrees(), maneuver.getManeuverLoss()==null?null:maneuver.getManeuverLoss().getMeters()); + maneuver.getDirectionChangeInDegrees(), maneuver.getManeuverLoss() == null ? null : maneuver + .getManeuverLoss().getMeters(), ((MarkPassingManeuver) maneuver).getSide()); + } else { + maneuverDTO = new ManeuverDTO(maneuver.getType(), maneuver.getNewTack(), new PositionDTO(maneuver + .getPosition().getLatDeg(), maneuver.getPosition().getLngDeg()), maneuver.getTimePoint() + .asDate(), createSpeedWithBearingDTO(maneuver.getSpeedWithBearingBefore()), + createSpeedWithBearingDTO(maneuver.getSpeedWithBearingAfter()), + maneuver.getDirectionChangeInDegrees(), maneuver.getManeuverLoss() == null ? null : maneuver + .getManeuverLoss().getMeters()); } result.add(maneuverDTO); } @@ -2645,28 +2789,29 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S public TrackedRace getExistingTrackedRace(RegattaAndRaceIdentifier regattaNameAndRaceName) { return getService().getExistingTrackedRace(regattaNameAndRaceName); } - + @Override public Regatta getRegatta(RegattaName regattaIdentifier) { return getService().getRegattaByName(regattaIdentifier.getRegattaName()); } - + /** - * Returns a servlet context that, when asked for a resource, first tries the original servlet context's implementation. If that - * fails, it prepends "war/" to the request because the war/ folder contains all the resources exposed externally - * through the HTTP server. + * Returns a servlet context that, when asked for a resource, first tries the original servlet context's + * implementation. If that fails, it prepends "war/" to the request because the war/ folder contains all the + * resources exposed externally through the HTTP server. */ @Override public ServletContext getServletContext() { return new DelegatingServletContext(super.getServletContext()); } - + @Override /** * Override of function to prevent exception "Blocked request without GWT permutation header (XSRF attack?)" when testing the GWT sites */ protected void checkPermutationStrongName() throws SecurityException { - //Override to prevent exception "Blocked request without GWT permutation header (XSRF attack?)" when testing the GWT sites + // Override to prevent exception "Blocked request without GWT permutation header (XSRF attack?)" when testing + // the GWT sites return; } @@ -2674,11 +2819,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S public List getLeaderboardGroups(boolean withGeoLocationData) { ArrayList leaderboardGroupDTOs = new ArrayList(); Map leaderboardGroups = getService().getLeaderboardGroups(); - + for (LeaderboardGroup leaderboardGroup : leaderboardGroups.values()) { leaderboardGroupDTOs.add(convertToLeaderboardGroupDTO(leaderboardGroup, withGeoLocationData)); } - + return leaderboardGroupDTOs; } @@ -2686,8 +2831,9 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S public LeaderboardGroupDTO getLeaderboardGroupByName(String groupName, boolean withGeoLocationData) { return convertToLeaderboardGroupDTO(getService().getLeaderboardGroupByName(groupName), withGeoLocationData); } - - private LeaderboardGroupDTO convertToLeaderboardGroupDTO(LeaderboardGroup leaderboardGroup, boolean withGeoLocationData) { + + private LeaderboardGroupDTO convertToLeaderboardGroupDTO(LeaderboardGroup leaderboardGroup, + boolean withGeoLocationData) { LeaderboardGroupDTO groupDTO = new LeaderboardGroupDTO(); groupDTO.name = leaderboardGroup.getName(); groupDTO.description = leaderboardGroup.getDescription(); @@ -2697,13 +2843,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } Leaderboard overallLeaderboard = leaderboardGroup.getOverallLeaderboard(); if (overallLeaderboard != null) { - groupDTO.setOverallLeaderboardDiscardThresholds(overallLeaderboard.getResultDiscardingRule().getDiscardIndexResultsStartingWithHowManyRaces()); + groupDTO.setOverallLeaderboardDiscardThresholds(overallLeaderboard.getResultDiscardingRule() + .getDiscardIndexResultsStartingWithHowManyRaces()); groupDTO.setOverallLeaderboardScoringSchemeType(overallLeaderboard.getScoringScheme().getType()); } return groupDTO; } - - + private PlacemarkDTO convertToPlacemarkDTO(Placemark placemark) { Position position = placemark.getPosition(); return new PlacemarkDTO(placemark.getName(), placemark.getCountryCode(), new PositionDTO(position.getLatDeg(), @@ -2721,16 +2867,19 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public LeaderboardGroupDTO createLeaderboardGroup(String groupName, String description, boolean displayGroupsInReverseOrder, - int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType) { - CreateLeaderboardGroup createLeaderboardGroupOp = new CreateLeaderboardGroup(groupName, description, displayGroupsInReverseOrder, - new ArrayList(), overallLeaderboardDiscardThresholds, overallLeaderboardScoringSchemeType); + public LeaderboardGroupDTO createLeaderboardGroup(String groupName, String description, + boolean displayGroupsInReverseOrder, int[] overallLeaderboardDiscardThresholds, + ScoringSchemeType overallLeaderboardScoringSchemeType) { + CreateLeaderboardGroup createLeaderboardGroupOp = new CreateLeaderboardGroup(groupName, description, + displayGroupsInReverseOrder, new ArrayList(), overallLeaderboardDiscardThresholds, + overallLeaderboardScoringSchemeType); return convertToLeaderboardGroupDTO(getService().apply(createLeaderboardGroupOp), false); } @Override - public void updateLeaderboardGroup(String oldName, String newName, String description, List leaderboardNames, - int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType) { + public void updateLeaderboardGroup(String oldName, String newName, String description, + List leaderboardNames, int[] overallLeaderboardDiscardThresholds, + ScoringSchemeType overallLeaderboardScoringSchemeType) { getService().apply( new UpdateLeaderboardGroup(oldName, newName, description, leaderboardNames, overallLeaderboardDiscardThresholds, overallLeaderboardScoringSchemeType)); @@ -2741,29 +2890,32 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S ReplicationService service = getReplicationService(); Set replicaDTOs = new HashSet(); for (ReplicaDescriptor replicaDescriptor : service.getReplicaInfo()) { - final Map>, Integer> statistics = service.getStatistics(replicaDescriptor); + final Map>, Integer> statistics = service + .getStatistics(replicaDescriptor); Map replicationCountByOperationClassName = new HashMap(); for (Map.Entry>, Integer> e : statistics.entrySet()) { replicationCountByOperationClassName.put(e.getKey().getName(), e.getValue()); } - replicaDTOs.add(new ReplicaDTO(replicaDescriptor.getIpAddress().getHostName(), replicaDescriptor.getRegistrationTime().asDate(), - replicationCountByOperationClassName)); + replicaDTOs.add(new ReplicaDTO(replicaDescriptor.getIpAddress().getHostName(), replicaDescriptor + .getRegistrationTime().asDate(), replicationCountByOperationClassName)); } ReplicationMasterDTO master; ReplicationMasterDescriptor replicatingFromMaster = service.isReplicatingFromMaster(); if (replicatingFromMaster == null) { master = null; } else { - master = new ReplicationMasterDTO(replicatingFromMaster.getHostname(), replicatingFromMaster.getMessagingPort(), - replicatingFromMaster.getServletPort()); + master = new ReplicationMasterDTO(replicatingFromMaster.getHostname(), + replicatingFromMaster.getMessagingPort(), replicatingFromMaster.getServletPort()); } return new ReplicationStateDTO(master, replicaDTOs); } @Override - public void startReplicatingFromMaster(String masterName, String exchangeName, int servletPort, int messagingPort) throws IOException, ClassNotFoundException { + public void startReplicatingFromMaster(String masterName, String exchangeName, int servletPort, int messagingPort) + throws IOException, ClassNotFoundException { getReplicationService().startToReplicateFrom( - ReplicationFactory.INSTANCE.createReplicationMasterDescriptor(masterName, exchangeName, servletPort, messagingPort)); + ReplicationFactory.INSTANCE.createReplicationMasterDescriptor(masterName, exchangeName, servletPort, + messagingPort)); } @Override @@ -2777,13 +2929,15 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public void updateEvent(String eventName, Serializable id, VenueDTO venue, String publicationUrl, boolean isPublic, List regattaNames) { + public void updateEvent(String eventName, Serializable id, VenueDTO venue, String publicationUrl, boolean isPublic, + List regattaNames) { getService().apply(new UpdateEvent(id, eventName, venue.name, publicationUrl, isPublic, regattaNames)); } @Override public EventDTO createEvent(String eventName, String venue, String publicationUrl, boolean isPublic) { - return convertToEventDTO(getService().apply(new CreateEvent(eventName, venue, publicationUrl, isPublic, new ArrayList()))); + return convertToEventDTO(getService().apply( + new CreateEvent(eventName, venue, publicationUrl, isPublic, new ArrayList()))); } @Override @@ -2800,14 +2954,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S public EventDTO getEventByName(String eventName) { EventDTO result = null; for (Event event : getService().getAllEvents()) { - if(event.getName().equals(eventName)) { + if (event.getName().equals(eventName)) { result = convertToEventDTO(event); break; } } return result; } - + private EventDTO convertToEventDTO(Event event) { EventDTO eventDTO = new EventDTO(event.getName()); eventDTO.venue = new VenueDTO(); @@ -2816,7 +2970,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S eventDTO.isPublic = event.isPublic(); eventDTO.id = event.getId(); eventDTO.regattas = new ArrayList(); - for (Regatta regatta: event.getRegattas()) { + for (Regatta regatta : event.getRegattas()) { RegattaDTO regattaDTO = new RegattaDTO(); regattaDTO.name = regatta.getName(); eventDTO.regattas.add(regattaDTO); @@ -2830,19 +2984,21 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } private RaceColumnInSeriesDTO convertToRaceColumnInSeriesDTO(RaceColumnInSeries raceColumnInSeries) { - RaceColumnInSeriesDTO raceColumnInSeriesDTO = new RaceColumnInSeriesDTO(raceColumnInSeries.getSeries().getName(), - raceColumnInSeries.getRegatta().getName()); + RaceColumnInSeriesDTO raceColumnInSeriesDTO = new RaceColumnInSeriesDTO(raceColumnInSeries.getSeries() + .getName(), raceColumnInSeries.getRegatta().getName()); raceColumnInSeriesDTO.name = raceColumnInSeries.getName(); raceColumnInSeriesDTO.setMedalRace(raceColumnInSeries.isMedalRace()); return raceColumnInSeriesDTO; } - + @Override - public List addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName, List columnNames) { + public List addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName, + List columnNames) { List result = new ArrayList(); - for(String columnName: columnNames) { - RaceColumnInSeries raceColumnInSeries = getService().apply(new AddColumnToSeries(regattaIdentifier, seriesName, columnName)); - if(raceColumnInSeries != null) { + for (String columnName : columnNames) { + RaceColumnInSeries raceColumnInSeries = getService().apply( + new AddColumnToSeries(regattaIdentifier, seriesName, columnName)); + if (raceColumnInSeries != null) { result.add(convertToRaceColumnInSeriesDTO(raceColumnInSeries)); } } @@ -2850,18 +3006,21 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public RaceColumnInSeriesDTO addRaceColumnToSeries(RegattaIdentifier regattaIdentifier, String seriesName, String columnName) { + public RaceColumnInSeriesDTO addRaceColumnToSeries(RegattaIdentifier regattaIdentifier, String seriesName, + String columnName) { RaceColumnInSeriesDTO result = null; - RaceColumnInSeries raceColumnInSeries = getService().apply(new AddColumnToSeries(regattaIdentifier, seriesName, columnName)); - if(raceColumnInSeries != null) { + RaceColumnInSeries raceColumnInSeries = getService().apply( + new AddColumnToSeries(regattaIdentifier, seriesName, columnName)); + if (raceColumnInSeries != null) { result = convertToRaceColumnInSeriesDTO(raceColumnInSeries); } return result; } @Override - public void removeRaceColumnsFromSeries(RegattaIdentifier regattaIdentifier, String seriesName, List columnNames) { - for(String columnName: columnNames) { + public void removeRaceColumnsFromSeries(RegattaIdentifier regattaIdentifier, String seriesName, + List columnNames) { + for (String columnName : columnNames) { getService().apply(new RemoveColumnFromSeries(regattaIdentifier, seriesName, columnName)); } } @@ -2882,13 +3041,15 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public RegattaDTO createRegatta(String regattaName, String boatClassName, + public RegattaDTO createRegatta( + String regattaName, + String boatClassName, LinkedHashMap>, Boolean>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal, boolean persistent, ScoringSchemeType scoringSchemeType) { Regatta regatta = getService().apply( new AddSpecificRegatta(regattaName, boatClassName, UUID.randomUUID(), - seriesNamesWithFleetNamesAndFleetOrderingAndMedal, - persistent, baseDomainFactory.createScoringScheme(scoringSchemeType))); + seriesNamesWithFleetNamesAndFleetOrderingAndMedal, persistent, baseDomainFactory + .createScoringScheme(scoringSchemeType))); return convertToRegattaDTO(regatta); } @@ -2924,7 +3085,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S return new ScoreCorrectionEntryDTO(scoreCorrectionForCompetitor.getPoints(), scoreCorrectionForCompetitor.isDiscarded(), scoreCorrectionForCompetitor.getMaxPointsReason()); } - + private FregResultProvider getFregService() { FregResultProvider result = null; for (ScoreCorrectionProvider scp : getScoreCorrectionProviders()) { @@ -2968,7 +3129,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public List>> getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(String leaderboardName, Date date) throws NoWindException { + public List>> getRankedCompetitorsFromBestToWorstAfterEachRaceColumn( + String leaderboardName, Date date) throws NoWindException { Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName); final TimePoint timePoint; if (date == null) { @@ -2984,7 +3146,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } Map> preResult = leaderboard .getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(timePoint); - List>> result = new ArrayList>>(); + List>> result = new ArrayList>>(); for (RaceColumn raceColumn : leaderboard.getRaceColumns()) { List competitorList = getCompetitorDTOList(preResult.get(raceColumn)); result.add(new Pair>(raceColumn.getName(), competitorList)); @@ -2996,7 +3158,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S public List getOverallLeaderboardNamesContaining(String leaderboardName) { Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName); if (leaderboard == null) { - throw new IllegalArgumentException("Couldn't find leaderboard named "+leaderboardName); + throw new IllegalArgumentException("Couldn't find leaderboard named " + leaderboardName); } List result = new ArrayList(); for (Map.Entry leaderboardEntry : getService().getLeaderboards().entrySet()) { @@ -3012,17 +3174,27 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public List getPreviousSwissTimingArchiveConfigurations() { - Iterable configs = swissTimingAdapterPersistence.getSwissTimingArchiveConfigurations(); + Iterable configs = swissTimingAdapterPersistence + .getSwissTimingArchiveConfigurations(); List result = new ArrayList(); for (SwissTimingArchiveConfiguration stArchiveConfig : configs) { result.add(new SwissTimingArchiveConfigurationDTO(stArchiveConfig.getJsonUrl())); } return result; - } + } @Override public void storeSwissTimingArchiveConfiguration(String swissTimingJsonUrl) { - swissTimingAdapterPersistence.storeSwissTimingArchiveConfiguration(swissTimingFactory.createSwissTimingArchiveConfiguration( - swissTimingJsonUrl)); + swissTimingAdapterPersistence.storeSwissTimingArchiveConfiguration(swissTimingFactory + .createSwissTimingArchiveConfiguration(swissTimingJsonUrl)); + } + + @Override + public String generatePolarSheetForRaces(List selectedRaces) { + String id = UUID.randomUUID().toString(); + PolarSheetGenerationWorker genWorker = new PolarSheetGenerationWorker(selectedRaces); + polarSheetGenerationWorkers.put(id, genWorker); + genWorker.startPolarSheetGeneration(); + return id; } } \ No newline at end of file From 519d442deb294998d3968e4a5b358ccbc1b7cd33 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Fri, 25 Jan 2013 10:54:14 +0100 Subject: [PATCH 13/37] Added comment for waitForLatest parameter method: getManeuvers class: TrackedRace --- .../sailing/domain/tracking/TrackedRace.java | 236 +++++++++--------- 1 file changed, 120 insertions(+), 116 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java index 84fb96081d1..b0c8f8b10d6 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java @@ -5,10 +5,10 @@ import java.util.List; import java.util.NavigableSet; import java.util.SortedSet; -import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Course; import com.sap.sailing.domain.base.Leg; +import com.sap.sailing.domain.base.Mark; import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.base.impl.DouglasPeucker; @@ -40,41 +40,42 @@ import com.sap.sailing.domain.common.impl.Util.Pair; */ public interface TrackedRace extends Serializable { final long MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS = 30000; - + final long DEFAULT_LIVE_DELAY_IN_MILLISECONDS = 5000; RaceDefinition getRace(); - + RegattaAndRaceIdentifier getRaceIdentifier(); - + /** - * Computes the estimated start time for this race (not to be confused with the {@link #getStartOfTracking()} time point - * which is expected to be before the race start time). When there are no {@link MarkPassing}s for the first mark, null - * is returned. If there are mark passings for the first mark and the start time is less than - * {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS} before the first mark passing for the + * Computes the estimated start time for this race (not to be confused with the {@link #getStartOfTracking()} time + * point which is expected to be before the race start time). When there are no {@link MarkPassing}s for the first + * mark, null is returned. If there are mark passings for the first mark and the start time is less + * than {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS} before the first mark passing for the * first mark. Otherwise, the first mark passing for the first mark minus - * {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS} is returned as the race start time.

+ * {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS} is returned as the race start time. + *

* * If no start time can be determined this way, null is returned. */ TimePoint getStartOfRace(); - + /** - * Determine the race end time is tricky. Boats may sink, stop, not finish, although they started the race. We therefore - * cannot wait for all boats to reach the finish line. - * The following rules are used to calculate the endOfRace: + * Determine the race end time is tricky. Boats may sink, stop, not finish, although they started the race. We + * therefore cannot wait for all boats to reach the finish line. The following rules are used to calculate the + * endOfRace: *

    - *
  1. Returns null if no boat passed the finish line
  2. - *
  3. Returns time of the last mark passing recorded for the finish line
  4. - *
  5. TODO: Returns the time of the first passing of the finish line + the target window (defined in the competition rules) - * if a target window has been defined for the race
  6. - *
+ *
  • Returns null if no boat passed the finish line
  • + *
  • Returns time of the last mark passing recorded for the finish line
  • + *
  • TODO: Returns the time of the first passing of the finish line + the target window (defined in the + * competition rules) if a target window has been defined for the race
  • + * */ TimePoint getEndOfRace(); /** - * Returns a list of the first and last mark passing times of all course waypoints. Callers wanting to iterate over the - * result must synchronize on the result. + * Returns a list of the first and last mark passing times of all course waypoints. Callers wanting to iterate over + * the result must synchronize on the result. */ Iterable>> getMarkPassingsTimes(); @@ -82,89 +83,84 @@ public interface TrackedRace extends Serializable { * Shorthand for {@link #getStart()}.{@link TimePoint#compareTo(TimePoint) compareTo(at)} <= 0 */ boolean hasStarted(TimePoint at); - + /** * Clients can safely iterate over the iterable returned because it's a non-live copy of the tracked legs of this - * tracked race. This implies that should an update to the underlying list of waypoints in this race's {@link Course} - * take place after this method has returned, then this won't be reflected in the result returned. Callers should - * obtain the {@link Course#lockForRead() course's read lock} while using the result of this call if they want to - * ensure that no course update is applied concurrently. + * tracked race. This implies that should an update to the underlying list of waypoints in this race's + * {@link Course} take place after this method has returned, then this won't be reflected in the result returned. + * Callers should obtain the {@link Course#lockForRead() course's read lock} while using the result of this call if + * they want to ensure that no course update is applied concurrently. */ Iterable getTrackedLegs(); - + TrackedLeg getTrackedLeg(Leg leg); - + /** - * Tracking information about the leg competitor is on at timePoint, or - * null if the competitor hasn't started any leg yet at timePoint or has - * already finished the race. + * Tracking information about the leg competitor is on at timePoint, or null + * if the competitor hasn't started any leg yet at timePoint or has already finished the race. */ TrackedLegOfCompetitor getCurrentLeg(Competitor competitor, TimePoint timePoint); - + /** * Tells which leg the leader at timePoint is on */ TrackedLeg getCurrentLeg(TimePoint timePoint); - + /** * Precondition: waypoint must still be part of {@link #getRace()}.{@link RaceDefinition#getCourse() getCourse()}. */ TrackedLeg getTrackedLegFinishingAt(Waypoint endOfLeg); - + /** * Precondition: waypoint must still be part of {@link #getRace()}.{@link RaceDefinition#getCourse() getCourse()}. */ TrackedLeg getTrackedLegStartingAt(Waypoint startOfLeg); - + /** * The raw, updating feed of a single competitor participating in this race */ GPSFixTrack getTrack(Competitor competitor); - + /** - * Tells the leg on which the competitor was at time at. - * If the competitor hasn't passed the start waypoint yet, null is - * returned because the competitor was not yet on any leg at that point in time. If - * the time point happens to be after the last fix received from that competitor, - * the last known leg for that competitor is returned. If the time point is after the - * competitor's mark passing for the finish line, null is returned. - * For all legs except the last, if the time point equals a mark passing time point - * of the leg's starting waypoint, that leg is returned. For the time point of - * the mark passing for the finish line, the last leg is returned. + * Tells the leg on which the competitor was at time at. If the competitor hasn't passed + * the start waypoint yet, null is returned because the competitor was not yet on any leg at that point + * in time. If the time point happens to be after the last fix received from that competitor, the last known leg for + * that competitor is returned. If the time point is after the competitor's mark passing for the finish line, + * null is returned. For all legs except the last, if the time point equals a mark passing time point + * of the leg's starting waypoint, that leg is returned. For the time point of the mark passing for the finish line, + * the last leg is returned. */ TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, TimePoint at); - + TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, Leg leg); - + /** * @return a sequential number counting the updates that occurred to this tracked race. Callers may use this to ask * for updates newer than such a sequence number. */ long getUpdateCount(); - + int getRankDifference(Competitor competitor, Leg leg, TimePoint timePoint); - + /** - * Computes the rank of the competitor in this race for the current time. + * Computes the rank of the competitor in this race for the current time. */ int getRank(Competitor competitor) throws NoWindException; - + /** - * Computes the rank of competitor in this race. A competitor is ahead of all - * competitors that are one or more legs behind. Within the same leg, the rank is determined - * by the windward distance to go and therefore depends on the assumptions of the wind direction - * for the given timePoint. If the race hasn't {@link #hasStarted(TimePoint) started} - * yet, the result is undefined. + * Computes the rank of competitor in this race. A competitor is ahead of all competitors that are one + * or more legs behind. Within the same leg, the rank is determined by the windward distance to go and therefore + * depends on the assumptions of the wind direction for the given timePoint. If the race hasn't + * {@link #hasStarted(TimePoint) started} yet, the result is undefined. * - * @return 0 in case the competitor hasn't participated in the race; a rank starting - * with 1 where rank 1 identifies the leader otherwise + * @return 0 in case the competitor hasn't participated in the race; a rank starting with + * 1 where rank 1 identifies the leader otherwise */ int getRank(Competitor competitor, TimePoint timePoint) throws NoWindException; - + /** - * For a competitor, computes the distance (TODO not yet clear whether over ground or - * projected onto wind direction) into the race secondsIntoTheRace after - * the race {@link TrackedRace#getStart() started}. + * For a competitor, computes the distance (TODO not yet clear whether over ground or projected onto wind direction) + * into the race secondsIntoTheRace after the race {@link TrackedRace#getStart() started}. */ Distance getStartAdvantage(Competitor competitor, double secondsIntoTheRace); @@ -182,14 +178,14 @@ public interface TrackedRace extends Serializable { Iterable getMarkPassingsInOrder(Waypoint waypoint); /** - * Obtains the {@link MarkPassing} for competitor passing waypoint. If no such - * mark passing has been reported (yet), null is returned. + * Obtains the {@link MarkPassing} for competitor passing waypoint. If no such mark + * passing has been reported (yet), null is returned. */ MarkPassing getMarkPassing(Competitor competitor, Waypoint waypoint); /** - * Yields the track describing mark's movement over time; never null because a - * new track will be created in case no track was present for mark so far. + * Yields the track describing mark's movement over time; never null because a new track + * will be created in case no track was present for mark so far. */ GPSFixTrack getOrCreateTrack(Mark mark); @@ -203,7 +199,7 @@ public interface TrackedRace extends Serializable { * is returned. Otherwise, the center of gravity between the mark positions is computed and returned. */ Position getApproximatePosition(Waypoint waypoint, TimePoint timePoint); - + /** * Same as {@link #getWind(Position, TimePoint, Iterable) getWind(p, at, Collections.emptyList())} */ @@ -211,8 +207,8 @@ public interface TrackedRace extends Serializable { /** * Obtains estimated interpolated wind information for a given position and time point. The information is taken - * from all wind sources available except for those listed in windSourcesToExclude, using the confidences - * of the wind values provided by the various sources during averaging. + * from all wind sources available except for those listed in windSourcesToExclude, using the + * confidences of the wind values provided by the various sources during averaging. */ Wind getWind(Position p, TimePoint at, Iterable windSourcesToExclude); @@ -230,10 +226,11 @@ public interface TrackedRace extends Serializable { Iterable getWindSources(); /** - * Same as {@link #getOrCreateWindTrack(WindSource, long) getOrCreateWindTrack(windSource, getMillisecondsOverWhichToAverageWind())}. + * Same as {@link #getOrCreateWindTrack(WindSource, long) getOrCreateWindTrack(windSource, + * getMillisecondsOverWhichToAverageWind())}. */ WindTrack getOrCreateWindTrack(WindSource windSource); - + WindTrack getOrCreateWindTrack(WindSource windSource, long delayForWindEstimationCacheInvalidation); /** @@ -242,26 +239,26 @@ public interface TrackedRace extends Serializable { void waitForNextUpdate(int sinceUpdate) throws InterruptedException; /** - * Time stamp of the start of the actual tracking. - * The value can be null (e.g. if we have not received any signal from the tracking infrastructure) + * Time stamp of the start of the actual tracking. The value can be null (e.g. if we have not received any signal + * from the tracking infrastructure) */ TimePoint getStartOfTracking(); /** - * Time stamp of the end of the actual tracking. - * The value can be null (e.g. if we have not received any signal from the tracking infrastructure) + * Time stamp of the end of the actual tracking. The value can be null (e.g. if we have not received any signal from + * the tracking infrastructure) */ TimePoint getEndOfTracking(); /** - * Regardless of the order in which events were received, this method returns the latest time point contained by any of - * the events received and processed. + * Regardless of the order in which events were received, this method returns the latest time point contained by any + * of the events received and processed. */ TimePoint getTimePointOfNewestEvent(); /** - * Regardless of the order in which events were received, this method returns the oldest time point contained by any of - * the events received and processed. + * Regardless of the order in which events were received, this method returns the oldest time point contained by any + * of the events received and processed. */ TimePoint getTimePointOfOldestEvent(); @@ -273,17 +270,18 @@ public interface TrackedRace extends Serializable { * some tracking providers such as TracTrac. If the caller wants to iterate on the resulting collection or * construct a {@link SortedSet#headSet(Object)} or {@link SortedSet#tailSet(Object)} and then iterate over * that, the caller needs to invoke {@link #lockForRead(Iterable)} with the collection returned as parameter - * because insertions into the competitor's mark passing collection will obtain the corresponding write lock. + * because insertions into the competitor's mark passing collection will obtain the corresponding write + * lock. */ NavigableSet getMarkPassings(Competitor competitor); - + void lockForRead(Iterable markPassings); - + void unlockAfterRead(Iterable markPassings); /** - * Time stamp that the event received last from the underlying push service carried on it. - * Note that these times may not increase monotonically. + * Time stamp that the event received last from the underlying push service carried on it. Note that these times may + * not increase monotonically. */ TimePoint getTimePointOfLastEvent(); @@ -295,7 +293,7 @@ public interface TrackedRace extends Serializable { * Gets the current delay of incoming events to the real time of the events in milliseconds */ long getDelayToLiveInMillis(); - + /** * Estimates the wind direction based on the observed boat courses at the time given for the position provided. The * estimate is based on the assumption that the boats which are on an upwind or a downwind leg sail with very @@ -320,13 +318,12 @@ public interface TrackedRace extends Serializable { * we may be able to also infer the wind speed from the boat tracks. */ Wind getEstimatedWindDirection(Position position, TimePoint timePoint); - + /** - * Determines whether the competitor is sailing on port or starboard tack at the - * timePoint requested. Note that this will have to retrieve information about the wind. - * This, in turn, can lead to the current thread obtaining the monitor of the various wind tracks, - * and, if the {@link WindSource#TRACK_BASED_ESTIMATION} source is used, also the monitors of the - * competitors' GPS tracks. + * Determines whether the competitor is sailing on port or starboard tack at the timePoint + * requested. Note that this will have to retrieve information about the wind. This, in turn, can lead to the + * current thread obtaining the monitor of the various wind tracks, and, if the + * {@link WindSource#TRACK_BASED_ESTIMATION} source is used, also the monitors of the competitors' GPS tracks. */ Tack getTack(Competitor competitor, TimePoint timePoint) throws NoWindException; @@ -344,30 +341,34 @@ public interface TrackedRace extends Serializable { * mark positions are not known (yet) */ Wind getDirectionFromStartToNextMark(TimePoint at); - + /** - * Uses a {@link DouglasPeucker Douglas-Peucker} algorithm to approximate this track's fixes starting at - * time from until time point to such that the maximum distance between the - * track's fixes and the approximation is at most maxDistance. + * Uses a {@link DouglasPeucker Douglas-Peucker} algorithm to approximate this track's fixes starting at time + * from until time point to such that the maximum distance between the track's fixes and + * the approximation is at most maxDistance. */ List approximate(Competitor competitor, Distance maxDistance, TimePoint from, TimePoint to); /** * @return a non-null but perhaps empty list of the maneuvers that competitor performed in - * this race between from and to. + * this race between from and to. Depending on waitForLatest the + * result is taken from the cache straight away (waitForLatest==false) or, if a re-calculation + * for the key is still ongoing, the result of that ongoing re-calculation is returned. */ - List getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest) throws NoWindException; + List getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest) + throws NoWindException; /** - * @return true if this race is known to start with an {@link LegType#UPWIND upwind} leg. - * If this is the case, the wind estimation may default to using the first leg's direction at race start - * time as the direction the wind comes from. + * @return true if this race is known to start with an {@link LegType#UPWIND upwind} leg. If this is + * the case, the wind estimation may default to using the first leg's direction at race start time as the + * direction the wind comes from. */ boolean raceIsKnownToStartUpwind(); /** - * Many calculations require valid wind data. In order to prevent NoWindException's to be handled by those calculation - * this method can be used to check whether the tracked race has sufficient wind information available. + * Many calculations require valid wind data. In order to prevent NoWindException's to be handled by those + * calculation this method can be used to check whether the tracked race has sufficient wind information available. + * * @return true if {@link #getWind(Position, TimePoint)} delivers a (not null) wind fix. */ boolean hasWindData(); @@ -379,23 +380,23 @@ public interface TrackedRace extends Serializable { boolean hasGPSData(); /** - * Adds a race change listener to the set of listeners that will be notified about changes to this race. - * The listener won't be serialized together with this object. + * Adds a race change listener to the set of listeners that will be notified about changes to this race. The + * listener won't be serialized together with this object. */ void addListener(RaceChangeListener listener); - + void removeListener(RaceChangeListener listener); Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint); Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint) throws NoWindException; - + /** * Calls {@link #getWindWithConfidence(Position, TimePoint, Iterable)} and excludes those wind sources listed in * {@link #getWindSourcesToExclude}. */ WindWithConfidence> getWindWithConfidence(Position p, TimePoint at); - + /** * Lists those wind sources which by default are not considered in {@link #getWind(Position, TimePoint)} and * {@link #getWindWithConfidence(Position, TimePoint)}. @@ -405,8 +406,8 @@ public interface TrackedRace extends Serializable { /** * Loops over this tracked race's wind sources and from each asks its averaged wind for the position p * and time point at, using the particular wind source's averaging interval. The confidences delivered - * by each wind source are used during computing the averaged result across the wind sources. The result has the averaged - * confidence attached. + * by each wind source are used during computing the averaged result across the wind sources. The result has the + * averaged confidence attached. */ WindWithConfidence> getWindWithConfidence(Position p, TimePoint at, Iterable windSourcesToExclude); @@ -418,7 +419,8 @@ public interface TrackedRace extends Serializable { WindWithConfidence getEstimatedWindDirectionWithConfidence(Position position, TimePoint timePoint); /** - * After the call returns, {@link #getWindSourcesToExclude()} returns an iterable that equals windSourcesToExclude + * After the call returns, {@link #getWindSourcesToExclude()} returns an iterable that equals + * windSourcesToExclude */ void setWindSourcesToExclude(Iterable windSourcesToExclude); @@ -429,25 +431,27 @@ public interface TrackedRace extends Serializable { * if true and any cache update is currently going on, wait for the update to complete and * then fetch the updated value; otherwise, serve this requests from whatever is currently in the cache */ - Distance getAverageCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException; + Distance getAverageCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) + throws NoWindException; WindStore getWindStore(); Competitor getOverallLeader(TimePoint timePoint) throws NoWindException; /** - * Returns the competitors of this tracked race, according to their ranking. Competitors whose {@link #getRank(Competitor)} is 0 will - * be sorted "worst". + * Returns the competitors of this tracked race, according to their ranking. Competitors whose + * {@link #getRank(Competitor)} is 0 will be sorted "worst". */ List getCompetitorsFromBestToWorst(TimePoint timePoint) throws NoWindException; - Distance getAverageCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalyses) throws NoWindException; + Distance getAverageCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, + boolean waitForLatestAnalyses) throws NoWindException; /** * When provided with a {@link WindStore} during construction, the tracked race will asynchronously load the wind - * data for this tracked race from the wind store in a background thread and update this tracked race with the results. - * Clients that want to wait for the wind loading process to complete can do so by calling this method which will block - * until the wind loading has completed. + * data for this tracked race from the wind store in a background thread and update this tracked race with the + * results. Clients that want to wait for the wind loading process to complete can do so by calling this method + * which will block until the wind loading has completed. */ void waitUntilWindLoadingComplete() throws InterruptedException; } From 4a9b3aa0bf158ceb91d3de4c564129deac28ae0a Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Fri, 25 Jan 2013 11:23:34 +0100 Subject: [PATCH 14/37] Added serverside polar sheet generation workers. data needs to be queried from the polarsheetgenerationworker --- .../domain/polarsheets/PerRaceWorker.java | 80 +++++++++++++++++++ .../PolarSheetGenerationWorker.java | 65 +++++++++++++-- .../gwt/ui/server/SailingServiceImpl.java | 7 +- 3 files changed, 146 insertions(+), 6 deletions(-) create mode 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java new file mode 100644 index 00000000000..13748eefdba --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java @@ -0,0 +1,80 @@ +package com.sap.sailing.domain.polarsheets; + +import java.util.Iterator; + +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.RaceDefinition; +import com.sap.sailing.domain.base.SpeedWithBearing; +import com.sap.sailing.domain.common.Bearing; +import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.TimePoint; +import com.sap.sailing.domain.tracking.GPSFixMoving; +import com.sap.sailing.domain.tracking.GPSFixTrack; +import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sailing.domain.tracking.Wind; + +public class PerRaceWorker implements Runnable { + + private final TrackedRace race; + + private final PolarSheetGenerationWorker polarSheetGenerationWorker; + + public PerRaceWorker(PolarSheetGenerationWorker polarSheetGenerationWorker, TrackedRace race) { + this.race = race; + this.polarSheetGenerationWorker = polarSheetGenerationWorker; + } + + @Override + public void run() { + TimePoint startTime = race.getStartOfRace(); + TimePoint endTime = race.getEndOfRace(); + RaceDefinition raceDefinition = race.getRace(); + Iterable competitors = raceDefinition.getCompetitors(); + + for (Competitor competitor : competitors) { + getPolarDataForCompetitor(startTime, endTime, competitor); + } + + polarSheetGenerationWorker.workerDone(this); + + } + + private void getPolarDataForCompetitor(final TimePoint startTime, final TimePoint endTime, + final Competitor competitor) { + Runnable perCompetitorWorker = new Runnable() { + + @Override + public void run() { + GPSFixTrack track = race.getTrack(competitor); + Iterator fixesIterator = track.getFixesIterator(startTime, true); + // TODO maneuver exclusion + // List maneuvers = race.getManeuvers(competitor, startTime, endTime, false); + + while (fixesIterator.hasNext()) { + GPSFixMoving fix = fixesIterator.next(); + if (fix.getTimePoint().after(endTime)) { + break; + } + + SpeedWithBearing speedWithBearing = fix.getSpeed(); + double speed = speedWithBearing.getMetersPerSecond(); + Bearing bearing = speedWithBearing.getBearing(); + Position position = fix.getPosition(); + Wind wind = race.getWind(position, fix.getTimePoint()); + Bearing windBearing = wind.getBearing(); + double windSpeed = wind.getMetersPerSecond(); + + // TODO Figure out if this normalizing is okay concerning different windspeeds and bearings + double normalizedSpeed = speed / windSpeed; + double angleToWind = bearing.getDifferenceTo(windBearing).getDegrees(); + + polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed); + } + } + }; + + Thread perCompetitorThread = new Thread(perCompetitorWorker); + perCompetitorThread.start(); + + } +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java index 671711d1ec6..23b550634ab 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java @@ -1,20 +1,75 @@ package com.sap.sailing.domain.polarsheets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.domain.tracking.TrackedRace; public class PolarSheetGenerationWorker { - private final List selectedRaces; + private boolean finished = false; - public PolarSheetGenerationWorker(List selectedRaces) { - this.selectedRaces = selectedRaces; + private final Set workers; + + private final Map> polarData; + + public PolarSheetGenerationWorker(Set trackedRaces) { + polarData = initializePolarDataContainer(); + workers = new HashSet(); + for (TrackedRace race : trackedRaces) { + workers.add(new PerRaceWorker(this, race)); + } + } + + private Map> initializePolarDataContainer() { + HashMap> container = new HashMap>(); + for (int i = 0; i < 360; i++) { + container.put(i, new ArrayList()); + } + return container; } public void startPolarSheetGeneration() { - // TODO Auto-generated method stub + for (PerRaceWorker worker : workers) { + Thread workerThread = new Thread(worker); + workerThread.start(); + } + } + public void addPolarData(long round, double normalizedSpeed) { + polarData.get(round).add(normalizedSpeed); + } + + public Map getPolarData() { + Map averagedPolarData = new HashMap(); + for (Entry> entry : polarData.entrySet()) { + double sum = 0; + for (Double singleData : entry.getValue()) { + sum = sum + singleData; + } + double average = sum / entry.getValue().size(); + averagedPolarData.put(entry.getKey(), average); + } + + return averagedPolarData; + } + + public void workerDone(PerRaceWorker worker) { + if (workers.contains(worker)) { + workers.remove(worker); + if (workers.isEmpty()) { + finished = true; + } + } + } + + public boolean isFinished() { + return finished; } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 67f9b817ed2..8aa05c495f3 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -3192,7 +3192,12 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S @Override public String generatePolarSheetForRaces(List selectedRaces) { String id = UUID.randomUUID().toString(); - PolarSheetGenerationWorker genWorker = new PolarSheetGenerationWorker(selectedRaces); + RacingEventService service = getService(); + Set trackedRaces = new HashSet(); + for (RegattaAndRaceIdentifier race : selectedRaces) { + trackedRaces.add(service.getTrackedRace(race)); + } + PolarSheetGenerationWorker genWorker = new PolarSheetGenerationWorker(trackedRaces); polarSheetGenerationWorkers.put(id, genWorker); genWorker.startPolarSheetGeneration(); return id; From b4cd90a6d0df808070ed0170ac522e2633f98ae2 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Mon, 28 Jan 2013 16:01:50 +0100 Subject: [PATCH 15/37] Downgraded Highcharts lib from 2.3.5 to 2.3.3 --- .../js/adapters/mootools-adapter.js | 10 +- .../js/adapters/mootools-adapter.src.js | 29 +- .../js/adapters/prototype-adapter.js | 2 +- .../js/adapters/prototype-adapter.src.js | 2 +- .../highcharts/js/highcharts-more.js | 58 +- .../highcharts/js/highcharts.js | 484 ++++--- .../highcharts/js/highcharts.src.js | 1202 +++++++---------- .../highcharts/js/modules/canvas-tools.js | 2 +- .../highcharts/js/modules/canvas-tools.src.js | 2 +- .../highcharts/js/modules/data.js | 11 +- .../highcharts/js/modules/data.src.js | 261 +--- .../highcharts/js/modules/exporting.js | 32 +- .../highcharts/js/modules/exporting.src.js | 134 +- 13 files changed, 900 insertions(+), 1329 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/mootools-adapter.js b/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/mootools-adapter.js index cddecb8d1de..cc8ca2af965 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/mootools-adapter.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/mootools-adapter.js @@ -1,5 +1,5 @@ /* - Highcharts JS v2.3.5 (2012-12-19) + Highcharts JS v2.3.3 (2012-10-04) MooTools adapter (c) 2010-2011 Torstein Hønsi @@ -7,7 +7,7 @@ License: www.highcharts.com/license */ (function(){var e=window,i=document,f=e.MooTools.version.substring(0,3),g=f==="1.2"||f==="1.1",j=g||f==="1.3",h=e.$extend||function(){return Object.append.apply(Object,arguments)};e.HighchartsAdapter={init:function(a){var b=Fx.prototype,c=b.start,d=Fx.Morph.prototype,e=d.compute;b.start=function(b,d){var e=this.element;if(b.d)this.paths=a.init(e,e.d,this.toD);c.apply(this,arguments);return this};d.compute=function(b,c,d){var f=this.paths;if(f)this.element.attr("d",a.step(f[0],f[1],d,this.toD));else return e.apply(this, -arguments)}},adapterRun:function(a,b){if(b==="width"||b==="height")return parseInt($(a).getStyle(b),10)},getScript:function(a,b){var c=i.getElementsByTagName("head")[0],d=i.createElement("script");d.type="text/javascript";d.src=a;d.onload=b;c.appendChild(d)},animate:function(a,b,c){var d=a.attr,f=c&&c.complete;if(d&&!a.setStyle)a.getStyle=a.attr,a.setStyle=function(){var a=arguments;this.attr.call(this,a[0],a[1][0])},a.$family=function(){return!0};e.HighchartsAdapter.stop(a);c=new Fx.Morph(d?a:$(a), -h({transition:Fx.Transitions.Quad.easeInOut},c));if(d)c.element=a;if(b.d)c.toD=b.d;f&&c.addEvent("complete",f);c.start(b);a.fx=c},each:function(a,b){return g?$each(a,b):Array.each(a,b)},map:function(a,b){return a.map(b)},grep:function(a,b){return a.filter(b)},inArray:function(a,b,c){return b.indexOf(a,c)},merge:function(){var a=arguments,b=[{}],c=a.length;if(g)a=$merge.apply(null,a);else{for(;c--;)typeof a[c]!=="boolean"&&(b[c+1]=a[c]);a=Object.merge.apply(Object,b)}return a},offset:function(a){a= -$(a).getOffsets();return{left:a.x,top:a.y}},extendWithEvents:function(a){a.addEvent||(a.nodeName?$(a):h(a,new Events))},addEvent:function(a,b,c){typeof b==="string"&&(b==="unload"&&(b="beforeunload"),e.HighchartsAdapter.extendWithEvents(a),a.addEvent(b,c))},removeEvent:function(a,b,c){typeof a!=="string"&&a.addEvent&&(b?(b==="unload"&&(b="beforeunload"),c?a.removeEvent(b,c):a.removeEvents&&a.removeEvents(b)):a.removeEvents())},fireEvent:function(a,b,c,d){b={type:b,target:a};b=j?new Event(b):new DOMEvent(b); -b=h(b,c);b.preventDefault=function(){d=null};a.fireEvent&&a.fireEvent(b.type,b);d&&d(b)},washMouseEvent:function(a){return a.event||a},stop:function(a){a.fx&&a.fx.cancel()}}})(); +arguments)}},adapterRun:function(a,b){if(b==="width"||b==="height")return parseInt($(a).getStyle(b),10)},getScript:function(a,b){var c=i.getElementsByTagName("head")[0],d=i.createElement("script");d.type="text/javascript";d.src=a;d.onload=b;c.appendChild(d)},animate:function(a,b,c){var d=a.attr,f=c&&c.complete;if(d&&!a.setStyle)a.getStyle=a.attr,a.setStyle=function(){var b=arguments;a.attr.call(a,b[0],b[1][0])},a.$family=function(){return!0};e.HighchartsAdapter.stop(a);c=new Fx.Morph(d?a:$(a),h({transition:Fx.Transitions.Quad.easeInOut}, +c));if(d)c.element=a;if(b.d)c.toD=b.d;f&&c.addEvent("complete",f);c.start(b);a.fx=c},each:function(a,b){return g?$each(a,b):Array.each(a,b)},map:function(a,b){return a.map(b)},grep:function(a,b){return a.filter(b)},inArray:function(a,b,c){return b.indexOf(a,c)},merge:function(){var a=arguments,b=[{}],c=a.length;if(g)a=$merge.apply(null,a);else{for(;c--;)typeof a[c]!=="boolean"&&(b[c+1]=a[c]);a=Object.merge.apply(Object,b)}return a},offset:function(a){a=$(a).getOffsets();return{left:a.x,top:a.y}}, +extendWithEvents:function(a){a.addEvent||(a.nodeName?$(a):h(a,new Events))},addEvent:function(a,b,c){typeof b==="string"&&(b==="unload"&&(b="beforeunload"),e.HighchartsAdapter.extendWithEvents(a),a.addEvent(b,c))},removeEvent:function(a,b,c){typeof a!=="string"&&(e.HighchartsAdapter.extendWithEvents(a),b?(b==="unload"&&(b="beforeunload"),c?a.removeEvent(b,c):a.removeEvents&&a.removeEvents(b)):a.removeEvents())},fireEvent:function(a,b,c,d){b={type:b,target:a};b=j?new Event(b):new DOMEvent(b);b=h(b, +c);b.preventDefault=function(){d=null};a.fireEvent&&a.fireEvent(b.type,b);d&&d(b)},washMouseEvent:function(a){return a.event||a},stop:function(a){a.fx&&a.fx.cancel()}}})(); diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/mootools-adapter.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/mootools-adapter.src.js index fcae32f5c76..a5215c8e065 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/mootools-adapter.src.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/mootools-adapter.src.js @@ -1,5 +1,5 @@ /** - * @license Highcharts JS v2.3.5 (2012-12-19) + * @license Highcharts JS v2.3.3 (2012-10-04) * MooTools adapter * * (c) 2010-2011 Torstein Hønsi @@ -116,7 +116,7 @@ win.HighchartsAdapter = { el.getStyle = el.attr; el.setStyle = function () { // property value is given as array in Moo - break it down var args = arguments; - this.attr.call(this, args[0], args[1][0]); + el.attr.call(el, args[0], args[1][0]); }; // dirty hack to trick Moo into handling el as an element wrapper el.$family = function () { return true; }; @@ -266,20 +266,19 @@ win.HighchartsAdapter = { return; } - if (el.addEvent) { // If el doesn't have an addEvent method, there are no events to remove - if (type) { - if (type === 'unload') { // Moo self destructs before custom unload events - type = 'beforeunload'; - } - - if (fn) { - el.removeEvent(type, fn); - } else if (el.removeEvents) { // #958 - el.removeEvents(type); - } - } else { - el.removeEvents(); + win.HighchartsAdapter.extendWithEvents(el); + if (type) { + if (type === 'unload') { // Moo self destructs before custom unload events + type = 'beforeunload'; } + + if (fn) { + el.removeEvent(type, fn); + } else if (el.removeEvents) { // #958 + el.removeEvents(type); + } + } else { + el.removeEvents(); } }, diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/prototype-adapter.js b/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/prototype-adapter.js index 6441d2a9526..ab53e919f8a 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/prototype-adapter.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/prototype-adapter.js @@ -1,5 +1,5 @@ /* - Highcharts JS v2.3.5 (2012-12-19) + Highcharts JS v2.3.3 (2012-10-04) Prototype adapter @author Michael Nelson, Torstein Hønsi. diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/prototype-adapter.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/prototype-adapter.src.js index 1f698c5c8ac..50a8b36dfde 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/prototype-adapter.src.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/adapters/prototype-adapter.src.js @@ -1,5 +1,5 @@ /** - * @license Highcharts JS v2.3.5 (2012-12-19) + * @license Highcharts JS v2.3.3 (2012-10-04) * Prototype adapter * * @author Michael Nelson, Torstein Hønsi. diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-more.js b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-more.js index cc23e4c0eb0..4bdc2e9a377 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-more.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts-more.js @@ -1,35 +1,35 @@ /* - Highcharts JS v2.3.5 (2012-12-19) + Highcharts JS v2.3.3 (2012-10-04) (c) 2009-2011 Torstein Hønsi License: www.highcharts.com/license */ -(function(i,v){function A(a,b,c){this.init.call(this,a,b,c)}function B(a,b,c){a.call(this,b,c);if(this.chart.polar)this.closeSegment=function(a){var b=this.xAxis.center;a.push("L",b[0],b[1])},this.closedStacks=!0}function C(a,b){var c=this.chart,d=this.options.animation,g=this.group,f=this.markerGroup,e=this.xAxis.center,h=c.plotLeft,m=c.plotTop;if(c.polar){if(c.renderer.isSVG)if(d===!0&&(d={}),b){if(g.attrSetters.scaleX=g.attrSetters.scaleY=function(a,b){this[b]=a;this.scaleX!==v&&this.scaleY!== -v&&this.element.setAttribute("transform","translate("+this.translateX+","+this.translateY+") scale("+this.scaleX+","+this.scaleY+")");return!1},c={translateX:e[0]+h,translateY:e[1]+m,scaleX:0,scaleY:0},g.attr(c),f)f.attrSetters=g.attrSetters,f.attr(c)}else c={translateX:h,translateY:m,scaleX:1,scaleY:1},g.animate(c,d),f&&f.animate(c,d),this.animate=null}else a.call(this,b)}var q=i.each,w=i.extend,p=i.merge,G=i.map,o=i.pick,x=i.pInt,n=i.getOptions().plotOptions,j=i.seriesTypes,D=i.extendClass,E=i.splat, -l=i.wrap,s=i.Axis,H=i.Tick,z=i.Series,r=j.column.prototype,t=function(){};w(A.prototype,{init:function(a,b,c){var d=this,g=d.defaultOptions;d.chart=b;if(b.angular)g.background={};d.options=a=p(g,a);(a=a.background)&&q([].concat(E(a)).reverse(),function(a){var b=a.backgroundColor,a=p(d.defaultBackgroundOptions,a);if(b)a.backgroundColor=b;a.color=a.backgroundColor;c.options.plotBands.unshift(a)})},defaultOptions:{center:["50%","50%"],size:"85%",startAngle:0},defaultBackgroundOptions:{shape:"circle", -borderWidth:1,borderColor:"silver",backgroundColor:{linearGradient:{x1:0,y1:0,x2:0,y2:1},stops:[[0,"#FFF"],[1,"#DDD"]]},from:Number.MIN_VALUE,innerRadius:0,to:Number.MAX_VALUE,outerRadius:"105%"}});var y=s.prototype,s=H.prototype,I={getOffset:t,redraw:function(){this.isDirty=!1},render:function(){this.isDirty=!1},setScale:t,setCategories:t,setTitle:t},F={isRadial:!0,defaultRadialGaugeOptions:{labels:{align:"center",x:0,y:null},minorGridLineWidth:0,minorTickInterval:"auto",minorTickLength:10,minorTickPosition:"inside", -minorTickWidth:1,plotBands:[],tickLength:10,tickPosition:"inside",tickWidth:2,title:{rotation:0},zIndex:2},defaultRadialXOptions:{gridLineWidth:1,labels:{align:null,distance:15,x:0,y:null},maxPadding:0,minPadding:0,plotBands:[],showLastLabel:!1,tickLength:0},defaultRadialYOptions:{gridLineInterpolation:"circle",labels:{align:"right",x:-3,y:-2},plotBands:[],showLastLabel:!1,title:{x:4,text:null,rotation:90}},setOptions:function(a){this.options=p(this.defaultOptions,this.defaultRadialOptions,a)},getOffset:function(){y.getOffset.call(this); -this.chart.axisOffset[this.side]=0;this.center=this.pane.center=j.pie.prototype.getCenter.call(this.pane)},getLinePath:function(a,b){var c=this.center,b=o(b,c[2]/2-this.offset);return this.chart.renderer.symbols.arc(this.left+c[0],this.top+c[1],b,b,{start:this.startAngleRad,end:this.endAngleRad,open:!0,innerR:0})},setAxisTranslation:function(){y.setAxisTranslation.call(this);if(this.center&&(this.transA=this.isCircular?(this.endAngleRad-this.startAngleRad)/(this.max-this.min||1):this.center[2]/2/ -(this.max-this.min||1),this.isXAxis))this.minPixelPadding=this.transA*this.minPointOffset+(this.reversed?(this.endAngleRad-this.startAngleRad)/4:0)},beforeSetTickPositions:function(){this.autoConnect&&(this.max+=this.categories&&1||this.pointRange||this.closestPointRange)},setAxisSize:function(){y.setAxisSize.call(this);if(this.center)this.len=this.width=this.height=this.isCircular?this.center[2]*(this.endAngleRad-this.startAngleRad)/2:this.center[2]/2},getPosition:function(a,b){if(!this.isCircular)b= -this.translate(a),a=this.min;return this.postTranslate(this.translate(a),o(b,this.center[2]/2)-this.offset)},postTranslate:function(a,b){var c=this.chart,d=this.center,a=this.startAngleRad+a;return{x:c.plotLeft+d[0]+Math.cos(a)*b,y:c.plotTop+d[1]+Math.sin(a)*b}},getPlotBandPath:function(a,b,c){var d=this.center,g=this.startAngleRad,f=d[2]/2,e=[o(c.outerRadius,"100%"),c.innerRadius,o(c.thickness,10)],h=/%$/,m,k=this.isCircular;this.options.gridLineInterpolation==="polygon"?d=this.getPlotLinePath(a).concat(this.getPlotLinePath(b, -!0)):(k||(e[0]=this.translate(a),e[1]=this.translate(b)),e=G(e,function(a){h.test(a)&&(a=x(a,10)*f/100);return a}),c.shape==="circle"||!k?(a=-Math.PI/2,b=Math.PI*1.5,m=!0):(a=g+this.translate(a),b=g+this.translate(b)),d=this.chart.renderer.symbols.arc(this.left+d[0],this.top+d[1],e[0],e[0],{start:a,end:b,innerR:o(e[1],e[0]-e[2]),open:m}));return d},getPlotLinePath:function(a,b){var c=this.center,d=this.chart,g=this.getPosition(a),f,e,h;this.isCircular?h=["M",c[0]+d.plotLeft,c[1]+d.plotTop,"L",g.x, -g.y]:this.options.gridLineInterpolation==="circle"?(a=this.translate(a))&&(h=this.getLinePath(0,a)):(f=d.xAxis[0],h=[],a=this.translate(a),c=f.tickPositions,f.autoConnect&&(c=c.concat([c[0]])),b&&(c=[].concat(c).reverse()),q(c,function(b,c){e=f.getPosition(b,a);h.push(c?"L":"M",e.x,e.y)}));return h},getTitlePosition:function(){var a=this.center,b=this.chart,c=this.options.title;return{x:b.plotLeft+a[0]+(c.x||0),y:b.plotTop+a[1]-{high:0.5,middle:0.25,low:0}[c.align]*a[2]+(c.y||0)}}};l(y,"init",function(a, -b,c){var d=b.angular,g=b.polar,f=c.isX,e=d&&f,h,m;m=b.options;var k=c.pane||0;if(d){if(w(this,e?I:F),h=!f)this.defaultRadialOptions=this.defaultRadialGaugeOptions}else if(g)w(this,F),this.defaultRadialOptions=(h=f)?this.defaultRadialXOptions:p(this.defaultYAxisOptions,this.defaultRadialYOptions);a.call(this,b,c);if(!e&&(d||g)){a=this.options;if(!b.panes)b.panes=[];this.pane=b.panes[k]=k=new A(E(m.pane)[k],b,this);k=k.options;b.inverted=!1;m.chart.zoomType=null;this.startAngleRad=b=(k.startAngle-90)* -Math.PI/180;this.endAngleRad=m=(o(k.endAngle,k.startAngle+360)-90)*Math.PI/180;this.offset=a.offset||0;if((this.isCircular=h)&&c.max===v&&m-b===2*Math.PI)this.autoConnect=!0}});l(s,"getPosition",function(a,b,c,d,g){var f=this.axis;return f.getPosition?f.getPosition(c):a.call(this,b,c,d,g)});l(s,"getLabelPosition",function(a,b,c,d,g,f,e,h,m){var k=this.axis,i=f.y,j=f.align,l=(k.translate(this.pos)+k.startAngleRad+Math.PI/2)/Math.PI*180;k.isRadial?(a=k.getPosition(this.pos,k.center[2]/2+o(f.distance, --25)),f.rotation==="auto"?d.attr({rotation:l}):i===null&&(i=x(d.styles.lineHeight)*0.9-d.getBBox().height/2),j===null&&(j=k.isCircular?l>20&&l<160?"left":l>200&&l<340?"right":"center":"center",d.attr({align:j})),a.x+=f.x,a.y+=i):a=a.call(this,b,c,d,g,f,e,h,m);return a});l(s,"getMarkPath",function(a,b,c,d,g,f,e){var h=this.axis;h.isRadial?(a=h.getPosition(this.pos,h.center[2]/2+d),b=["M",b,c,"L",a.x,a.y]):b=a.call(this,b,c,d,g,f,e);return b});n.arearange=p(n.area,{lineWidth:1,marker:null,threshold:null, -tooltip:{pointFormat:'{series.name}: {point.low} - {point.high}
    '},trackByArea:!0,dataLabels:{verticalAlign:null,xLow:0,xHigh:0,yLow:0,yHigh:0},shadow:!1});s=i.extendClass(i.Point,{applyOptions:function(a,b){var c=this.series,d=c.pointArrayMap,g=0,f=0,e=d.length;if(typeof a==="object"&&typeof a.length!=="number")w(this,a),this.options=a;else if(a.length){if(a.length>e){if(typeof a[0]==="string")this.name=a[0];else if(typeof a[0]==="number")this.x= -a[0];g++}for(;fMath.PI/2&&(j-=Math.PI),h=g+Math.cos(j)*b,i=f+Math.sin(j)*b,e=g+Math.cos(Math.PI+j)*k,j=f+Math.sin(Math.PI+j)*k,c.rightContX=e,c.rightContY=j;d?(c=["C",a.rightContX||a.plotX,a.rightContY||a.plotY,h||g,i||f,g,f],a.rightContX=a.rightContY=null):c=["M",g,f]}else c=a.call(this,b,c,d);return c}); -l(u,"translate",function(a){a.call(this);if(this.chart.polar&&!this.preventPostTranslate)for(var a=this.points,b=a.length;b--;)this.toXY(a[b])});l(u,"getSegmentPath",function(a,b){var c=this.points;if(this.chart.polar&&this.options.connectEnds!==!1&&b[b.length-1]===c[c.length-1]&&c[0].y!==null)this.connectEnds=!0,b=[].concat(b,[c[0]]);return a.call(this,b)});l(u,"animate",C);l(r,"animate",C);l(u,"setTooltipPoints",function(a,b){this.chart.polar&&w(this.xAxis,{tooltipLen:360,tooltipPosName:"deg"}); -return a.call(this,b)});l(r,"translate",function(a){var b=this.xAxis,c=this.yAxis.len,d=b.center,g=b.startAngleRad,f=this.chart.renderer,e,h;this.preventPostTranslate=!0;a.call(this);if(b.isRadial){b=this.points;for(h=b.length;h--;)e=b[h],a=e.barX+g,e.shapeType="path",e.shapeArgs={d:f.symbols.arc(d[0],d[1],c-e.plotY,null,{start:a,end:a+e.pointWidth,innerR:c-o(e.yBottom,c)})},this.toXY(e)}});l(r,"alignDataLabel",function(a,b,c,d,g,f){if(this.chart.polar){a=b.rectPlotX/Math.PI*180;if(d.align===null)d.align= -a>20&&a<160?"left":a>200&&a<340?"right":"center";if(d.verticalAlign===null)d.verticalAlign=a<45||a>315?"bottom":a>135&&a<225?"top":"middle";u.alignDataLabel.call(this,b,c,d,g,f)}else a.call(this,b,c,d,g,f)});l(n,"getIndex",function(a,b){var c,d=this.chart,g;d.polar?(g=d.xAxis[0].center,c=b.chartX-g[0]-d.plotLeft,d=b.chartY-g[1]-d.plotTop,c=180-Math.round(Math.atan2(c,d)/Math.PI*180)):c=a.call(this,b);return c});l(n,"getMouseCoordinates",function(a,b){var c=this.chart,d={xAxis:[],yAxis:[]};c.polar? -q(c.axes,function(a){var f=a.isXAxis,e=a.center,h=b.chartX-e[0]-c.plotLeft,e=b.chartY-e[1]-c.plotTop;d[f?"xAxis":"yAxis"].push({axis:a,value:a.translate(f?Math.PI-Math.atan2(h,e):Math.sqrt(Math.pow(h,2)+Math.pow(e,2)),!0)})}):d=a.call(this,b);return d})})(Highcharts); +(function(h,u){function z(a,b,c){this.init.call(this,a,b,c)}function A(a,b,c){a.call(this,b,c);if(this.chart.polar)this.closeSegment=function(a){var b=this.xAxis.center;a.push("L",b[0],b[1])},this.closedStacks=!0}function B(a,b){var c=this.chart,d=this.options.animation,e=this.group,g=this.markerGroup,f=this.xAxis.center,j=c.plotLeft,n=c.plotTop;if(c.polar){if(c.renderer.isSVG)if(d===!0&&(d={}),b){if(e.attrSetters.scaleX=e.attrSetters.scaleY=function(a,b){this[b]=a;this.scaleX!==u&&this.scaleY!== +u&&this.element.setAttribute("transform","translate("+this.translateX+","+this.translateY+") scale("+this.scaleX+","+this.scaleY+")");return!1},c={translateX:f[0]+j,translateY:f[1]+n,scaleX:0,scaleY:0},e.attr(c),g)g.attrSetters=e.attrSetters,g.attr(c)}else c={translateX:j,translateY:n,scaleX:1,scaleY:1},e.animate(c,d),g&&g.animate(c,d),this.animate=null}else a.call(this,b)}var p=h.each,v=h.extend,o=h.merge,D=h.map,m=h.pick,w=h.pInt,k=h.getOptions().plotOptions,i=h.seriesTypes,E=h.extendClass,l=h.wrap, +r=h.Axis,G=h.Tick,y=h.Series,q=i.column.prototype,s=function(){};v(z.prototype,{init:function(a,b,c){var d=this,e=d.defaultOptions;d.chart=b;if(b.angular)e.background={};d.options=a=o(e,a);(a=a.background)&&p([].concat(h.splat(a)).reverse(),function(a){var b=a.backgroundColor,a=o(d.defaultBackgroundOptions,a);if(b)a.backgroundColor=b;a.color=a.backgroundColor;c.options.plotBands.unshift(a)})},defaultOptions:{center:["50%","50%"],size:"85%",startAngle:0},defaultBackgroundOptions:{shape:"circle",borderWidth:1, +borderColor:"silver",backgroundColor:{linearGradient:{x1:0,y1:0,x2:0,y2:1},stops:[[0,"#FFF"],[1,"#DDD"]]},from:Number.MIN_VALUE,innerRadius:0,to:Number.MAX_VALUE,outerRadius:"105%"}});var x=r.prototype,r=G.prototype,H={getOffset:s,redraw:function(){this.isDirty=!1},render:function(){this.isDirty=!1},setScale:s,setCategories:s,setTitle:s},F={isRadial:!0,defaultRadialGaugeOptions:{labels:{align:"center",x:0,y:null},minorGridLineWidth:0,minorTickInterval:"auto",minorTickLength:10,minorTickPosition:"inside", +minorTickWidth:1,plotBands:[],tickLength:10,tickPosition:"inside",tickWidth:2,title:{rotation:0},zIndex:2},defaultRadialXOptions:{gridLineWidth:1,labels:{align:null,distance:15,x:0,y:null},maxPadding:0,minPadding:0,plotBands:[],showLastLabel:!1,tickLength:0},defaultRadialYOptions:{gridLineInterpolation:"circle",labels:{align:"right",x:-3,y:-2},plotBands:[],showLastLabel:!1,title:{x:4,text:null,rotation:90}},setOptions:function(a){this.options=o(this.defaultOptions,this.defaultRadialOptions,a)},getOffset:function(){x.getOffset.call(this); +this.chart.axisOffset[this.side]=0;this.center=this.pane.center=i.pie.prototype.getCenter.call(this.pane)},getLinePath:function(a,b){var c=this.center,b=m(b,c[2]/2-this.offset);return this.chart.renderer.symbols.arc(this.left+c[0],this.top+c[1],b,b,{start:this.startAngleRad,end:this.endAngleRad,open:!0,innerR:0})},setAxisTranslation:function(){x.setAxisTranslation.call(this);if(this.center&&(this.transA=this.isCircular?(this.endAngleRad-this.startAngleRad)/(this.max-this.min||1):this.center[2]/2/ +(this.max-this.min||1),this.isXAxis))this.minPixelPadding=this.transA*this.minPointOffset+(this.reversed?(this.endAngleRad-this.startAngleRad)/4:0)},beforeSetTickPositions:function(){this.autoConnect&&(this.max+=this.categories&&1||this.pointRange||this.closestPointRange)},setAxisSize:function(){x.setAxisSize.call(this);if(this.center)this.len=this.width=this.height=this.isCircular?this.center[2]*(this.endAngleRad-this.startAngleRad)/2:this.center[2]/2},getPosition:function(a,b){if(!this.isCircular)b= +this.translate(a),a=this.min;return this.postTranslate(this.translate(a),m(b,this.center[2]/2)-this.offset)},postTranslate:function(a,b){var c=this.chart,d=this.center,a=this.startAngleRad+a;return{x:c.plotLeft+d[0]+Math.cos(a)*b,y:c.plotTop+d[1]+Math.sin(a)*b}},getPlotBandPath:function(a,b,c){var d=this.center,e=this.startAngleRad,g=d[2]/2,f=[m(c.outerRadius,"100%"),c.innerRadius,m(c.thickness,10)],j=/%$/,n,C=this.isCircular;this.options.gridLineInterpolation==="polygon"?d=this.getPlotLinePath(a).concat(this.getPlotLinePath(b, +!0)):(C||(f[0]=this.translate(a),f[1]=this.translate(b)),f=D(f,function(a){j.test(a)&&(a=w(a,10)*g/100);return a}),c.shape==="circle"||!C?(a=-Math.PI/2,b=Math.PI*1.5,n=!0):(a=e+this.translate(a),b=e+this.translate(b)),d=this.chart.renderer.symbols.arc(this.left+d[0],this.top+d[1],f[0],f[0],{start:a,end:b,innerR:m(f[1],f[0]-f[2]),open:n}));return d},getPlotLinePath:function(a,b){var c=this.center,d=this.chart,e=this.getPosition(a),g,f,j;this.isCircular?j=["M",c[0]+d.plotLeft,c[1]+d.plotTop,"L",e.x, +e.y]:this.options.gridLineInterpolation==="circle"?(a=this.translate(a))&&(j=this.getLinePath(0,a)):(g=d.xAxis[0],j=[],a=this.translate(a),c=g.tickPositions,g.autoConnect&&(c=c.concat([c[0]])),b&&(c=[].concat(c).reverse()),p(c,function(b,c){f=g.getPosition(b,a);j.push(c?"L":"M",f.x,f.y)}));return j},getTitlePosition:function(){var a=this.center,b=this.chart,c=this.options.title;return{x:b.plotLeft+a[0]+(c.x||0),y:b.plotTop+a[1]-{high:0.5,middle:0.25,low:0}[c.align]*a[2]+(c.y||0)}}};l(x,"init",function(a, +b,c){var d=this,e=b.angular,g=b.polar,f=c.isX,j=e&&f,n;if(e){if(v(this,j?H:F),n=!f)this.defaultRadialOptions=this.defaultRadialGaugeOptions}else if(g)v(this,F),this.defaultRadialOptions=(n=f)?this.defaultRadialXOptions:o(this.defaultYAxisOptions,this.defaultRadialYOptions);a.call(this,b,c);if(!j&&(e||g)){a=this.options;if(!b.panes)b.panes=D(h.splat(b.options.pane),function(a){return new z(a,b,d)});this.pane=e=b.panes[c.pane||0];g=e.options;b.inverted=!1;b.options.chart.zoomType=null;this.startAngleRad= +e=(g.startAngle-90)*Math.PI/180;this.endAngleRad=g=(m(g.endAngle,g.startAngle+360)-90)*Math.PI/180;this.offset=a.offset||0;if((this.isCircular=n)&&c.max===u&&g-e===2*Math.PI)this.autoConnect=!0}});l(r,"getPosition",function(a,b,c,d,e){var g=this.axis;return g.getPosition?g.getPosition(c):a.call(this,b,c,d,e)});l(r,"getLabelPosition",function(a,b,c,d,e,g,f,j,n){var h=this.axis,i=g.y,l=g.align,k=(h.translate(this.pos)+h.startAngleRad+Math.PI/2)/Math.PI*180;h.isRadial?(a=h.getPosition(this.pos,h.center[2]/ +2+m(g.distance,-25)),g.rotation==="auto"?d.attr({rotation:k}):i===null&&(i=w(d.styles.lineHeight)*0.9-d.getBBox().height/2),l===null&&(l=h.isCircular?k>20&&k<160?"left":k>200&&k<340?"right":"center":"center",d.attr({align:l})),a.x+=g.x,a.y+=i):a=a.call(this,b,c,d,e,g,f,j,n);return a});l(r,"getMarkPath",function(a,b,c,d,e,g,f){var j=this.axis;j.isRadial?(a=j.getPosition(this.pos,j.center[2]/2+d),b=["M",b,c,"L",a.x,a.y]):b=a.call(this,b,c,d,e,g,f);return b});k.arearange=o(k.area,{lineWidth:1,marker:null, +threshold:null,tooltip:{pointFormat:'{series.name}: {point.low} - {point.high}
    '},trackByArea:!0,dataLabels:{verticalAlign:null,xLow:0,xHigh:0,yLow:0,yHigh:0},shadow:!1});r=h.extendClass(h.Point,{applyOptions:function(a,b){var c=this.series,d=c.pointArrayMap,e=0,g=0,f=d.length;if(typeof a==="object"&&typeof a.length!=="number")v(this,a),this.options=a;else if(a.length){if(a.length>f){if(typeof a[0]==="string")this.name=a[0];else if(typeof a[0]=== +"number")this.x=a[0];e++}for(;gMath.PI/2&&(k-=Math.PI),j=e+Math.cos(k)*b,h=g+Math.sin(k)*b,f=e+Math.cos(Math.PI+k)*i,k=g+Math.sin(Math.PI+k)*i,c.rightContX=f,c.rightContY=k;d?(c=["C",a.rightContX||a.plotX,a.rightContY||a.plotY,j||e,h||g,e,g],a.rightContX=a.rightContY=null):c=["M",e,g]}else c=a.call(this,b,c,d);return c});l(t,"translate",function(a){a.call(this);if(this.chart.polar&&!this.preventPostTranslate)for(var a=this.points,b=a.length;b--;)this.toXY(a[b])});l(t,"getSegmentPath",function(a,b){var c= +this.points;if(this.chart.polar&&this.options.connectEnds!==!1&&b[b.length-1]===c[c.length-1]&&c[0].y!==null)this.connectEnds=!0,b=[].concat(b,[c[0]]);return a.call(this,b)});l(t,"animate",B);l(q,"animate",B);l(t,"setTooltipPoints",function(a,b){this.chart.polar&&v(this.xAxis,{tooltipLen:360,tooltipPosName:"deg"});return a.call(this,b)});l(q,"translate",function(a){var b=this.xAxis,c=this.yAxis.len,d=b.center,e=b.startAngleRad,g=this.chart.renderer,f,h;this.preventPostTranslate=!0;a.call(this);if(b.isRadial){b= +this.points;for(h=b.length;h--;)f=b[h],a=f.barX+e,f.shapeType="path",f.shapeArgs={d:g.symbols.arc(d[0],d[1],c-f.plotY,null,{start:a,end:a+f.pointWidth,innerR:c-m(f.yBottom,c)})},this.toXY(f)}});l(q,"alignDataLabel",function(a,b,c,d,e,g){if(this.chart.polar){a=b.rectPlotX/Math.PI*180;if(d.align===null)d.align=a>20&&a<160?"left":a>200&&a<340?"right":"center";if(d.verticalAlign===null)d.verticalAlign=a<45||a>315?"bottom":a>135&&a<225?"top":"middle";t.alignDataLabel.call(this,b,c,d,e,g)}else a.call(this, +b,c,d,e,g)});l(k,"getIndex",function(a,b){var c,d=this.chart,e;d.polar?(e=d.xAxis[0].center,c=b.chartX-e[0]-d.plotLeft,d=b.chartY-e[1]-d.plotTop,c=180-Math.round(Math.atan2(c,d)/Math.PI*180)):c=a.call(this,b);return c});l(k,"getMouseCoordinates",function(a,b){var c=this.chart,d={xAxis:[],yAxis:[]};c.polar?p(c.axes,function(a){var g=a.isXAxis,f=a.center,h=b.chartX-f[0]-c.plotLeft,f=b.chartY-f[1]-c.plotTop;d[g?"xAxis":"yAxis"].push({axis:a,value:a.translate(g?Math.PI-Math.atan2(h,f):Math.sqrt(Math.pow(h, +2)+Math.pow(f,2)),!0)})}):d=a.call(this,b);return d})})(Highcharts); diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts.js b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts.js index 7d9a0b1202a..a77be0b6e7c 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/highcharts.js @@ -1,250 +1,246 @@ /* - Highcharts JS v2.3.5 (2012-12-19) + Highcharts JS v2.3.3 (2012-10-04) - (c) 2009-2012 Torstein Hønsi + (c) 2009-2011 Torstein Hønsi License: www.highcharts.com/license */ -(function(){function x(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function ia(){for(var a=0,b=arguments,c=b.length,d={};a-1?b.split(".")[1].length:0):a=isNaN(b=M(b))?2:b;var b=a,c=c===void 0?e.decimalPoint:c,d=d===void 0?e.thousandsSep:d,e=f<0?"-":"",a=String(z(f=M(+f||0).toFixed(b))),g=a.length>3?a.length%3:0;return e+(g?a.substr(0,g)+d:"")+a.substr(g).replace(/(\d{3})(?=\d)/g, -"$1"+d)+(b?c+M(f-a).toFixed(b).slice(2):"")}function ua(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function hb(a,b,c,d){var e,c=n(c,1);e=a/c;b||(b=[1,2,2.5,5,10],d&&d.allowDecimals===!1&&(c===1?b=[1,2,5,10]:c<=0.1&&(b=[1/c])));for(d=0;d=D[ib]&&(i.setMilliseconds(0),i.setSeconds(j>=D[Va]?0:k*U(i.getSeconds()/k)));if(j>=D[Va])i[Db](j>=D[Ka]?0:k*U(i[jb]()/k));if(j>=D[Ka])i[Eb](j>=D[ma]? -0:k*U(i[kb]()/k));if(j>=D[ma])i[lb](j>=D[La]?1:k*U(i[Ma]()/k));j>=D[La]&&(i[Fb](j>=D[va]?0:k*U(i[Xa]()/k)),h=i[Ya]());j>=D[va]&&(h-=h%k,i[Gb](h));if(j===D[Wa])i[lb](i[Ma]()-i[mb]()+n(d,1));b=1;h=i[Ya]();for(var d=i.getTime(),l=i[Xa](),m=i[Ma](),i=g?0:(864E5+i.getTimezoneOffset()*6E4)%864E5;dc&&(c=a[b]);return c}function Ga(a,b){for(var c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function Na(a){$a||($a=T(ga));a&&$a.appendChild(a);$a.innerHTML= -""}function Oa(a,b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw c;else L.console&&console.log(c)}function da(a){return parseFloat(a.toPrecision(14))}function xa(a,b){Pa=n(a,b.animation)}function Jb(){var a=N.global.useUTC,b=a?"getUTC":"get",c=a?"setUTC":"set";Za=a?Date.UTC:function(a,b,c,g,h,i){return(new Date(a,b,n(c,1),n(g,0),n(h,0),n(i,0))).getTime()};jb=b+"Minutes";kb=b+"Hours";mb=b+"Day";Ma=b+"Date";Xa=b+"Month";Ya=b+"FullYear";Db=c+"Minutes";Eb=c+"Hours";lb=c+"Date"; -Fb=c+"Month";Gb=c+"FullYear"}function ya(){}function Qa(a,b,c){this.axis=a;this.pos=b;this.type=c||"";this.isNew=!0;c||this.addLabel()}function nb(a,b){this.axis=a;if(b)this.options=b,this.id=b.id;return this}function Kb(a,b,c,d,e,f){var g=a.chart.inverted;this.axis=a;this.isNegative=c;this.options=b;this.x=d;this.stack=e;this.percent=f==="percent";this.alignOptions={align:b.align||(g?c?"left":"right":"center"),verticalAlign:b.verticalAlign||(g?"middle":c?"bottom":"top"),y:n(b.y,g?4:c?14:-6),x:n(b.x, -g?c?-6:6:0)};this.textAlign=b.textAlign||(g?c?"right":"left":"center")}function ob(){this.init.apply(this,arguments)}function pb(a,b){var c=b.borderWidth,d=b.style,e=z(d.padding);this.chart=a;this.options=b;this.crosshairs=[];this.now={x:0,y:0};this.isHidden=!0;this.label=a.renderer.label("",0,0,b.shape,null,null,b.useHTML,null,"tooltip").attr({padding:e,fill:b.backgroundColor,"stroke-width":c,r:b.borderRadius,zIndex:8}).css(d).css({padding:0}).hide().add();V||this.label.shadow(b.shadow);this.shared= -b.shared}function qb(a,b){var c=V?"":b.chart.zoomType;this.zoomX=/x/.test(c);this.zoomY=/y/.test(c);this.options=b;this.chart=a;this.init(a,b.tooltip)}function rb(a){this.init(a)}function sb(){this.init.apply(this,arguments)}var A,C=document,L=window,K=Math,u=K.round,U=K.floor,za=K.ceil,s=K.max,O=K.min,M=K.abs,W=K.cos,Z=K.sin,Aa=K.PI,ab=Aa*2/360,na=navigator.userAgent,Lb=L.opera,Ea=/msie/i.test(na)&&!Lb,Ra=C.documentMode===8,bb=/AppleWebKit/.test(na),cb=/Firefox/.test(na),Mb=/(Mobile|Android|Windows Phone)/.test(na), -oa="http://www.w3.org/2000/svg",ca=!!C.createElementNS&&!!C.createElementNS(oa,"svg").createSVGRect,Sb=cb&&parseInt(na.split("Firefox/")[1],10)<4,V=!ca&&!Ea&&!!C.createElement("canvas").getContext,Sa,Ba=C.documentElement.ontouchstart!==A,Nb={},tb=0,$a,N,db,Pa,ub,D,pa=function(){},Ha=[],ga="div",Q="none",vb="rgba(192,192,192,"+(ca?1.0E-4:0.002)+")",Bb="millisecond",ib="second",Va="minute",Ka="hour",ma="day",Wa="week",La="month",va="year",wb="stroke-width",Za,jb,kb,mb,Ma,Xa,Ya,Db,Eb,lb,Fb,Gb,$={};L.Highcharts= -{};db=function(a,b,c){if(!r(b)||isNaN(b))return"Invalid date";var a=n(a,"%Y-%m-%d %H:%M:%S"),d=new Date(b),e,f=d[kb](),g=d[mb](),h=d[Ma](),i=d[Xa](),j=d[Ya](),k=N.lang,l=k.weekdays,b={a:l[g].substr(0,3),A:l[g],d:ua(h),e:h,b:k.shortMonths[i],B:k.months[i],m:ua(i+1),y:j.toString().substr(2,2),Y:j,H:ua(f),I:ua(f%12||12),l:f%12||12,M:ua(d[jb]()),p:f<12?"AM":"PM",P:f<12?"am":"pm",S:ua(d.getSeconds()),L:ua(u(b%1E3),3)};for(e in b)for(;a.indexOf("%"+e)!==-1;)a=a.replace("%"+e,b[e]);return c?a.substr(0,1).toUpperCase()+ -a.substr(1):a};Hb.prototype={wrapColor:function(a){if(this.color>=a)this.color=0},wrapSymbol:function(a){if(this.symbol>=a)this.symbol=0}};D=ia(Bb,1,ib,1E3,Va,6E4,Ka,36E5,ma,864E5,Wa,6048E5,La,26784E5,va,31556952E3);ub={init:function(a,b,c){var b=b||"",d=a.shift,e=b.indexOf("C")>-1,f=e?7:3,g,b=b.split(" "),c=[].concat(c),h,i,j=function(a){for(g=a.length;g--;)a[g]==="M"&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};e&&(j(b),j(c));a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6));if(d<= -c.length/f)for(;d--;)c=[].concat(c).splice(0,f).concat(c);a.shift=0;if(b.length)for(a=c.length;b.length{point.key}
    ',pointFormat:'{series.name}: {point.y}
    ',shadow:!0,shared:V,snap:Mb?25:10,style:{color:"#333333",fontSize:"12px",padding:"5px",whiteSpace:"nowrap"}},credits:{enabled:!0, -text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"10px"}}};var X=N.plotOptions,ea=X.line;Jb();var qa=function(a){var b=[],c;(function(a){(c=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/.exec(a))?b=[z(c[1]),z(c[2]),z(c[3]),parseFloat(c[4],10)]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))&&(b=[z(c[1],16),z(c[2],16),z(c[3], -16),1])})(a);return{get:function(c){return b&&!isNaN(b[0])?c==="rgb"?"rgb("+b[0]+","+b[1]+","+b[2]+")":c==="a"?b[3]:"rgba("+b.join(",")+")":a},brighten:function(a){if(Da(a)&&a!==0){var c;for(c=0;c<3;c++)b[c]+=z(a*255),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},setOpacity:function(a){b[3]=a;return this}}};ya.prototype={init:function(a,b){this.element=b==="span"?T(b):C.createElementNS(oa,b);this.renderer=a;this.attrSetters={}},animate:function(a,b,c){b=n(b,Pa,!0);fb(this);if(b){b=B(b);if(c)b.complete= -c;xb(this,a,b)}else this.attr(a),c&&c()},attr:function(a,b){var c,d,e,f,g=this.element,h=g.nodeName.toLowerCase(),i=this.renderer,j,k=this.attrSetters,l=this.shadows,m,q,p=this;ja(a)&&r(b)&&(c=a,a={},a[c]=b);if(ja(a))c=a,h==="circle"?c={x:"cx",y:"cy"}[c]||c:c==="strokeWidth"&&(c="stroke-width"),p=w(g,c)||this[c]||0,c!=="d"&&c!=="visibility"&&(p=parseFloat(p));else for(c in a)if(j=!1,d=a[c],e=k[c]&&k[c].call(this,d,c),e!==!1){e!==A&&(d=e);if(c==="d")d&&d.join&&(d=d.join(" ")),/(NaN| {2}|^$)/.test(d)&& -(d="M 0 0");else if(c==="x"&&h==="text"){for(e=0;em&&/[ \-]/.test(b.textContent||b.innerText))I(b,{width:m+"px",display:"block",whiteSpace:"normal"}),k=m;m=a.fontMetrics(b.style.fontSize).b;t= -p<0&&-k;H=q<0&&-l;y=p*q<0;t+=q*m*(y?1-h:h);H-=p*m*(j?y?h:1-h:1);i&&(t-=k*h*(p<0?-1:1),j&&(H-=l*h*(q<0?-1:1)),I(b,{textAlign:g}));this.xCorr=t;this.yCorr=H}I(b,{left:e+t+"px",top:f+H+"px"});if(bb)l=b.offsetHeight;this.cTT=ra}}else this.alignOnAdd=!0},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c=this.inverted,d=this.rotation,e=[];c&&(a+=this.attr("width"),b+=this.attr("height"));(a||b)&&e.push("translate("+a+","+b+")");c?e.push("rotate(90) scale(-1,1)"):d&&e.push("rotate("+ -d+" "+(this.x||0)+" "+(this.y||0)+")");e.length&&w(this.element,"transform",e.join(" "))},toFront:function(){var a=this.element;a.parentNode.appendChild(a);return this},align:function(a,b,c){a?(this.alignOptions=a,this.alignByTranslate=b,c||this.renderer.alignedObjects.push(this)):(a=this.alignOptions,b=this.alignByTranslate);var c=n(c,this.renderer),d=a.align,e=a.verticalAlign,f=(c.x||0)+(a.x||0),g=(c.y||0)+(a.y||0),h={};if(d==="right"||d==="center")f+=(c.width-(a.width||0))/{right:1,center:2}[d]; -h[b?"translateX":"x"]=u(f);if(e==="bottom"||e==="middle")g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1);h[b?"translateY":"y"]=u(g);this[this.placed?"animate":"attr"](h);this.placed=!0;this.alignAttr=h;return this},getBBox:function(){var a=this.bBox,b=this.renderer,c,d=this.rotation;c=this.element;var e=this.styles,f=d*ab;if(!a){if(c.namespaceURI===oa||b.forExport){try{a=c.getBBox?x({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight}}catch(g){}if(!a||a.width<0)a={width:0,height:0}}else a= -this.htmlGetBBox();if(b.isSVG){b=a.width;c=a.height;if(Ea&&e&&e.fontSize==="11px"&&c===22.700000762939453)a.height=c=14;if(d)a.width=M(c*Z(f))+M(b*W(f)),a.height=M(c*W(f))+M(b*Z(f))}this.bBox=a}return a},show:function(){return this.attr({visibility:"visible"})},hide:function(){return this.attr({visibility:"hidden"})},add:function(a){var b=this.renderer,c=a||b,d=c.element||b.box,e=d.childNodes,f=this.element,g=w(f,"zIndex"),h;if(a)this.parentGroup=a;this.parentInverted=a&&a.inverted;this.textStr!== -void 0&&b.buildText(this);if(g)c.handleZ=!0,g=z(g);if(c.handleZ)for(c=0;cg||!r(g)&&r(b))){d.insertBefore(f,a);h=!0;break}h||d.appendChild(f);this.added=!0;F(this,"add");return this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var a=this,b=a.element||{},c=a.shadows,d,e;b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=null;fb(a);if(a.clipPath)a.clipPath=a.clipPath.destroy();if(a.stops){for(e=0;e/g,'').replace(/<(i|em)>/g,'').replace(/
    /g,"").split(//g),d=b.childNodes,e=/style="([^"]+)"/,f=/href="([^"]+)"/,g=w(b,"x"),h=a.styles,i=h&&h.width&&z(h.width),j=h&&h.lineHeight,k,h=d.length,l=[];h--;)b.removeChild(d[h]);i&&!a.added&&this.box.appendChild(b);c[c.length-1]===""&&c.pop();o(c,function(c,d){var h,y=0,t,c=c.replace(//g,"|||");h=c.split("|||");o(h,function(c){if(c!==""||h.length===1){var m={},n=C.createElementNS(oa,"tspan"),o;e.test(c)&& -(o=c.match(e)[1].replace(/(;| |^)color([ :])/,"$1fill$2"),w(n,"style",o));f.test(c)&&(w(n,"onclick",'location.href="'+c.match(f)[1]+'"'),I(n,{cursor:"pointer"}));c=(c.replace(/<(.|\n)*?>/g,"")||" ").replace(/</g,"<").replace(/>/g,">");n.appendChild(C.createTextNode(c));y?m.dx=3:m.x=g;if(!y){if(d){!ca&&a.renderer.forExport&&I(n,{display:"block"});t=L.getComputedStyle&&z(L.getComputedStyle(k,null).getPropertyValue("line-height"));if(!t||isNaN(t)){var r;if(!(r=j))if(!(r=k.offsetHeight))l[d]=b.getBBox? -b.getBBox().height:a.renderer.fontMetrics(b.style.fontSize).h,r=u(l[d]-(l[d-1]||0))||18;t=r}w(n,"dy",t)}k=n}w(n,m);b.appendChild(n);y++;if(i)for(var c=c.replace(/([^\^])-/g,"$1- ").split(" "),E=[];c.length||E.length;)delete a.bBox,r=a.getBBox().width,m=r>i,!m||c.length===1?(c=E,E=[],c.length&&(n=C.createElementNS(oa,"tspan"),w(n,{dy:j||16,x:g}),o&&w(n,"style",o),b.appendChild(n),r>i&&(i=r))):(n.removeChild(n.firstChild),E.unshift(c.pop())),c.length&&n.appendChild(C.createTextNode(c.join(" ").replace(/- /g, -"-")))}})})},button:function(a,b,c,d,e,f,g){var h=this.label(a,b,c),i=0,j,k,l,m,q,a={x1:0,y1:0,x2:0,y2:1},e=B(ia(wb,1,"stroke","#999","fill",ia("linearGradient",a,"stops",[[0,"#FFF"],[1,"#DDD"]]),"r",3,"padding",3,"style",ia("color","black")),e);l=e.style;delete e.style;f=B(e,ia("stroke","#68A","fill",ia("linearGradient",a,"stops",[[0,"#FFF"],[1,"#ACF"]])),f);m=f.style;delete f.style;g=B(e,ia("stroke","#68A","fill",ia("linearGradient",a,"stops",[[0,"#9BD"],[1,"#CDF"]])),g);q=g.style;delete g.style; -J(h.element,"mouseenter",function(){h.attr(f).css(m)});J(h.element,"mouseleave",function(){j=[e,f,g][i];k=[l,m,q][i];h.attr(j).css(k)});h.setState=function(a){(i=a)?a===2&&h.attr(g).css(q):h.attr(e).css(l)};return h.on("click",function(){d.call(h)}).attr(e).css(x({cursor:"default"},l))},crispLine:function(a,b){a[1]===a[4]&&(a[1]=a[4]=u(a[1])-b%2/2);a[2]===a[5]&&(a[2]=a[5]=u(a[2])+b%2/2);return a},path:function(a){var b={fill:Q};Ia(a)?b.d=a:Y(a)&&x(b,a);return this.createElement("path").attr(b)},circle:function(a, -b,c){a=Y(a)?a:{x:a,y:b,r:c};return this.createElement("circle").attr(a)},arc:function(a,b,c,d,e,f){if(Y(a))b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x;return this.symbol("arc",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0})},rect:function(a,b,c,d,e,f){e=Y(a)?a.r:e;e=this.createElement("rect").attr({rx:e,ry:e,fill:Q});return e.attr(Y(a)?a:e.crisp(f,a,b,s(c,0),s(d,0)))},setSize:function(a,b,c){var d=this.alignedObjects,e=d.length;this.width=a;this.height=b;for(this.boxWrapper[n(c,!0)?"animate": -"attr"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement("g");return r(a)?b.attr({"class":"highcharts-"+a}):b},image:function(a,b,c,d,e){var f={preserveAspectRatio:Q};arguments.length>1&&x(f,{x:b,y:c,width:d,height:e});f=this.createElement("image").attr(f);f.element.setAttributeNS?f.element.setAttributeNS("http://www.w3.org/1999/xlink","href",a):f.element.setAttribute("hc-svg-href",a);return f},symbol:function(a,b,c,d,e,f){var g,h=this.symbols[a],h=h&&h(u(b),u(c),d,e, -f),i=/^url\((.*?)\)$/,j,k;h?(g=this.path(h),x(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&x(g,f)):i.test(a)&&(k=function(a,b){a.element&&(a.attr({width:b[0],height:b[1]}),a.alignByTranslate||a.translate(u((d-b[0])/2),u((e-b[1])/2)))},j=a.match(i)[1],a=Nb[j],g=this.image(j).attr({x:b,y:c}),a?k(g,a):(g.attr({width:0,height:0}),T("img",{onload:function(){k(g,Nb[j]=[this.width,this.height])},src:j})));return g},symbols:{circle:function(a,b,c,d){var e=0.166*c;return["M",a+c/2,b,"C",a+c+e,b,a+c+e,b+d, -a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d/2,a+c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,e){var f=e.start,c=e.r||c||d,g=e.end-1.0E-6,d=e.innerR,h=e.open,i=W(f),j=Z(f),k=W(g),g=Z(g),e=e.end-f');if(b)c=b===ga||b==="span"||b==="img"?c.join(""):a.prepVML(c),this.element=T(c);this.renderer=a;this.attrSetters={}},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;a&&a.inverted&&b.invertChild(c,d);d.appendChild(c);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();F(this,"add");return this}, -updateTransform:ya.prototype.htmlUpdateTransform,attr:function(a,b){var c,d,e,f=this.element||{},g=f.style,h=f.nodeName,i=this.renderer,j=this.symbolName,k,l=this.shadows,m,q=this.attrSetters,p=this;ja(a)&&r(b)&&(c=a,a={},a[c]=b);if(ja(a))c=a,p=c==="strokeWidth"||c==="stroke-width"?this.strokeweight:this[c];else for(c in a)if(d=a[c],m=!1,e=q[c]&&q[c].call(this,d,c),e!==!1&&d!==null){e!==A&&(d=e);if(j&&/^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(c))k||(this.symbolAttr(a),k=!0),m= -!0;else if(c==="d"){d=d||[];this.d=d.join(" ");e=d.length;for(m=[];e--;)m[e]=Da(d[e])?u(d[e]*10)-5:d[e]==="Z"?"x":d[e];d=m.join(" ")||"x";f.path=d;if(l)for(e=l.length;e--;)l[e].path=l[e].cutOff?this.cutOffPath(d,l[e].cutOff):d;m=!0}else if(c==="visibility"){if(l)for(e=l.length;e--;)l[e].style[c]=d;h==="DIV"&&(d=d==="hidden"?"-999em":0,c="top");g[c]=d;m=!0}else if(c==="zIndex")d&&(g[c]=d),m=!0;else if(c==="width"||c==="height")d=s(0,d),this[c]=d,this.updateClipping?(this[c]=d,this.updateClipping()): -g[c]=d,m=!0;else if(c==="x"||c==="y")this[c]=d,g[{x:"left",y:"top"}[c]]=d;else if(c==="class")f.className=d;else if(c==="stroke")d=i.color(d,f,c),c="strokecolor";else if(c==="stroke-width"||c==="strokeWidth")f.stroked=d?!0:!1,c="strokeweight",this[c]=d,Da(d)&&(d+="px");else if(c==="dashstyle")(f.getElementsByTagName("stroke")[0]||T(i.prepVML([""]),null,null,f))[c]=d||"solid",this.dashstyle=d,m=!0;else if(c==="fill")if(h==="SPAN")g.color=d;else{if(h!=="IMG")f.filled=d!==Q?!0:!1,d=i.color(d, -f,c,this),c="fillcolor"}else if(h==="shape"&&c==="rotation")this[c]=d,f.style.left=-u(Z(d*ab)+1)+"px",f.style.top=u(W(d*ab))+"px";else if(c==="translateX"||c==="translateY"||c==="rotation")this[c]=d,this.updateTransform(),m=!0;else if(c==="text")this.bBox=null,f.innerHTML=d,m=!0;m||(Ra?f[c]=d:w(f,c,d))}return p},clip:function(a){var b=this,c,d=b.element,e=d.parentNode;a?(c=a.members,ta(c,b),c.push(b),b.destroyClip=function(){ta(c,b)},e&&e.className==="highcharts-tracker"&&!Ra&&I(d,{visibility:"hidden"}), -a=a.getCSS(b)):(b.destroyClip&&b.destroyClip(),a={clip:Ra?"inherit":"rect(auto)"});return b.css(a)},css:ya.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&Na(a)},destroy:function(){this.destroyClip&&this.destroyClip();return ya.prototype.destroy.apply(this)},empty:function(){for(var a=this.element.childNodes,b=a.length,c;b--;)c=a[b],c.parentNode.removeChild(c)},on:function(a,b){this.element["on"+a]=function(){var a=L.event;a.target=a.srcElement;b(a)};return this},cutOffPath:function(a, -b){var c,a=a.split(/[ ,]/);c=a.length;if(c===9||c===11)a[c-4]=a[c-2]=z(a[c-2])-10*b;return a.join(" ")},shadow:function(a,b,c){var d=[],e,f=this.element,g=this.renderer,h,i=f.style,j,k=f.path,l,m,q,p;k&&typeof k.value!=="string"&&(k="x");m=k;if(a){q=n(a.width,3);p=(a.opacity||0.15)/q;for(e=1;e<=3;e++){l=q*2+1-2*e;c&&(m=this.cutOffPath(k.value,l+0.5));j=[''];h=T(g.prepVML(j),null, -{left:z(i.left)+n(a.offsetX,1),top:z(i.top)+n(a.offsetY,1)});if(c)h.cutOff=l+1;j=[''];T(g.prepVML(j),null,null,h);b?b.element.appendChild(h):f.parentNode.insertBefore(h,f);d.push(h)}this.shadows=d}return this}};ha=ba(ya,ha);var fa={Element:ha,isIE8:na.indexOf("MSIE 8.0")>-1,init:function(a,b,c){var d,e;this.alignedObjects=[];d=this.createElement(ga);e=d.element;e.style.position="relative";a.appendChild(d.element);this.box=e;this.boxWrapper=d; -this.setSize(b,c,!1);if(!C.namespaces.hcv)C.namespaces.add("hcv","urn:schemas-microsoft-com:vml"),C.createStyleSheet().cssText="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "},isHidden:function(){return!this.box.offsetWidth},clipRect:function(a,b,c,d){var e=this.createElement(),f=Y(a);return x(e,{members:[],left:f?a.x:a,top:f?a.y:b,width:f?a.width:c,height:f?a.height:d,getCSS:function(a){var b=a.inverted,c=this.top,d=this.left,e=d+this.width, -f=c+this.height,c={clip:"rect("+u(b?d:c)+"px,"+u(b?f:e)+"px,"+u(b?e:f)+"px,"+u(b?c:d)+"px)"};!b&&Ra&&a.element.nodeName!=="IMG"&&x(c,{width:e+"px",height:f+"px"});return c},updateClipping:function(){o(e.members,function(a){a.css(e.getCSS(a))})}})},color:function(a,b,c,d){var e=this,f,g=/^rgba/,h,i,j=Q;a&&a.linearGradient?i="gradient":a&&a.radialGradient&&(i="pattern");if(i){var k,l,m=a.linearGradient||a.radialGradient,q,p,n,t,H,r="",a=a.stops,v,s=[],u=function(){h=[''];T(e.prepVML(h),null,null,b)};q=a[0];v=a[a.length-1];q[0]>0&&a.unshift([0,q[1]]);v[0]<1&&a.push([1,v[1]]);o(a,function(a,b){g.test(a[1])?(f=qa(a[1]),k=f.get("rgb"),l=f.get("a")):(k=a[1],l=1);s.push(a[0]*100+"% "+k);b?(n=l,t=k):(p=l,H=k)});if(c==="fill")if(i==="gradient")c=m.x1||m[0]||0,a=m.y1||m[1]||0,q=m.x2||m[2]||0,m=m.y2||m[3]||0,r='angle="'+(90-K.atan((m-a)/(q-c))*180/Aa)+'"',u();else{var j=m.r,E=j*2,S=j*2,x=m.cx,A=m.cy,w= -b.radialReference,z,j=function(){w&&(z=d.getBBox(),x+=(w[0]-z.x)/z.width-0.5,A+=(w[1]-z.y)/z.height-0.5,E*=w[2]/z.width,S*=w[2]/z.height);r='src="'+N.global.VMLRadialGradientURL+'" size="'+E+","+S+'" origin="0.5,0.5" position="'+x+","+A+'" color2="'+H+'" ';u()};d.added?j():J(d,"add",j);j=t}else j=k}else if(g.test(a)&&b.tagName!=="IMG")f=qa(a),h=["<",c,' opacity="',f.get("a"),'"/>'],T(this.prepVML(h),null,null,b),j=f.get("rgb");else{j=b.getElementsByTagName(c);if(j.length)j[0].opacity=1;j=a}return j}, -prepVML:function(a){var b=this.isIE8,a=a.join("");b?(a=a.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),a=a.indexOf('style="')===-1?a.replace("/>",' style="display:inline-block;behavior:url(#default#VML);" />'):a.replace('style="','style="display:inline-block;behavior:url(#default#VML);')):a=a.replace("<","1&&f.attr({x:b,y:c,width:d,height:e});return f},rect:function(a,b,c,d,e,f){if(Y(a))b=a.y,c=a.width,d=a.height,f=a.strokeWidth,a=a.x;var g=this.symbol("rect");g.r=e;return g.attr(g.crisp(f,a,b,s(c,0),s(d,0)))},invertChild:function(a,b){var c=b.style;I(a,{flip:"x", -left:z(c.width)-1,top:z(c.height)-1,rotation:-90})},symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,h=e.r||c||d,c=W(f),d=Z(f),i=W(g),j=Z(g),k=e.innerR,l=0.08/h,m=k&&0.1/k||0;if(g-f===0)return["x"];else 2*Aa-g+fj&&(c=!1)):h+k>m&&(h=m-k,d&&h+l0&&b.height>0){f=B({align:c&&k&&"center",x:c?!k&&4:10,verticalAlign:!c&&k&&"middle",y:c?k?16:10:k?6:-4,rotation:c&&!k&&90},f);if(!g)a.label=g=v.text(f.text,0,0).attr({align:f.textAlign||f.align,rotation:f.rotation,zIndex:o}).css(f.style).add();b=[p[1],p[4],n(p[6],p[1])];p=[p[2],p[5],n(p[7],p[2])];c=Fa(b);k=Fa(p);g.align(f,!1,{x:c,y:k,width:wa(b)-c,height:wa(p)-k});g.show()}else g&&g.hide();return a},destroy:function(){ta(this.axis.plotLinesAndBands, -this);Ga(this,this.axis)}};Kb.prototype={destroy:function(){Ga(this,this.axis)},setTotal:function(a){this.cum=this.total=a},render:function(a){var b=this.options.formatter.call(this);this.label?this.label.attr({text:b,visibility:"hidden"}):this.label=this.axis.chart.renderer.text(b,0,0).css(this.options.style).attr({align:this.textAlign,rotation:this.options.rotation,visibility:"hidden"}).add(a)},setOffset:function(a,b){var c=this.axis,d=c.chart,e=d.inverted,f=this.isNegative,g=c.translate(this.percent? -100:this.total,0,0,0,1),c=c.translate(0),c=M(g-c),h=d.xAxis[0].translate(this.x)+a,i=d.plotHeight,f={x:e?f?g:g-c:h,y:e?i-h-b:f?i-g-c:i-g,width:e?c:b,height:e?b:c};if(e=this.label)e.align(this.alignOptions,null,f),f=e.alignAttr,e.attr({visibility:this.options.crop===!1||d.isInsidePlot(f.x,f.y)?ca?"inherit":"visible":"hidden"})}};ob.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S",minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b",month:"%b '%y",year:"%Y"}, -endOnTick:!1,gridLineColor:"#C0C0C0",labels:G,lineColor:"#C0D0E0",lineWidth:1,minPadding:0.01,maxPadding:0.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:5,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#6D869F",fontWeight:"bold"}},type:"linear"},defaultYAxisOptions:{endOnTick:!0,gridLineWidth:1, -tickPixelInterval:72,showLastLabel:!0,labels:{align:"right",x:-8,y:3},lineWidth:0,maxPadding:0.05,minPadding:0.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Y-values"},stackLabels:{enabled:!1,formatter:function(){return this.total},style:G.style}},defaultLeftAxisOptions:{labels:{align:"right",x:-8,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{align:"left",x:8,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{align:"center",x:0,y:14},title:{rotation:0}},defaultTopAxisOptions:{labels:{align:"center", +(function(){function r(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function ka(){for(var a=0,b=arguments,c=b.length,d={};a-1?b.split(".")[1].length:0):a=isNaN(b=L(b))?2:b;var b=a,c=c===void 0?e.decimalPoint:c,d=d===void 0?e.thousandsSep:d,e=f<0?"-":"",a=String(w(f=L(+f||0).toFixed(b))),g=a.length>3?a.length%3:0;return e+(g?a.substr(0,g)+d:"")+a.substr(g).replace(/(\d{3})(?=\d)/g, +"$1"+d)+(b?c+L(f-a).toFixed(b).slice(2):"")}function sa(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function hb(a,b,c,d){var e,c=o(c,1);e=a/c;b||(b=[1,2,2.5,5,10],d&&d.allowDecimals===!1&&(c===1?b=[1,2,5,10]:c<=0.1&&(b=[1/c])));for(d=0;d=B[ib]&&(i.setMilliseconds(0),i.setSeconds(b>=B[Ua]?0:j*T(i.getSeconds()/j)));if(b>=B[Ua])i[Ab](b>=B[Ja]?0:j*T(i[jb]()/j));if(b>=B[Ja])i[Bb](b>=B[oa]?0:j*T(i[kb]()/ +j));if(b>=B[oa])i[lb](b>=B[Ka]?1:j*T(i[La]()/j));b>=B[Ka]&&(i[Cb](b>=B[ta]?0:j*T(i[Wa]()/j)),h=i[Xa]());b>=B[ta]&&(h-=h%j,i[Db](h));if(b===B[Va])i[lb](i[La]()-i[mb]()+o(d,1));d=1;h=i[Xa]();for(var k=i.getTime(),l=i[Wa](),m=i[La](),i=g?0:(864E5+i.getTimezoneOffset()*6E4)%864E5;kc&&(c=a[b]);return c}function Ea(a,b){for(var c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function Na(a){Za||(Za=Q(ia));a&&Za.appendChild(a);Za.innerHTML=""}function $a(a, +b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw c;else K.console&&console.log(c)}function ea(a){return parseFloat(a.toPrecision(14))}function ua(a,b){Oa=o(a,b.animation)}function Gb(){var a=M.global.useUTC,b=a?"getUTC":"get",c=a?"setUTC":"set";Ya=a?Date.UTC:function(a,b,c,g,h,i){return(new Date(a,b,o(c,1),o(g,0),o(h,0),o(i,0))).getTime()};jb=b+"Minutes";kb=b+"Hours";mb=b+"Day";La=b+"Date";Wa=b+"Month";Xa=b+"FullYear";Ab=c+"Minutes";Bb=c+"Hours";lb=c+"Date";Cb=c+"Month"; +Db=c+"FullYear"}function va(){}function Pa(a,b,c){this.axis=a;this.pos=b;this.type=c||"";this.isNew=!0;c||this.addLabel()}function nb(a,b){this.axis=a;if(b)this.options=b,this.id=b.id;return this}function Hb(a,b,c,d,e,f){var g=a.chart.inverted;this.axis=a;this.isNegative=c;this.options=b;this.x=d;this.stack=e;this.percent=f==="percent";this.alignOptions={align:b.align||(g?c?"left":"right":"center"),verticalAlign:b.verticalAlign||(g?"middle":c?"bottom":"top"),y:o(b.y,g?4:c?14:-6),x:o(b.x,g?c?-6:6: +0)};this.textAlign=b.textAlign||(g?c?"right":"left":"center")}function ob(){this.init.apply(this,arguments)}function pb(a,b){var c=b.borderWidth,d=b.style,e=w(d.padding);this.chart=a;this.options=b;this.crosshairs=[];this.now={x:0,y:0};this.isHidden=!0;this.label=a.renderer.label("",0,0,b.shape,null,null,b.useHTML,null,"tooltip").attr({padding:e,fill:b.backgroundColor,"stroke-width":c,r:b.borderRadius,zIndex:8}).css(d).css({padding:0}).hide().add();U||this.label.shadow(b.shadow);this.shared=b.shared} +function qb(a,b){var c=U?"":b.chart.zoomType;this.zoomX=/x/.test(c);this.zoomY=/y/.test(c);this.options=b;this.chart=a;this.init(a,b.tooltip)}function rb(a){this.init(a)}function sb(a,b){var c,d=a.series;a.series=null;c=A(M,a);c.series=a.series=d;var d=c.chart,e=d.margin,e=X(e)?e:[e,e,e,e];this.optionsMarginTop=o(d.marginTop,e[0]);this.optionsMarginRight=o(d.marginRight,e[1]);this.optionsMarginBottom=o(d.marginBottom,e[2]);this.optionsMarginLeft=o(d.marginLeft,e[3]);this.runChartClick=(e=d.events)&& +!!e.click;this.callback=b;this.isResizing=0;this.options=c;this.axes=[];this.series=[];this.hasCartesianSeries=d.showAxes;this.init(e)}var x,C=document,K=window,J=Math,s=J.round,T=J.floor,wa=J.ceil,y=J.max,O=J.min,L=J.abs,V=J.cos,Y=J.sin,xa=J.PI,ab=xa*2/360,Fa=navigator.userAgent,Ib=K.opera,Ca=/msie/i.test(Fa)&&!Ib,Qa=C.documentMode===8,tb=/AppleWebKit/.test(Fa),bb=/Firefox/.test(Fa),pa="http://www.w3.org/2000/svg",Z=!!C.createElementNS&&!!C.createElementNS(pa,"svg").createSVGRect,Pb=bb&&parseInt(Fa.split("Firefox/")[1], +10)<4,U=!Z&&!Ca&&!!C.createElement("canvas").getContext,Ra,fa=C.documentElement.ontouchstart!==x,Jb={},ub=0,Za,M,cb,Oa,vb,B,ya=function(){},ia="div",R="none",wb="rgba(192,192,192,"+(Z?1.0E-6:0.0020)+")",zb="millisecond",ib="second",Ua="minute",Ja="hour",oa="day",Va="week",Ka="month",ta="year",Ya,jb,kb,mb,La,Wa,Xa,Ab,Bb,lb,Cb,Db,$={};K.Highcharts={};cb=function(a,b,c){if(!t(b)||isNaN(b))return"Invalid date";var a=o(a,"%Y-%m-%d %H:%M:%S"),d=new Date(b),e,f=d[kb](),g=d[mb](),h=d[La](),i=d[Wa](),j=d[Xa](), +k=M.lang,l=k.weekdays,b={a:l[g].substr(0,3),A:l[g],d:sa(h),e:h,b:k.shortMonths[i],B:k.months[i],m:sa(i+1),y:j.toString().substr(2,2),Y:j,H:sa(f),I:sa(f%12||12),l:f%12||12,M:sa(d[jb]()),p:f<12?"AM":"PM",P:f<12?"am":"pm",S:sa(d.getSeconds()),L:sa(s(b%1E3),3)};for(e in b)a=a.replace("%"+e,b[e]);return c?a.substr(0,1).toUpperCase()+a.substr(1):a};Eb.prototype={wrapColor:function(a){if(this.color>=a)this.color=0},wrapSymbol:function(a){if(this.symbol>=a)this.symbol=0}};B=ka(zb,1,ib,1E3,Ua,6E4,Ja,36E5, +oa,864E5,Va,6048E5,Ka,2592E6,ta,31556952E3);vb={init:function(a,b,c){var b=b||"",d=a.shift,e=b.indexOf("C")>-1,f=e?7:3,g,b=b.split(" "),c=[].concat(c),h,i,j=function(a){for(g=a.length;g--;)a[g]==="M"&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};e&&(j(b),j(c));a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6));if(d<=c.length/f)for(;d--;)c=[].concat(c).splice(0,f).concat(c);a.shift=0;if(b.length)for(a=c.length;b.length{point.key}
    ',pointFormat:'{series.name}: {point.y}
    ',shadow:!0,shared:U,snap:fa?25:10,style:{color:"#333333",fontSize:"12px",padding:"5px",whiteSpace:"nowrap"}},credits:{enabled:!0,text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5}, +style:{cursor:"pointer",color:"#909090",fontSize:"10px"}}};var W=M.plotOptions,ga=W.line;Gb();var qa=function(a){var b=[],c;(function(a){(c=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/.exec(a))?b=[w(c[1]),w(c[2]),w(c[3]),parseFloat(c[4],10)]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))&&(b=[w(c[1],16),w(c[2],16),w(c[3],16),1])})(a);return{get:function(c){return b&&!isNaN(b[0])?c==="rgb"?"rgb("+b[0]+","+b[1]+","+b[2]+")":c==="a"? +b[3]:"rgba("+b.join(",")+")":a},brighten:function(a){if(Aa(a)&&a!==0){var c;for(c=0;c<3;c++)b[c]+=w(a*255),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},setOpacity:function(a){b[3]=a;return this}}};va.prototype={init:function(a,b){this.element=b==="span"?Q(b):C.createElementNS(pa,b);this.renderer=a;this.attrSetters={}},animate:function(a,b,c){b=o(b,Oa,!0);eb(this);if(b){b=A(b);if(c)b.complete=c;xb(this,a,b)}else this.attr(a),c&&c()},attr:function(a,b){var c,d,e,f,g=this.element,h=g.nodeName.toLowerCase(), +i=this.renderer,j,k=this.attrSetters,l=this.shadows,m,p,u=this;la(a)&&t(b)&&(c=a,a={},a[c]=b);if(la(a))c=a,h==="circle"?c={x:"cx",y:"cy"}[c]||c:c==="strokeWidth"&&(c="stroke-width"),u=z(g,c)||this[c]||0,c!=="d"&&c!=="visibility"&&(u=parseFloat(u));else for(c in a)if(j=!1,d=a[c],e=k[c]&&k[c].call(this,d,c),e!==!1){e!==x&&(d=e);if(c==="d")d&&d.join&&(d=d.join(" ")),/(NaN| {2}|^$)/.test(d)&&(d="M 0 0");else if(c==="x"&&h==="text"){for(e=0;em&&/[ \-]/.test(b.innerText)&&(H(b,{width:m+"px",display:"block",whiteSpace:"normal"}),k=m);m=a.fontMetrics(b.style.fontSize).b;q=u<0&&-k;D=p<0&&-l;da=u*p<0;q+=p*m*(da?1-h:h);D-=u*m*(j?da?h:1-h:1);i&&(q-=k*h*(u<0?-1:1),j&&(D-=l*h*(p<0?-1:1)),H(b,{textAlign:g}));this.xCorr=q;this.yCorr=D}H(b,{left:e+q+"px",top:f+D+"px"});this.cTT=aa}}else this.alignOnAdd= +!0},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c=this.inverted,d=this.rotation,e=[];c&&(a+=this.attr("width"),b+=this.attr("height"));(a||b)&&e.push("translate("+a+","+b+")");c?e.push("rotate(90) scale(-1,1)"):d&&e.push("rotate("+d+" "+(this.x||0)+" "+(this.y||0)+")");e.length&&z(this.element,"transform",e.join(" "))},toFront:function(){var a=this.element;a.parentNode.appendChild(a);return this},align:function(a,b,c){a?(this.alignOptions=a,this.alignByTranslate=b,c|| +this.renderer.alignedObjects.push(this)):(a=this.alignOptions,b=this.alignByTranslate);var c=o(c,this.renderer),d=a.align,e=a.verticalAlign,f=(c.x||0)+(a.x||0),g=(c.y||0)+(a.y||0),h={};if(d==="right"||d==="center")f+=(c.width-(a.width||0))/{right:1,center:2}[d];h[b?"translateX":"x"]=s(f);if(e==="bottom"||e==="middle")g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1);h[b?"translateY":"y"]=s(g);this[this.placed?"animate":"attr"](h);this.placed=!0;this.alignAttr=h;return this},getBBox:function(){var a= +this.bBox,b=this.renderer,c,d=this.rotation,e=this.element,f=this.styles,g=d*ab;if(!a){if(e.namespaceURI===pa||b.forExport){try{a=e.getBBox?r({},e.getBBox()):{width:e.offsetWidth,height:e.offsetHeight}}catch(h){}if(!a||a.width<0)a={width:0,height:0}}else a=this.htmlGetBBox();if(b.isSVG&&(b=a.width,c=a.height,d))a.width=L(c*Y(g))+L(b*V(g)),a.height=L(c*V(g))+L(b*Y(g));if(Ca&&f&&f.fontSize==="11px"&&c===22.700000762939453)a.height=14;this.bBox=a}return a},show:function(){return this.attr({visibility:"visible"})}, +hide:function(){return this.attr({visibility:"hidden"})},add:function(a){var b=this.renderer,c=a||b,d=c.element||b.box,e=d.childNodes,f=this.element,g=z(f,"zIndex"),h;if(a)this.parentGroup=a;this.parentInverted=a&&a.inverted;this.textStr!==void 0&&b.buildText(this);if(g)c.handleZ=!0,g=w(g);if(c.handleZ)for(c=0;cg||!t(g)&&t(b))){d.insertBefore(f,a);h=!0;break}h||d.appendChild(f);this.added=!0;E(this,"add");return this},safeRemoveChild:function(a){var b= +a.parentNode;b&&b.removeChild(a)},destroy:function(){var a=this,b=a.element||{},c=a.shadows,d,e;b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=null;eb(a);if(a.clipPath)a.clipPath=a.clipPath.destroy();if(a.stops){for(e=0;e/g,'').replace(/<(i|em)>/g,'').replace(/
    /g,"").split(//g),d=b.childNodes,e=/style="([^"]+)"/,f=/href="([^"]+)"/,g=z(b,"x"),h=a.styles,i=h&&h.width&&w(h.width),j=h&&h.lineHeight,k,h=d.length,l=[];h--;)b.removeChild(d[h]);i&&!a.added&&this.box.appendChild(b); +c[c.length-1]===""&&c.pop();n(c,function(c,d){var h,da=0,q,c=c.replace(//g,"|||");h=c.split("|||");n(h,function(c){if(c!==""||h.length===1){var m={},o=C.createElementNS(pa,"tspan"),n;e.test(c)&&(n=c.match(e)[1].replace(/(;| |^)color([ :])/,"$1fill$2"),z(o,"style",n));f.test(c)&&(z(o,"onclick",'location.href="'+c.match(f)[1]+'"'),H(o,{cursor:"pointer"}));c=(c.replace(/<(.|\n)*?>/g,"")||" ").replace(/</g,"<").replace(/>/g,">");o.appendChild(C.createTextNode(c)); +da?m.dx=3:m.x=g;if(!da){if(d){!Z&&a.renderer.forExport&&H(o,{display:"block"});q=K.getComputedStyle&&w(K.getComputedStyle(k,null).getPropertyValue("line-height"));if(!q||isNaN(q)){var F;if(!(F=j))if(!(F=k.offsetHeight))l[d]=b.getBBox?b.getBBox().height:a.renderer.fontMetrics(b.style.fontSize).h,F=s(l[d]-(l[d-1]||0))||18;q=F}z(o,"dy",q)}k=o}z(o,m);b.appendChild(o);da++;if(i)for(var c=c.replace(/([^\^])-/g,"$1- ").split(" "),t=[];c.length||t.length;)delete a.bBox,F=a.getBBox().width,m=F>i,!m||c.length=== +1?(c=t,t=[],c.length&&(o=C.createElementNS(pa,"tspan"),z(o,{dy:j||16,x:g}),n&&z(o,"style",n),b.appendChild(o),F>i&&(i=F))):(o.removeChild(o.firstChild),t.unshift(c.pop())),c.length&&o.appendChild(C.createTextNode(c.join(" ").replace(/- /g,"-")))}})})},button:function(a,b,c,d,e,f,g){var h=this.label(a,b,c),i=0,j,k,l,m,p,a={x1:0,y1:0,x2:0,y2:1},e=A(ka("stroke-width",1,"stroke","#999","fill",ka("linearGradient",a,"stops",[[0,"#FFF"],[1,"#DDD"]]),"r",3,"padding",3,"style",ka("color","black")),e);l=e.style; +delete e.style;f=A(e,ka("stroke","#68A","fill",ka("linearGradient",a,"stops",[[0,"#FFF"],[1,"#ACF"]])),f);m=f.style;delete f.style;g=A(e,ka("stroke","#68A","fill",ka("linearGradient",a,"stops",[[0,"#9BD"],[1,"#CDF"]])),g);p=g.style;delete g.style;I(h.element,"mouseenter",function(){h.attr(f).css(m)});I(h.element,"mouseleave",function(){j=[e,f,g][i];k=[l,m,p][i];h.attr(j).css(k)});h.setState=function(a){(i=a)?a===2&&h.attr(g).css(p):h.attr(e).css(l)};return h.on("click",function(){d.call(h)}).attr(e).css(r({cursor:"default"}, +l))},crispLine:function(a,b){a[1]===a[4]&&(a[1]=a[4]=s(a[1])-b%2/2);a[2]===a[5]&&(a[2]=a[5]=s(a[2])+b%2/2);return a},path:function(a){var b={fill:R};Ha(a)?b.d=a:X(a)&&r(b,a);return this.createElement("path").attr(b)},circle:function(a,b,c){a=X(a)?a:{x:a,y:b,r:c};return this.createElement("circle").attr(a)},arc:function(a,b,c,d,e,f){if(X(a))b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x;return this.symbol("arc",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0})},rect:function(a,b,c,d,e,f){e=X(a)? +a.r:e;e=this.createElement("rect").attr({rx:e,ry:e,fill:R});return e.attr(X(a)?a:e.crisp(f,a,b,y(c,0),y(d,0)))},setSize:function(a,b,c){var d=this.alignedObjects,e=d.length;this.width=a;this.height=b;for(this.boxWrapper[o(c,!0)?"animate":"attr"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement("g");return t(a)?b.attr({"class":"highcharts-"+a}):b},image:function(a,b,c,d,e){var f={preserveAspectRatio:R};arguments.length>1&&r(f,{x:b,y:c,width:d,height:e});f=this.createElement("image").attr(f); +f.element.setAttributeNS?f.element.setAttributeNS("http://www.w3.org/1999/xlink","href",a):f.element.setAttribute("hc-svg-href",a);return f},symbol:function(a,b,c,d,e,f){var g,h=this.symbols[a],h=h&&h(s(b),s(c),d,e,f),i=/^url\((.*?)\)$/,j,k;h?(g=this.path(h),r(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&r(g,f)):i.test(a)&&(k=function(a,b){a.attr({width:b[0],height:b[1]});a.alignByTranslate||a.translate(-s(b[0]/2),-s(b[1]/2))},j=a.match(i)[1],a=Jb[j],g=this.image(j).attr({x:b,y:c}),a?k(g,a):(g.attr({width:0, +height:0}),Q("img",{onload:function(){k(g,Jb[j]=[this.width,this.height])},src:j})));return g},symbols:{circle:function(a,b,c,d){var e=0.166*c;return["M",a+c/2,b,"C",a+c+e,b,a+c+e,b+d,a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return["M",a,b,"L",a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return["M",a+c/2,b,"L",a+c,b+d/2,a+ +c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,e){var f=e.start,c=e.r||c||d,g=e.end-1.0E-6,d=e.innerR,h=e.open,i=V(f),j=Y(f),k=V(g),g=Y(g),e=e.end-f');if(b)c=b===ia||b==="span"||b==="img"?c.join(""):a.prepVML(c),this.element=Q(c);this.renderer=a;this.attrSetters={}},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;a&&a.inverted&&b.invertChild(c,d);d.appendChild(c);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();E(this,"add"); +return this},updateTransform:va.prototype.htmlUpdateTransform,attr:function(a,b){var c,d,e,f=this.element||{},g=f.style,h=f.nodeName,i=this.renderer,j=this.symbolName,k,l=this.shadows,m,p=this.attrSetters,u=this;la(a)&&t(b)&&(c=a,a={},a[c]=b);if(la(a))c=a,u=c==="strokeWidth"||c==="stroke-width"?this.strokeweight:this[c];else for(c in a)if(d=a[c],m=!1,e=p[c]&&p[c].call(this,d,c),e!==!1&&d!==null){e!==x&&(d=e);if(j&&/^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(c))k||(this.symbolAttr(a), +k=!0),m=!0;else if(c==="d"){d=d||[];this.d=d.join(" ");e=d.length;for(m=[];e--;)m[e]=Aa(d[e])?s(d[e]*10)-5:d[e]==="Z"?"x":d[e];d=m.join(" ")||"x";f.path=d;if(l)for(e=l.length;e--;)l[e].path=l[e].cutOff?this.cutOffPath(d,l[e].cutOff):d;m=!0}else if(c==="visibility"){if(l)for(e=l.length;e--;)l[e].style[c]=d;h==="DIV"&&(d=d==="hidden"?"-999em":0,c="top");g[c]=d;m=!0}else if(c==="zIndex")d&&(g[c]=d),m=!0;else if(c==="width"||c==="height")d=y(0,d),this[c]=d,this.updateClipping?(this[c]=d,this.updateClipping()): +g[c]=d,m=!0;else if(c==="x"||c==="y")this[c]=d,g[{x:"left",y:"top"}[c]]=d;else if(c==="class")f.className=d;else if(c==="stroke")d=i.color(d,f,c),c="strokecolor";else if(c==="stroke-width"||c==="strokeWidth")f.stroked=d?!0:!1,c="strokeweight",this[c]=d,Aa(d)&&(d+="px");else if(c==="dashstyle")(f.getElementsByTagName("stroke")[0]||Q(i.prepVML([""]),null,null,f))[c]=d||"solid",this.dashstyle=d,m=!0;else if(c==="fill")h==="SPAN"?g.color=d:(f.filled=d!==R?!0:!1,d=i.color(d,f,c,this),c="fillcolor"); +else if(h==="shape"&&c==="rotation")this[c]=d,f.style.left=-s(Y(d*ab)+1)+"px",f.style.top=s(V(d*ab))+"px";else if(c==="translateX"||c==="translateY"||c==="rotation")this[c]=d,this.updateTransform(),m=!0;else if(c==="text")this.bBox=null,f.innerHTML=d,m=!0;m||(Qa?f[c]=d:z(f,c,d))}return u},clip:function(a){var b=this,c,d=b.element,e=d.parentNode;a?(c=a.members,c.push(b),b.destroyClip=function(){Ba(c,b)},e&&e.className==="highcharts-tracker"&&!Qa&&H(d,{visibility:"hidden"}),a=a.getCSS(b)):(b.destroyClip&& +b.destroyClip(),a={clip:Qa?"inherit":"rect(auto)"});return b.css(a)},css:va.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&Na(a)},destroy:function(){this.destroyClip&&this.destroyClip();return va.prototype.destroy.apply(this)},empty:function(){for(var a=this.element.childNodes,b=a.length,c;b--;)c=a[b],c.parentNode.removeChild(c)},on:function(a,b){this.element["on"+a]=function(){var a=K.event;a.target=a.srcElement;b(a)};return this},cutOffPath:function(a,b){var c,a=a.split(/[ ,]/);c=a.length; +if(c===9||c===11)a[c-4]=a[c-2]=w(a[c-2])-10*b;return a.join(" ")},shadow:function(a,b,c){var d=[],e,f=this.element,g=this.renderer,h,i=f.style,j,k=f.path,l,m,p,u;k&&typeof k.value!=="string"&&(k="x");m=k;if(a){p=o(a.width,3);u=(a.opacity||0.15)/p;for(e=1;e<=3;e++){l=p*2+1-2*e;c&&(m=this.cutOffPath(k.value,l+0.5));j=[''];h=Q(g.prepVML(j),null,{left:w(i.left)+o(a.offsetX,1),top:w(i.top)+ +o(a.offsetY,1)});if(c)h.cutOff=l+1;j=[''];Q(g.prepVML(j),null,null,h);b?b.element.appendChild(h):f.parentNode.insertBefore(h,f);d.push(h)}this.shadows=d}return this}};ja=ca(va,ja);var ha={Element:ja,isIE8:Fa.indexOf("MSIE 8.0")>-1,init:function(a,b,c){var d,e;this.alignedObjects=[];d=this.createElement(ia);e=d.element;e.style.position="relative";a.appendChild(d.element);this.box=e;this.boxWrapper=d;this.setSize(b,c,!1);if(!C.namespaces.hcv)C.namespaces.add("hcv", +"urn:schemas-microsoft-com:vml"),C.createStyleSheet().cssText="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "},isHidden:function(){return!this.box.offsetWidth},clipRect:function(a,b,c,d){var e=this.createElement(),f=X(a);return r(e,{members:[],left:f?a.x:a,top:f?a.y:b,width:f?a.width:c,height:f?a.height:d,getCSS:function(a){var b=a.inverted,c=this.top,d=this.left,e=d+this.width,f=c+this.height,c={clip:"rect("+s(b?d:c)+"px,"+s(b?f:e)+"px,"+ +s(b?e:f)+"px,"+s(b?c:d)+"px)"};!b&&Qa&&a.element.nodeName!=="IMG"&&r(c,{width:e+"px",height:f+"px"});return c},updateClipping:function(){n(e.members,function(a){a.css(e.getCSS(a))})}})},color:function(a,b,c,d){var e=this,f,g=/^rgba/,h,i,j=R;a&&a.linearGradient?i="gradient":a&&a.radialGradient&&(i="pattern");if(i){var k,l,m=a.linearGradient||a.radialGradient,p,u,o,q,D,t="",a=a.stops,s,v=[],F=function(){h=['']; +Q(e.prepVML(h),null,null,b)};p=a[0];s=a[a.length-1];p[0]>0&&a.unshift([0,p[1]]);s[0]<1&&a.push([1,s[1]]);n(a,function(a,b){g.test(a[1])?(f=qa(a[1]),k=f.get("rgb"),l=f.get("a")):(k=a[1],l=1);v.push(a[0]*100+"% "+k);b?(o=l,q=k):(u=l,D=k)});if(c==="fill")if(i==="gradient")c=m.x1||m[0]||0,a=m.y1||m[1]||0,p=m.x2||m[2]||0,m=m.y2||m[3]||0,t='angle="'+(90-J.atan((m-a)/(p-c))*180/xa)+'"',F();else{var j=m.r,r=j*2,P=j*2,y=m.cx,x=m.cy,A=b.radialReference,w,j=function(){A&&(w=d.getBBox(),y+=(A[0]-w.x)/w.width- +0.5,x+=(A[1]-w.y)/w.height-0.5,r*=A[2]/w.width,P*=A[2]/w.height);t='src="'+M.global.VMLRadialGradientURL+'" size="'+r+","+P+'" origin="0.5,0.5" position="'+y+","+x+'" color2="'+D+'" ';F()};d.added?j():I(d,"add",j);j=q}else j=k}else if(g.test(a)&&b.tagName!=="IMG")f=qa(a),h=["<",c,' opacity="',f.get("a"),'"/>'],Q(this.prepVML(h),null,null,b),j=f.get("rgb");else{j=b.getElementsByTagName(c);if(j.length)j[0].opacity=1;j=a}return j},prepVML:function(a){var b=this.isIE8,a=a.join("");b?(a=a.replace("/>", +' xmlns="urn:schemas-microsoft-com:vml" />'),a=a.indexOf('style="')===-1?a.replace("/>",' style="display:inline-block;behavior:url(#default#VML);" />'):a.replace('style="','style="display:inline-block;behavior:url(#default#VML);')):a=a.replace("<","1&&f.attr({x:b,y:c,width:d,height:e});return f},rect:function(a,b,c,d,e,f){if(X(a))b=a.y,c=a.width,d=a.height,f=a.strokeWidth,a=a.x;var g=this.symbol("rect");g.r=e;return g.attr(g.crisp(f,a,b,y(c,0),y(d,0)))},invertChild:function(a,b){var c=b.style;H(a,{flip:"x",left:w(c.width)-1,top:w(c.height)-1,rotation:-90})}, +symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,h=e.r||c||d,c=V(f),d=Y(f),i=V(g),j=Y(g),k=e.innerR,l=0.08/h,m=k&&0.1/k||0;if(g-f===0)return["x"];else 2*xa-g+fj&&(c=!1)):h+k>m&&(h=m-k,d&&h+l0&&b.height>0){f=A({align:c&&k&&"center",x:c?!k&&4:10,verticalAlign:!c&&k&&"middle",y:c?k?16:10:k?6:-4,rotation:c&&!k&&90},f);if(!g)a.label=g=r.text(f.text,0,0).attr({align:f.textAlign||f.align,rotation:f.rotation,zIndex:D}).css(f.style).add();b=[u[1],u[4],o(u[6],u[1])];u=[u[2],u[5],o(u[7],u[2])];c=Ma(b);k=Ma(u);g.align(f,!1,{x:c,y:k,width:Da(b)-c,height:Da(u)-k});g.show()}else g&&g.hide();return a},destroy:function(){Ba(this.axis.plotLinesAndBands,this);Ea(this,this.axis)}}; +Hb.prototype={destroy:function(){Ea(this,this.axis)},setTotal:function(a){this.cum=this.total=a},render:function(a){var b=this.options.formatter.call(this);this.label?this.label.attr({text:b,visibility:"hidden"}):this.label=this.axis.chart.renderer.text(b,0,0).css(this.options.style).attr({align:this.textAlign,rotation:this.options.rotation,visibility:"hidden"}).add(a)},setOffset:function(a,b){var c=this.axis,d=c.chart,e=d.inverted,f=this.isNegative,g=c.translate(this.percent?100:this.total,0,0,0, +1),c=c.translate(0),c=L(g-c),h=d.xAxis[0].translate(this.x)+a,i=d.plotHeight,f={x:e?f?g:g-c:h,y:e?i-h-b:f?i-g-c:i-g,width:e?c:b,height:e?b:c};if(e=this.label)e.align(this.alignOptions,null,f),f=e.alignAttr,e.attr({visibility:this.options.crop===!1||d.isInsidePlot(f.x,f.y)?Z?"inherit":"visible":"hidden"})}};ob.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S",minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b",month:"%b '%y",year:"%Y"},endOnTick:!1,gridLineColor:"#C0C0C0", +labels:G,lineColor:"#C0D0E0",lineWidth:1,minPadding:0.01,maxPadding:0.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:5,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#6D869F",fontWeight:"bold"}},type:"linear"},defaultYAxisOptions:{endOnTick:!0,gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0, +labels:{align:"right",x:-8,y:3},lineWidth:0,maxPadding:0.05,minPadding:0.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Y-values"},stackLabels:{enabled:!1,formatter:function(){return this.total},style:G.style}},defaultLeftAxisOptions:{labels:{align:"right",x:-8,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{align:"left",x:8,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{align:"center",x:0,y:14},title:{rotation:0}},defaultTopAxisOptions:{labels:{align:"center", x:0,y:-5},title:{rotation:0}},init:function(a,b){var c=b.isX;this.horiz=a.inverted?!c:c;this.xOrY=(this.isXAxis=c)?"x":"y";this.opposite=b.opposite;this.side=this.horiz?this.opposite?0:2:this.opposite?1:3;this.setOptions(b);var d=this.options,e=d.type,f=e==="datetime";this.labelFormatter=d.labels.formatter||this.defaultLabelFormatter;this.staggerLines=this.horiz&&d.labels.staggerLines;this.userOptions=b;this.minPixelPadding=0;this.chart=a;this.reversed=d.reversed;this.categories=d.categories;this.isLog= -e==="logarithmic";this.isLinked=r(d.linkedTo);this.isDatetimeAxis=f;this.tickmarkOffset=d.categories&&d.tickmarkPlacement==="between"?0.5:0;this.ticks={};this.minorTicks={};this.plotLinesAndBands=[];this.alternateBands={};this.len=0;this.minRange=this.userMinRange=d.minRange||d.maxZoom;this.range=d.range;this.offset=d.offset||0;this.stacks={};this.min=this.max=null;var g,d=this.options.events;a.axes.push(this);a[c?"xAxis":"yAxis"].push(this);this.series=[];if(a.inverted&&c&&this.reversed===A)this.reversed= -!0;this.removePlotLine=this.removePlotBand=this.removePlotBandOrLine;this.addPlotLine=this.addPlotBand=this.addPlotBandOrLine;for(g in d)J(this,g,d[g]);if(this.isLog)this.val2lin=ka,this.lin2val=aa},setOptions:function(a){this.options=B(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],B(N[this.isXAxis?"xAxis":"yAxis"],a))},defaultLabelFormatter:function(){var a= -this.axis,b=this.value,c=this.dateTimeLabelFormat,d=N.lang.numericSymbols,e=d&&d.length,f,g=a.isLog?b:a.tickInterval;if(a.categories)f=b;else if(c)f=db(c,b);else if(e&&g>=1E3)for(;e--&&f===A;)a=Math.pow(1E3,e+1),g>=a&&d[e]!==null&&(f=Ja(b/a,-1)+d[e]);f===A&&(f=b>=1E3?Ja(b,0):Ja(b,-1));return f},getSeriesExtremes:function(){var a=this,b=a.chart,c=a.stacks,d=[],e=[],f;a.hasVisibleSeries=!1;a.dataMin=a.dataMax=null;o(a.series,function(g){if(g.visible||!b.options.chart.ignoreHiddenSeries){var h=g.options, -i,j,k,l,m,q,p,y,t,o=h.threshold,u,v=[],x=0;a.hasVisibleSeries=!0;if(a.isLog&&o<=0)o=h.threshold=null;if(a.isXAxis){if(h=g.xData,h.length)a.dataMin=O(n(a.dataMin,h[0]),Fa(h)),a.dataMax=s(n(a.dataMax,h[0]),wa(h))}else{var z,E,S,w=g.cropped,B=g.xAxis.getExtremes(),C=!!g.modifyValue;i=h.stacking;a.usePercentage=i==="percent";if(i)m=h.stack,l=g.type+n(m,""),q="-"+l,g.stackKey=l,j=d[l]||[],d[l]=j,k=e[q]||[],e[q]=k;if(a.usePercentage)a.dataMin=0,a.dataMax=99;h=g.processedXData;p=g.processedYData;u=p.length; -for(f=0;f=B.min&&(h[f-1]||y)<=B.max))if(y=t.length)for(;y--;)t[y]!==null&&(v[x++]=t[y]);else v[x++]=t;if(!a.usePercentage&&v.length)a.dataMin=O(n(a.dataMin,v[0]),Fa(v)),a.dataMax=s(n(a.dataMax,v[0]),wa(v));if(r(o))if(a.dataMin>=o)a.dataMin=o,a.ignoreMinPadding= -!0;else if(a.dataMaxe+this.width)l=!0}else if(c=e,h=k-this.right,gf+this.height)l=!0;return l?null:d.renderer.crispLine(["M",c,g,"L",h,i],b||0)},getPlotBandPath:function(a,b){var c=this.getPlotLinePath(b),d=this.getPlotLinePath(a);d&&c?d.push(c[4],c[5],c[1],c[2]):d=null;return d},getLinearTickPositions:function(a, -b,c){for(var d,b=da(U(b/a)*a),c=da(za(c/a)*a),e=[];b<=c;){e.push(b);b=da(b+a);if(b===d)break;d=b}return e},getLogTickPositions:function(a,b,c,d){var e=this.options,f=this.len,g=[];if(!d)this._minorAutoInterval=null;if(a>=0.5)a=u(a),g=this.getLinearTickPositions(a,b,c);else if(a>=0.08)for(var f=U(b),h,i,j,k,l,e=a>0.3?[1,2,4]:a>0.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];fb&&g.push(k),k>c&&(l=!0),k=j}else if(b=aa(b),c=aa(c),a=e[d?"minorTickInterval": -"tickInterval"],a=n(a==="auto"?null:a,this._minorAutoInterval,(c-b)*(e.tickPixelInterval/(d?5:1))/((d?f/this.tickPositions.length:f)||1)),a=hb(a,null,K.pow(10,U(K.log(a)/K.LN10))),g=Ta(this.getLinearTickPositions(a,b,c),ka),!d)this._minorAutoInterval=a/5;if(!d)this.tickInterval=a;return g},getMinorTickPositions:function(){var a=this.options,b=this.tickPositions,c=this.minorTickInterval,d=[],e;if(this.isLog){e=b.length;for(a=1;a=this.minRange,f,g,h,i,j;if(this.isXAxis&&this.minRange===A&&!this.isLog)r(a.min)||r(a.max)?this.minRange=null:(o(this.series,function(a){i=a.xData;for(g=j=a.xIncrement?1:i.length-1;g>0;g--)if(h=i[g]-i[g-1],f===A||h0||!b.ignoreMaxPadding))b.max+=c*j}b.tickInterval=b.min===b.max||b.min===void 0||b.max===void 0?1:h&&!l&&q===b.linkedParent.options.tickPixelInterval?b.linkedParent.tickInterval:n(l,p?1:(b.max-b.min)*q/(b.len||1));g&&!a&&o(b.series,function(a){a.processData(b.min!==b.oldMin||b.max!==b.oldMax)});b.setAxisTranslation(a); -b.beforeSetTickPositions&&b.beforeSetTickPositions();if(b.postProcessTickInterval)b.tickInterval=b.postProcessTickInterval(b.tickInterval);if(!l&&b.tickIntervale&&i.shift(),d.endOnTick?b.max=f:b.max+hb[d]&&this.options.alignTicks!==!1)b[d]=c.length;a.maxTicks=b},adjustTickAmount:function(){var a=this.xOrY,b=this.tickPositions,c=this.chart.maxTicks;if(c&&c[a]&&!this.isDatetimeAxis&&!this.categories&&!this.isLinked&&this.options.alignTicks!==!1){var d=this.tickAmount,e=b.length;this.tickAmount=a=c[a];if(ea||a===null?a=c:b=a.min&&b<=a.max)j[b]||(j[b]=new Qa(a,b)),H&&j[b].isNew&&j[b].render(c,!0),j[b].isActive=!0,j[b].render(c)}),q&&o(g,function(b,c){if(c%2===0&&b1||M(b-f.y)>1))clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){e&&e.move(a,b,c,d)},32)},hide:function(){if(!this.isHidden){var a=this.chart.hoverPoints;this.label.hide();a&&o(a,function(a){a.setState()});this.chart.hoverPoints=null;this.isHidden=!0}},hideCrosshairs:function(){o(this.crosshairs, -function(a){a&&a.hide()})},getAnchor:function(a,b){var c,d=this.chart,e=d.inverted,f=0,g=0,h,a=la(a);c=a[0].tooltipPos;c||(o(a,function(a){h=a.series.yAxis;f+=a.plotX;g+=(a.plotLow?(a.plotLow+a.plotHigh)/2:a.plotY)+(!e&&h?h.top-d.plotTop:0)}),f/=a.length,g/=a.length,c=[e?d.plotWidth-g:f,this.shared&&!e&&a.length>1&&b?b.chartY-d.plotTop:e?d.plotHeight-f:g]);return Ta(c,u)},getPosition:function(a,b,c){var d=this.chart,e=d.plotLeft,f=d.plotTop,g=d.plotWidth,h=d.plotHeight,i=n(this.options.distance,12), -j=c.plotX,c=c.plotY,d=j+e+(d.inverted?i:-a-i),k=c-b+f+15,l;d<7&&(d=e+s(j,0)+i);d+a>e+g&&(d-=d+a-(e+g),k=c-b+f-i,l=!0);k=k&&c<=k+b&&(k=c+f+i));k+b>f+h&&(k=s(f,f+h-b-i));return{x:d,y:k}},refresh:function(a,b){function c(){var a=this.points||la(this),b=a[0].series,c;c=[b.tooltipHeaderFormatter(a[0].key)];o(a,function(a){b=a.series;c.push(b.tooltipFormatter&&b.tooltipFormatter(a)||a.point.tooltipFormatter(b.tooltipOptions.pointFormat))});c.push(f.footerFormat||"");return c.join("")} -var d=this.chart,e=this.label,f=this.options,g,h,i,j={},k,l=[];k=f.formatter||c;var j=d.hoverPoints,m,q=f.crosshairs;i=this.shared;h=this.getAnchor(a,b);g=h[0];h=h[1];i&&(!a.series||!a.series.noSharedTooltip)?(d.hoverPoints=a,j&&o(j,function(a){a.setState()}),o(a,function(a){a.setState("hover");l.push(a.getLabelConfig())}),j={x:a[0].category,y:a[0].y},j.points=l,a=a[0]):j=a.getLabelConfig();k=k.call(j);j=a.series;i=i||!j.isCartesian||j.tooltipOutsidePlot||d.isInsidePlot(g,h);k===!1||!i?this.hide(): -(this.isHidden&&e.show(),e.attr({text:k}),m=f.borderColor||a.color||j.color||"#606060",e.attr({stroke:m}),e=(f.positioner||this.getPosition).call(this,e.width,e.height,{plotX:g,plotY:h}),this.move(u(e.x),u(e.y),g+d.plotLeft,h+d.plotTop),this.isHidden=!1);if(q){q=la(q);for(e=q.length;e--;)if(i=a.series[e?"yAxis":"xAxis"],q[e]&&i)if(i=i.getPlotLinePath(e?n(a.stackY,a.y):a.x,1),this.crosshairs[e])this.crosshairs[e].attr({d:i,visibility:"visible"});else{j={"stroke-width":q[e].width||1,stroke:q[e].color|| -"#C0C0C0",zIndex:q[e].zIndex||2};if(q[e].dashStyle)j.dashstyle=q[e].dashStyle;this.crosshairs[e]=d.renderer.path(i).attr(j).add()}}F(d,"tooltipRefresh",{text:k,x:g+d.plotLeft,y:h+d.plotTop,borderColor:m})}};qb.prototype={normalizeMouseEvent:function(a){var b,c,d,a=a||L.event;if(!a.target)a.target=a.srcElement;a=Pb(a);d=a.touches?a.touches.item(0):a;this.chartPosition=b=Vb(this.chart.container);d.pageX===A?(c=a.x,b=a.y):(c=d.pageX-b.left,b=d.pageY-b.top);return x(a,{chartX:u(c),chartY:u(b)})},getMouseCoordinates:function(a){var b= -{xAxis:[],yAxis:[]},c=this.chart;o(c.axes,function(d){var e=d.isXAxis;b[e?"xAxis":"yAxis"].push({axis:d,value:d.translate(((c.inverted?!e:e)?a.chartX-c.plotLeft:d.top+d.len-a.chartY)-d.minPixelPadding,!0)})});return b},getIndex:function(a){var b=this.chart;return b.inverted?b.plotHeight+b.plotTop-a.chartY:a.chartX-b.plotLeft},onmousemove:function(a){var b=this.chart,c=b.series,d=b.tooltip,e,f=b.hoverPoint,g=b.hoverSeries,h,i,j=b.chartWidth,k=this.getIndex(a);if(d&&this.options.tooltip.shared&&(!g|| -!g.noSharedTooltip)){e=[];h=c.length;for(i=0;ij&&e.splice(h,1);if(e.length&&e[0].plotX!==this.hoverX)d.refresh(e,a),this.hoverX=e[0].plotX}if(g&&g.tracker&&(b=g.tooltipPoints[k])&&b!==f)b.onMouseOver()},resetTracker:function(a){var b=this.chart, -c=b.hoverSeries,d=b.hoverPoint,e=b.tooltip,b=e&&e.shared?b.hoverPoints:d;(a=a&&e&&b)&&la(b)[0].plotX===A&&(a=!1);if(a)e.refresh(b);else{if(d)d.onMouseOut();if(c)c.onMouseOut();e&&(e.hide(),e.hideCrosshairs());this.hoverX=null}},setDOMEvents:function(){function a(){if(b.selectionMarker){var f={xAxis:[],yAxis:[]},g=b.selectionMarker.getBBox(),h=g.x-c.plotLeft,l=g.y-c.plotTop,m;e&&(o(c.axes,function(a){if(a.options.zoomEnabled!==!1){var b=a.isXAxis,d=c.inverted?!b:b,e=a.translate(d?h:c.plotHeight-l- -g.height,!0,0,0,1),d=a.translate((d?h+g.width:c.plotHeight-l)-2*a.minPixelPadding,!0,0,0,1);!isNaN(e)&&!isNaN(d)&&(f[b?"xAxis":"yAxis"].push({axis:a,min:O(e,d),max:s(e,d)}),m=!0)}}),m&&F(c,"selection",f,function(a){c.zoom(a)}));b.selectionMarker=b.selectionMarker.destroy()}if(c)I(d,{cursor:"auto"}),c.cancelClick=e,c.mouseIsDown=e=!1;R(C,"mouseup",a);Ba&&R(C,"touchend",a)}var b=this,c=b.chart,d=c.container,e,f=b.zoomX&&!c.inverted||b.zoomY&&c.inverted,g=b.zoomY&&!c.inverted||b.zoomX&&c.inverted;b.hideTooltipOnMouseMove= -function(a){a=Pb(a);b.chartPosition&&c.hoverSeries&&c.hoverSeries.isCartesian&&!c.isInsidePlot(a.pageX-b.chartPosition.left-c.plotLeft,a.pageY-b.chartPosition.top-c.plotTop)&&b.resetTracker()};b.hideTooltipOnMouseLeave=function(){b.resetTracker();b.chartPosition=null};d.onmousedown=function(d){d=b.normalizeMouseEvent(d);d.type.indexOf("touch")===-1&&d.preventDefault&&d.preventDefault();c.mouseIsDown=!0;c.cancelClick=!1;c.mouseDownX=b.mouseDownX=d.chartX;b.mouseDownY=d.chartY;J(C,"mouseup",a);Ba&& -J(C,"touchend",a)};var h=function(a){if(!a||!(a.touches&&a.touches.length>1)){var a=b.normalizeMouseEvent(a),d=a.type,h=a.chartX,l=a.chartY,m=!c.isInsidePlot(h-c.plotLeft,l-c.plotTop);if(d.indexOf("touch")===-1)a.returnValue=!1;d==="touchstart"&&(w(a.target,"isTracker")?c.runTrackerClick||a.preventDefault():!c.runChartClick&&!m&&a.preventDefault());if(m)hc.plotLeft+c.plotWidth&&(h=c.plotLeft+c.plotWidth),lc.plotTop+c.plotHeight&&(l=c.plotTop+c.plotHeight); -if(c.mouseIsDown&&d!=="touchstart"&&(e=Math.sqrt(Math.pow(b.mouseDownX-h,2)+Math.pow(b.mouseDownY-l,2)),e>10)){d=c.isInsidePlot(b.mouseDownX-c.plotLeft,b.mouseDownY-c.plotTop);if(c.hasCartesianSeries&&(b.zoomX||b.zoomY)&&d&&!b.selectionMarker)b.selectionMarker=c.renderer.rect(c.plotLeft,c.plotTop,f?1:c.plotWidth,g?1:c.plotHeight,0).attr({fill:b.options.chart.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add();if(b.selectionMarker&&f){var q=h-b.mouseDownX;b.selectionMarker.attr({width:M(q), -x:(q>0?0:q)+b.mouseDownX})}b.selectionMarker&&g&&(l-=b.mouseDownY,b.selectionMarker.attr({height:M(l),y:(l>0?0:l)+b.mouseDownY}));d&&!b.selectionMarker&&b.options.chart.panning&&c.pan(h)}if(!m)b.onmousemove(a);return m||!c.hasCartesianSeries}};if(!/Android 4\.0/.test(na))d.onmousemove=h;J(d,"mouseleave",b.hideTooltipOnMouseLeave);Ba||J(C,"mousemove",b.hideTooltipOnMouseMove);d.ontouchstart=function(a){if(b.zoomX||b.zoomY)d.onmousedown(a);h(a)};d.ontouchmove=h;d.ontouchend=function(){e&&b.resetTracker()}; -d.onclick=function(a){var d=c.hoverPoint,e,f,a=b.normalizeMouseEvent(a);a.cancelBubble=!0;if(!c.cancelClick)d&&(w(a.target,"isTracker")||w(a.target.parentNode,"isTracker"))?(e=d.plotX,f=d.plotY,x(d,{pageX:b.chartPosition.left+c.plotLeft+(c.inverted?c.plotWidth-f:e),pageY:b.chartPosition.top+c.plotTop+(c.inverted?c.plotHeight-e:f)}),F(d.series,"click",x(a,{point:d})),d.firePointEvent("click",a)):(x(a,b.getMouseCoordinates(a)),c.isInsidePlot(a.chartX-c.plotLeft,a.chartY-c.plotTop)&&F(c,"click",a))}}, -destroy:function(){var a=this.chart,b=a.container;if(a.trackerGroup)a.trackerGroup=a.trackerGroup.destroy();R(b,"mouseleave",this.hideTooltipOnMouseLeave);R(C,"mousemove",this.hideTooltipOnMouseMove);b.onclick=b.onmousedown=b.onmousemove=b.ontouchstart=b.ontouchend=b.ontouchmove=null;clearInterval(this.tooltipTimeout)},init:function(a,b){if(!a.trackerGroup)a.trackerGroup=a.renderer.g("tracker").attr({zIndex:9}).add();if(b.enabled)a.tooltip=new pb(a,b);this.setDOMEvents()}};rb.prototype={init:function(a){var b= -this,c=b.options=a.options.legend;if(c.enabled){var d=c.itemStyle,e=n(c.padding,8),f=c.itemMarginTop||0;b.baseline=z(d.fontSize)+3+f;b.itemStyle=d;b.itemHiddenStyle=B(d,c.itemHiddenStyle);b.itemMarginTop=f;b.padding=e;b.initialItemX=e;b.initialItemY=e-5;b.maxItemWidth=0;b.chart=a;b.itemHeight=0;b.lastLineHeight=0;b.render();J(b.chart,"endResize",function(){b.positionCheckboxes()})}},colorizeItem:function(a,b){var c=this.options,d=a.legendItem,e=a.legendLine,f=a.legendSymbol,g=this.itemHiddenStyle.color, -c=b?c.itemStyle.color:g,h=b?a.color:g,g=a.options&&a.options.marker,i={stroke:h,fill:h},j;d&&d.css({fill:c});e&&e.attr({stroke:h});if(f){if(g)for(j in g=a.convertAttribs(g),g)d=g[j],d!==A&&(i[j]=d);f.attr(i)}},positionItem:function(a){var b=this.options,c=b.symbolPadding,b=!b.rtl,d=a._legendItemPos,e=d[0],d=d[1],f=a.checkbox;a.legendGroup&&a.legendGroup.translate(b?e:this.legendWidth-e-2*c-4,d);if(f)f.x=e,f.y=d},destroyItem:function(a){var b=a.checkbox;o(["legendItem","legendLine","legendSymbol", -"legendGroup"],function(b){a[b]&&a[b].destroy()});b&&Na(a.checkbox)},destroy:function(){var a=this.group,b=this.box;if(b)this.box=b.destroy();if(a)this.group=a.destroy()},positionCheckboxes:function(a){var b=this.group.alignAttr,c,d=this.clipHeight||this.legendHeight;if(b)c=b.translateY,o(this.allItems,function(e){var f=e.checkbox,g;f&&(g=c+f.y+(a||0)+3,I(f,{left:b.translateX+e.legendItemWidth+f.x-20+"px",top:g+"px",display:g>c-6&&g(m||c.chartWidth-2*k-o))b.itemX=o,b.itemY+=n+b.lastLineHeight+q,b.lastLineHeight=0;b.maxItemWidth=s(b.maxItemWidth,e);b.lastItemY=n+b.itemY+q;b.lastLineHeight=s(g,b.lastLineHeight);a._legendItemPos=[b.itemX,b.itemY];f?b.itemX+=e:(b.itemY+=n+g+q,b.lastLineHeight=g);b.offsetWidth= -m||s(f?b.itemX-o:e,b.offsetWidth)},render:function(){var a=this,b=a.chart,c=b.renderer,d=a.group,e,f,g,h,i=a.box,j=a.options,k=a.padding,l=j.borderWidth,m=j.backgroundColor;a.itemX=a.initialItemX;a.itemY=a.initialItemY;a.offsetWidth=0;a.lastItemY=0;if(!d)a.group=d=c.g("legend").attr({zIndex:7}).add(),a.contentGroup=c.g().attr({zIndex:1}).add(d),a.scrollGroup=c.g().add(a.contentGroup),a.clipRect=c.clipRect(0,0,9999,b.chartHeight),a.contentGroup.clip(a.clipRect);e=[];o(b.series,function(a){var b=a.options; -b.showInLegend&&(e=e.concat(a.legendItems||(b.legendType==="point"?a.data:a)))});Ib(e,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)});j.reversed&&e.reverse();a.allItems=e;a.display=f=!!e.length;o(e,function(b){a.renderItem(b)});g=j.width||a.offsetWidth;h=a.lastItemY+a.lastLineHeight;h=a.handleOverflow(h);if(l||m){g+=k;h+=k;if(i){if(g>0&&h>0)i[i.isNew?"attr":"animate"](i.crisp(null,null,null,g,h)),i.isNew=!1}else a.box=i=c.rect(0,0,g,h,j.borderRadius, -l||0).attr({stroke:j.borderColor,"stroke-width":l||0,fill:m||Q}).add(d).shadow(j.shadow),i.isNew=!0;i[f?"show":"hide"]()}a.legendWidth=g;a.legendHeight=h;o(e,function(b){a.positionItem(b)});f&&d.align(x({width:g,height:h},j),!0,b.spacingBox);b.isResizing||this.positionCheckboxes()},handleOverflow:function(a){var b=this,c=this.chart,d=c.renderer,e=this.options,f=e.y,f=c.spacingBox.height+(e.verticalAlign==="top"?-f:f)-this.padding,g=e.maxHeight,h=this.clipRect,i=e.navigation,j=n(i.animation,!0),k= -i.arrowSize||12,l=this.nav;e.layout==="horizontal"&&(f/=2);g&&(f=O(f,g));if(a>f){this.clipHeight=c=f-20;this.pageCount=za(a/c);this.currentPage=n(this.currentPage,1);this.fullHeight=a;h.attr({height:c});if(!l)this.nav=l=d.g().attr({zIndex:1}).add(this.group),this.up=d.symbol("triangle",0,0,k,k).on("click",function(){b.scroll(-1,j)}).add(l),this.pager=d.text("",15,10).css(i.style).add(l),this.down=d.symbol("triangle-down",0,0,k,k).on("click",function(){b.scroll(1,j)}).add(l);b.scroll(0);a=f}else if(l)h.attr({height:c.chartHeight}), -l.hide(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0;return a},scroll:function(a,b){var c=this.pageCount,d=this.currentPage+a,e=this.clipHeight,f=this.options.navigation,g=f.activeColor,h=f.inactiveColor,f=this.pager,i=this.padding;d>c&&(d=c);if(d>0)b!==A&&xa(b,this.chart),this.nav.attr({translateX:i,translateY:e+7,visibility:"visible"}),this.up.attr({fill:d===1?h:g}).css({cursor:d===1?"default":"pointer"}),f.attr({text:d+"/"+this.pageCount}),this.down.attr({x:18+this.pager.getBBox().width, -fill:d===c?h:g}).css({cursor:d===c?"default":"pointer"}),e=-O(e*(d-1),this.fullHeight-e+i)+1,this.scrollGroup.animate({translateY:e}),f.attr({text:d+"/"+c}),this.currentPage=d,this.positionCheckboxes(e)}};sb.prototype={init:function(a,b){var c,d=a.series;a.series=null;c=B(N,a);c.series=a.series=d;var d=c.chart,e=d.margin,e=Y(e)?e:[e,e,e,e];this.optionsMarginTop=n(d.marginTop,e[0]);this.optionsMarginRight=n(d.marginRight,e[1]);this.optionsMarginBottom=n(d.marginBottom,e[2]);this.optionsMarginLeft= -n(d.marginLeft,e[3]);this.runChartClick=(e=d.events)&&!!e.click;this.callback=b;this.isResizing=0;this.options=c;this.axes=[];this.series=[];this.hasCartesianSeries=d.showAxes;var f;this.index=Ha.length;Ha.push(this);d.reflow!==!1&&J(this,"load",this.initReflow);if(e)for(f in e)J(this,f,e[f]);this.xAxis=[];this.yAxis=[];this.animation=V?!1:n(d.animation,!0);this.pointCount=0;this.counters=new Hb;this.firstRender()},initSeries:function(a){var b=this.options.chart,b=new $[a.type||b.type||b.defaultSeriesType]; -b.init(this,a);return b},addSeries:function(a,b,c){var d,e=this;a&&(xa(c,e),b=n(b,!0),F(e,"addSeries",{options:a},function(){d=e.initSeries(a);e.isDirtyLegend=!0;b&&e.redraw()}));return d},isInsidePlot:function(a,b,c){var d=c?b:a,a=c?a:b;return d>=0&&d<=this.plotWidth&&a>=0&&a<=this.plotHeight},adjustTickAmounts:function(){this.options.chart.alignTicks!==!1&&o(this.axes,function(a){a.adjustTickAmount()});this.maxTicks=null},redraw:function(a){var b=this.axes,c=this.series,d=this.tracker,e=this.legend, -f=this.isDirtyLegend,g,h=this.isDirtyBox,i=c.length,j=i,k=this.renderer,l=k.isHidden(),m=[];xa(a,this);for(l&&this.cloneRenderTo();j--;)if(a=c[j],a.isDirty&&a.options.stacking){g=!0;break}if(g)for(j=i;j--;)if(a=c[j],a.options.stacking)a.isDirty=!0;o(c,function(a){a.isDirty&&a.options.legendType==="point"&&(f=!0)});if(f&&e.options.enabled)e.render(),this.isDirtyLegend=!1;if(this.hasCartesianSeries){if(!this.isResizing)this.maxTicks=null,o(b,function(a){a.setScale()});this.adjustTickAmounts();this.getMargins(); -o(b,function(a){if(a.isDirtyExtremes)a.isDirtyExtremes=!1,m.push(function(){F(a,"afterSetExtremes",a.getExtremes())});if(a.isDirty||h||g)a.redraw(),h=!0})}h&&this.drawChartBox();o(c,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()});d&&d.resetTracker&&d.resetTracker(!0);k.draw();F(this,"redraw");l&&this.cloneRenderTo(!0);o(m,function(a){a.call()})},showLoading:function(a){var b=this.options,c=this.loadingDiv,d=b.loading;if(!c)this.loadingDiv=c=T(ga,{className:"highcharts-loading"}, -x(d.style,{left:this.plotLeft+"px",top:this.plotTop+"px",width:this.plotWidth+"px",height:this.plotHeight+"px",zIndex:10,display:Q}),this.container),this.loadingSpan=T("span",null,d.labelStyle,c);this.loadingSpan.innerHTML=a||b.lang.loading;if(!this.loadingShown)I(c,{opacity:0,display:""}),xb(c,{opacity:d.style.opacity},{duration:d.showDuration||0}),this.loadingShown=!0},hideLoading:function(){var a=this.options,b=this.loadingDiv;b&&xb(b,{opacity:0},{duration:a.loading.hideDuration||100,complete:function(){I(b, -{display:Q})}});this.loadingShown=!1},get:function(a){var b=this.axes,c=this.series,d,e;for(d=0;dO(e.dataMin,e.min)&&c19?this.containerHeight:400))},cloneRenderTo:function(a){var b=this.renderToClone,c=this.container;a?b&&(this.renderTo.appendChild(c),Na(b),delete this.renderToClone):(c&&this.renderTo.removeChild(c),this.renderToClone=b=this.renderTo.cloneNode(0),I(b,{position:"absolute",top:"-9999px",display:"block"}),C.body.appendChild(b),c&&b.appendChild(c))},getContainer:function(){var a,b=this.options.chart,c,d,e;this.renderTo=a=b.renderTo;e="highcharts-"+tb++;if(ja(a))this.renderTo= -a=C.getElementById(a);a||Oa(13,!0);c=z(w(a,"data-highcharts-chart"));!isNaN(c)&&Ha[c]&&Ha[c].destroy();w(a,"data-highcharts-chart",this.index);a.innerHTML="";a.offsetWidth||this.cloneRenderTo();this.getChartSize();c=this.chartWidth;d=this.chartHeight;this.container=a=T(ga,{className:"highcharts-container"+(b.className?" "+b.className:""),id:e},x({position:"relative",overflow:"hidden",width:c+"px",height:d+"px",textAlign:"left",lineHeight:"normal",zIndex:0},b.style),this.renderToClone||a);this.renderer= -b.forExport?new sa(a,c,d,!0):new Sa(a,c,d);V&&this.renderer.create(this,a,c,d)},getMargins:function(){var a=this.options.chart,b=a.spacingTop,c=a.spacingRight,d=a.spacingBottom,a=a.spacingLeft,e,f=this.legend,g=this.optionsMarginTop,h=this.optionsMarginLeft,i=this.optionsMarginRight,j=this.optionsMarginBottom,k=this.chartTitleOptions,l=this.chartSubtitleOptions,m=this.options.legend,q=n(m.margin,10),p=m.x,y=m.y,t=m.align,u=m.verticalAlign;this.resetMargins();e=this.axisOffset;if((this.title||this.subtitle)&& -!r(this.optionsMarginTop))if(l=s(this.title&&!k.floating&&!k.verticalAlign&&k.y||0,this.subtitle&&!l.floating&&!l.verticalAlign&&l.y||0))this.plotTop=s(this.plotTop,l+n(k.margin,15)+b);if(f.display&&!m.floating)if(t==="right"){if(!r(i))this.marginRight=s(this.marginRight,f.legendWidth-p+q+c)}else if(t==="left"){if(!r(h))this.plotLeft=s(this.plotLeft,f.legendWidth+p+q+a)}else if(u==="top"){if(!r(g))this.plotTop=s(this.plotTop,f.legendHeight+y+q+b)}else if(u==="bottom"&&!r(j))this.marginBottom=s(this.marginBottom, -f.legendHeight-y+q+d);this.extraBottomMargin&&(this.marginBottom+=this.extraBottomMargin);this.extraTopMargin&&(this.plotTop+=this.extraTopMargin);this.hasCartesianSeries&&o(this.axes,function(a){a.getOffset()});r(h)||(this.plotLeft+=e[3]);r(g)||(this.plotTop+=e[0]);r(j)||(this.marginBottom+=e[2]);r(i)||(this.marginRight+=e[1]);this.setChartSize()},initReflow:function(){function a(a){var g=c.width||eb(d,"width"),h=c.height||eb(d,"height"),a=a?a.target:L;if(!b.hasUserSize&&g&&h&&(a===L||a===C)){if(g!== -b.containerWidth||h!==b.containerHeight)clearTimeout(e),b.reflowTimeout=e=setTimeout(function(){if(b.container)b.setSize(g,h,!1),b.hasUserSize=null},100);b.containerWidth=g;b.containerHeight=h}}var b=this,c=b.options.chart,d=b.renderTo,e;J(L,"resize",a);J(b,"destroy",function(){R(L,"resize",a)})},setSize:function(a,b,c){var d=this,e,f,g=d.resetZoomButton,h=d.title,i=d.subtitle,j;d.isResizing+=1;j=function(){d&&F(d,"endResize",null,function(){d.isResizing-=1})};xa(c,d);d.oldChartHeight=d.chartHeight; -d.oldChartWidth=d.chartWidth;if(r(a))d.chartWidth=e=s(0,u(a)),d.hasUserSize=!!e;if(r(b))d.chartHeight=f=s(0,u(b));I(d.container,{width:e+"px",height:f+"px"});d.renderer.setSize(e,f,c);d.plotWidth=e-d.plotLeft-d.marginRight;d.plotHeight=f-d.plotTop-d.marginBottom;d.maxTicks=null;o(d.axes,function(a){a.isDirty=!0;a.setScale()});o(d.series,function(a){a.isDirty=!0});d.isDirtyLegend=!0;d.isDirtyBox=!0;d.getMargins();a=d.spacingBox;h&&h.align(null,null,a);i&&i.align(null,null,a);g&&g.align&&g.align(null, -null,d[g.alignTo]);d.redraw(c);d.oldChartHeight=null;F(d,"resize");Pa===!1?j():setTimeout(j,Pa&&Pa.duration||500)},setChartSize:function(){var a=this.inverted,b=this.chartWidth,c=this.chartHeight,d=this.options.chart,e=d.spacingTop,f=d.spacingRight,g=d.spacingBottom,h=d.spacingLeft,i,j,k,l;this.plotLeft=i=u(this.plotLeft);this.plotTop=j=u(this.plotTop);this.plotWidth=k=s(0,u(b-i-this.marginRight));this.plotHeight=l=s(0,u(c-j-this.marginBottom));this.plotSizeX=a?l:k;this.plotSizeY=a?k:l;this.plotBorderWidth= -a=d.plotBorderWidth||0;this.spacingBox={x:h,y:e,width:b-h-f,height:c-e-g};this.plotBox={x:i,y:j,width:k,height:l};this.clipBox={x:a/2,y:a/2,width:this.plotSizeX-a,height:this.plotSizeY-a};o(this.axes,function(a){a.setAxisSize();a.setAxisTranslation()})},resetMargins:function(){var a=this.options.chart,b=a.spacingRight,c=a.spacingBottom,d=a.spacingLeft;this.plotTop=n(this.optionsMarginTop,a.spacingTop);this.marginRight=n(this.optionsMarginRight,b);this.marginBottom=n(this.optionsMarginBottom,c);this.plotLeft= -n(this.optionsMarginLeft,d);this.axisOffset=[0,0,0,0]},drawChartBox:function(){var a=this.options.chart,b=this.renderer,c=this.chartWidth,d=this.chartHeight,e=this.chartBackground,f=this.plotBackground,g=this.plotBorder,h=this.plotBGImage,i=a.borderWidth||0,j=a.backgroundColor,k=a.plotBackgroundColor,l=a.plotBackgroundImage,m=a.plotBorderWidth||0,n,p=this.plotLeft,o=this.plotTop,t=this.plotWidth,r=this.plotHeight,u=this.plotBox,v=this.clipRect,s=this.clipBox;n=i+(a.shadow?8:0);if(i||j)if(e)e.animate(e.crisp(null, -null,null,c-n,d-n));else{e={fill:j||Q};if(i)e.stroke=a.borderColor,e["stroke-width"]=i;this.chartBackground=b.rect(n/2,n/2,c-n,d-n,a.borderRadius,i).attr(e).add().shadow(a.shadow)}if(k)f?f.animate(u):this.plotBackground=b.rect(p,o,t,r,0).attr({fill:k}).add().shadow(a.plotShadow);if(l)h?h.animate(u):this.plotBGImage=b.image(l,p,o,t,r).add();v?v.animate({width:s.width,height:s.height}):this.clipRect=b.clipRect(s);if(m)g?g.animate(g.crisp(null,p,o,t,r)):this.plotBorder=b.rect(p,o,t,r,0,m).attr({stroke:a.plotBorderColor, -"stroke-width":m,zIndex:1}).add();this.isDirtyBox=!1},propFromSeries:function(){var a=this,b=a.options.chart,c,d=a.options.series,e,f;o(["inverted","angular","polar"],function(g){c=$[b.type||b.defaultSeriesType];f=a[g]||b[g]||c&&c.prototype[g];for(e=d&&d.length;!f&&e--;)(c=$[d[e].type])&&c.prototype[g]&&(f=!0);a[g]=f})},render:function(){var a=this,b=a.axes,c=a.renderer,d=a.options,e=d.labels,d=d.credits,f;a.setTitle();a.legend=new rb(a);o(b,function(a){a.setScale()});a.getMargins();a.maxTicks=null; -o(b,function(a){a.setTickPositions(!0);a.setMaxTicks()});a.adjustTickAmounts();a.getMargins();a.drawChartBox();a.hasCartesianSeries&&o(b,function(a){a.render()});if(!a.seriesGroup)a.seriesGroup=c.g("series-group").attr({zIndex:3}).add();o(a.series,function(a){a.translate();a.setTooltipPoints();a.render()});e.items&&o(e.items,function(b){var d=x(e.style,b.style),f=z(d.left)+a.plotLeft,j=z(d.top)+a.plotTop+12;delete d.left;delete d.top;c.text(b.html,f,j).attr({zIndex:2}).css(d).add()});if(d.enabled&& -!a.credits)f=d.href,a.credits=c.text(d.text,0,0).on("click",function(){if(f)location.href=f}).attr({align:d.position.align,zIndex:8}).css(d.style).add().align(d.position);a.hasRendered=!0},destroy:function(){var a=this,b=a.axes,c=a.series,d=a.container,e,f=d&&d.parentNode;F(a,"destroy");Ha[a.index]=A;a.renderTo.removeAttribute("data-highcharts-chart");R(a);for(e=b.length;e--;)b[e]=b[e].destroy();for(e=c.length;e--;)c[e]=c[e].destroy();o("title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,tracker,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer".split(","), -function(b){var c=a[b];c&&c.destroy&&(a[b]=c.destroy())});if(d)d.innerHTML="",R(d),f&&Na(d);for(e in a)delete a[e]},isReadyToRender:function(){var a=this;return!ca&&L==L.top&&C.readyState!=="complete"||V&&!L.canvg?(V?Rb.push(function(){a.firstRender()},a.options.global.canvasToolsURL):C.attachEvent("onreadystatechange",function(){C.detachEvent("onreadystatechange",a.firstRender);C.readyState==="complete"&&a.firstRender()}),!1):!0},firstRender:function(){var a=this,b=a.options,c=a.callback;if(a.isReadyToRender()){a.getContainer(); -F(a,"init");if(Highcharts.RangeSelector&&b.rangeSelector.enabled)a.rangeSelector=new Highcharts.RangeSelector(a);a.resetMargins();a.setChartSize();a.propFromSeries();a.getAxes();o(b.series||[],function(b){a.initSeries(b)});if(Highcharts.Scroller&&(b.navigator.enabled||b.scrollbar.enabled))a.scroller=new Highcharts.Scroller(a);a.tracker=new qb(a,b);a.render();a.renderer.draw();c&&c.apply(a,[a]);o(a.callbacks,function(b){b.apply(a,[a])});a.cloneRenderTo(!0);F(a,"load")}}};sb.prototype.callbacks=[]; -var Ua=function(){};Ua.prototype={init:function(a,b,c){var d=a.chart.counters;this.series=a;this.applyOptions(b,c);this.pointAttr={};if(a.options.colorByPoint)b=a.chart.options.colors,this.color=this.color||b[d.color++],d.wrapColor(b.length);a.chart.pointCount++;return this},applyOptions:function(a,b){var c=this.series,d=typeof a;this.config=a;if(d==="number"||a===null)this.y=a;else if(typeof a[0]==="number")this.x=a[0],this.y=a[1];else if(d==="object"&&typeof a.length!=="number"){x(this,a);this.options= -a;if(a.dataLabels)c._hasPointLabels=!0;if(a.marker)c._hasPointMarkers=!0}else if(typeof a[0]==="string")this.name=a[0],this.y=a[1];if(this.x===A)this.x=b===A?c.autoIncrement():b},destroy:function(){var a=this.series.chart,b=a.hoverPoints,c;a.pointCount--;if(b&&(this.setState(),ta(b,this),!b.length))a.hoverPoints=null;if(this===a.hoverPoint)this.onMouseOut();if(this.graphic||this.dataLabel)R(this),this.destroyElements();this.legendItem&&a.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var a= -"graphic,tracker,dataLabel,dataLabelUpper,group,connector,shadowGroup".split(","),b,c=6;c--;)b=a[c],this[b]&&(this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},select:function(a,b){var c=this,d=c.series.chart,a=n(a,!c.selected);c.firePointEvent(a?"select":"unselect",{accumulate:b},function(){c.selected=a;c.setState(a&&"select");b||o(d.getSelectedPoints(), -function(a){if(a.selected&&a!==c)a.selected=!1,a.setState(""),a.firePointEvent("unselect")})})},onMouseOver:function(){var a=this.series,b=a.chart,c=b.tooltip,d=b.hoverPoint;if(d&&d!==this)d.onMouseOut();this.firePointEvent("mouseOver");c&&(!c.shared||a.noSharedTooltip)&&c.refresh(this);this.setState("hover");b.hoverPoint=this},onMouseOut:function(){var a=this.series.chart,b=a.hoverPoints;if(!b||Ub(this,b)===-1)this.firePointEvent("mouseOut"),this.setState(),a.hoverPoint=null},tooltipFormatter:function(a){var b= -this.series,c=b.tooltipOptions,d=a.match(/\{(series|point)\.[a-zA-Z]+\}/g),e=/[{\.}]/,f,g,h,i,j={y:0,open:0,high:0,low:0,close:0,percentage:1,total:1};c.valuePrefix=c.valuePrefix||c.yPrefix;c.valueDecimals=n(c.valueDecimals,c.yDecimals);c.valueSuffix=c.valueSuffix||c.ySuffix;for(i in d)g=d[i],ja(g)&&g!==a&&(h=(" "+g).split(e),f={point:this,series:b}[h[1]],h=h[2],f===this&&j.hasOwnProperty(h)?(f=j[h]?h:"value",f=(c[f+"Prefix"]||"")+Ja(this[h],n(c[f+"Decimals"],-1))+(c[f+"Suffix"]||"")):f=f[h],a=a.replace(g, -f));return a},update:function(a,b,c){var d=this,e=d.series,f=d.graphic,g,h=e.data,i=h.length,j=e.chart,b=n(b,!0);d.firePointEvent("update",{options:a},function(){d.applyOptions(a);Y(a)&&(e.getAttribs(),f&&f.attr(d.pointAttr[e.state]));for(g=0;ga+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart.options,c=b.plotOptions,d=c[this.type],e=a.data;a.data=null;c=B(d,c.series,a);c.data=a.data=e;this.tooltipOptions=B(b.tooltip,c.tooltip);d.marker===null&&delete c.marker;return c},getColor:function(){var a=this.options, -b=this.chart.options.colors,c=this.chart.counters;this.color=a.color||!a.colorByPoint&&b[c.color++]||"gray";c.wrapColor(b.length)},getSymbol:function(){var a=this.options.marker,b=this.chart,c=b.options.symbols,b=b.counters;this.symbol=a.symbol||c[b.symbol++];if(/^url/.test(this.symbol))a.radius=0;b.wrapSymbol(c.length)},drawLegendSymbol:function(a){var b=this.options,c=b.marker,d=a.options.symbolWidth,e=this.chart.renderer,f=this.legendGroup,a=a.baseline,g;if(b.lineWidth){g={"stroke-width":b.lineWidth}; -if(b.dashStyle)g.dashstyle=b.dashStyle;this.legendLine=e.path(["M",0,a-4,"L",d,a-4]).attr(g).add(f)}if(c&&c.enabled)b=c.radius,this.legendSymbol=e.symbol(this.symbol,d/2-b,a-4-b,2*b,2*b).add(f)},addPoint:function(a,b,c,d){var e=this.options,f=this.data,g=this.graph,h=this.area,i=this.chart,j=this.xData,k=this.yData,l=g&&g.shift||0,m=e.data,q=this.pointClass.prototype;xa(d,i);if(g&&c)g.shift=l+1;if(h){if(c)h.shift=l+1;h.isArea=!0}b=n(b,!0);d={series:this};q.applyOptions.apply(d,[a]);j.push(d.x);k.push(q.toYData? -q.toYData.call(d):d.y);m.push(a);e.legendType==="point"&&this.generatePoints();c&&(f[0]&&f[0].remove?f[0].remove(!1):(f.shift(),j.shift(),k.shift(),m.shift()));this.getAttribs();this.isDirtyData=this.isDirty=!0;b&&i.redraw()},setData:function(a,b){var c=this.points,d=this.options,e=this.initialColor,f=this.chart,g=null,h=this.xAxis,i,j=this.pointClass.prototype;this.xIncrement=null;this.pointRange=h&&h.categories?1:d.pointRange;if(r(e))f.counters.color=e;var e=[],k=[],l=a?a.length:[],m=(i=this.pointArrayMap)&& -i.length;if(l>(d.turboThreshold||1E3)){for(i=0;g===null&&i1&&e[1]k||this.forceCrop))if(a=i.getExtremes(),i=a.min,k=a.max,b[d-1]k)b=[],c=[];else if(b[0]k){for(a=0;a=i){e=s(0,a-1);break}for(;ak){f=a+1;break}b=b.slice(e,f);c=c.slice(e,f);g=!0}for(a=b.length-1;a>0;a--)if(d=b[a]-b[a-1],d>0&&(h===A||d=0&&c<=d;)i[c++]=g}this.tooltipPoints=i}},tooltipHeaderFormatter:function(a){var b=this.tooltipOptions,c=b.xDateFormat,d=this.xAxis,e=d&&d.options.type==="datetime", -f;if(e&&!c)for(f in D)if(D[f]>=d.closestPointRange){c=b.dateTimeLabelFormats[f];break}return b.headerFormat.replace("{point.key}",e&&Da(a)?db(c,a):a).replace("{series.name}",this.name).replace("{series.color}",this.color)},onMouseOver:function(){var a=this.chart,b=a.hoverSeries;if(b&&b!==this)b.onMouseOut();this.options.events.mouseOver&&F(this,"mouseOver");this.setState("hover");a.hoverSeries=this},onMouseOut:function(){var a=this.options,b=this.chart,c=b.tooltip,d=b.hoverPoint;if(d)d.onMouseOut(); -this&&a.events.mouseOut&&F(this,"mouseOut");c&&!a.stickyTracking&&!c.shared&&c.hide();this.setState();b.hoverSeries=null},animate:function(a){var b=this,c=b.chart,d=c.renderer,e;e=b.options.animation;var f=c.clipBox,g=c.inverted,h;if(e&&!Y(e))e=X[b.type].animation;h="_sharedClip"+e.duration+e.easing;if(a)a=c[h],e=c[h+"m"],a||(c[h]=a=d.clipRect(x(f,{width:0})),c[h+"m"]=e=d.clipRect(-99,g?-c.plotLeft:-c.plotTop,99,g?c.chartWidth:c.chartHeight)),b.group.clip(a),b.markerGroup.clip(e),b.sharedClipKey= -h;else{if(a=c[h])a.animate({width:c.plotSizeX},e),c[h+"m"].animate({width:c.plotSizeX+99},e);b.animate=null;b.animationTimeout=setTimeout(function(){b.afterAnimate()},e.duration)}},afterAnimate:function(){var a=this.chart,b=this.sharedClipKey,c=this.group,d=this.trackerGroup;c&&this.options.clip!==!1&&(c.clip(a.clipRect),d&&d.clip(a.clipRect),this.markerGroup.clip());setTimeout(function(){b&&a[b]&&(a[b]=a[b].destroy(),a[b+"m"]=a[b+"m"].destroy())},100)},drawPoints:function(){var a,b=this.points,c= -this.chart,d,e,f,g,h,i,j,k,l=this.options.marker,m,o=this.markerGroup;if(l.enabled||this._hasPointMarkers)for(f=b.length;f--;)if(g=b[f],d=g.plotX,e=g.plotY,k=g.graphic,i=g.marker||{},a=l.enabled&&i.enabled===A||i.enabled,m=c.isInsidePlot(d,e,c.inverted),a&&e!==A&&!isNaN(e))if(a=g.pointAttr[g.selected?"select":""],h=a.r,i=n(i.symbol,this.symbol),j=i.indexOf("url")===0,k)k.attr({visibility:m?ca?"inherit":"visible":"hidden"}).animate(x({x:d-h,y:e-h},k.symbolName?{width:2*h,height:2*h}:{}));else{if(m&& -(h>0||j))g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(o)}else if(k)g.graphic=k.destroy()},convertAttribs:function(a,b,c,d){var e=this.pointAttrToOptions,f,g,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=n(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var a=this,b=X[a.type].marker?a.options.marker:a.options,c=b.states,d=c.hover,e,f=a.color,g={stroke:f,fill:f},h=a.points||[],i=[],j,k=a.pointAttrToOptions,l;a.options.marker?(d.radius=d.radius||b.radius+2,d.lineWidth= -d.lineWidth||b.lineWidth+1):d.color=d.color||qa(d.color||f).brighten(d.brightness).get();i[""]=a.convertAttribs(b,g);o(["hover","select"],function(b){i[b]=a.convertAttribs(c[b],i[""])});a.pointAttr=i;for(f=h.length;f--;){g=h[f];if((b=g.options&&g.options.marker||g.options)&&b.enabled===!1)b.radius=0;e=a.options.colorByPoint;if(g.options)for(l in k)r(b[k[l]])&&(e=!0);if(e){b=b||{};j=[];c=b.states||{};e=c.hover=c.hover||{};if(!a.options.marker)e.color=qa(e.color||g.color).brighten(e.brightness||d.brightness).get(); -j[""]=a.convertAttribs(x({color:g.color},b),i[""]);j.hover=a.convertAttribs(c.hover,i.hover,j[""]);j.select=a.convertAttribs(c.select,i.select,j[""])}else j=i;g.pointAttr=j}},destroy:function(){var a=this,b=a.chart,c=/AppleWebKit\/533/.test(na),d,e,f=a.data||[],g,h,i;F(a,"destroy");R(a);o(["xAxis","yAxis"],function(b){if(i=a[b])ta(i.series,a),i.isDirty=!0});a.legendItem&&a.chart.legend.destroyItem(a);for(e=f.length;e--;)(g=f[e])&&g.destroy&&g.destroy();a.points=null;clearTimeout(a.animationTimeout); -o("area,graph,dataLabelsGroup,group,markerGroup,tracker,trackerGroup".split(","),function(b){a[b]&&(d=c&&b==="group"?"hide":"destroy",a[b][d]())});if(b.hoverSeries===a)b.hoverSeries=null;ta(b.series,a);for(h in a)delete a[h]},drawDataLabels:function(){var a=this,b=a.options.dataLabels,c=a.points,d,e,f,g;if(b.enabled||a._hasPointLabels)a.dlProcessOptions&&a.dlProcessOptions(b),g=a.plotGroup("dataLabelsGroup","data-labels",a.visible?"visible":"hidden",b.zIndex||6),e=b,o(c,function(c){var i,j=c.dataLabel, -k,l=!0;d=c.options&&c.options.dataLabels;i=e.enabled||d&&d.enabled;if(j&&!i)c.dataLabel=j.destroy();else if(i){i=b.rotation;b=B(e,d);f=b.formatter.call(c.getLabelConfig(),b);b.style.color=n(b.color,b.style.color,a.color,"black");if(j)j.attr({text:f}),l=!1;else if(r(f)){j={fill:b.backgroundColor,stroke:b.borderColor,"stroke-width":b.borderWidth,r:b.borderRadius||0,rotation:i,padding:b.padding,zIndex:1};for(k in j)j[k]===A&&delete j[k];j=c.dataLabel=a.chart.renderer[i?"text":"label"](f,0,-999,null, -null,null,b.useHTML).attr(j).css(b.style).add(g).shadow(b.shadow)}j&&a.alignDataLabel(c,j,b,null,l)}})},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=n(a.plotX,-999),a=n(a.plotY,-999),i=b.getBBox(),d=x({x:g?f.plotWidth-a:h,y:u(g?f.plotHeight-h:a),width:0,height:0},d);x(c,{width:i.width,height:i.height});c.rotation?(d={align:c.align,x:d.x+c.x+d.width/2,y:d.y+c.y+d.height/2},b[e?"attr":"animate"](d)):(b.align(c,null,d),d=b.alignAttr);b.attr({visibility:c.crop===!1||f.isInsidePlot(d.x, -d.y)||f.isInsidePlot(h,a,g)?f.renderer.isSVG?"inherit":"visible":"hidden"})},getSegmentPath:function(a){var b=this,c=[],d=b.options.step;o(a,function(e,f){var g=e.plotX,h=e.plotY,i;b.getPointSpline?c.push.apply(c,b.getPointSpline(a,e,f)):(c.push(f?"L":"M"),d&&f&&(i=a[f-1],d==="right"?c.push(i.plotX,h):d==="center"?c.push((i.plotX+g)/2,i.plotY,(i.plotX+g)/2,h):c.push(g,i.plotY)),c.push(e.plotX,e.plotY))});return c},getGraphPath:function(){var a=this,b=[],c,d=[];o(a.segments,function(e){c=a.getSegmentPath(e); -e.length>1?b=b.concat(c):d.push(e[0])});a.singlePoints=d;return a.graphPath=b},drawGraph:function(){var a=this.options,b=this.graph,c=this.group,d=a.lineColor||this.color,e=a.lineWidth,f=a.dashStyle,g=this.getGraphPath();if(b)fb(b),b.animate({d:g});else if(e){b={stroke:d,"stroke-width":e,zIndex:1};if(f)b.dashstyle=f;this.graph=this.chart.renderer.path(g).attr(b).add(c).shadow(a.shadow)}},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};o(["group","trackerGroup","markerGroup"], -function(c){b[c]&&b[c].attr(a).invert()})}var b=this,c=b.chart;J(c,"resize",a);J(b,"destroy",function(){R(c,"resize",a)});a();b.invertGroups=a},plotGroup:function(a,b,c,d,e){var f=this[a],g=this.chart,h=this.xAxis,i=this.yAxis;f||(this[a]=f=g.renderer.g(b).attr({visibility:c,zIndex:d||0.1}).add(e));f.translate(h?h.left:g.plotLeft,i?i.top:g.plotTop);return f},render:function(){var a=this.chart,b,c=this.options,d=c.animation&&!!this.animate,e=this.visible?"visible":"hidden",f=c.zIndex,g=this.hasRendered, -h=a.seriesGroup;b=this.plotGroup("group","series",e,f,h);this.markerGroup=this.plotGroup("markerGroup","markers",e,f,h);d&&this.animate(!0);this.getAttribs();b.inverted=a.inverted;this.drawGraph&&this.drawGraph();this.drawPoints();this.drawDataLabels();this.options.enableMouseTracking!==!1&&this.drawTracker();a.inverted&&this.invertGroups();c.clip!==!1&&!this.sharedClipKey&&!g&&(b.clip(a.clipRect),this.trackerGroup&&this.trackerGroup.clip(a.clipRect));d?this.animate():g||this.afterAnimate();this.isDirty= -this.isDirtyData=!1;this.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirtyData,c=this.group;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:this.xAxis.left,translateY:this.yAxis.top}));this.translate();this.setTooltipPoints(!0);this.render();b&&F(this,"updatedData")},setState:function(a){var b=this.options,c=this.graph,d=b.states,b=b.lineWidth,a=a||"";if(this.state!==a)this.state=a,d[a]&&d[a].enabled===!1||(a&&(b=d[a].lineWidth||b+1),c&&!c.dashstyle&& -c.attr({"stroke-width":b},a?0:500))},setVisible:function(a,b){var c=this.chart,d=this.legendItem,e=this.group,f=this.tracker,g=this.dataLabelsGroup,h=this.markerGroup,i,j=this.points,k=c.options.chart.ignoreHiddenSeries;i=this.visible;i=(this.visible=a=a===A?!i:a)?"show":"hide";if(e)e[i]();if(h)h[i]();if(f)f[i]();else if(j)for(e=j.length;e--;)if(f=j[e],f.tracker)f.tracker[i]();if(c.hoverSeries===this)this.onMouseOut();if(g)g[i]();d&&c.legend.colorizeItem(this,a);this.isDirty=!0;this.options.stacking&& -o(c.series,function(a){if(a.options.stacking&&a.visible)a.isDirty=!0});if(k)c.isDirtyBox=!0;b!==!1&&c.redraw();F(this,i)},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},select:function(a){this.selected=a=a===A?!this.selected:a;if(this.checkbox)this.checkbox.checked=a;F(this,a?"select":"unselect")},drawTracker:function(){var a=this,b=a.options,c=b.trackByArea,d=[].concat(c?a.areaPath:a.graphPath),e=d.length,f=a.chart,g=f.renderer,h=f.options.tooltip.snap,i=a.tracker,j=b.cursor, -j=j&&{cursor:j},k=a.singlePoints,l=this.isCartesian&&this.plotGroup("trackerGroup",null,"visible",b.zIndex||1,f.trackerGroup),m,n=function(){if(f.hoverSeries!==a)a.onMouseOver()},o=function(){if(!b.stickyTracking)a.onMouseOut()};if(e&&!c)for(m=e+1;m--;)d[m]==="M"&&d.splice(m+1,0,d[m+1]-h,d[m+2],"L"),(m&&d[m]==="M"||m===e)&&d.splice(m,0,"L",d[m-2]+h,d[m-1]);for(m=0;m=0;d--)da&&i>e?(i=s(a,e),k=2*e-i):ig&&k>e?(k=s(g,e),i=2*e-k):kw?g-w:z-(f<=z?w:0));c.barX=i;c.pointWidth=u;c.shapeType= -"rect";c.shapeArgs=f=b.renderer.Element.prototype.crisp.call(0,e,i,j,x,k);e%2&&(f.y-=1,f.height+=1);c.trackerArgs=M(k)<3&&B(c.shapeArgs,{height:6,y:j-3})})},getSymbol:pa,drawLegendSymbol:G.prototype.drawLegendSymbol,drawGraph:pa,drawPoints:function(){var a=this,b=a.options,c=a.chart.renderer,d;o(a.points,function(e){var f=e.plotY,g=e.graphic;if(f!==A&&!isNaN(f)&&e.y!==null)d=e.shapeArgs,g?(fb(g),g.animate(B(d))):e.graphic=c[e.shapeType](d).attr(e.pointAttr[e.selected?"select":""]).add(a.group).shadow(b.shadow, -null,b.stacking&&!b.borderRadius);else if(g)e.graphic=g.destroy()})},drawTracker:function(){for(var a=this,b=a.chart,c=b.renderer,d,e,f=+new Date,g=a.options,h=(d=g.cursor)&&{cursor:d},i=a.isCartesian&&a.plotGroup("trackerGroup",null,"visible",g.zIndex||1,b.trackerGroup),j,k,l=a.points,m,n=l.length,o=function(c){j=c.relatedTarget||c.fromElement;if(b.hoverSeries!==a&&w(j,"isTracker")!==f)a.onMouseOver();l[c.target._i].onMouseOver()},r=function(b){if(!g.stickyTracking&&(j=b.relatedTarget||b.toElement, -w(j,"isTracker")!==f))a.onMouseOut()};n--;)if(m=l[n],e=m.tracker,d=m.trackerArgs||m.shapeArgs,k=m.plotY,k=!a.isCartesian||k!==A&&!isNaN(k),delete d.strokeWidth,m.y!==null&&k){if(e)e.attr(d);else if(m.tracker=e=c[m.shapeType](d).attr({isTracker:f,fill:vb,visibility:a.visible?"visible":"hidden"}).on("mouseover",o).on("mouseout",r).css(h).add(m.group||i),Ba)e.on("touchstart",o);e.element._i=n}},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=a.below||a.plotY>n(this.translatedThreshold, -f.plotSizeY),i=this.options.stacking||c.inside;if(a.shapeArgs&&(d=B(a.shapeArgs),g&&(d={x:f.plotWidth-d.y-d.height,y:f.plotHeight-d.x-d.width,width:d.height,height:d.width}),!i))g?(d.x+=h?0:d.width,d.width=0):(d.y+=h?d.height:0,d.height=0);c.align=n(c.align,!g||i?"center":h?"right":"left");c.verticalAlign=n(c.verticalAlign,g||i?"middle":h?"top":"bottom");P.prototype.alignDataLabel.call(this,a,b,c,d,e)},animate:function(a){var b=this,c=b.points,d=b.options;if(!a)o(c,function(a){var c=a.graphic,a=a.shapeArgs, -g=b.yAxis,h=d.threshold;c&&(c.attr({height:0,y:r(h)?g.getThreshold(h):g.translate(g.getExtremes().min,0,1,0,1)}),c.animate({height:a.height,y:a.y},d.animation))}),b.animate=null},remove:function(){var a=this,b=a.chart;b.hasRendered&&o(b.series,function(b){if(b.type===a.type)b.isDirty=!0});P.prototype.remove.apply(a,arguments)}});$.column=fa;X.bar=B(X.column);Ca=ba(fa,{type:"bar",inverted:!0});$.bar=Ca;X.scatter=B(ea,{lineWidth:0,states:{hover:{lineWidth:0}},tooltip:{headerFormat:'{series.name}
    ', -pointFormat:"x: {point.x}
    y: {point.y}
    "}});Ca=ba(P,{type:"scatter",sorted:!1,requireSorting:!1,translate:function(){var a=this;P.prototype.translate.apply(a);o(a.points,function(b){b.shapeType="circle";b.shapeArgs={x:b.plotX,y:b.plotY,r:a.chart.options.tooltip.snap}})},drawTracker:function(){for(var a=this,b=a.options.cursor,b=b&&{cursor:b},c=a.points,d=c.length,e,f=a.markerGroup,g=function(b){a.onMouseOver();if(b.target._i!==A)c[b.target._i].onMouseOver()};d--;)if(e=c[d].graphic)e.element._i= -d;if(a._hasTracking)a._hasTracking=!0;else if(f.attr({isTracker:!0}).on("mouseover",g).on("mouseout",function(){if(!a.options.stickyTracking)a.onMouseOut()}).css(b),Ba)f.on("touchstart",g)},setTooltipPoints:pa});$.scatter=Ca;X.pie=B(ea,{borderColor:"#FFFFFF",borderWidth:1,center:["50%","50%"],colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name}},legendType:"point",marker:null,size:"75%",showInLegend:!1,slicedOffset:10,states:{hover:{brightness:0.1,shadow:!1}}}); -pa={type:"pie",isCartesian:!1,pointClass:ba(Ua,{init:function(){Ua.prototype.init.apply(this,arguments);var a=this,b;x(a,{visible:a.visible!==!1,name:n(a.name,"Slice")});b=function(){a.slice()};J(a,"select",b);J(a,"unselect",b);return a},setVisible:function(a){var b=this.series,c=b.chart,d=this.tracker,e=this.dataLabel,f=this.connector,g=this.shadowGroup,h;h=(this.visible=a=a===A?!this.visible:a)?"show":"hide";this.group[h]();if(d)d[h]();if(e)e[h]();if(f)f[h]();if(g)g[h]();this.legendItem&&c.legend.colorizeItem(this, -a);if(!b.isDirty&&b.options.ignoreHiddenPoint)b.isDirty=!0,c.redraw()},slice:function(a,b,c){var d=this.series.chart,e=this.slicedTranslation;xa(c,d);n(b,!0);a=this.sliced=r(a)?a:!this.sliced;a={translateX:a?e[0]:d.plotLeft,translateY:a?e[1]:d.plotTop};this.group.animate(a);this.shadowGroup&&this.shadowGroup.animate(a)}}),requireSorting:!1,pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},getColor:function(){this.initialColor=this.chart.counters.color},animate:function(){var a= -this,b=a.startAngleRad;o(a.points,function(c){var d=c.graphic,c=c.shapeArgs;d&&(d.attr({r:a.center[3]/2,start:b,end:b}),d.animate({r:c.r,start:c.start,end:c.end},a.options.animation))});a.animate=null},setData:function(a,b){P.prototype.setData.call(this,a,!1);this.processData();this.generatePoints();n(b,!0)&&this.chart.redraw()},getCenter:function(){var a=this.options,b=this.chart,c=b.plotWidth,d=b.plotHeight,a=a.center.concat([a.size,a.innerSize||0]),e=O(c,d),f;return Ta(a,function(a,b){return(f= -/%$/.test(a))?[c,d,e,e][b]*z(a)/100:a})},translate:function(){this.generatePoints();var a=0,b=0,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,f,g=this.chart,h,i,j,k=this.startAngleRad=Aa/180*((c.startAngle||0)%360-90),l=this.points,m=2*Aa,n=c.dataLabels.distance,o=c.ignoreHiddenPoint,r,t=l.length,s;this.center=f=this.getCenter();this.getX=function(a,b){j=K.asin((a-f[1])/(f[2]/2+n));return f[0]+(b?-1:1)*W(j)*(f[2]/2+n)};for(r=0;r0.75*m&&(j-=2*Aa);s.slicedTranslation=Ta([W(j)*d+g.plotLeft,Z(j)*d+g.plotTop],u);h=W(j)*f[2]/2;i=Z(j)*f[2]/2;s.tooltipPos=[f[0]+h*0.7,f[1]+i*0.7];s.half=j0,p=[[],[]],r,t,s,u=2,v,x=function(a,b){return b.y- -a.y},z=function(a,b){a.sort(function(a,c){return(c.angle-a.angle)*b})};if(d.enabled||this._hasPointLabels){P.prototype.drawDataLabels.apply(this);o(a,function(a){a.dataLabel&&p[a.half].push(a)});for(a=p[0][0]&&p[0][0].dataLabel&&(p[0][0].dataLabel.getBBox().height||21);u--;){var w=[],A=[],B=p[u],C=B.length,D;z(B,u-0.5);if(j>0){for(v=m-l-j;v<=m+l+j;v+=a)w.push(v);s=w.length;if(C>s){h=[].concat(B);h.sort(x);for(v=C;v--;)h[v].rank=v;for(v=C;v--;)B[v].rank>=s&&B.splice(v,1);C=B.length}for(v=0;v0){if(t=A.pop(),D=t.i,t=t.y,r>t&&w[D+1]!==null||r=1E3)for(;e--&&f===x;)a=Math.pow(1E3,e+1),g>=a&&d[e]!==null&&(f=Ia(b/a,-1)+d[e]);f===x&&(f=b>=1E3?Ia(b,0):Ia(b,-1));return f},getSeriesExtremes:function(){var a=this,b=a.chart,c=a.stacks,d=[],e=[],f;a.hasVisibleSeries=!1;a.dataMin=a.dataMax=null;n(a.series,function(g){if(g.visible||!b.options.chart.ignoreHiddenSeries){var h=g.options, +i,j,k,l,m,p,u,n,q,D=h.threshold,s,r=[],v=0;a.hasVisibleSeries=!0;if(a.isLog&&D<=0)D=h.threshold=null;if(a.isXAxis){if(h=g.xData,h.length)a.dataMin=O(o(a.dataMin,h[0]),Ma(h)),a.dataMax=y(o(a.dataMax,h[0]),Da(h))}else{var F,w,P,A=g.cropped,z=g.xAxis.getExtremes(),C=!!g.modifyValue;i=h.stacking;a.usePercentage=i==="percent";if(i)m=h.stack,l=g.type+o(m,""),p="-"+l,g.stackKey=l,j=d[l]||[],d[l]=j,k=e[p]||[],e[p]=k;if(a.usePercentage)a.dataMin=0,a.dataMax=99;h=g.processedXData;u=g.processedYData;s=u.length; +for(f=0;f=z.min&&(h[f-1]||n)<=z.max))if(n=q.length)for(;n--;)q[n]!==null&&(r[v++]=q[n]);else r[v++]=q;if(!a.usePercentage&&r.length)a.dataMin=O(o(a.dataMin,r[0]),Ma(r)),a.dataMax=y(o(a.dataMax,r[0]),Da(r));if(t(D))if(a.dataMin>=D)a.dataMin=D,a.ignoreMinPadding=!0;else if(a.dataMax< +D)a.dataMax=D,a.ignoreMaxPadding=!0}}})},translate:function(a,b,c,d,e,f){var g=this.len,h=1,i=0,j=d?this.oldTransA:this.transA,d=d?this.oldMin:this.min,e=this.options.ordinal||this.isLog&&e;if(!j)j=this.transA;c&&(h*=-1,i=g);this.reversed&&(h*=-1,i-=h*g);b?(this.reversed&&(a=g-a),a=a/j+d,e&&(a=this.lin2val(a))):(e&&(a=this.val2lin(a)),a=h*(a-d)*j+i+h*this.minPixelPadding+(f?j*this.pointRange/2:0));return a},getPlotLinePath:function(a,b,c){var d=this.chart,e=this.left,f=this.top,g,h,i,a=this.translate(a, +null,null,c),j=c&&d.oldChartHeight||d.chartHeight,k=c&&d.oldChartWidth||d.chartWidth,l;g=this.transB;c=h=s(a+g);g=i=s(j-a-g);if(isNaN(a))l=!0;else if(this.horiz){if(g=f,i=j-this.bottom,ce+this.width)l=!0}else if(c=e,h=k-this.right,gf+this.height)l=!0;return l?null:d.renderer.crispLine(["M",c,g,"L",h,i],b||0)},getPlotBandPath:function(a,b){var c=this.getPlotLinePath(b),d=this.getPlotLinePath(a);d&&c?d.push(c[4],c[5],c[1],c[2]):d=null;return d},getLinearTickPositions:function(a,b,c){for(var d, +b=ea(T(b/a)*a),c=ea(wa(c/a)*a),e=[];b<=c;){e.push(b);b=ea(b+a);if(b===d)break;d=b}return e},getLogTickPositions:function(a,b,c,d){var e=this.options,f=this.len,g=[];if(!d)this._minorAutoInterval=null;if(a>=0.5)a=s(a),g=this.getLinearTickPositions(a,b,c);else if(a>=0.08)for(var f=T(b),h,i,j,k,l,e=a>0.3?[1,2,4]:a>0.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];fb&&g.push(k),k>c&&(l=!0),k=j}else if(b=ba(b),c=ba(c),a=e[d?"minorTickInterval":"tickInterval"], +a=o(a==="auto"?null:a,this._minorAutoInterval,(c-b)*(e.tickPixelInterval/(d?5:1))/((d?f/this.tickPositions.length:f)||1)),a=hb(a,null,J.pow(10,T(J.log(a)/J.LN10))),g=Sa(this.getLinearTickPositions(a,b,c),ma),!d)this._minorAutoInterval=a/5;if(!d)this.tickInterval=a;return g},getMinorTickPositions:function(){var a=this.tickPositions,b=this.minorTickInterval,c=[],d,e;if(this.isLog){e=a.length;for(d=1;d=this.minRange,f,g,h,i,j;if(this.isXAxis&&this.minRange===x&&!this.isLog)t(a.min)||t(a.max)?this.minRange=null:(n(this.series,function(a){i=a.xData;for(g=j=a.xIncrement?1:i.length-1;g>0;g--)if(h=i[g]-i[g-1],f===x||h0||!b.ignoreMaxPadding))b.max+=c*j}b.tickInterval=b.min===b.max||b.min===void 0||b.max===void 0?1:h&&!l&&p===b.linkedParent.options.tickPixelInterval?b.linkedParent.tickInterval:o(l,u?1:(b.max-b.min)*p/(b.len||1));g&&!a&&n(b.series,function(a){a.processData(b.min!==b.oldMin||b.max!==b.oldMax)});b.setAxisTranslation(a);b.beforeSetTickPositions&&b.beforeSetTickPositions();if(b.postProcessTickInterval)b.tickInterval=b.postProcessTickInterval(b.tickInterval); +if(!l&&b.tickIntervale&&i.shift(),d.endOnTick?b.max=f:b.max+hb[d]&&this.options.alignTicks!==!1)b[d]=c.length;a.maxTicks=b},adjustTickAmount:function(){var a=this.xOrY,b=this.tickPositions,c=this.chart.maxTicks;if(c&&c[a]&&!this.isDatetimeAxis&& +!this.categories&&!this.isLinked&&this.options.alignTicks!==!1){var d=this.tickAmount,e=b.length;this.tickAmount=a=c[a];if(ea||a===null?a=c:b=a.min&&b<=a.max)j[b]||(j[b]=new Pa(a,b)),D&&j[b].isNew&&j[b].render(c,!0),j[b].isActive=!0,j[b].render(c)}),p&&n(g,function(b,c){if(c%2===0&&b1||L(b-f.y)>1))clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){e&&e.move(a,b,c,d)},32)},hide:function(){if(!this.isHidden){var a=this.chart.hoverPoints;this.label.hide();a&&n(a,function(a){a.setState()});this.chart.hoverPoints=null;this.isHidden=!0}},hideCrosshairs:function(){n(this.crosshairs,function(a){a&&a.hide()})},getAnchor:function(a,b){var c,d=this.chart,e=d.inverted,f= +0,g=0,h,a=na(a);c=a[0].tooltipPos;c||(n(a,function(a){h=a.series.yAxis;f+=a.plotX;g+=(a.plotLow?(a.plotLow+a.plotHigh)/2:a.plotY)+(!e&&h?h.top-d.plotTop:0)}),f/=a.length,g/=a.length,c=[e?d.plotWidth-g:f,this.shared&&!e&&a.length>1&&b?b.chartY-d.plotTop:e?d.plotHeight-f:g]);return Sa(c,s)},getPosition:function(a,b,c){var d=this.chart,e=d.plotLeft,f=d.plotTop,g=d.plotWidth,h=d.plotHeight,i=o(this.options.distance,12),j=c.plotX,c=c.plotY,d=j+e+(d.inverted?i:-a-i),k=c-b+f+15,l;d<7&&(d=e+y(j,0)+i);d+a> +e+g&&(d-=d+a-(e+g),k=c-b+f-i,l=!0);k=k&&c<=k+b&&(k=c+f+i));k+b>f+h&&(k=y(f,f+h-b-i));return{x:d,y:k}},refresh:function(a,b){function c(){var a=this.points||na(this),b=a[0].series,c;c=[b.tooltipHeaderFormatter(a[0].key)];n(a,function(a){b=a.series;c.push(b.tooltipFormatter&&b.tooltipFormatter(a)||a.point.tooltipFormatter(b.tooltipOptions.pointFormat))});c.push(f.footerFormat||"");return c.join("")}var d=this.chart,e=this.label,f=this.options,g,h,i,j={},k,l=[];k=f.formatter||c;var j= +d.hoverPoints,m,p=f.crosshairs;i=this.shared;h=this.getAnchor(a,b);g=h[0];h=h[1];i&&(!a.series||!a.series.noSharedTooltip)?(d.hoverPoints=a,j&&n(j,function(a){a.setState()}),n(a,function(a){a.setState("hover");l.push(a.getLabelConfig())}),j={x:a[0].category,y:a[0].y},j.points=l,a=a[0]):j=a.getLabelConfig();k=k.call(j);j=a.series;i=i||!j.isCartesian||j.tooltipOutsidePlot||d.isInsidePlot(g,h);k===!1||!i?this.hide():(this.isHidden&&e.show(),e.attr({text:k}),m=f.borderColor||a.color||j.color||"#606060", +e.attr({stroke:m}),e=(f.positioner||this.getPosition).call(this,e.width,e.height,{plotX:g,plotY:h}),this.move(s(e.x),s(e.y),g+d.plotLeft,h+d.plotTop),this.isHidden=!1);if(p){p=na(p);for(e=p.length;e--;)if(i=a.series[e?"yAxis":"xAxis"],p[e]&&i)if(i=i.getPlotLinePath(e?o(a.stackY,a.y):a.x,1),this.crosshairs[e])this.crosshairs[e].attr({d:i,visibility:"visible"});else{j={"stroke-width":p[e].width||1,stroke:p[e].color||"#C0C0C0",zIndex:p[e].zIndex||2};if(p[e].dashStyle)j.dashstyle=p[e].dashStyle;this.crosshairs[e]= +d.renderer.path(i).attr(j).add()}}E(d,"tooltipRefresh",{text:k,x:g+d.plotLeft,y:h+d.plotTop,borderColor:m})}};qb.prototype={normalizeMouseEvent:function(a){var b,c,d,a=a||K.event;if(!a.target)a.target=a.srcElement;a=Lb(a);d=a.touches?a.touches.item(0):a;this.chartPosition=b=Sb(this.chart.container);d.pageX===x?(c=a.x,b=a.y):(c=d.pageX-b.left,b=d.pageY-b.top);return r(a,{chartX:s(c),chartY:s(b)})},getMouseCoordinates:function(a){var b={xAxis:[],yAxis:[]},c=this.chart;n(c.axes,function(d){var e=d.isXAxis; +b[e?"xAxis":"yAxis"].push({axis:d,value:d.translate(((c.inverted?!e:e)?a.chartX-c.plotLeft:d.top+d.len-a.chartY)-d.minPixelPadding,!0)})});return b},getIndex:function(a){var b=this.chart;return b.inverted?b.plotHeight+b.plotTop-a.chartY:a.chartX-b.plotLeft},onmousemove:function(a){var b=this.chart,c=b.series,d=b.tooltip,e,f=b.hoverPoint,g=b.hoverSeries,h,i,j=b.chartWidth,k=this.getIndex(a);if(d&&this.options.tooltip.shared&&(!g||!g.noSharedTooltip)){e=[];h=c.length;for(i=0;ij&&e.splice(h,1);if(e.length&&e[0].plotX!==this.hoverX)d.refresh(e,a),this.hoverX=e[0].plotX}if(g&&g.tracker&&(b=g.tooltipPoints[k])&&b!==f)b.onMouseOver()},resetTracker:function(a){var b=this.chart,c=b.hoverSeries,d=b.hoverPoint,e=b.tooltip,b=e&&e.shared?b.hoverPoints:d;(a=a&&e&&b)&& +na(b)[0].plotX===x&&(a=!1);if(a)e.refresh(b);else{if(d)d.onMouseOut();if(c)c.onMouseOut();e&&(e.hide(),e.hideCrosshairs());this.hoverX=null}},setDOMEvents:function(){function a(){if(b.selectionMarker){var f={xAxis:[],yAxis:[]},g=b.selectionMarker.getBBox(),h=g.x-c.plotLeft,l=g.y-c.plotTop,m;e&&(n(c.axes,function(a){if(a.options.zoomEnabled!==!1){var b=a.isXAxis,d=c.inverted?!b:b,e=a.translate(d?h:c.plotHeight-l-g.height,!0,0,0,1),d=a.translate((d?h+g.width:c.plotHeight-l)-2*a.minPixelPadding,!0,0, +0,1);!isNaN(e)&&!isNaN(d)&&(f[b?"xAxis":"yAxis"].push({axis:a,min:O(e,d),max:y(e,d)}),m=!0)}}),m&&E(c,"selection",f,function(a){c.zoom(a)}));b.selectionMarker=b.selectionMarker.destroy()}if(c)H(d,{cursor:"auto"}),c.cancelClick=e,c.mouseIsDown=e=!1;S(C,fa?"touchend":"mouseup",a)}var b=this,c=b.chart,d=c.container,e,f=b.zoomX&&!c.inverted||b.zoomY&&c.inverted,g=b.zoomY&&!c.inverted||b.zoomX&&c.inverted;b.hideTooltipOnMouseMove=function(a){a=Lb(a);b.chartPosition&&c.hoverSeries&&c.hoverSeries.isCartesian&& +!c.isInsidePlot(a.pageX-b.chartPosition.left-c.plotLeft,a.pageY-b.chartPosition.top-c.plotTop)&&b.resetTracker()};b.hideTooltipOnMouseLeave=function(){b.resetTracker();b.chartPosition=null};d.onmousedown=function(d){d=b.normalizeMouseEvent(d);!fa&&d.preventDefault&&d.preventDefault();c.mouseIsDown=!0;c.cancelClick=!1;c.mouseDownX=b.mouseDownX=d.chartX;b.mouseDownY=d.chartY;I(C,fa?"touchend":"mouseup",a)};var h=function(a){if(!a||!(a.touches&&a.touches.length>1)){a=b.normalizeMouseEvent(a);if(!fa)a.returnValue= +!1;var d=a.chartX,h=a.chartY,l=!c.isInsidePlot(d-c.plotLeft,h-c.plotTop);fa&&a.type==="touchstart"&&(z(a.target,"isTracker")?c.runTrackerClick||a.preventDefault():!c.runChartClick&&!l&&a.preventDefault());if(l)dc.plotLeft+c.plotWidth&&(d=c.plotLeft+c.plotWidth),hc.plotTop+c.plotHeight&&(h=c.plotTop+c.plotHeight);if(c.mouseIsDown&&a.type!=="touchstart"&&(e=Math.sqrt(Math.pow(b.mouseDownX-d,2)+Math.pow(b.mouseDownY-h,2)),e>10)){var m=c.isInsidePlot(b.mouseDownX- +c.plotLeft,b.mouseDownY-c.plotTop);if(c.hasCartesianSeries&&(b.zoomX||b.zoomY)&&m&&!b.selectionMarker)b.selectionMarker=c.renderer.rect(c.plotLeft,c.plotTop,f?1:c.plotWidth,g?1:c.plotHeight,0).attr({fill:b.options.chart.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add();if(b.selectionMarker&&f){var p=d-b.mouseDownX;b.selectionMarker.attr({width:L(p),x:(p>0?0:p)+b.mouseDownX})}b.selectionMarker&&g&&(h-=b.mouseDownY,b.selectionMarker.attr({height:L(h),y:(h>0?0:h)+b.mouseDownY}));m&&!b.selectionMarker&& +b.options.chart.panning&&c.pan(d)}if(!l)b.onmousemove(a);return l||!c.hasCartesianSeries}};d.onmousemove=h;I(d,"mouseleave",b.hideTooltipOnMouseLeave);I(C,"mousemove",b.hideTooltipOnMouseMove);d.ontouchstart=function(a){if(b.zoomX||b.zoomY)d.onmousedown(a);h(a)};d.ontouchmove=h;d.ontouchend=function(){e&&b.resetTracker()};d.onclick=function(a){var d=c.hoverPoint,e,f,a=b.normalizeMouseEvent(a);a.cancelBubble=!0;if(!c.cancelClick)d&&(z(a.target,"isTracker")||z(a.target.parentNode,"isTracker"))?(e=d.plotX, +f=d.plotY,r(d,{pageX:b.chartPosition.left+c.plotLeft+(c.inverted?c.plotWidth-f:e),pageY:b.chartPosition.top+c.plotTop+(c.inverted?c.plotHeight-e:f)}),E(d.series,"click",r(a,{point:d})),d.firePointEvent("click",a)):(r(a,b.getMouseCoordinates(a)),c.isInsidePlot(a.chartX-c.plotLeft,a.chartY-c.plotTop)&&E(c,"click",a))}},destroy:function(){var a=this.chart,b=a.container;if(a.trackerGroup)a.trackerGroup=a.trackerGroup.destroy();S(b,"mouseleave",this.hideTooltipOnMouseLeave);S(C,"mousemove",this.hideTooltipOnMouseMove); +b.onclick=b.onmousedown=b.onmousemove=b.ontouchstart=b.ontouchend=b.ontouchmove=null;clearInterval(this.tooltipTimeout)},init:function(a,b){if(!a.trackerGroup)a.trackerGroup=a.renderer.g("tracker").attr({zIndex:9}).add();if(b.enabled)a.tooltip=new pb(a,b);this.setDOMEvents()}};rb.prototype={init:function(a){var b=this,c=b.options=a.options.legend;if(c.enabled){var d=c.itemStyle,e=o(c.padding,8),f=c.itemMarginTop||0;b.baseline=w(d.fontSize)+3+f;b.itemStyle=d;b.itemHiddenStyle=A(d,c.itemHiddenStyle); +b.itemMarginTop=f;b.padding=e;b.initialItemX=e;b.initialItemY=e-5;b.maxItemWidth=0;b.chart=a;b.itemHeight=0;b.lastLineHeight=0;b.render();I(b.chart,"endResize",function(){b.positionCheckboxes()})}},colorizeItem:function(a,b){var c=this.options,d=a.legendItem,e=a.legendLine,f=a.legendSymbol,g=this.itemHiddenStyle.color,c=b?c.itemStyle.color:g,h=b?a.color:g,g=a.options&&a.options.marker,i={stroke:h,fill:h},j;d&&d.css({fill:c});e&&e.attr({stroke:h});if(f){if(g)for(j in g=a.convertAttribs(g),g)d=g[j], +d!==x&&(i[j]=d);f.attr(i)}},positionItem:function(a){var b=this.options,c=b.symbolPadding,b=!b.rtl,d=a._legendItemPos,e=d[0],d=d[1],f=a.checkbox;a.legendGroup&&a.legendGroup.translate(b?e:this.legendWidth-e-2*c-4,d);if(f)f.x=e,f.y=d},destroyItem:function(a){var b=a.checkbox;n(["legendItem","legendLine","legendSymbol","legendGroup"],function(b){a[b]&&a[b].destroy()});b&&Na(a.checkbox)},destroy:function(){var a=this.group,b=this.box;if(b)this.box=b.destroy();if(a)this.group=a.destroy()},positionCheckboxes:function(){var a= +this;n(a.allItems,function(b){var c=b.checkbox,d=a.group.alignAttr;c&&H(c,{left:d.translateX+b.legendItemWidth+c.x-20+"px",top:d.translateY+c.y+3+"px"})})},renderItem:function(a){var u;var b=this,c=b.chart,d=c.renderer,e=b.options,f=e.layout==="horizontal",g=e.symbolWidth,h=e.symbolPadding,i=b.itemStyle,j=b.itemHiddenStyle,k=b.padding,l=!e.rtl,m=e.width,p=e.itemMarginBottom||0,o=b.itemMarginTop,n=b.initialItemX,q=a.legendItem,t=a.series||a,r=t.options,s=r.showCheckbox;if(!q&&(a.legendGroup=d.g("legend-item").attr({zIndex:1}).add(b.scrollGroup), +t.drawLegendSymbol(b,a),a.legendItem=q=d.text(e.labelFormatter.call(a),l?g+h:-h,b.baseline,e.useHTML).css(A(a.visible?i:j)).attr({align:l?"left":"right",zIndex:2}).add(a.legendGroup),a.legendGroup.on("mouseover",function(){a.setState("hover");q.css(b.options.itemHoverStyle)}).on("mouseout",function(){q.css(a.visible?i:j);a.setState()}).on("click",function(b){var c=function(){a.setVisible()},b={browserEvent:b};a.firePointEvent?a.firePointEvent("legendItemClick",b,c):E(a,"legendItemClick",b,c)}),b.colorizeItem(a, +a.visible),r&&s))a.checkbox=Q("input",{type:"checkbox",checked:a.selected,defaultChecked:a.selected},e.itemCheckboxStyle,c.container),I(a.checkbox,"click",function(b){E(a,"checkboxClick",{checked:b.target.checked},function(){a.select()})});d=q.getBBox();u=a.legendItemWidth=e.itemWidth||g+h+d.width+k+(s?20:0),e=u;b.itemHeight=g=d.height;if(f&&b.itemX-n+e>(m||c.chartWidth-2*k-n))b.itemX=n,b.itemY+=o+b.lastLineHeight+p,b.lastLineHeight=0;b.maxItemWidth=y(b.maxItemWidth,e);b.lastItemY=o+b.itemY+p;b.lastLineHeight= +y(g,b.lastLineHeight);a._legendItemPos=[b.itemX,b.itemY];f?b.itemX+=e:(b.itemY+=o+g+p,b.lastLineHeight=g);b.offsetWidth=m||y(f?b.itemX-n:e,b.offsetWidth)},render:function(){var a=this,b=a.chart,c=b.renderer,d=a.group,e,f,g,h,i=a.box,j=a.options,k=a.padding,l=j.borderWidth,m=j.backgroundColor;a.itemX=a.initialItemX;a.itemY=a.initialItemY;a.offsetWidth=0;a.lastItemY=0;if(!d)a.group=d=c.g("legend").attr({zIndex:7}).add(),a.contentGroup=c.g().attr({zIndex:1}).add(d),a.scrollGroup=c.g().add(a.contentGroup), +a.clipRect=c.clipRect(0,0,9999,b.chartHeight),a.contentGroup.clip(a.clipRect);e=[];n(b.series,function(a){var b=a.options;b.showInLegend&&(e=e.concat(a.legendItems||(b.legendType==="point"?a.data:a)))});Fb(e,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)});j.reversed&&e.reverse();a.allItems=e;a.display=f=!!e.length;n(e,function(b){a.renderItem(b)});g=j.width||a.offsetWidth;h=a.lastItemY+a.lastLineHeight;h=a.handleOverflow(h);if(l||m){g+=k;h+=k;if(i){if(g> +0&&h>0)i[i.isNew?"attr":"animate"](i.crisp(null,null,null,g,h)),i.isNew=!1}else a.box=i=c.rect(0,0,g,h,j.borderRadius,l||0).attr({stroke:j.borderColor,"stroke-width":l||0,fill:m||R}).add(d).shadow(j.shadow),i.isNew=!0;i[f?"show":"hide"]()}a.legendWidth=g;a.legendHeight=h;n(e,function(b){a.positionItem(b)});f&&d.align(r({width:g,height:h},j),!0,b.spacingBox);b.isResizing||this.positionCheckboxes()},handleOverflow:function(a){var b=this,c=this.chart,d=c.renderer,e=this.options,f=e.y,f=c.spacingBox.height+ +(e.verticalAlign==="top"?-f:f)-this.padding,g=e.maxHeight,h=this.clipRect,i=e.navigation,j=o(i.animation,!0),k=i.arrowSize||12,l=this.nav;e.layout==="horizontal"&&(f/=2);g&&(f=O(f,g));if(a>f){this.clipHeight=c=f-20;this.pageCount=wa(a/c);this.currentPage=o(this.currentPage,1);this.fullHeight=a;h.attr({height:c});if(!l)this.nav=l=d.g().attr({zIndex:1}).add(this.group),this.up=d.symbol("triangle",0,0,k,k).on("click",function(){b.scroll(-1,j)}).add(l),this.pager=d.text("",15,10).css(i.style).add(l), +this.down=d.symbol("triangle-down",0,0,k,k).on("click",function(){b.scroll(1,j)}).add(l);b.scroll(0);a=f}else l&&(h.attr({height:c.chartHeight}),l.hide(),this.scrollGroup.attr({translateY:1}));return a},scroll:function(a,b){var c=this.pageCount,d=this.currentPage+a,e=this.clipHeight,f=this.options.navigation,g=f.activeColor,f=f.inactiveColor,h=this.pager,i=this.padding;d>c&&(d=c);if(d>0)b!==x&&ua(b,this.chart),this.nav.attr({translateX:i,translateY:e+7,visibility:"visible"}),this.up.attr({fill:d=== +1?f:g}).css({cursor:d===1?"default":"pointer"}),h.attr({text:d+"/"+this.pageCount}),this.down.attr({x:18+this.pager.getBBox().width,fill:d===c?f:g}).css({cursor:d===c?"default":"pointer"}),this.scrollGroup.animate({translateY:-O(e*(d-1),this.fullHeight-e+i)+1}),h.attr({text:d+"/"+c}),this.currentPage=d}};sb.prototype={initSeries:function(a){var b=this.options.chart,b=new $[a.type||b.type||b.defaultSeriesType];b.init(this,a);return b},addSeries:function(a,b,c){var d,e=this;a&&(ua(c,e),b=o(b,!0),E(e, +"addSeries",{options:a},function(){d=e.initSeries(a);e.isDirtyLegend=!0;b&&e.redraw()}));return d},isInsidePlot:function(a,b,c){var d=c?b:a,a=c?a:b;return d>=0&&d<=this.plotWidth&&a>=0&&a<=this.plotHeight},adjustTickAmounts:function(){this.options.chart.alignTicks!==!1&&n(this.axes,function(a){a.adjustTickAmount()});this.maxTicks=null},redraw:function(a){var b=this.axes,c=this.series,d=this.tracker,e=this.legend,f=this.isDirtyLegend,g,h=this.isDirtyBox,i=c.length,j=i,k=this.renderer,l=k.isHidden(), +m=[];ua(a,this);for(l&&this.cloneRenderTo();j--;)if(a=c[j],a.isDirty&&a.options.stacking){g=!0;break}if(g)for(j=i;j--;)if(a=c[j],a.options.stacking)a.isDirty=!0;n(c,function(a){a.isDirty&&a.options.legendType==="point"&&(f=!0)});if(f&&e.options.enabled)e.render(),this.isDirtyLegend=!1;if(this.hasCartesianSeries){if(!this.isResizing)this.maxTicks=null,n(b,function(a){a.setScale()});this.adjustTickAmounts();this.getMargins();n(b,function(a){if(a.isDirtyExtremes)a.isDirtyExtremes=!1,m.push(function(){E(a, +"afterSetExtremes",a.getExtremes())});if(a.isDirty||h||g)a.redraw(),h=!0})}h&&this.drawChartBox();n(c,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()});d&&d.resetTracker&&d.resetTracker(!0);k.draw();E(this,"redraw");l&&this.cloneRenderTo(!0);n(m,function(a){a.call()})},showLoading:function(a){var b=this.options,c=this.loadingDiv,d=b.loading;if(!c)this.loadingDiv=c=Q(ia,{className:"highcharts-loading"},r(d.style,{left:this.plotLeft+"px",top:this.plotTop+"px",width:this.plotWidth+ +"px",height:this.plotHeight+"px",zIndex:10,display:R}),this.container),this.loadingSpan=Q("span",null,d.labelStyle,c);this.loadingSpan.innerHTML=a||b.lang.loading;if(!this.loadingShown)H(c,{opacity:0,display:""}),xb(c,{opacity:d.style.opacity},{duration:d.showDuration||0}),this.loadingShown=!0},hideLoading:function(){var a=this.options,b=this.loadingDiv;b&&xb(b,{opacity:0},{duration:a.loading.hideDuration||100,complete:function(){H(b,{display:R})}});this.loadingShown=!1},get:function(a){var b=this.axes, +c=this.series,d,e;for(d=0;dO(e.dataMin,e.min)&&c19?this.containerHeight: +400)},cloneRenderTo:function(a){var b=this.renderToClone,c=this.container;a?b&&(this.renderTo.appendChild(c),Na(b),delete this.renderToClone):(c&&this.renderTo.removeChild(c),this.renderToClone=b=this.renderTo.cloneNode(0),H(b,{position:"absolute",top:"-9999px",display:"block"}),C.body.appendChild(b),c&&b.appendChild(c))},getContainer:function(){var a,b=this.options.chart,c,d,e;this.renderTo=a=b.renderTo;e="highcharts-"+ub++;if(la(a))this.renderTo=a=C.getElementById(a);a||$a(13,!0);a.innerHTML=""; +a.offsetWidth||this.cloneRenderTo();this.getChartSize();c=this.chartWidth;d=this.chartHeight;this.container=a=Q(ia,{className:"highcharts-container"+(b.className?" "+b.className:""),id:e},r({position:"relative",overflow:"hidden",width:c+"px",height:d+"px",textAlign:"left",lineHeight:"normal",zIndex:0},b.style),this.renderToClone||a);this.renderer=b.forExport?new ra(a,c,d,!0):new Ra(a,c,d);U&&this.renderer.create(this,a,c,d)},getMargins:function(){var a=this.options.chart,b=a.spacingTop,c=a.spacingRight, +d=a.spacingBottom,a=a.spacingLeft,e,f=this.legend,g=this.optionsMarginTop,h=this.optionsMarginLeft,i=this.optionsMarginRight,j=this.optionsMarginBottom,k=this.chartTitleOptions,l=this.chartSubtitleOptions,m=this.options.legend,p=o(m.margin,10),u=m.x,r=m.y,q=m.align,s=m.verticalAlign;this.resetMargins();e=this.axisOffset;if((this.title||this.subtitle)&&!t(this.optionsMarginTop))if(l=y(this.title&&!k.floating&&!k.verticalAlign&&k.y||0,this.subtitle&&!l.floating&&!l.verticalAlign&&l.y||0))this.plotTop= +y(this.plotTop,l+o(k.margin,15)+b);if(f.display&&!m.floating)if(q==="right"){if(!t(i))this.marginRight=y(this.marginRight,f.legendWidth-u+p+c)}else if(q==="left"){if(!t(h))this.plotLeft=y(this.plotLeft,f.legendWidth+u+p+a)}else if(s==="top"){if(!t(g))this.plotTop=y(this.plotTop,f.legendHeight+r+p+b)}else if(s==="bottom"&&!t(j))this.marginBottom=y(this.marginBottom,f.legendHeight-r+p+d);this.extraBottomMargin&&(this.marginBottom+=this.extraBottomMargin);this.extraTopMargin&&(this.plotTop+=this.extraTopMargin); +this.hasCartesianSeries&&n(this.axes,function(a){a.getOffset()});t(h)||(this.plotLeft+=e[3]);t(g)||(this.plotTop+=e[0]);t(j)||(this.marginBottom+=e[2]);t(i)||(this.marginRight+=e[1]);this.setChartSize()},initReflow:function(){function a(a){var g=c.width||db(d,"width"),h=c.height||db(d,"height"),a=a?a.target:K;if(g&&h&&(a===K||a===C)){if(g!==b.containerWidth||h!==b.containerHeight)clearTimeout(e),b.reflowTimeout=e=setTimeout(function(){b.container&&b.resize(g,h,!1)},100);b.containerWidth=g;b.containerHeight= +h}}var b=this,c=b.options.chart,d=b.renderTo,e;I(K,"resize",a);I(b,"destroy",function(){S(K,"resize",a)})},resize:function(a,b,c){var d=this,e,f,g=d.resetZoomButton,h=d.title,i=d.subtitle,j;d.isResizing+=1;j=function(){d&&E(d,"endResize",null,function(){d.isResizing-=1})};ua(c,d);d.oldChartHeight=d.chartHeight;d.oldChartWidth=d.chartWidth;if(t(a))d.chartWidth=e=s(a);if(t(b))d.chartHeight=f=s(b);H(d.container,{width:e+"px",height:f+"px"});d.renderer.setSize(e,f,c);d.plotWidth=e-d.plotLeft-d.marginRight; +d.plotHeight=f-d.plotTop-d.marginBottom;d.maxTicks=null;n(d.axes,function(a){a.isDirty=!0;a.setScale()});n(d.series,function(a){a.isDirty=!0});d.isDirtyLegend=!0;d.isDirtyBox=!0;d.getMargins();a=d.spacingBox;h&&h.align(null,null,a);i&&i.align(null,null,a);g&&g.align&&g.align(null,null,d[g.alignTo]);d.redraw(c);d.oldChartHeight=null;E(d,"resize");Oa===!1?j():setTimeout(j,Oa&&Oa.duration||500)},setChartSize:function(){var a=this.inverted,b=this.chartWidth,c=this.chartHeight,d=this.options.chart,e=d.spacingTop, +f=d.spacingRight,g=d.spacingBottom,h=d.spacingLeft,i,j,k,l;this.plotLeft=i=s(this.plotLeft);this.plotTop=j=s(this.plotTop);this.plotWidth=k=s(b-i-this.marginRight);this.plotHeight=l=s(c-j-this.marginBottom);this.plotSizeX=a?l:k;this.plotSizeY=a?k:l;this.plotBorderWidth=a=d.plotBorderWidth||0;this.spacingBox={x:h,y:e,width:b-h-f,height:c-e-g};this.plotBox={x:i,y:j,width:k,height:l};this.clipBox={x:a/2,y:a/2,width:this.plotSizeX-a,height:this.plotSizeY-a};n(this.axes,function(a){a.setAxisSize();a.setAxisTranslation()})}, +resetMargins:function(){var a=this.options.chart,b=a.spacingRight,c=a.spacingBottom,d=a.spacingLeft;this.plotTop=o(this.optionsMarginTop,a.spacingTop);this.marginRight=o(this.optionsMarginRight,b);this.marginBottom=o(this.optionsMarginBottom,c);this.plotLeft=o(this.optionsMarginLeft,d);this.axisOffset=[0,0,0,0]},drawChartBox:function(){var a=this.options.chart,b=this.renderer,c=this.chartWidth,d=this.chartHeight,e=this.chartBackground,f=this.plotBackground,g=this.plotBorder,h=this.plotBGImage,i=a.borderWidth|| +0,j=a.backgroundColor,k=a.plotBackgroundColor,l=a.plotBackgroundImage,m=a.plotBorderWidth||0,p,o=this.plotLeft,n=this.plotTop,q=this.plotWidth,r=this.plotHeight,t=this.plotBox,s=this.clipRect,v=this.clipBox;p=i+(a.shadow?8:0);if(i||j)if(e)e.animate(e.crisp(null,null,null,c-p,d-p));else{e={fill:j||R};if(i)e.stroke=a.borderColor,e["stroke-width"]=i;this.chartBackground=b.rect(p/2,p/2,c-p,d-p,a.borderRadius,i).attr(e).add().shadow(a.shadow)}if(k)f?f.animate(t):this.plotBackground=b.rect(o,n,q,r,0).attr({fill:k}).add().shadow(a.plotShadow); +if(l)h?h.animate(t):this.plotBGImage=b.image(l,o,n,q,r).add();s?s.animate({width:v.width,height:v.height}):this.clipRect=b.clipRect(v);if(m)g?g.animate(g.crisp(null,o,n,q,r)):this.plotBorder=b.rect(o,n,q,r,0,m).attr({stroke:a.plotBorderColor,"stroke-width":m,zIndex:1}).add();this.isDirtyBox=!1},propFromSeries:function(){var a=this,b=a.options.chart,c,d=a.options.series,e,f;n(["inverted","angular","polar"],function(g){c=$[b.type||b.defaultSeriesType];f=a[g]||b[g]||c&&c.prototype[g];for(e=d&&d.length;!f&& +e--;)(c=$[d[e].type])&&c.prototype[g]&&(f=!0);a[g]=f})},render:function(){var a=this,b=a.axes,c=a.renderer,d=a.options,e=d.labels,d=d.credits,f;a.setTitle();a.legend=new rb(a);n(b,function(a){a.setScale()});a.getMargins();a.maxTicks=null;n(b,function(a){a.setTickPositions(!0);a.setMaxTicks()});a.adjustTickAmounts();a.getMargins();a.drawChartBox();a.hasCartesianSeries&&n(b,function(a){a.render()});if(!a.seriesGroup)a.seriesGroup=c.g("series-group").attr({zIndex:3}).add();n(a.series,function(a){a.translate(); +a.setTooltipPoints();a.render()});e.items&&n(e.items,function(b){var d=r(e.style,b.style),f=w(d.left)+a.plotLeft,j=w(d.top)+a.plotTop+12;delete d.left;delete d.top;c.text(b.html,f,j).attr({zIndex:2}).css(d).add()});if(d.enabled&&!a.credits)f=d.href,a.credits=c.text(d.text,0,0).on("click",function(){if(f)location.href=f}).attr({align:d.position.align,zIndex:8}).css(d.style).add().align(d.position);a.hasRendered=!0},destroy:function(){var a=this,b=a.axes,c=a.series,d=a.container,e,f=d&&d.parentNode; +E(a,"destroy");S(a);for(e=b.length;e--;)b[e]=b[e].destroy();for(e=c.length;e--;)c[e]=c[e].destroy();n("title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,tracker,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer".split(","),function(b){var c=a[b];c&&c.destroy&&(a[b]=c.destroy())});if(d)d.innerHTML="",S(d),f&&Na(d);for(e in a)delete a[e]},firstRender:function(){var a=this,b=a.options,c=a.callback;if(!Z&&K==K.top&&C.readyState!=="complete"|| +U&&!K.canvg)U?Mb.push(function(){a.firstRender()},b.global.canvasToolsURL):C.attachEvent("onreadystatechange",function(){C.detachEvent("onreadystatechange",a.firstRender);C.readyState==="complete"&&a.firstRender()});else{a.getContainer();E(a,"init");if(Highcharts.RangeSelector&&b.rangeSelector.enabled)a.rangeSelector=new Highcharts.RangeSelector(a);a.resetMargins();a.setChartSize();a.propFromSeries();a.getAxes();n(b.series||[],function(b){a.initSeries(b)});if(Highcharts.Scroller&&(b.navigator.enabled|| +b.scrollbar.enabled))a.scroller=new Highcharts.Scroller(a);a.tracker=new qb(a,b);a.render();a.renderer.draw();c&&c.apply(a,[a]);n(a.callbacks,function(b){b.apply(a,[a])});a.cloneRenderTo(!0);E(a,"load")}},init:function(a){var b=this.options.chart,c;b.reflow!==!1&&I(this,"load",this.initReflow);if(a)for(c in a)I(this,c,a[c]);this.xAxis=[];this.yAxis=[];this.animation=U?!1:o(b.animation,!0);this.setSize=this.resize;this.pointCount=0;this.counters=new Eb;this.firstRender()}};sb.prototype.callbacks=[]; +var Ta=function(){};Ta.prototype={init:function(a,b,c){var d=a.chart.counters;this.series=a;this.applyOptions(b,c);this.pointAttr={};if(a.options.colorByPoint)b=a.chart.options.colors,this.color=this.color||b[d.color++],d.wrapColor(b.length);a.chart.pointCount++;return this},applyOptions:function(a,b){var c=this.series,d=typeof a;this.config=a;if(d==="number"||a===null)this.y=a;else if(typeof a[0]==="number")this.x=a[0],this.y=a[1];else if(d==="object"&&typeof a.length!=="number"){r(this,a);this.options= +a;if(a.dataLabels)c._hasPointLabels=!0;if(a.marker)c._hasPointMarkers=!0}else if(typeof a[0]==="string")this.name=a[0],this.y=a[1];if(this.x===x)this.x=b===x?c.autoIncrement():b},destroy:function(){var a=this.series.chart,b=a.hoverPoints,c;a.pointCount--;if(b&&(this.setState(),Ba(b,this),!b.length))a.hoverPoints=null;if(this===a.hoverPoint)this.onMouseOut();if(this.graphic||this.dataLabel)S(this),this.destroyElements();this.legendItem&&a.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var a= +"graphic,tracker,dataLabel,group,connector,shadowGroup".split(","),b,c=6;c--;)b=a[c],this[b]&&(this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},select:function(a,b){var c=this,d=c.series.chart,a=o(a,!c.selected);c.firePointEvent(a?"select":"unselect",{accumulate:b},function(){c.selected=a;c.setState(a&&"select");b||n(d.getSelectedPoints(),function(a){if(a.selected&& +a!==c)a.selected=!1,a.setState(""),a.firePointEvent("unselect")})})},onMouseOver:function(){var a=this.series,b=a.chart,c=b.tooltip,d=b.hoverPoint;if(d&&d!==this)d.onMouseOut();this.firePointEvent("mouseOver");c&&(!c.shared||a.noSharedTooltip)&&c.refresh(this);this.setState("hover");b.hoverPoint=this},onMouseOut:function(){var a=this.series.chart,b=a.hoverPoints;if(!b||Rb(this,b)===-1)this.firePointEvent("mouseOut"),this.setState(),a.hoverPoint=null},tooltipFormatter:function(a){var b=this.series, +c=b.tooltipOptions,d=a.match(/\{(series|point)\.[a-zA-Z]+\}/g),e=/[{\.}]/,f,g,h,i,j={y:0,open:0,high:0,low:0,close:0,percentage:1,total:1};c.valuePrefix=c.valuePrefix||c.yPrefix;c.valueDecimals=c.valueDecimals||c.yDecimals;c.valueSuffix=c.valueSuffix||c.ySuffix;for(i in d)g=d[i],la(g)&&g!==a&&(h=(" "+g).split(e),f={point:this,series:b}[h[1]],h=h[2],f===this&&j.hasOwnProperty(h)?(f=j[h]?h:"value",f=(c[f+"Prefix"]||"")+Ia(this[h],o(c[f+"Decimals"],-1))+(c[f+"Suffix"]||"")):f=f[h],a=a.replace(g,f)); +return a},update:function(a,b,c){var d=this,e=d.series,f=d.graphic,g,h=e.data,i=h.length,j=e.chart,b=o(b,!0);d.firePointEvent("update",{options:a},function(){d.applyOptions(a);X(a)&&(e.getAttribs(),f&&f.attr(d.pointAttr[e.state]));for(g=0;ga+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart.options,c=b.plotOptions,d=c[this.type],e=a.data;a.data=null;c=A(d,c.series,a);c.data=a.data=e;this.tooltipOptions=A(b.tooltip,c.tooltip);d.marker===null&&delete c.marker;return c},getColor:function(){var a=this.options,b=this.chart.options.colors,c=this.chart.counters;this.color=a.color|| +!a.colorByPoint&&b[c.color++]||"gray";c.wrapColor(b.length)},getSymbol:function(){var a=this.options.marker,b=this.chart,c=b.options.symbols,b=b.counters;this.symbol=a.symbol||c[b.symbol++];if(/^url/.test(this.symbol))a.radius=0;b.wrapSymbol(c.length)},drawLegendSymbol:function(a){var b=this.options,c=b.marker,d=a.options.symbolWidth,e=this.chart.renderer,f=this.legendGroup,a=a.baseline,g;if(b.lineWidth){g={"stroke-width":b.lineWidth};if(b.dashStyle)g.dashstyle=b.dashStyle;this.legendLine=e.path(["M", +0,a-4,"L",d,a-4]).attr(g).add(f)}if(c&&c.enabled)b=c.radius,this.legendSymbol=e.symbol(this.symbol,d/2-b,a-4-b,2*b,2*b).add(f)},addPoint:function(a,b,c,d){var e=this.data,f=this.graph,g=this.area,h=this.chart,i=this.xData,j=this.yData,k=f&&f.shift||0,l=this.options.data,m=this.pointClass.prototype;ua(d,h);if(f&&c)f.shift=k+1;if(g){if(c)g.shift=k+1;g.isArea=!0}b=o(b,!0);d={series:this};m.applyOptions.apply(d,[a]);i.push(d.x);j.push(m.toYData?m.toYData.call(d):d.y);l.push(a);c&&(e[0]&&e[0].remove?e[0].remove(!1): +(e.shift(),i.shift(),j.shift(),l.shift()));this.getAttribs();this.isDirtyData=this.isDirty=!0;b&&h.redraw()},setData:function(a,b){var c=this.points,d=this.options,e=this.initialColor,f=this.chart,g=null,h=this.xAxis,i,j=this.pointClass.prototype;this.xIncrement=null;this.pointRange=h&&h.categories?1:d.pointRange;if(t(e))f.counters.color=e;var e=[],k=[],l=a?a.length:[],m=(i=this.pointArrayMap)&&i.length;if(l>(d.turboThreshold||1E3)){for(i=0;g===null&&ik||this.forceCrop))if(a=i.getExtremes(), +i=a.min,k=a.max,b[d-1]k)b=[],c=[];else if(b[0]k){for(a=0;a=i){e=y(0,a-1);break}for(;ak){f=a+1;break}b=b.slice(e,f);c=c.slice(e,f);g=!0}for(a=b.length-1;a>0;a--)if(d=b[a]-b[a-1],d>0&&(h===x||d=0&&c<=d;)i[c++]=g}this.tooltipPoints=i}},tooltipHeaderFormatter:function(a){var b=this.tooltipOptions,c=b.xDateFormat,d=this.xAxis,e=d&&d.options.type==="datetime",f;if(e&&!c)for(f in B)if(B[f]>=d.closestPointRange){c=b.dateTimeLabelFormats[f];break}return b.headerFormat.replace("{point.key}",e&&Aa(a)? +cb(c,a):a).replace("{series.name}",this.name).replace("{series.color}",this.color)},onMouseOver:function(){var a=this.chart,b=a.hoverSeries;if(b&&b!==this)b.onMouseOut();this.options.events.mouseOver&&E(this,"mouseOver");this.setState("hover");a.hoverSeries=this},onMouseOut:function(){var a=this.options,b=this.chart,c=b.tooltip,d=b.hoverPoint;if(d)d.onMouseOut();this&&a.events.mouseOut&&E(this,"mouseOut");c&&!a.stickyTracking&&!c.shared&&c.hide();this.setState();b.hoverSeries=null},animate:function(a){var b= +this,c=b.chart,d=c.renderer,e;e=b.options.animation;var f=c.clipBox,g=c.inverted,h;if(e&&!X(e))e=W[b.type].animation;h="_sharedClip"+e.duration+e.easing;if(a)a=c[h],e=c[h+"m"],a||(c[h]=a=d.clipRect(r(f,{width:0})),c[h+"m"]=e=d.clipRect(-99,g?-c.plotLeft:-c.plotTop,99,g?c.chartWidth:c.chartHeight)),b.group.clip(a),b.markerGroup.clip(e),b.sharedClipKey=h;else{if(a=c[h])a.animate({width:c.plotSizeX},e),c[h+"m"].animate({width:c.plotSizeX+99},e);b.animate=null;b.animationTimeout=setTimeout(function(){b.afterAnimate()}, +e.duration)}},afterAnimate:function(){var a=this.chart,b=this.sharedClipKey,c=this.group;c&&this.options.clip!==!1&&(c.clip(a.clipRect),this.markerGroup.clip());setTimeout(function(){b&&a[b]&&(a[b]=a[b].destroy(),a[b+"m"]=a[b+"m"].destroy())},100)},drawPoints:function(){var a,b=this.points,c=this.chart,d,e,f,g,h,i,j,k,l=this.options.marker,m,p=this.markerGroup;if(l.enabled||this._hasPointMarkers)for(f=b.length;f--;)if(g=b[f],d=g.plotX,e=g.plotY,k=g.graphic,i=g.marker||{},a=l.enabled&&i.enabled=== +x||i.enabled,m=c.isInsidePlot(d,e,c.inverted),a&&e!==x&&!isNaN(e))if(a=g.pointAttr[g.selected?"select":""],h=a.r,i=o(i.symbol,this.symbol),j=i.indexOf("url")===0,k)k.attr({visibility:m?Z?"inherit":"visible":"hidden"}).animate(r({x:d-h,y:e-h},k.symbolName?{width:2*h,height:2*h}:{}));else{if(m&&(h>0||j))g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(p)}else if(k)g.graphic=k.destroy()},convertAttribs:function(a,b,c,d){var e=this.pointAttrToOptions,f,g,h={},a=a||{},b=b||{},c=c||{},d=d||{}; +for(f in e)g=e[f],h[f]=o(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var a=this,b=W[a.type].marker?a.options.marker:a.options,c=b.states,d=c.hover,e,f=a.color,g={stroke:f,fill:f},h=a.points||[],i=[],j,k=a.pointAttrToOptions,l;a.options.marker?(d.radius=d.radius||b.radius+2,d.lineWidth=d.lineWidth||b.lineWidth+1):d.color=d.color||qa(d.color||f).brighten(d.brightness).get();i[""]=a.convertAttribs(b,g);n(["hover","select"],function(b){i[b]=a.convertAttribs(c[b],i[""])});a.pointAttr=i;for(f= +h.length;f--;){g=h[f];if((b=g.options&&g.options.marker||g.options)&&b.enabled===!1)b.radius=0;e=a.options.colorByPoint;if(g.options)for(l in k)t(b[k[l]])&&(e=!0);if(e){b=b||{};j=[];c=b.states||{};e=c.hover=c.hover||{};if(!a.options.marker)e.color=qa(e.color||g.color).brighten(e.brightness||d.brightness).get();j[""]=a.convertAttribs(r({color:g.color},b),i[""]);j.hover=a.convertAttribs(c.hover,i.hover,j[""]);j.select=a.convertAttribs(c.select,i.select,j[""])}else j=i;g.pointAttr=j}},destroy:function(){var a= +this,b=a.chart,c=/AppleWebKit\/533/.test(Fa),d,e,f=a.data||[],g,h,i;E(a,"destroy");S(a);n(["xAxis","yAxis"],function(b){if(i=a[b])Ba(i.series,a),i.isDirty=!0});a.legendItem&&a.chart.legend.destroyItem(a);for(e=f.length;e--;)(g=f[e])&&g.destroy&&g.destroy();a.points=null;clearTimeout(a.animationTimeout);n("area,graph,dataLabelsGroup,group,markerGroup,tracker,trackerGroup".split(","),function(b){a[b]&&(d=c&&b==="group"?"hide":"destroy",a[b][d]())});if(b.hoverSeries===a)b.hoverSeries=null;Ba(b.series, +a);for(h in a)delete a[h]},drawDataLabels:function(){var a=this,b=a.options.dataLabels,c=a.points,d,e,f,g;if(b.enabled||a._hasPointLabels)a.dlProcessOptions&&a.dlProcessOptions(b),g=a.plotGroup("dataLabelsGroup","data-labels",a.visible?"visible":"hidden",6),e=b,n(c,function(c){var i,j=c.dataLabel,k,l=!0;d=c.options&&c.options.dataLabels;i=e.enabled||d&&d.enabled;if(j&&!i)c.dataLabel=j.destroy();else if(i){i=b.rotation;b=A(e,d);f=b.formatter.call(c.getLabelConfig(),b);b.style.color=o(b.color,b.style.color, +a.color,"black");if(j)j.attr({text:f}),l=!1;else if(t(f)){j={fill:b.backgroundColor,stroke:b.borderColor,"stroke-width":b.borderWidth,r:b.borderRadius||0,rotation:i,padding:b.padding,zIndex:1};for(k in j)j[k]===x&&delete j[k];j=c.dataLabel=a.chart.renderer[i?"text":"label"](f,0,-999,null,null,null,b.useHTML).attr(j).css(b.style).add(g).shadow(b.shadow)}j&&a.alignDataLabel(c,j,b,null,l)}})},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=o(a.plotX,-999),a=o(a.plotY,-999),i=b.getBBox(), +d=r({x:g?f.plotWidth-a:h,y:s(g?f.plotHeight-h:a),width:0,height:0},d);r(c,{width:i.width,height:i.height});c.rotation?(d={align:c.align,x:d.x+c.x+d.width/2,y:d.y+c.y+d.height/2},b[e?"attr":"animate"](d)):(b.align(c,null,d),d=b.alignAttr);b.attr({visibility:c.crop===!1||f.isInsidePlot(d.x,d.y)||f.isInsidePlot(h,a,g)?Z?"inherit":"visible":"hidden"})},getSegmentPath:function(a){var b=this,c=[];n(a,function(d,e){b.getPointSpline?c.push.apply(c,b.getPointSpline(a,d,e)):(c.push(e?"L":"M"),e&&b.options.step&& +c.push(d.plotX,a[e-1].plotY),c.push(d.plotX,d.plotY))});return c},getGraphPath:function(){var a=this,b=[],c,d=[];n(a.segments,function(e){c=a.getSegmentPath(e);e.length>1?b=b.concat(c):d.push(e[0])});a.singlePoints=d;return a.graphPath=b},drawGraph:function(){var a=this.options,b=this.graph,c=this.group,d=a.lineColor||this.color,e=a.lineWidth,f=a.dashStyle,g=this.getGraphPath();if(b)eb(b),b.animate({d:g});else if(e){b={stroke:d,"stroke-width":e,zIndex:1};if(f)b.dashstyle=f;this.graph=this.chart.renderer.path(g).attr(b).add(c).shadow(a.shadow)}}, +invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};n(["group","trackerGroup","markerGroup"],function(c){b[c]&&b[c].attr(a).invert()})}var b=this,c=b.chart;I(c,"resize",a);I(b,"destroy",function(){S(c,"resize",a)});a();b.invertGroups=a},plotGroup:function(a,b,c,d,e){var f=this[a],g=this.chart,h=this.xAxis,i=this.yAxis;f||(this[a]=f=g.renderer.g(b).attr({visibility:c,zIndex:d||0.1}).add(e));f.translate(h?h.left:g.plotLeft,i?i.top:g.plotTop);return f},render:function(){var a= +this.chart,b,c=this.options,d=c.animation&&!!this.animate,e=this.visible?"visible":"hidden",f=c.zIndex,g=this.hasRendered,h=a.seriesGroup;b=this.plotGroup("group","series",e,f,h);this.markerGroup=this.plotGroup("markerGroup","markers",e,f,h);d&&this.animate(!0);this.getAttribs();b.inverted=a.inverted;this.drawGraph&&this.drawGraph();this.drawPoints();this.drawDataLabels();this.options.enableMouseTracking!==!1&&this.drawTracker();a.inverted&&this.invertGroups();c.clip!==!1&&!this.sharedClipKey&&!g&& +(b.clip(a.clipRect),this.trackerGroup&&this.trackerGroup.clip(a.clipRect));d?this.animate():g||this.afterAnimate();this.isDirty=this.isDirtyData=!1;this.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirtyData,c=this.group;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:this.xAxis.left,translateY:this.yAxis.top}));this.translate();this.setTooltipPoints(!0);this.render();b&&E(this,"updatedData")},setState:function(a){var b=this.options,c=this.graph, +d=b.states,b=b.lineWidth,a=a||"";if(this.state!==a)this.state=a,d[a]&&d[a].enabled===!1||(a&&(b=d[a].lineWidth||b+1),c&&!c.dashstyle&&c.attr({"stroke-width":b},a?0:500))},setVisible:function(a,b){var c=this.chart,d=this.legendItem,e=this.group,f=this.tracker,g=this.dataLabelsGroup,h=this.markerGroup,i,j=this.points,k=c.options.chart.ignoreHiddenSeries;i=this.visible;i=(this.visible=a=a===x?!i:a)?"show":"hide";if(e)e[i]();if(h)h[i]();if(f)f[i]();else if(j)for(e=j.length;e--;)if(f=j[e],f.tracker)f.tracker[i](); +if(g)g[i]();d&&c.legend.colorizeItem(this,a);this.isDirty=!0;this.options.stacking&&n(c.series,function(a){if(a.options.stacking&&a.visible)a.isDirty=!0});if(k)c.isDirtyBox=!0;b!==!1&&c.redraw();E(this,i)},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},select:function(a){this.selected=a=a===x?!this.selected:a;if(this.checkbox)this.checkbox.checked=a;E(this,a?"select":"unselect")},drawTracker:function(){var a=this,b=a.options,c=b.trackByArea,d=[].concat(c?a.areaPath:a.graphPath), +e=d.length,f=a.chart,g=f.renderer,h=f.options.tooltip.snap,i=a.tracker,j=b.cursor,j=j&&{cursor:j},k=a.singlePoints,l=this.isCartesian&&this.plotGroup("trackerGroup",null,"visible",b.zIndex||1,f.trackerGroup),m;if(e&&!c)for(m=e+1;m--;)d[m]==="M"&&d.splice(m+1,0,d[m+1]-h,d[m+2],"L"),(m&&d[m]==="M"||m===e)&&d.splice(m,0,"L",d[m-2]+h,d[m-1]);for(m=0;m=0;d--)da&&i>e?(i=y(a,e),k=2*e-i):ig&&k>e?(k=y(g,e),i=2*e-k):kv?g-v:z-(f<=z?v:0));c.barX= +h;c.pointWidth=q;c.shapeType="rect";c.shapeArgs=f=b.renderer.Element.prototype.crisp.call(0,e,h,i,s,j);e%2&&(f.y-=1,f.height+=1);c.trackerArgs=L(j)<3&&A(c.shapeArgs,{height:6,y:i-3})})},getSymbol:ya,drawLegendSymbol:G.prototype.drawLegendSymbol,drawGraph:ya,drawPoints:function(){var a=this,b=a.options,c=a.chart.renderer,d;n(a.points,function(e){var f=e.plotY,g=e.graphic;if(f!==x&&!isNaN(f)&&e.y!==null)d=e.shapeArgs,g?(eb(g),g.animate(A(d))):e.graphic=c[e.shapeType](d).attr(e.pointAttr[e.selected? +"select":""]).add(a.group).shadow(b.shadow,null,b.stacking&&!b.borderRadius);else if(g)e.graphic=g.destroy()})},drawTracker:function(){var a=this,b=a.chart,c=b.renderer,d,e,f=+new Date,g=a.options,h=g.cursor,i=h&&{cursor:h},j=a.isCartesian&&a.plotGroup("trackerGroup",null,"visible",g.zIndex||1,b.trackerGroup),k,l,m;n(a.points,function(h){e=h.tracker;d=h.trackerArgs||h.shapeArgs;l=h.plotY;m=!a.isCartesian||l!==x&&!isNaN(l);delete d.strokeWidth;if(h.y!==null&&m)e?e.attr(d):h.tracker=c[h.shapeType](d).attr({isTracker:f, +fill:wb,visibility:a.visible?"visible":"hidden"}).on(fa?"touchstart":"mouseover",function(c){k=c.relatedTarget||c.fromElement;if(b.hoverSeries!==a&&z(k,"isTracker")!==f)a.onMouseOver();h.onMouseOver()}).on("mouseout",function(b){if(!g.stickyTracking&&(k=b.relatedTarget||b.toElement,z(k,"isTracker")!==f))a.onMouseOut()}).css(i).add(h.group||j)})},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=a.below||a.plotY>(this.translatedThreshold||f.plotSizeY),i=this.options.stacking||c.inside; +if(a.shapeArgs&&(d=A(a.shapeArgs),g&&(d={x:f.plotWidth-d.y-d.height,y:f.plotHeight-d.x-d.width,width:d.height,height:d.width}),!i))g?(d.x+=h?0:d.width,d.width=0):(d.y+=h?d.height:0,d.height=0);c.align=o(c.align,!g||i?"center":h?"right":"left");c.verticalAlign=o(c.verticalAlign,g||i?"middle":h?"top":"bottom");N.prototype.alignDataLabel.call(this,a,b,c,d,e)},animate:function(a){var b=this,c=b.points,d=b.options;if(!a)n(c,function(a){var c=a.graphic,a=a.shapeArgs,g=b.yAxis,h=d.threshold;c&&(c.attr({height:0, +y:t(h)?g.getThreshold(h):g.translate(g.getExtremes().min,0,1,0,1)}),c.animate({height:a.height,y:a.y},d.animation))}),b.animate=null},remove:function(){var a=this,b=a.chart;b.hasRendered&&n(b.series,function(b){if(b.type===a.type)b.isDirty=!0});N.prototype.remove.apply(a,arguments)}});$.column=ha;W.bar=A(W.column);za=ca(ha,{type:"bar",inverted:!0});$.bar=za;W.scatter=A(ga,{lineWidth:0,states:{hover:{lineWidth:0}},tooltip:{headerFormat:'{series.name}
    ', +pointFormat:"x: {point.x}
    y: {point.y}
    "}});za=ca(N,{type:"scatter",sorted:!1,translate:function(){var a=this;N.prototype.translate.apply(a);n(a.points,function(b){b.shapeType="circle";b.shapeArgs={x:b.plotX,y:b.plotY,r:a.chart.options.tooltip.snap}})},drawTracker:function(){for(var a=this,b=a.options.cursor,b=b&&{cursor:b},c=a.points,d=c.length,e;d--;)if(e=c[d].graphic)e.element._i=d;a._hasTracking?a._hasTracking=!0:a.markerGroup.attr({isTracker:!0}).on(fa?"touchstart":"mouseover", +function(b){a.onMouseOver();if(b.target._i!==x)c[b.target._i].onMouseOver()}).on("mouseout",function(){if(!a.options.stickyTracking)a.onMouseOut()}).css(b)}});$.scatter=za;W.pie=A(ga,{borderColor:"#FFFFFF",borderWidth:1,center:["50%","50%"],colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name}},legendType:"point",marker:null,size:"75%",showInLegend:!1,slicedOffset:10,states:{hover:{brightness:0.1,shadow:!1}}});ya={type:"pie",isCartesian:!1,pointClass:ca(Ta, +{init:function(){Ta.prototype.init.apply(this,arguments);var a=this,b;r(a,{visible:a.visible!==!1,name:o(a.name,"Slice")});b=function(){a.slice()};I(a,"select",b);I(a,"unselect",b);return a},setVisible:function(a){var b=this.series,c=b.chart,d=this.tracker,e=this.dataLabel,f=this.connector,g=this.shadowGroup,h;h=(this.visible=a=a===x?!this.visible:a)?"show":"hide";this.group[h]();if(d)d[h]();if(e)e[h]();if(f)f[h]();if(g)g[h]();this.legendItem&&c.legend.colorizeItem(this,a);if(!b.isDirty&&b.options.ignoreHiddenPoint)b.isDirty= +!0,c.redraw()},slice:function(a,b,c){var d=this.series.chart,e=this.slicedTranslation;ua(c,d);o(b,!0);a=this.sliced=t(a)?a:!this.sliced;a={translateX:a?e[0]:d.plotLeft,translateY:a?e[1]:d.plotTop};this.group.animate(a);this.shadowGroup&&this.shadowGroup.animate(a)}}),pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},getColor:function(){this.initialColor=this.chart.counters.color},animate:function(){var a=this;n(a.points,function(b){var c=b.graphic,b=b.shapeArgs,d= +-xa/2;c&&(c.attr({r:0,start:d,end:d}),c.animate({r:b.r,start:b.start,end:b.end},a.options.animation))});a.animate=null},setData:function(a,b){N.prototype.setData.call(this,a,!1);this.processData();this.generatePoints();o(b,!0)&&this.chart.redraw()},getCenter:function(){var a=this.options,b=this.chart,c=b.plotWidth,d=b.plotHeight,a=a.center.concat([a.size,a.innerSize||0]),e=O(c,d),f;return Sa(a,function(a,b){return(f=/%$/.test(a))?[c,d,e,e][b]*w(a)/100:a})},translate:function(){this.generatePoints(); +var a=0,b=-0.25,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,f,g=this.chart,h,i,j,k=this.points,l=2*xa,m=c.dataLabels.distance,o=c.ignoreHiddenPoint,n,r=k.length,q;this.center=f=this.getCenter();this.getX=function(a,b){j=J.asin((a-f[1])/(f[2]/2+m));return f[0]+(b?-1:1)*V(j)*(f[2]/2+m)};for(n=0;n0,r=[[],[]],s,q,t,w,y=2,v;if(d.enabled||this._hasPointLabels){N.prototype.drawDataLabels.apply(this);n(a,function(a){a.dataLabel&&r[a.labelPos[7]0){for(v=m-l-j;v<=m+l+j;v+=a)x.push(v);t=x.length;if(C>t){h=[].concat(z);h.sort(w);for(v=C;v--;)h[v].rank=v;for(v=C;v--;)z[v].rank>=t&&z.splice(v,1);C=z.length}for(v=0;v0){if(q=A.pop(),B=q.i,q=q.y,s>q&&x[B+1]!==null||s= timeUnits[SECOND]) { // second - minDate.setMilliseconds(0); - minDate.setSeconds(interval >= timeUnits[MINUTE] ? 0 : - count * mathFloor(minDate.getSeconds() / count)); - } - if (interval >= timeUnits[MINUTE]) { // minute - minDate[setMinutes](interval >= timeUnits[HOUR] ? 0 : - count * mathFloor(minDate[getMinutes]() / count)); - } - - if (interval >= timeUnits[HOUR]) { // hour - minDate[setHours](interval >= timeUnits[DAY] ? 0 : - count * mathFloor(minDate[getHours]() / count)); - } - - if (interval >= timeUnits[DAY]) { // day - minDate[setDate](interval >= timeUnits[MONTH] ? 1 : - count * mathFloor(minDate[getDate]() / count)); - } - - if (interval >= timeUnits[MONTH]) { // month - minDate[setMonth](interval >= timeUnits[YEAR] ? 0 : - count * mathFloor(minDate[getMonth]() / count)); - minYear = minDate[getFullYear](); - } - - if (interval >= timeUnits[YEAR]) { // year - minYear -= minYear % count; - minDate[setFullYear](minYear); - } - - // week is a special case that runs outside the hierarchy - if (interval === timeUnits[WEEK]) { - // get start of current week, independent of count - minDate[setDate](minDate[getDate]() - minDate[getDay]() + - pick(startOfWeek, 1)); - } - - - // get tick positions - i = 1; - minYear = minDate[getFullYear](); - var time = minDate.getTime(), - minMonth = minDate[getMonth](), - minDateDate = minDate[getDate](), - timezoneOffset = useUTC ? - 0 : - (24 * 3600 * 1000 + minDate.getTimezoneOffset() * 60 * 1000) % (24 * 3600 * 1000); // #950 - - // iterate and add tick positions at appropriate values - while (time < max) { - tickPositions.push(time); - - // if the interval is years, use Date.UTC to increase years - if (interval === timeUnits[YEAR]) { - time = makeTime(minYear + i * count, 0); - - // if the interval is months, use Date.UTC to increase months - } else if (interval === timeUnits[MONTH]) { - time = makeTime(minYear, minMonth + i * count); - - // if we're using global time, the interval is not fixed as it jumps - // one hour at the DST crossover - } else if (!useUTC && (interval === timeUnits[DAY] || interval === timeUnits[WEEK])) { - time = makeTime(minYear, minMonth, minDateDate + - i * count * (interval === timeUnits[DAY] ? 1 : 7)); - - // else, the interval is fixed and we use simple addition - } else { - time += interval * count; - - // mark new days if the time is dividable by day - if (interval <= timeUnits[HOUR] && time % timeUnits[DAY] === timezoneOffset) { - higherRanks[time] = DAY; - } - } - - i++; - } - - // push the last time - tickPositions.push(time); + + if (interval >= timeUnits[SECOND]) { // second + minDate.setMilliseconds(0); + minDate.setSeconds(interval >= timeUnits[MINUTE] ? 0 : + count * mathFloor(minDate.getSeconds() / count)); } + if (interval >= timeUnits[MINUTE]) { // minute + minDate[setMinutes](interval >= timeUnits[HOUR] ? 0 : + count * mathFloor(minDate[getMinutes]() / count)); + } + + if (interval >= timeUnits[HOUR]) { // hour + minDate[setHours](interval >= timeUnits[DAY] ? 0 : + count * mathFloor(minDate[getHours]() / count)); + } + + if (interval >= timeUnits[DAY]) { // day + minDate[setDate](interval >= timeUnits[MONTH] ? 1 : + count * mathFloor(minDate[getDate]() / count)); + } + + if (interval >= timeUnits[MONTH]) { // month + minDate[setMonth](interval >= timeUnits[YEAR] ? 0 : + count * mathFloor(minDate[getMonth]() / count)); + minYear = minDate[getFullYear](); + } + + if (interval >= timeUnits[YEAR]) { // year + minYear -= minYear % count; + minDate[setFullYear](minYear); + } + + // week is a special case that runs outside the hierarchy + if (interval === timeUnits[WEEK]) { + // get start of current week, independent of count + minDate[setDate](minDate[getDate]() - minDate[getDay]() + + pick(startOfWeek, 1)); + } + + + // get tick positions + i = 1; + minYear = minDate[getFullYear](); + var time = minDate.getTime(), + minMonth = minDate[getMonth](), + minDateDate = minDate[getDate](), + timezoneOffset = useUTC ? + 0 : + (24 * 3600 * 1000 + minDate.getTimezoneOffset() * 60 * 1000) % (24 * 3600 * 1000); // #950 + + // iterate and add tick positions at appropriate values + while (time < max) { + tickPositions.push(time); + + // if the interval is years, use Date.UTC to increase years + if (interval === timeUnits[YEAR]) { + time = makeTime(minYear + i * count, 0); + + // if the interval is months, use Date.UTC to increase months + } else if (interval === timeUnits[MONTH]) { + time = makeTime(minYear, minMonth + i * count); + + // if we're using global time, the interval is not fixed as it jumps + // one hour at the DST crossover + } else if (!useUTC && (interval === timeUnits[DAY] || interval === timeUnits[WEEK])) { + time = makeTime(minYear, minMonth, minDateDate + + i * count * (interval === timeUnits[DAY] ? 1 : 7)); + + // else, the interval is fixed and we use simple addition + } else { + time += interval * count; + + // mark new days if the time is dividable by day + if (interval <= timeUnits[HOUR] && time % timeUnits[DAY] === timezoneOffset) { + higherRanks[time] = DAY; + } + } + + i++; + } + + // push the last time + tickPositions.push(time); + // record information on the chosen unit - for dynamic label formatter tickPositions.info = extend(normalizedInterval, { higherRanks: higherRanks, @@ -880,7 +875,7 @@ timeUnits = hash( HOUR, 3600000, DAY, 24 * 3600000, WEEK, 7 * 24 * 3600000, - MONTH, 31 * 24 * 3600000, + MONTH, 30 * 24 * 3600000, YEAR, 31556952000 ); /*jslint white: false*/ @@ -1367,8 +1362,8 @@ defaultOptions = { }, global: { useUTC: true, - canvasToolsURL: 'http://code.highcharts.com/2.3.5/modules/canvas-tools.js', - VMLRadialGradientURL: 'http://code.highcharts.com/2.3.5/gfx/vml-radial-gradient.png' + canvasToolsURL: 'http://code.highcharts.com/2.3.3/modules/canvas-tools.js', + VMLRadialGradientURL: 'http://code.highcharts.com/2.3.3/gfx/vml-radial-gradient.png' }, chart: { //animation: true, @@ -1620,7 +1615,7 @@ defaultOptions = { pointFormat: '{series.name}: {point.y}
    ', shadow: true, shared: useCanVG, - snap: isTouchDevice ? 25 : 10, + snap: hasTouch ? 25 : 10, style: { color: '#333333', fontSize: '12px', @@ -2026,8 +2021,8 @@ SVGElement.prototype = { key = 'stroke-width'; } - // Chrome/Win < 6 bug (http://code.google.com/p/chromium/issues/detail?id=15461), #1369 - if (key === 'stroke-width' && value === 0 && (isWebKit || renderer.forExport)) { + // Chrome/Win < 6 bug (http://code.google.com/p/chromium/issues/detail?id=15461) + if (isWebKit && key === 'stroke-width' && value === 0) { value = 0.000001; } @@ -2218,15 +2213,17 @@ SVGElement.prototype = { * @param {Function} handler */ on: function (eventType, handler) { + var fn = handler; // touch if (hasTouch && eventType === 'click') { - this.element.ontouchstart = function (e) { + eventType = 'touchstart'; + fn = function (e) { e.preventDefault(); handler(); }; } // simplest possible event model for internal use - this.element['on' + eventType] = handler; + this.element['on' + eventType] = fn; return this; }, @@ -2407,7 +2404,7 @@ SVGElement.prototype = { height = pick(wrapper.elemHeight, elem.offsetHeight); // update textWidth - if (width > textWidth && /[ \-]/.test(elem.textContent || elem.innerText)) { // #983, #1254 + if (width > textWidth && /[ \-]/.test(elem.innerText)) { // #983 css(elem, { width: textWidth + PX, display: 'block', @@ -2447,11 +2444,6 @@ SVGElement.prototype = { left: (x + xCorr) + PX, top: (y + yCorr) + PX }); - - // force reflow in webkit to apply the left and top on useHTML element (#1249) - if (isWebKit) { - height = elem.offsetHeight; // assigned to height for JSLint purpose - } // record current text transform wrapper.cTT = currentTextTransform; @@ -2571,7 +2563,7 @@ SVGElement.prototype = { element = wrapper.element, styles = wrapper.styles, rad = rotation * deg2rad; - + if (!bBox) { // SVG elements if (element.namespaceURI === SVG_NS || renderer.forExport) { @@ -2607,12 +2599,7 @@ SVGElement.prototype = { if (renderer.isSVG) { width = bBox.width; height = bBox.height; - - // Workaround for wrong bounding box in IE9 and IE10 (#1101) - if (isIE && styles && styles.fontSize === '11px' && height === 22.700000762939453) { - bBox.height = height = 14; - } - + // Adjust for rotated text if (rotation) { bBox.width = mathAbs(height * mathSin(rad)) + mathAbs(width * mathCos(rad)); @@ -2620,6 +2607,11 @@ SVGElement.prototype = { } } + // Workaround for wrong bounding box in IE9 and IE10 (#1101) + if (isIE && styles && styles.fontSize === '11px' && height === 22.700000762939453) { + bBox.height = 14; + } + wrapper.bBox = bBox; } return bBox; @@ -3438,7 +3430,6 @@ SVGRenderer.prototype = { options ), - imageElement, imageRegex = /^url\((.*?)\)$/, imageSrc, imageSize, @@ -3465,25 +3456,23 @@ SVGRenderer.prototype = { // On image load, set the size and position centerImage = function (img, size) { - if (img.element) { // it may be destroyed in the meantime (#1390) - img.attr({ - width: size[0], - height: size[1] - }); + img.attr({ + width: size[0], + height: size[1] + }); - if (!img.alignByTranslate) { // #185 - img.translate( - mathRound((width - size[0]) / 2), // #1378 - mathRound((height - size[1]) / 2) - ); - } + if (!img.alignByTranslate) { // #185 + img.translate( + -mathRound(size[0] / 2), + -mathRound(size[1] / 2) + ); } }; imageSrc = symbol.match(imageRegex)[1]; imageSize = symbolSizes[imageSrc]; - // Ireate the image synchronously, add attribs async + // create the image synchronously, add attribs async obj = this.image(imageSrc) .attr({ x: x, @@ -3493,15 +3482,15 @@ SVGRenderer.prototype = { if (imageSize) { centerImage(obj, imageSize); } else { - // Initialize image to be 0 size so export will still function if there's no cached sizes. - // + // initialize image to be 0 size so export will still function if there's no cached sizes obj.attr({ width: 0, height: 0 }); - // Create a dummy JavaScript image to get the width and height. Due to a bug in IE < 8, - // the created element must be assigned to a variable in order to load (#292). - imageElement = createElement('img', { + // create a dummy JavaScript image to get the width and height + createElement('img', { onload: function () { - centerImage(obj, symbolSizes[imageSrc] = [this.width, this.height]); + var img = this; + + centerImage(obj, symbolSizes[imageSrc] = [img.width, img.height]); }, src: imageSrc }); @@ -3640,17 +3629,7 @@ SVGRenderer.prototype = { var renderer = this, colorObject, regexRgba = /^rgba/, - gradName, - gradAttr, - gradients, - gradientObject, - stops, - stopColor, - stopOpacity, - radialReference, - n, - id, - key = []; + gradName; // Apply linear or radial gradients if (color && color.linearGradient) { @@ -3660,59 +3639,47 @@ SVGRenderer.prototype = { } if (gradName) { - gradAttr = color[gradName]; - gradients = renderer.gradients; - stops = color.stops; - radialReference = elem.radialReference; - - // Keep < 2.2 kompatibility - if (isArray(gradAttr)) { - color[gradName] = gradAttr = { - x1: gradAttr[0], - y1: gradAttr[1], - x2: gradAttr[2], - y2: gradAttr[3], - gradientUnits: 'userSpaceOnUse' - }; - } - - // Correct the radial gradient for the radial reference system - if (gradName === 'radialGradient' && radialReference && !defined(gradAttr.gradientUnits)) { - extend(gradAttr, { - cx: (radialReference[0] - radialReference[2] / 2) + gradAttr.cx * radialReference[2], - cy: (radialReference[1] - radialReference[2] / 2) + gradAttr.cy * radialReference[2], - r: gradAttr.r * radialReference[2], - gradientUnits: 'userSpaceOnUse' - }); - } - - // Build the unique key to detect whether we need to create a new element (#1282) - for (n in gradAttr) { - if (n !== 'id') { - key.push(n, gradAttr[n]); - } - } - for (n in stops) { - key.push(stops[n]); - } - key = key.join(','); + var gradAttr = color[gradName], + gradients = renderer.gradients, + gradientObject, + stopColor, + stopOpacity, + radialReference = elem.radialReference; // Check if a gradient object with the same config object is created within this renderer - if (gradients[key]) { - id = gradients[key].id; + if (!gradAttr.id || !gradients[gradAttr.id]) { - } else { + // Keep < 2.2 kompatibility + if (isArray(gradAttr)) { + color[gradName] = gradAttr = { + x1: gradAttr[0], + y1: gradAttr[1], + x2: gradAttr[2], + y2: gradAttr[3], + gradientUnits: 'userSpaceOnUse' + }; + } + + // Correct the radial gradient for the radial reference system + if (gradName === 'radialGradient' && radialReference && !defined(gradAttr.gradientUnits)) { + extend(gradAttr, { + cx: (radialReference[0] - radialReference[2] / 2) + gradAttr.cx * radialReference[2], + cy: (radialReference[1] - radialReference[2] / 2) + gradAttr.cy * radialReference[2], + r: gradAttr.r * radialReference[2], + gradientUnits: 'userSpaceOnUse' + }); + } // Set the id and create the element - gradAttr.id = id = PREFIX + idCounter++; - gradients[key] = gradientObject = renderer.createElement(gradName) + gradAttr.id = PREFIX + idCounter++; + gradients[gradAttr.id] = gradientObject = renderer.createElement(gradName) .attr(gradAttr) .add(renderer.defs); // The gradient needs to keep a list of stops to be able to destroy them gradientObject.stops = []; - each(stops, function (stop) { + each(color.stops, function (stop) { var stopObject; if (regexRgba.test(stop[1])) { colorObject = Color(stop[1]); @@ -3734,7 +3701,7 @@ SVGRenderer.prototype = { } // Return the reference to the gradient object - return 'url(' + renderer.url + '#' + id + ')'; + return 'url(' + renderer.url + '#' + gradAttr.id + ')'; // Webkit and Batik can't show rgba. } else if (regexRgba.test(color)) { @@ -3976,8 +3943,7 @@ SVGRenderer.prototype = { crispAdjust = 0, deferredAttr = {}, baselineOffset, - attrSetters = wrapper.attrSetters, - needsBox; + attrSetters = wrapper.attrSetters; /** * This function runs after the label is added to the DOM (when the bounding box is @@ -3995,26 +3961,24 @@ SVGRenderer.prototype = { // update the label-scoped y offset baselineOffset = padding + renderer.fontMetrics(style && style.fontSize).b; - - if (needsBox) { - - // create the border box if it is not already present - if (!box) { - boxY = baseline ? -baselineOffset : 0; - - wrapper.box = box = shape ? - renderer.symbol(shape, -alignFactor * padding, boxY, wrapper.width, wrapper.height) : - renderer.rect(-alignFactor * padding, boxY, wrapper.width, wrapper.height, 0, deferredAttr[STROKE_WIDTH]); - box.add(wrapper); - } - - // apply the box attributes - box.attr(merge({ - width: wrapper.width, - height: wrapper.height - }, deferredAttr)); - deferredAttr = null; + + + // create the border box if it is not already present + if (!box) { + boxY = baseline ? -baselineOffset : 0; + + wrapper.box = box = shape ? + renderer.symbol(shape, -alignFactor * padding, boxY, wrapper.width, wrapper.height) : + renderer.rect(-alignFactor * padding, boxY, wrapper.width, wrapper.height, 0, deferredAttr[STROKE_WIDTH]); + box.add(wrapper); } + + // apply the box attributes + box.attr(merge({ + width: wrapper.width, + height: wrapper.height + }, deferredAttr)); + deferredAttr = null; } /** @@ -4068,7 +4032,7 @@ SVGRenderer.prototype = { y: y }); - if (box && defined(anchorX)) { + if (defined(anchorX)) { wrapper.attr({ anchorX: anchorX, anchorY: anchorY @@ -4120,15 +4084,11 @@ SVGRenderer.prototype = { // apply these to the box but not to the text attrSetters[STROKE_WIDTH] = function (value, key) { - needsBox = true; crispAdjust = value % 2 / 2; boxAttr(key, value); return false; }; attrSetters.stroke = attrSetters.fill = attrSetters.r = function (value, key) { - if (key === 'fill') { - needsBox = true; - } boxAttr(key, value); return false; }; @@ -4182,20 +4142,13 @@ SVGRenderer.prototype = { * Return the bounding box of the box, not the group */ getBBox: function () { - return { - width: bBox.width + 2 * padding, - height: bBox.height + 2 * padding, - x: bBox.x - padding, - y: bBox.y - padding - }; + return box.getBBox(); }, /** * Apply the shadow to the box */ shadow: function (b) { - if (box) { - box.shadow(b); - } + box.shadow(b); return wrapper; }, /** @@ -4216,9 +4169,6 @@ SVGRenderer.prototype = { } // Call base implementation to destroy the rest SVGElement.prototype.destroy.call(wrapper); - - // Release local pointers (#1298) - wrapper = renderer = updateBoxSize = updateTextPadding = boxAttr = getSizeAfterAdd = null; } }); } @@ -4509,7 +4459,7 @@ var VMLElement = { if (nodeName === 'SPAN') { // text color elemStyle.color = value; - } else if (nodeName !== 'IMG') { // #1336 + } else { element.filled = value !== NONE ? true : false; value = renderer.color(value, element, key, wrapper); @@ -4566,7 +4516,6 @@ var VMLElement = { if (clipRect) { clipMembers = clipRect.members; - erase(clipMembers, wrapper); // Ensure unique list of elements (#1258) clipMembers.push(wrapper); wrapper.destroyClip = function () { erase(clipMembers, wrapper); @@ -5773,9 +5722,10 @@ Tick.prototype = { // Set the new position, and show or hide if (show) { label[tick.isNew ? 'attr' : 'animate'](xy); + label.show(); tick.isNew = false; } else { - label.attr('y', -9999); // #1338 + label.hide(); } } }, @@ -6593,14 +6543,11 @@ Axis.prototype = { pointStack = isNegative ? negPointStack : posPointStack; key = isNegative ? negKey : stackKey; - // Set the stack value and y for extremes - if (defined(pointStack[x])) { // we're adding to the stack - pointStack[x] = correctFloat(pointStack[x] + y); - y = [y, pointStack[x]]; // consider both the actual value and the stack (#1376) + y = pointStack[x] = + defined(pointStack[x]) ? + correctFloat(pointStack[x] + y) : + y; - } else { // it's the first point in the stack - pointStack[x] = y; - } // add the series if (!stacks[key]) { @@ -6612,7 +6559,7 @@ Axis.prototype = { if (!stacks[key][x]) { stacks[key][x] = new StackItem(axis, axis.options.stackLabels, isNegative, x, stackOption, stacking); } - stacks[key][x].setTotal(pointStack[x]); + stacks[key][x].setTotal(y); } // Handle non null values @@ -6641,6 +6588,12 @@ Axis.prototype = { } } + // record the least unit distance + /*if (findPointRange) { + series.pointRange = pointRange || 1; + } + series.closestPointRange = pointRange;*/ + // Get the dataMin and dataMax so far. If percentage is used, the min and max are // always 0 and 100. If the length of activeYData is 0, continue with null values. if (!axis.usePercentage && activeYData.length) { @@ -6918,7 +6871,6 @@ Axis.prototype = { */ getMinorTickPositions: function () { var axis = this, - options = axis.options, tickPositions = axis.tickPositions, minorTickInterval = axis.minorTickInterval; @@ -6934,20 +6886,13 @@ Axis.prototype = { axis.getLogTickPositions(minorTickInterval, tickPositions[i - 1], tickPositions[i], true) ); } - } else if (axis.isDatetimeAxis && options.minorTickInterval === 'auto') { // #1314 - minorTickPositions = minorTickPositions.concat( - getTimeTicks( - normalizeTimeTickInterval(minorTickInterval), - axis.min, - axis.max, - options.startOfWeek - ) - ); + } else { for (pos = axis.min + (tickPositions[0] - axis.min) % minorTickInterval; pos <= axis.max; pos += minorTickInterval) { minorTickPositions.push(pos); } } + return minorTickPositions; }, @@ -7091,7 +7036,7 @@ Axis.prototype = { // is some other value axis.closestPointRange = closestPointRange; } - + // secondary values axis.oldTransA = transA; //axis.translationSlope = axis.transA = transA = axis.len / ((range + (2 * minPointOffset)) || 1); @@ -7157,18 +7102,15 @@ Axis.prototype = { // adjust min and max for the minimum range axis.adjustForMinRange(); - - // Pad the values to get clear of the chart's edges. To avoid tickInterval taking the padding - // into account, we do this after computing tick interval (#1337). + + // pad the values to get clear of the chart's edges if (!categories && !axis.usePercentage && !isLinked && defined(axis.min) && defined(axis.max)) { - length = axis.max - axis.min; - if (length) { - if (!defined(options.min) && !defined(axis.userMin) && minPadding && (axis.dataMin < 0 || !axis.ignoreMinPadding)) { - axis.min -= length * minPadding; - } - if (!defined(options.max) && !defined(axis.userMax) && maxPadding && (axis.dataMax > 0 || !axis.ignoreMaxPadding)) { - axis.max += length * maxPadding; - } + length = (axis.max - axis.min) || 1; + if (!defined(options.min) && !defined(axis.userMin) && minPadding && (axis.dataMin < 0 || !axis.ignoreMinPadding)) { + axis.min -= length * minPadding; + } + if (!defined(options.max) && !defined(axis.userMax) && maxPadding && (axis.dataMax > 0 || !axis.ignoreMaxPadding)) { + axis.max += length * maxPadding; } } @@ -7251,8 +7193,7 @@ Axis.prototype = { // reset min/max or remove extremes based on start/end on tick var roundedMin = tickPositions[0], roundedMax = tickPositions[tickPositions.length - 1], - minPointOffset = axis.minPointOffset || 0, - singlePad; + minPointOffset = axis.minPointOffset || 0; if (options.startOnTick) { axis.min = roundedMin; @@ -7266,14 +7207,6 @@ Axis.prototype = { tickPositions.pop(); } - // When there is only one point, or all points have the same value on this axis, then min - // and max are equal and tickPositions.length is 1. In this case, add some padding - // in order to center the point, but leave it with one tick. #1337. - if (tickPositions.length === 1) { - singlePad = 1e-9; // The lowest possible number to avoid extra padding on columns - axis.min -= singlePad; - axis.max += singlePad; - } } }, @@ -7761,30 +7694,28 @@ Axis.prototype = { // Major ticks. Pull out the first item and render it last so that // we can get the position of the neighbour label. #808. - if (tickPositions.length) { // #1300 - each(tickPositions.slice(1).concat([tickPositions[0]]), function (pos, i) { - - // Reorganize the indices - i = (i === tickPositions.length - 1) ? 0 : i + 1; - - // linked axes need an extra check to find out if - if (!isLinked || (pos >= axis.min && pos <= axis.max)) { - - if (!ticks[pos]) { - ticks[pos] = new Tick(axis, pos); - } - - // render new ticks in old position - if (slideInTicks && ticks[pos].isNew) { - ticks[pos].render(i, true); - } - - ticks[pos].isActive = true; - ticks[pos].render(i); + each(tickPositions.slice(1).concat([tickPositions[0]]), function (pos, i) { + + // Reorganize the indices + i = (i === tickPositions.length - 1) ? 0 : i + 1; + + // linked axes need an extra check to find out if + if (!isLinked || (pos >= axis.min && pos <= axis.max)) { + + if (!ticks[pos]) { + ticks[pos] = new Tick(axis, pos); } - - }); - } + + // render new ticks in old position + if (slideInTicks && ticks[pos].isNew) { + ticks[pos].render(i, true); + } + + ticks[pos].isActive = true; + ticks[pos].render(i); + } + + }); // alternate grid color if (alternateGridColor) { @@ -8563,7 +8494,7 @@ MouseTracker.prototype = { for (j = 0; j < i; j++) { if (series[j].visible && series[j].options.enableMouseTracking !== false && - !series[j].noSharedTooltip && series[j].tooltipPoints && series[j].tooltipPoints.length) { + !series[j].noSharedTooltip && series[j].tooltipPoints.length) { point = series[j].tooltipPoints[index]; point._dist = mathAbs(index - point[series[j].xAxis.tooltipPosName || 'plotX']); distance = mathMin(distance, point._dist); @@ -8726,10 +8657,7 @@ MouseTracker.prototype = { chart.mouseIsDown = hasDragged = false; } - removeEvent(doc, 'mouseup', drop); - if (hasTouch) { - removeEvent(doc, 'touchend', drop); - } + removeEvent(doc, hasTouch ? 'touchend' : 'mouseup', drop); } /** @@ -8764,7 +8692,7 @@ MouseTracker.prototype = { e = mouseTracker.normalizeMouseEvent(e); // issue #295, dragging not always working in Firefox - if (e.type.indexOf('touch') === -1 && e.preventDefault) { + if (!hasTouch && e.preventDefault) { e.preventDefault(); } @@ -8774,15 +8702,11 @@ MouseTracker.prototype = { chart.mouseDownX = mouseTracker.mouseDownX = e.chartX; mouseTracker.mouseDownY = e.chartY; - addEvent(doc, 'mouseup', drop); - if (hasTouch) { - addEvent(doc, 'touchend', drop); - } + addEvent(doc, hasTouch ? 'touchend' : 'mouseup', drop); }; // The mousemove, touchmove and touchstart event handler var mouseMove = function (e) { - // let the system handle multitouch operations like two finger scroll // and pinching if (e && e.touches && e.touches.length > 1) { @@ -8791,19 +8715,16 @@ MouseTracker.prototype = { // normalize e = mouseTracker.normalizeMouseEvent(e); - - var type = e.type, - chartX = e.chartX, - chartY = e.chartY, - isOutsidePlot = !chart.isInsidePlot(chartX - chart.plotLeft, chartY - chart.plotTop); - - - if (type.indexOf('touch') === -1) { // not for touch actions + if (!hasTouch) { // not for touch devices e.returnValue = false; } + var chartX = e.chartX, + chartY = e.chartY, + isOutsidePlot = !chart.isInsidePlot(chartX - chart.plotLeft, chartY - chart.plotTop); + // on touch devices, only trigger click if a handler is defined - if (type === 'touchstart') { + if (hasTouch && e.type === 'touchstart') { if (attr(e.target, 'isTracker')) { if (!chart.runTrackerClick) { e.preventDefault(); @@ -8836,7 +8757,7 @@ MouseTracker.prototype = { } } - if (chart.mouseIsDown && type !== 'touchstart') { // make selection + if (chart.mouseIsDown && e.type !== 'touchstart') { // make selection // determine if the mouse has moved more than 10px hasDragged = Math.sqrt( @@ -8900,10 +8821,10 @@ MouseTracker.prototype = { return isOutsidePlot || !chart.hasCartesianSeries; }; - // When the mouse enters the container, run mouseMove - if (!/Android 4\.0/.test(userAgent)) { // This hurts. Best effort for #1385. - container.onmousemove = mouseMove; - } + /* + * When the mouse enters the container, run mouseMove + */ + container.onmousemove = mouseMove; /* * When the mouse leaves the container, hide the tracking (tooltip). @@ -8913,9 +8834,7 @@ MouseTracker.prototype = { // issue #149 workaround // The mouseleave event above does not always fire. Whenever the mouse is moving // outside the plotarea, hide the tooltip - if (!hasTouch) { // #1385 - addEvent(doc, 'mousemove', mouseTracker.hideTooltipOnMouseMove); - } + addEvent(doc, 'mousemove', mouseTracker.hideTooltipOnMouseMove); container.ontouchstart = function (e) { // For touch devices, use touchmove to zoom @@ -9205,27 +9124,19 @@ Legend.prototype = { /** * Position the checkboxes after the width is determined */ - positionCheckboxes: function (scrollOffset) { - var alignAttr = this.group.alignAttr, - translateY, - clipHeight = this.clipHeight || this.legendHeight; + positionCheckboxes: function () { + var legend = this; - if (alignAttr) { - translateY = alignAttr.translateY; - each(this.allItems, function (item) { - var checkbox = item.checkbox, - top; - - if (checkbox) { - top = (translateY + checkbox.y + (scrollOffset || 0) + 3); - css(checkbox, { - left: (alignAttr.translateX + item.legendItemWidth + checkbox.x - 20) + PX, - top: top + PX, - display: top > translateY - 6 && top < translateY + clipHeight - 6 ? '' : NONE - }); - } - }); - } + each(legend.allItems, function (item) { + var checkbox = item.checkbox, + alignAttr = legend.group.alignAttr; + if (checkbox) { + css(checkbox, { + left: (alignAttr.translateX + item.legendItemWidth + checkbox.x - 20) + PX, + top: (alignAttr.translateY + checkbox.y + 3) + PX + }); + } + }); }, /** @@ -9254,8 +9165,7 @@ Legend.prototype = { li = item.legendItem, series = item.series || item, itemOptions = series.options, - showCheckbox = itemOptions.showCheckbox, - useHTML = options.useHTML; + showCheckbox = itemOptions.showCheckbox; if (!li) { // generate it once, later move it @@ -9273,7 +9183,7 @@ Legend.prototype = { options.labelFormatter.call(item), ltr ? symbolWidth + symbolPadding : -symbolPadding, legend.baseline, - useHTML + options.useHTML ) .css(merge(item.visible ? itemStyle : itemHiddenStyle)) // merge to prevent modifying original (#1021) .attr({ @@ -9282,8 +9192,8 @@ Legend.prototype = { }) .add(item.legendGroup); - // Set the events on the item group, or in case of useHTML, the item itself (#1249) - (useHTML ? li : item.legendGroup).on('mouseover', function () { + // Set the events on the item group + item.legendGroup.on('mouseover', function () { item.setState(HOVER_STATE); li.css(legend.options.itemHoverStyle); }) @@ -9602,7 +9512,6 @@ Legend.prototype = { this.scrollGroup.attr({ translateY: 1 }); - this.clipHeight = 0; // #1379 } return legendHeight; @@ -9621,8 +9530,7 @@ Legend.prototype = { activeColor = navOptions.activeColor, inactiveColor = navOptions.inactiveColor, pager = this.pager, - padding = this.padding, - scrollOffset; + padding = this.padding; // When resizing while looking at the last page if (currentPage > pageCount) { @@ -9657,9 +9565,8 @@ Legend.prototype = { cursor: currentPage === pageCount ? 'default' : 'pointer' }); - scrollOffset = -mathMin(clipHeight * (currentPage - 1), this.fullHeight - clipHeight + padding) + 1; this.scrollGroup.animate({ - translateY: scrollOffset + translateY: -mathMin(clipHeight * (currentPage - 1), this.fullHeight - clipHeight + padding) + 1 }); pager.attr({ text: currentPage + '/' + pageCount @@ -9667,7 +9574,6 @@ Legend.prototype = { this.currentPage = currentPage; - this.positionCheckboxes(scrollOffset); } } @@ -9680,108 +9586,72 @@ Legend.prototype = { * @param {Object} options * @param {Function} callback Function to run when the chart has loaded */ -function Chart() { - this.init.apply(this, arguments); +function Chart(userOptions, callback) { + // Handle regular options + var options, + seriesOptions = userOptions.series; // skip merging data points to increase performance + userOptions.series = null; + options = merge(defaultOptions, userOptions); // do the merge + options.series = userOptions.series = seriesOptions; // set back the series data + + var optionsChart = options.chart, + optionsMargin = optionsChart.margin, + margin = isObject(optionsMargin) ? + optionsMargin : + [optionsMargin, optionsMargin, optionsMargin, optionsMargin]; + + this.optionsMarginTop = pick(optionsChart.marginTop, margin[0]); + this.optionsMarginRight = pick(optionsChart.marginRight, margin[1]); + this.optionsMarginBottom = pick(optionsChart.marginBottom, margin[2]); + this.optionsMarginLeft = pick(optionsChart.marginLeft, margin[3]); + + var chartEvents = optionsChart.events; + + this.runChartClick = chartEvents && !!chartEvents.click; + this.callback = callback; + this.isResizing = 0; + this.options = options; + //chartTitleOptions = UNDEFINED; + //chartSubtitleOptions = UNDEFINED; + + this.axes = []; + this.series = []; + this.hasCartesianSeries = optionsChart.showAxes; + //this.axisOffset = UNDEFINED; + //this.maxTicks = UNDEFINED; // handle the greatest amount of ticks on grouped axes + //this.inverted = UNDEFINED; + //this.loadingShown = UNDEFINED; + //this.container = UNDEFINED; + //this.chartWidth = UNDEFINED; + //this.chartHeight = UNDEFINED; + //this.marginRight = UNDEFINED; + //this.marginBottom = UNDEFINED; + //this.containerWidth = UNDEFINED; + //this.containerHeight = UNDEFINED; + //this.oldChartWidth = UNDEFINED; + //this.oldChartHeight = UNDEFINED; + + //this.renderTo = UNDEFINED; + //this.renderToClone = UNDEFINED; + //this.tracker = UNDEFINED; + + //this.spacingBox = UNDEFINED + + //this.legend = UNDEFINED; + + // Elements + //this.chartBackground = UNDEFINED; + //this.plotBackground = UNDEFINED; + //this.plotBGImage = UNDEFINED; + //this.plotBorder = UNDEFINED; + //this.loadingDiv = UNDEFINED; + //this.loadingSpan = UNDEFINED; + + this.init(chartEvents); } Chart.prototype = { - /** - * Initialize the chart - */ - init: function (userOptions, callback) { - - // Handle regular options - var options, - seriesOptions = userOptions.series; // skip merging data points to increase performance - - userOptions.series = null; - options = merge(defaultOptions, userOptions); // do the merge - options.series = userOptions.series = seriesOptions; // set back the series data - - var optionsChart = options.chart, - optionsMargin = optionsChart.margin, - margin = isObject(optionsMargin) ? - optionsMargin : - [optionsMargin, optionsMargin, optionsMargin, optionsMargin]; - - this.optionsMarginTop = pick(optionsChart.marginTop, margin[0]); - this.optionsMarginRight = pick(optionsChart.marginRight, margin[1]); - this.optionsMarginBottom = pick(optionsChart.marginBottom, margin[2]); - this.optionsMarginLeft = pick(optionsChart.marginLeft, margin[3]); - - var chartEvents = optionsChart.events; - - this.runChartClick = chartEvents && !!chartEvents.click; - this.callback = callback; - this.isResizing = 0; - this.options = options; - //chartTitleOptions = UNDEFINED; - //chartSubtitleOptions = UNDEFINED; - - this.axes = []; - this.series = []; - this.hasCartesianSeries = optionsChart.showAxes; - //this.axisOffset = UNDEFINED; - //this.maxTicks = UNDEFINED; // handle the greatest amount of ticks on grouped axes - //this.inverted = UNDEFINED; - //this.loadingShown = UNDEFINED; - //this.container = UNDEFINED; - //this.chartWidth = UNDEFINED; - //this.chartHeight = UNDEFINED; - //this.marginRight = UNDEFINED; - //this.marginBottom = UNDEFINED; - //this.containerWidth = UNDEFINED; - //this.containerHeight = UNDEFINED; - //this.oldChartWidth = UNDEFINED; - //this.oldChartHeight = UNDEFINED; - - //this.renderTo = UNDEFINED; - //this.renderToClone = UNDEFINED; - //this.tracker = UNDEFINED; - - //this.spacingBox = UNDEFINED - - //this.legend = UNDEFINED; - - // Elements - //this.chartBackground = UNDEFINED; - //this.plotBackground = UNDEFINED; - //this.plotBGImage = UNDEFINED; - //this.plotBorder = UNDEFINED; - //this.loadingDiv = UNDEFINED; - //this.loadingSpan = UNDEFINED; - - var chart = this, - eventType; - - // Add the chart to the global lookup - chart.index = charts.length; - charts.push(chart); - - // Set up auto resize - if (optionsChart.reflow !== false) { - addEvent(chart, 'load', chart.initReflow); - } - - // Chart event handlers - if (chartEvents) { - for (eventType in chartEvents) { - addEvent(chart, eventType, chartEvents[eventType]); - } - } - - chart.xAxis = []; - chart.yAxis = []; - - // Expose methods and variables - chart.animation = useCanVG ? false : pick(optionsChart.animation, true); - chart.pointCount = 0; - chart.counters = new ChartCounters(); - - chart.firstRender(); - }, - /** * Initialize an individual series, called internally before render time */ @@ -9952,13 +9822,13 @@ Chart.prototype = { } + // the plot areas size has changed if (isDirtyBox) { chart.drawChartBox(); } - // redraw affected series each(series, function (serie) { if (serie.isDirty && serie.visible && @@ -9967,6 +9837,7 @@ Chart.prototype = { } }); + // move tooltip or reset if (tracker && tracker.resetTracker) { tracker.resetTracker(true); @@ -10320,10 +10191,10 @@ Chart.prototype = { chart.containerWidth = adapterRun(renderTo, 'width'); chart.containerHeight = adapterRun(renderTo, 'height'); - chart.chartWidth = mathMax(0, pick(optionsChart.width, chart.containerWidth, 600)); - chart.chartHeight = mathMax(0, pick(optionsChart.height, + chart.chartWidth = optionsChart.width || chart.containerWidth || 600; + chart.chartHeight = optionsChart.height || // the offsetHeight of an empty container is 0 in standard browsers, but 19 in IE7: - chart.containerHeight > 19 ? chart.containerHeight : 400)); + (chart.containerHeight > 19 ? chart.containerHeight : 400); }, /** @@ -10371,8 +10242,6 @@ Chart.prototype = { chartWidth, chartHeight, renderTo, - indexAttrName = 'data-highcharts-chart', - oldChartIndex, containerId; chart.renderTo = renderTo = optionsChart.renderTo; @@ -10386,15 +10255,6 @@ Chart.prototype = { if (!renderTo) { error(13, true); } - - // If the container already holds a chart, destroy it - oldChartIndex = pInt(attr(renderTo, indexAttrName)); - if (!isNaN(oldChartIndex) && charts[oldChartIndex]) { - charts[oldChartIndex].destroy(); - } - - // Make a reference to the chart from the div - attr(renderTo, indexAttrName, chart.index); // remove previous chart renderTo.innerHTML = ''; @@ -10567,14 +10427,13 @@ Chart.prototype = { // Width and height checks for display:none. Target is doc in IE8 and Opera, // win in Firefox, Chrome and IE9. - if (!chart.hasUserSize && width && height && (target === win || target === doc)) { + if (width && height && (target === win || target === doc)) { if (width !== chart.containerWidth || height !== chart.containerHeight) { clearTimeout(reflowTimeout); chart.reflowTimeout = reflowTimeout = setTimeout(function () { if (chart.container) { // It may have been destroyed in the meantime (#1257) - chart.setSize(width, height, false); - chart.hasUserSize = null; + chart.resize(width, height, false); } }, 100); } @@ -10594,7 +10453,8 @@ Chart.prototype = { * @param {Number} height * @param {Object|Boolean} animation */ - setSize: function (width, height, animation) { + // TODO: This method is called setSize in the api + resize: function (width, height, animation) { var chart = this, chartWidth, chartHeight, @@ -10620,11 +10480,10 @@ Chart.prototype = { chart.oldChartHeight = chart.chartHeight; chart.oldChartWidth = chart.chartWidth; if (defined(width)) { - chart.chartWidth = chartWidth = mathMax(0, mathRound(width)); - chart.hasUserSize = !!chartWidth; + chart.chartWidth = chartWidth = mathRound(width); } if (defined(height)) { - chart.chartHeight = chartHeight = mathMax(0, mathRound(height)); + chart.chartHeight = chartHeight = mathRound(height); } css(chart.container, { @@ -10705,8 +10564,8 @@ Chart.prototype = { chart.plotLeft = plotLeft = mathRound(chart.plotLeft); chart.plotTop = plotTop = mathRound(chart.plotTop); - chart.plotWidth = plotWidth = mathMax(0, mathRound(chartWidth - plotLeft - chart.marginRight)); - chart.plotHeight = plotHeight = mathMax(0, mathRound(chartHeight - plotTop - chart.marginBottom)); + chart.plotWidth = plotWidth = mathRound(chartWidth - plotLeft - chart.marginRight); + chart.plotHeight = plotHeight = mathRound(chartHeight - plotTop - chart.marginBottom); chart.plotSizeX = inverted ? plotHeight : plotWidth; chart.plotSizeY = inverted ? plotWidth : plotHeight; @@ -11025,13 +10884,9 @@ Chart.prototype = { container = chart.container, i, parentNode = container && container.parentNode; - + // fire the chart.destoy event fireEvent(chart, 'destroy'); - - // Delete the chart from charts lookup array - charts[chart.index] = UNDEFINED; - chart.renderTo.removeAttribute('data-highcharts-chart'); // remove events removeEvent(chart); @@ -11050,9 +10905,7 @@ Chart.prototype = { } // ==== Destroy chart properties: - each(['title', 'subtitle', 'chartBackground', 'plotBackground', 'plotBGImage', - 'plotBorder', 'seriesGroup', 'clipRect', 'credits', 'tracker', 'scroller', - 'rangeSelector', 'legend', 'resetZoomButton', 'tooltip', 'renderer'], function (name) { + each(['title', 'subtitle', 'chartBackground', 'plotBackground', 'plotBGImage', 'plotBorder', 'seriesGroup', 'clipRect', 'credits', 'tracker', 'scroller', 'rangeSelector', 'legend', 'resetZoomButton', 'tooltip', 'renderer'], function (name) { var prop = chart[name]; if (prop && prop.destroy) { @@ -11077,34 +10930,6 @@ Chart.prototype = { }, - - /** - * VML namespaces can't be added until after complete. Listening - * for Perini's doScroll hack is not enough. - */ - isReadyToRender: function () { - var chart = this; - - // Note: in spite of JSLint's complaints, win == win.top is required - /*jslint eqeq: true*/ - if ((!hasSVG && (win == win.top && doc.readyState !== 'complete')) || (useCanVG && !win.canvg)) { - /*jslint eqeq: false*/ - if (useCanVG) { - // Delay rendering until canvg library is downloaded and ready - CanVGController.push(function () { chart.firstRender(); }, chart.options.global.canvasToolsURL); - } else { - doc.attachEvent('onreadystatechange', function () { - doc.detachEvent('onreadystatechange', chart.firstRender); - if (doc.readyState === 'complete') { - chart.firstRender(); - } - }); - } - return false; - } - return true; - }, - /** * Prepare for first rendering after all data are loaded */ @@ -11113,12 +10938,29 @@ Chart.prototype = { options = chart.options, callback = chart.callback; - // Check whether the chart is ready to render - if (!chart.isReadyToRender()) { + // VML namespaces can't be added until after complete. Listening + // for Perini's doScroll hack is not enough. + var ONREADYSTATECHANGE = 'onreadystatechange', + COMPLETE = 'complete'; + // Note: in spite of JSLint's complaints, win == win.top is required + /*jslint eqeq: true*/ + if ((!hasSVG && (win == win.top && doc.readyState !== COMPLETE)) || (useCanVG && !win.canvg)) { + /*jslint eqeq: false*/ + if (useCanVG) { + // Delay rendering until canvg library is downloaded and ready + CanVGController.push(function () { chart.firstRender(); }, options.global.canvasToolsURL); + } else { + doc.attachEvent(ONREADYSTATECHANGE, function () { + doc.detachEvent(ONREADYSTATECHANGE, chart.firstRender); + if (doc.readyState === COMPLETE) { + chart.firstRender(); + } + }); + } return; } - // Create the container + // create the container chart.getContainer(); // Run an early event after the container and renderer are established @@ -11172,6 +11014,73 @@ Chart.prototype = { fireEvent(chart, 'load'); + }, + + init: function (chartEvents) { + var chart = this, + optionsChart = chart.options.chart, + eventType; + + // Run chart + + // Set up auto resize + if (optionsChart.reflow !== false) { + addEvent(chart, 'load', chart.initReflow); + } + + // Chart event handlers + if (chartEvents) { + for (eventType in chartEvents) { + addEvent(chart, eventType, chartEvents[eventType]); + } + } + + chart.xAxis = []; + chart.yAxis = []; + + // Expose methods and variables + chart.animation = useCanVG ? false : pick(optionsChart.animation, true); + chart.setSize = chart.resize; + chart.pointCount = 0; + chart.counters = new ChartCounters(); + /* + if ($) $(function () { + $container = $('#container'); + var origChartWidth, + origChartHeight; + if ($container) { + $('') + .insertBefore($container) + .click(function () { + if (origChartWidth === UNDEFINED) { + origChartWidth = chartWidth; + origChartHeight = chartHeight; + } + chart.resize(chartWidth *= 1.1, chartHeight *= 1.1); + }); + $('') + .insertBefore($container) + .click(function () { + if (origChartWidth === UNDEFINED) { + origChartWidth = chartWidth; + origChartHeight = chartHeight; + } + chart.resize(chartWidth *= 0.9, chartHeight *= 0.9); + }); + $('') + .insertBefore($container) + .click(function () { + if (origChartWidth === UNDEFINED) { + origChartWidth = chartWidth; + origChartHeight = chartHeight; + } + chart.resize(origChartWidth, origChartHeight); + }); + } + }) + */ + + chart.firstRender(); } }; // end Chart @@ -11199,6 +11108,7 @@ Point.prototype = { if (series.options.colorByPoint) { defaultColors = series.chart.options.colors; point.color = point.color || defaultColors[counters.color++]; + // loop back to zero counters.wrapColor(defaultColors.length); } @@ -11302,7 +11212,7 @@ Point.prototype = { */ destroyElements: function () { var point = this, - props = ['graphic', 'tracker', 'dataLabel', 'dataLabelUpper', 'group', 'connector', 'shadowGroup'], + props = ['graphic', 'tracker', 'dataLabel', 'group', 'connector', 'shadowGroup'], prop, i = 6; while (i--) { @@ -11427,7 +11337,7 @@ Point.prototype = { // Backwards compatibility to y naming in early Highstock seriesTooltipOptions.valuePrefix = seriesTooltipOptions.valuePrefix || seriesTooltipOptions.yPrefix; - seriesTooltipOptions.valueDecimals = pick(seriesTooltipOptions.valueDecimals, seriesTooltipOptions.yDecimals); // #1248 + seriesTooltipOptions.valueDecimals = seriesTooltipOptions.valueDecimals || seriesTooltipOptions.yDecimals; seriesTooltipOptions.valueSuffix = seriesTooltipOptions.valueSuffix || seriesTooltipOptions.ySuffix; // loop over the variables defined on the form {series.name}, {point.y} etc @@ -11496,7 +11406,7 @@ Point.prototype = { for (i = 0; i < dataLength; i++) { if (data[i] === point) { series.xData[i] = point.x; - series.yData[i] = point.toYData ? point.toYData() : point.y; + series.yData[i] = point.y; series.options.data[i] = options; break; } @@ -11714,7 +11624,6 @@ Series.prototype = { type: 'line', pointClass: Point, sorted: true, // requires the data to be sorted - requireSorting: true, pointAttrToOptions: { // mapping between SVG attributes and the corresponding options stroke: 'lineColor', 'stroke-width': 'lineWidth', @@ -12009,7 +11918,6 @@ Series.prototype = { */ addPoint: function (options, redraw, shift, animation) { var series = this, - seriesOptions = series.options, data = series.data, graph = series.graph, area = series.area, @@ -12017,7 +11925,7 @@ Series.prototype = { xData = series.xData, yData = series.yData, currentShift = (graph && graph.shift) || 0, - dataOptions = seriesOptions.data, + dataOptions = series.options.data, point, proto = series.pointClass.prototype; @@ -12045,10 +11953,6 @@ Series.prototype = { yData.push(proto.toYData ? proto.toYData.call(point) : point.y); dataOptions.push(options); - // Generate points to be added to the legend (#1329) - if (seriesOptions.legendType === 'point') { - series.generatePoints(); - } // Shift the first point off the parallel arrays // todo: consider series.removePoint(i) method @@ -12154,12 +12058,6 @@ Series.prototype = { yData[i] = pointProto.toYData ? pointProto.toYData.call(pt) : pt.y; } } - - // Unsorted data is not supported by the line tooltip as well as data grouping and - // navigation in Stock charts (#725) - if (series.requireSorting && xData.length > 1 && xData[1] < xData[0]) { - error(15); - } // Forgetting to cast strings to numbers is a common caveat when handling CSV or JSON if (isString(yData[0])) { @@ -12563,6 +12461,10 @@ Series.prototype = { chart = series.chart, hoverSeries = chart.hoverSeries; + /*if (!hasTouch && chart.mouseIsDown) { + return; + }*/ + // set normal state to previous series if (hoverSeries && hoverSeries !== series) { hoverSeries.onMouseOut(); @@ -12682,14 +12584,10 @@ Series.prototype = { afterAnimate: function () { var chart = this.chart, sharedClipKey = this.sharedClipKey, - group = this.group, - trackerGroup = this.trackerGroup; + group = this.group; if (group && this.options.clip !== false) { group.clip(chart.clipRect); - if (trackerGroup) { - trackerGroup.clip(chart.clipRect); // #484 - } this.markerGroup.clip(); // no clip } @@ -13030,7 +12928,7 @@ Series.prototype = { 'dataLabelsGroup', 'data-labels', series.visible ? VISIBLE : HIDDEN, - options.zIndex || 6 + 6 ); // Make the labels for each point @@ -13163,7 +13061,7 @@ Series.prototype = { // Show or hide based on the final aligned position dataLabel.attr({ visibility: options.crop === false || chart.isInsidePlot(alignAttr.x, alignAttr.y) || chart.isInsidePlot(plotX, plotY, inverted) ? - (chart.renderer.isSVG ? 'inherit' : VISIBLE) : + (hasSVG ? 'inherit' : VISIBLE) : HIDDEN }); @@ -13174,15 +13072,10 @@ Series.prototype = { */ getSegmentPath: function (segment) { var series = this, - segmentPath = [], - step = series.options.step; - + segmentPath = []; + // build the segment line each(segment, function (point, i) { - - var plotX = point.plotX, - plotY = point.plotY, - lastPoint; if (series.getPointSpline) { // generate the spline as defined in the SplineSeries object segmentPath.push.apply(segmentPath, series.getPointSpline(segment, point, i)); @@ -13193,28 +13086,12 @@ Series.prototype = { segmentPath.push(i ? L : M); // step line? - if (step && i) { - lastPoint = segment[i - 1]; - if (step === 'right') { - segmentPath.push( - lastPoint.plotX, - plotY - ); - - } else if (step === 'center') { - segmentPath.push( - (lastPoint.plotX + plotX) / 2, - lastPoint.plotY, - (lastPoint.plotX + plotX) / 2, - plotY - ); - - } else { - segmentPath.push( - plotX, - lastPoint.plotY - ); - } + if (i && series.options.step) { + var lastPoint = segment[i - 1]; + segmentPath.push( + point.plotX, + lastPoint.plotY + ); } // normal line to next point @@ -13550,11 +13427,6 @@ Series.prototype = { } } } - - // hide tooltip (#1361) - if (chart.hoverSeries === series) { - series.onMouseOut(); - } if (dataLabelsGroup) { @@ -13641,17 +13513,7 @@ Series.prototype = { singlePoints = series.singlePoints, trackerGroup = this.isCartesian && this.plotGroup('trackerGroup', null, VISIBLE, options.zIndex || 1, chart.trackerGroup), singlePoint, - i, - onMouseOver = function () { - if (chart.hoverSeries !== series) { - series.onMouseOver(); - } - }, - onMouseOut = function () { - if (!options.stickyTracking) { - series.onMouseOut(); - } - }; + i; // Extend end points. A better way would be to use round linecaps, // but those are not clickable in VML. @@ -13682,23 +13544,27 @@ Series.prototype = { } else { // create - series.tracker = tracker = renderer.path(trackerPath) + series.tracker = renderer.path(trackerPath) .attr({ isTracker: true, - 'stroke-linejoin': 'round', // #1225 + 'stroke-linejoin': 'bevel', visibility: series.visible ? VISIBLE : HIDDEN, stroke: TRACKER_FILL, fill: trackByArea ? TRACKER_FILL : NONE, 'stroke-width' : options.lineWidth + (trackByArea ? 0 : 2 * snap) }) - .on('mouseover', onMouseOver) - .on('mouseout', onMouseOut) + .on(hasTouch ? 'touchstart' : 'mouseover', function () { + if (chart.hoverSeries !== series) { + series.onMouseOver(); + } + }) + .on('mouseout', function () { + if (!options.stickyTracking) { + series.onMouseOut(); + } + }) .css(css) .add(trackerGroup); - - if (hasTouch) { - tracker.on('touchstart', onMouseOver); - } } } @@ -14062,7 +13928,6 @@ var ColumnSeries = extendClass(Series, { borderWidth = options.borderWidth, columnCount = 0, xAxis = series.xAxis, - yAxis = series.yAxis, reversedXAxis = xAxis.reversed, stackGroups = {}, stackKey, @@ -14075,6 +13940,7 @@ var ColumnSeries = extendClass(Series, { // chart.orderStacks() function and call it on init, addSeries and removeSeries if (options.grouping === false) { columnCount = 1; + } else { each(chart.series, function (otherSeries) { var otherOptions = otherSeries.options; @@ -14107,24 +13973,23 @@ var ColumnSeries = extendClass(Series, { pointOffsetWidth * options.pointPadding, pointWidth = pick(optionPointWidth, pointOffsetWidth - 2 * pointPadding), // exact point width, used in polar charts barW = mathCeil(mathMax(pointWidth, 1 + 2 * borderWidth)), // rounded and postprocessed for border width - colIndex = (reversedXAxis ? - columnCount - (series.columnIndex || 0) : // #1251 - series.columnIndex) || 0, + colIndex = (reversedXAxis ? columnCount - + series.columnIndex : series.columnIndex) || 0, pointXOffset = pointPadding + (groupPadding + colIndex * pointOffsetWidth - (categoryWidth / 2)) * (reversedXAxis ? -1 : 1), threshold = options.threshold, - translatedThreshold = series.translatedThreshold = yAxis.getThreshold(threshold), + translatedThreshold = series.translatedThreshold = series.yAxis.getThreshold(threshold), minPointLength = pick(options.minPointLength, 5); // record the new values each(points, function (point) { - var plotY = mathMin(mathMax(-999, point.plotY), yAxis.len + 999), // Don't draw too far outside plot area (#1303) + var plotY = point.plotY, yBottom = pick(point.yBottom, translatedThreshold), barX = point.plotX + pointXOffset, barY = mathCeil(mathMin(plotY, yBottom)), barH = mathCeil(mathMax(plotY, yBottom) - barY), - stack = yAxis.stacks[(point.y < 0 ? '-' : '') + series.stackKey], + stack = series.yAxis.stacks[(point.y < 0 ? '-' : '') + series.stackKey], shapeArgs; // Record the offset'ed position and width of the bar to be able to align the stacking total correctly @@ -14213,7 +14078,7 @@ var ColumnSeries = extendClass(Series, { }, /** * Draw the individual tracker elements. - * This method is inherited by pie charts too. + * This method is inherited by scatter and pie charts too. */ drawTracker: function () { var series = this, @@ -14228,28 +14093,9 @@ var ColumnSeries = extendClass(Series, { trackerGroup = series.isCartesian && series.plotGroup('trackerGroup', null, VISIBLE, options.zIndex || 1, chart.trackerGroup), rel, plotY, - validPlotY, - points = series.points, - point, - i = points.length, - onMouseOver = function (event) { - rel = event.relatedTarget || event.fromElement; - if (chart.hoverSeries !== series && attr(rel, 'isTracker') !== trackerLabel) { - series.onMouseOver(); - } - points[event.target._i].onMouseOver(); - }, - onMouseOut = function (event) { - if (!options.stickyTracking) { - rel = event.relatedTarget || event.toElement; - if (attr(rel, 'isTracker') !== trackerLabel) { - series.onMouseOut(); - } - } - }; + validPlotY; - while (i--) { - point = points[i]; + each(series.points, function (point) { tracker = point.tracker; shapeArgs = point.trackerArgs || point.shapeArgs; plotY = point.plotY; @@ -14260,25 +14106,34 @@ var ColumnSeries = extendClass(Series, { tracker.attr(shapeArgs); } else { - point.tracker = tracker = + point.tracker = renderer[point.shapeType](shapeArgs) .attr({ isTracker: trackerLabel, fill: TRACKER_FILL, visibility: series.visible ? VISIBLE : HIDDEN }) - .on('mouseover', onMouseOver) - .on('mouseout', onMouseOut) + .on(hasTouch ? 'touchstart' : 'mouseover', function (event) { + rel = event.relatedTarget || event.fromElement; + if (chart.hoverSeries !== series && attr(rel, 'isTracker') !== trackerLabel) { + series.onMouseOver(); + } + point.onMouseOver(); + + }) + .on('mouseout', function (event) { + if (!options.stickyTracking) { + rel = event.relatedTarget || event.toElement; + if (attr(rel, 'isTracker') !== trackerLabel) { + series.onMouseOut(); + } + } + }) .css(css) .add(point.group || trackerGroup); // pies have point group - see issue #118 - - if (hasTouch) { - tracker.on('touchstart', onMouseOver); - } } - tracker.element._i = i; } - } + }); }, /** @@ -14287,7 +14142,7 @@ var ColumnSeries = extendClass(Series, { alignDataLabel: function (point, dataLabel, options, alignTo, isNew) { var chart = this.chart, inverted = chart.inverted, - below = point.below || (point.plotY > pick(this.translatedThreshold, chart.plotSizeY)), + below = point.below || (point.plotY > (this.translatedThreshold || chart.plotSizeY)), inside = (this.options.stacking || options.inside); // draw it inside the box? // Align to the column itself, or the top of it @@ -14377,7 +14232,6 @@ var ColumnSeries = extendClass(Series, { } }, - /** * Remove this series from the chart */ @@ -14434,7 +14288,6 @@ defaultPlotOptions.scatter = merge(defaultSeriesOptions, { var ScatterSeries = extendClass(Series, { type: 'scatter', sorted: false, - requireSorting: false, /** * Extend the base Series' translate method by adding shape type and * arguments for the point trackers @@ -14464,19 +14317,7 @@ var ScatterSeries = extendClass(Series, { css = cursor && { cursor: cursor }, points = series.points, i = points.length, - graphic, - markerGroup = series.markerGroup, - onMouseOver = function (e) { - series.onMouseOver(); - if (e.target._i !== UNDEFINED) { // undefined on graph in scatterchart - points[e.target._i].onMouseOver(); - } - }, - onMouseOut = function () { - if (!series.options.stickyTracking) { - series.onMouseOut(); - } - }; + graphic; // Set an expando property for the point index, used below while (i--) { @@ -14488,23 +14329,26 @@ var ScatterSeries = extendClass(Series, { // Add the event listeners, we need to do this only once if (!series._hasTracking) { - markerGroup + series.markerGroup .attr({ isTracker: true }) - .on('mouseover', onMouseOver) - .on('mouseout', onMouseOut) + .on(hasTouch ? 'touchstart' : 'mouseover', function (e) { + series.onMouseOver(); + if (e.target._i !== UNDEFINED) { // undefined on graph in scatterchart + points[e.target._i].onMouseOver(); + } + }) + .on('mouseout', function () { + if (!series.options.stickyTracking) { + series.onMouseOut(); + } + }) .css(css); - if (hasTouch) { - markerGroup.on('touchstart', onMouseOver); - } - } else { series._hasTracking = true; } - }, - - setTooltipPoints: noop + } }); seriesTypes.scatter = ScatterSeries; @@ -14656,7 +14500,6 @@ var PieSeries = { type: 'pie', isCartesian: false, pointClass: PiePoint, - requireSorting: false, pointAttrToOptions: { // mapping between SVG attributes and the corresponding options stroke: 'borderColor', 'stroke-width': 'borderWidth', @@ -14676,19 +14519,19 @@ var PieSeries = { */ animate: function () { var series = this, - points = series.points, - startAngleRad = series.startAngleRad; + points = series.points; each(points, function (point) { var graphic = point.graphic, - args = point.shapeArgs; + args = point.shapeArgs, + up = -mathPI / 2; if (graphic) { // start values graphic.attr({ - r: series.center[3] / 2, // animate from inner radius (#779) - start: startAngleRad, - end: startAngleRad + r: 0, + start: up, + end: up }); // animate @@ -14754,7 +14597,7 @@ var PieSeries = { var total = 0, series = this, - cumulative = 0, + cumulative = -0.25, // start at top precision = 1000, // issue #172 options = series.options, slicedOffset = options.slicedOffset, @@ -14764,7 +14607,6 @@ var PieSeries = { start, end, angle, - startAngleRad = series.startAngleRad = mathPI / 180 * ((options.startAngle || 0) % 360 - 90), points = series.points, circ = 2 * mathPI, fraction, @@ -14802,11 +14644,11 @@ var PieSeries = { // set start and end angle fraction = total ? point.y / total : 0; - start = mathRound((startAngleRad + (cumulative * circ)) * precision) / precision; + start = mathRound(cumulative * circ * precision) / precision; if (!ignoreHiddenPoint || point.visible) { cumulative += fraction; } - end = mathRound((startAngleRad + (cumulative * circ)) * precision) / precision; + end = mathRound(cumulative * circ * precision) / precision; // set the shape point.shapeType = 'arc'; @@ -14821,9 +14663,6 @@ var PieSeries = { // center for the sliced out slice angle = (end + start) / 2; - if (angle > 0.75 * circ) { - angle -= 2 * mathPI; - } point.slicedTranslation = map([ mathCos(angle) * slicedOffset + chart.plotLeft, mathSin(angle) * slicedOffset + chart.plotTop @@ -14836,9 +14675,6 @@ var PieSeries = { positions[0] + radiusX * 0.7, positions[1] + radiusY * 0.7 ]; - - point.half = angle < circ / 4 ? 0 : 1; - point.angle = angle; // set the anchor point for data labels point.labelPos = [ @@ -14850,7 +14686,7 @@ var PieSeries = { positions[1] + radiusY, // a/a labelDistance < 0 ? // alignment 'center' : - point.half ? 'right' : 'left', // alignment + angle < circ / 4 ? 'left' : 'right', // alignment angle // center angle ]; @@ -14987,16 +14823,9 @@ var PieSeries = { y, visibility, rankArr, + sort, i = 2, - j, - sort = function (a, b) { - return b.y - a.y; - }, - sortByAngle = function (points, sign) { - points.sort(function (a, b) { - return (b.angle - a.angle) * sign; - }); - }; + j; // get out if not enabled if (!options.enabled && !series._hasPointLabels) { @@ -15009,9 +14838,17 @@ var PieSeries = { // arrange points for detection collision each(data, function (point) { if (point.dataLabel) { // it may have been cancelled in the base method (#407) - halves[point.half].push(point); + halves[ + point.labelPos[7] < mathPI / 2 ? 0 : 1 + ].push(point); } }); + halves[1].reverse(); + + // define the sorting algorithm + sort = function (a, b) { + return b.y - a.y; + }; // assume equal label heights labelHeight = halves[0][0] && halves[0][0].dataLabel && (halves[0][0].dataLabel.getBBox().height || 21); // 21 is for #968 @@ -15028,9 +14865,6 @@ var PieSeries = { pos, length = points.length, slotIndex; - - // Sort by angle - sortByAngle(points, i - 0.5); // Only do anti-collision when we are outside the pie and have connectors (#856) if (distanceOption > 0) { @@ -15247,14 +15081,10 @@ extend(Highcharts, { VMLRenderer: VMLRenderer, // Various - arrayMin: arrayMin, - arrayMax: arrayMax, - charts: charts, dateFormat: dateFormat, pathAnim: pathAnim, getOptions: getOptions, hasBidiBug: hasBidiBug, - isTouchDevice: isTouchDevice, numberFormat: numberFormat, seriesTypes: seriesTypes, setOptions: setOptions, @@ -15276,6 +15106,6 @@ extend(Highcharts, { canvas: useCanVG, vml: !hasSVG && !useCanVG, product: 'Highcharts', - version: '2.3.5' + version: '2.3.3' }); }()); diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.js index 3425fc7ea3b..619c527cf94 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.js @@ -11,7 +11,7 @@ Requires: rgbcolor.js - http://www.phpied.com/rgb-color-parser-in-javascript/ - Highcharts JS v2.3.5 (2012-12-19) + Highcharts JS v2.3.3 (2012-10-04) CanVGRenderer Extension module (c) 2011-2012 Torstein Hønsi, Erik Olsson diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.src.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.src.js index 8e8954d9677..35c1f5689a7 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.src.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/canvas-tools.src.js @@ -2908,7 +2908,7 @@ if (CanvasRenderingContext2D) { }); } }/** - * @license Highcharts JS v2.3.5 (2012-12-19) + * @license Highcharts JS v2.3.3 (2012-10-04) * CanVGRenderer Extension module * * (c) 2011-2012 Torstein Hønsi, Erik Olsson diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/data.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/data.js index 9f6116a3be3..3c9a519b965 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/data.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/data.js @@ -5,10 +5,7 @@ License: www.highcharts.com/license */ -(function(h){var l=h.each,m=function(a){this.init(a)};h.extend(m.prototype,{init:function(a){this.options=a;this.columns=a.columns||this.rowsToColumns(a.rows)||[];this.columns.length?this.dataFound():(this.parseCSV(),this.parseTable(),this.parseGoogleSpreadsheet())},dataFound:function(){this.parseTypes();this.findHeaderRow();this.parsed();this.complete()},parseCSV:function(){var a=this.options,b=a.csv,d=this.columns,c=a.startRow||0,g=a.endRow||Number.MAX_VALUE,f=a.startColumn||0,j=a.endColumn||Number.MAX_VALUE; -b&&(b=b.replace(/\r\n/g,"\n").replace(/\r/g,"\n").split(a.lineDelimiter||"\n"),l(b,function(b,k){if(k>=c&&k<=g){var e=b.split(a.itemDelimiter||",");l(e,function(a,b){b>=f&&b<=j&&(d[b-f]||(d[b-f]=[]),d[b-f][k-c]=a)})}}),this.dataFound())},parseTable:function(){var a=this.options,b=a.table,d=this.columns,c=a.startRow||0,g=a.endRow||Number.MAX_VALUE,f=a.startColumn||0,j=a.endColumn||Number.MAX_VALUE,i;b&&(typeof b==="string"&&(b=document.getElementById(b)),l(b.getElementsByTagName("tr"),function(a,b){i= -0;b>=c&&b<=g&&l(a.childNodes,function(a){if((a.tagName==="TD"||a.tagName==="TH")&&i>=f&&i<=j)d[i]||(d[i]=[]),d[i][b-c]=a.innerHTML,i+=1})}),this.dataFound())},parseGoogleSpreadsheet:function(){var a=this,b=this.options,d=b.googleSpreadsheetKey,c=this.columns;d&&jQuery.getJSON("https://spreadsheets.google.com/feeds/cells/"+d+"/"+(b.googleSpreadsheetWorksheet||"od6")+"/public/values?alt=json-in-script&callback=?",function(b){var b=b.feed.entry,d,j=b.length,i=0,k=0,e;for(e=0;e31536E6?a[b].isDatetime=!0:a[b].isNumeric= -!0):(c=this.parseDate(c),b===0&&typeof c==="number"&&!isNaN(c)?(a[b][d]=c,a[b].isDatetime=!0):a[b][d]=f)},dateFormats:{"YYYY-mm-dd":{regex:"^([0-9]{4})-([0-9]{2})-([0-9]{2})$",parser:function(a){return Date.UTC(+a[1],a[2]-1,+a[3])}}},parseDate:function(a){var b=this.options.parseDate,d,c,g;b&&(d=b);if(typeof a==="string")for(c in this.dateFormats)b=this.dateFormats[c],(g=a.match(b.regex))&&(d=b.parser(g));return d},rowsToColumns:function(a){var b,d,c,g,f;if(a){f=[];d=a.length;for(b=0;b1&&(c=a.shift(),this.headerRow===0&&c.shift(),(b=c.isNumeric||c.isDatetime)||(d=c),c.isDatetime&&(g="datetime"));j=[];for(e=0;e=c&&k<=f){var h=b.split(a.itemDelimiter||",");l(h,function(a, +b){b>=e&&b<=j&&(d[b-e]||(d[b-e]=[]),d[b-e][k-c]=a)})}}))},parseTable:function(){var a=this.options,b=a.table,d=this.columns,c=a.startRow||0,f=a.endRow||Number.MAX_VALUE,e=a.startColumn||0,j=a.endColumn||Number.MAX_VALUE,g;b&&(typeof b==="string"&&(b=document.getElementById(b)),l(b.getElementsByTagName("tr"),function(a,b){g=0;b>=c&&b<=f&&l(a.childNodes,function(a){if((a.tagName==="TD"||a.tagName==="TH")&&g>=e&&g<=j)d[g]||(d[g]=[]),d[g][b-c]=a.innerHTML,g+=1})}))},findHeaderRow:function(){l(this.columns, +function(){});this.headerRow=0},trim:function(a){return a.replace(/^\s+|\s+$/g,"")},parseTypes:function(){for(var a=this.columns,b=a.length,d,c,f,e;b--;)for(d=a[b].length;d--;)c=a[b][d],f=parseFloat(c),e=this.trim(c),e==f?(a[b][d]=f,f>31536E6?a[b].isDatetime=!0:a[b].isNumeric=!0):(c=Date.parse(c),b===0&&typeof c==="number"&&!isNaN(c)?(a[b][d]=c,a[b].isDatetime=!0):a[b][d]=e)},parsed:function(){this.options.parsed&&this.options.parsed.call(this,this.columns)},complete:function(){var a=this.columns, +b,d,c,f,e=this.options,j,g,k,h,i;if(e.complete){a.length>1&&(c=a.shift(),this.headerRow===0&&c.shift(),(b=c.isNumeric||c.isDatetime)||(d=c),c.isDatetime&&(f="datetime"));j=[];for(h=0;h> - * A two-dimensional array representing the input data on tabular form. This input can - * be used when the data is already parsed, for example from a grid view component. - * Each cell can be a string or number. If not switchRowsAndColumns is set, the columns - * are interpreted as series. See also the rows option. - * - * - complete : Function(chartOptions) - * The callback that is evaluated when the data is finished loading, optionally from an - * external source, and parsed. The first argument passed is a finished chart options - * object, containing series and an xAxis with categories if applicable. Thise options - * can be extended with additional options and passed directly to the chart constructor. - * - * - csv : String - * A comma delimited string to be parsed. Related options are startRow, endRow, startColumn - * and endColumn to delimit what part of the table is used. The lineDelimiter and - * itemDelimiter options define the CSV delimiter formats. - * - * - endColumn : Integer - * In tabular input data, the first row (indexed by 0) to use. Defaults to the last - * column containing data. - * - * - endRow : Integer - * In tabular input data, the last row (indexed by 0) to use. Defaults to the last row - * containing data. - * - * - googleSpreadsheetKey : String - * A Google Spreadsheet key. See https://developers.google.com/gdata/samples/spreadsheet_sample - * for general information on GS. - * - * - googleSpreadsheetKey : String - * The Google Spreadsheet worksheet. The available id's can be read from - * https://spreadsheets.google.com/feeds/worksheets/{key}/public/basic - * - * - itemDilimiter : String - * Item or cell delimiter for parsing CSV. Defaults to ",". - * - * - lineDilimiter : String - * Line delimiter for parsing CSV. Defaults to "\n". - * - * - parsed : Function - * A callback function to access the parsed columns, the two-dimentional input data - * array directly, before they are interpreted into series data and categories. - * - * - parseDate : Function - * A callback function to parse string representations of dates into JavaScript timestamps. - * Return an integer on success. - * - * - rows : Array> - * The same as the columns input option, but defining rows intead of columns. - * - * - startColumn : Integer - * In tabular input data, the first column (indexed by 0) to use. - * - * - startRow : Integer - * In tabular input data, the first row (indexed by 0) to use. - * - * - table : String|HTMLElement - * A HTML table or the id of such to be parsed as input data. Related options ara startRow, - * endRow, startColumn and endColumn to delimit what part of the table is used. */ -/*global jQuery */ (function (Highcharts) { // Utilities @@ -96,28 +29,14 @@ */ init: function (options) { this.options = options; - this.columns = options.columns || this.rowsToColumns(options.rows) || []; - - // No need to parse or interpret anything - if (this.columns.length) { - this.dataFound(); - - // Parse and interpret - } else { - - // Parse a CSV string if options.csv is given - this.parseCSV(); - - // Parse a HTML table if options.table is given - this.parseTable(); - - // Parse a Google Spreadsheet - this.parseGoogleSpreadsheet(); - } - - }, - - dataFound: function () { + this.columns = []; + + + // Parse a CSV string if options.csv is given + this.parseCSV(); + + // Parse a HTML table if options.table is given + this.parseTable(); // Interpret the values into right types this.parseTypes(); @@ -147,11 +66,7 @@ lines; if (csv) { - - lines = csv - .replace(/\r\n/g, "\n") // Unix - .replace(/\r/g, "\n") // Mac - .split(options.lineDelimiter || "\n"); + lines = csv.split(options.lineDelimiter || '\n'); each(lines, function (line, rowNo) { if (rowNo >= startRow && rowNo <= endRow) { @@ -166,8 +81,7 @@ } }); } - }); - this.dataFound(); + }); } }, @@ -205,58 +119,6 @@ }); } }); - - this.dataFound(); // continue - } - }, - - /** - * TODO: - * - switchRowsAndColumns - * - startRow, endRow etc. - */ - parseGoogleSpreadsheet: function () { - var self = this, - options = this.options, - googleSpreadsheetKey = options.googleSpreadsheetKey, - columns = this.columns; - - if (googleSpreadsheetKey) { - jQuery.getJSON('https://spreadsheets.google.com/feeds/cells/' + - googleSpreadsheetKey + '/' + (options.googleSpreadsheetWorksheet || 'od6') + - '/public/values?alt=json-in-script&callback=?', - function (json) { - - // Prepare the data from the spreadsheat - var cells = json.feed.entry, - cell, - cellCount = cells.length, - colCount = 0, - rowCount = 0, - i; - - // First, find the total number of columns and rows that - // are actually filled with data - for (i = 0; i < cellCount; i++) { - cell = cells[i]; - colCount = Math.max(colCount, cell.gs$cell.col); - rowCount = Math.max(rowCount, cell.gs$cell.row); - } - - // Set up arrays containing the column data - for (i = 0; i < colCount; i++) { - columns[i] = new Array(rowCount); - } - - // Loop over the cells and assign the value to the right - // place in the column arrays - for (i = 0; i < cellCount; i++) { - cell = cells[i]; - columns[cell.gs$cell.col - 1][cell.gs$cell.row - 1] = - cell.content.$t; - } - self.dataFound(); - }); } }, @@ -279,8 +141,7 @@ * Trim a string from whitespace */ trim: function (str) { - //return typeof str === 'number' ? str : str.replace(/^\s+|\s+$/g, ''); // fails with spreadsheet - return typeof str === 'string' ? str.replace(/^\s+|\s+$/g, '') : str; + return str.replace(/^\s+|\s+$/g, ''); }, /** @@ -315,7 +176,7 @@ } } else { // string, continue to determine if it is a date string or really a string - dateVal = this.parseDate(val); + dateVal = Date.parse(val); if (col === 0 && typeof dateVal === 'number' && !isNaN(dateVal)) { // is date columns[col][row] = dateVal; @@ -327,73 +188,9 @@ } } - } - }, - //* - dateFormats: { - 'YYYY-mm-dd': { - regex: '^([0-9]{4})-([0-9]{2})-([0-9]{2})$', - parser: function (match) { - return Date.UTC(+match[1], match[2] - 1, +match[3]); - } - } - }, - // */ - /** - * Parse a date and return it as a number. Overridable through options.parseDate. - */ - parseDate: function (val) { - var parseDate = this.options.parseDate, - ret, - key, - format, - match; - - if (parseDate) { - ret = parseDate; - } - - if (typeof val === 'string') { - for (key in this.dateFormats) { - format = this.dateFormats[key]; - match = val.match(format.regex); - if (match) { - ret = format.parser(match); - } - } - } - return ret; + } }, - /** - * Reorganize rows into columns - */ - rowsToColumns: function (rows) { - var row, - rowsLength, - col, - colsLength, - columns; - - if (rows) { - columns = []; - rowsLength = rows.length; - for (row = 0; row < rowsLength; row++) { - colsLength = rows[row].length; - for (col = 0; col < colsLength; col++) { - if (!columns[col]) { - columns[col] = []; - } - columns[col][row] = rows[row][col]; - } - } - } - return columns; - }, - - /** - * A hook for working directly on the parsed columns - */ parsed: function () { if (this.options.parsed) { this.options.parsed.call(this, this.columns); @@ -477,36 +274,4 @@ Highcharts.data = function (options) { return new Data(options); }; - - // Extend Chart.init so that the Chart constructor accepts a new configuration - // option group, data. - Highcharts.wrap(Highcharts.Chart.prototype, 'init', function (proceed, userOptions, callback) { - var chart = this; - - if (userOptions && userOptions.data) { - Highcharts.data(Highcharts.extend(userOptions.data, { - complete: function (dataOptions) { - var datasets = []; - - // Don't merge the data arrays themselves - each(dataOptions.series, function (series, i) { - datasets[i] = series.data; - series.data = null; - }); - - // Do the merge - userOptions = Highcharts.merge(dataOptions, userOptions); - - // Re-insert the data - each(datasets, function (data, i) { - userOptions.series[i].data = data; - }); - proceed.call(chart, userOptions, callback); - } - })); - } else { - proceed.call(chart, userOptions, callback); - } - }); - }(Highcharts)); diff --git a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.js b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.js index 5c0d0e5c61c..655f1c5ea42 100644 --- a/java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.js +++ b/java/com.sap.sailing.gwt.ui/highcharts/js/modules/exporting.js @@ -1,23 +1,23 @@ /* - Highcharts JS v2.3.5 (2012-12-19) + Highcharts JS v2.3.3 (2012-10-04) Exporting module (c) 2010-2011 Torstein Hønsi License: www.highcharts.com/license */ -(function(e){function y(a){for(var b=a.length;b--;)typeof a[b]==="number"&&(a[b]=Math.round(a[b])-0.5);return a}var z=e.Chart,u=e.addEvent,B=e.removeEvent,j=e.createElement,v=e.discardElement,t=e.css,l=e.merge,k=e.each,o=e.extend,C=Math.max,i=document,D=window,E=e.isTouchDevice,A=e.Renderer.prototype.symbols,w=e.getOptions();o(w.lang,{downloadPNG:"Download PNG image",downloadJPEG:"Download JPEG image",downloadPDF:"Download PDF document",downloadSVG:"Download SVG vector image",exportButtonTitle:"Export to raster or vector image", -printButtonTitle:"Print the chart"});w.navigation={menuStyle:{border:"1px solid #A0A0A0",background:"#FFFFFF"},menuItemStyle:{padding:"0 5px",background:"none",color:"#303030",fontSize:E?"14px":"11px"},menuItemHoverStyle:{background:"#4572A5",color:"#FFFFFF"},buttonOptions:{align:"right",backgroundColor:{linearGradient:[0,0,0,20],stops:[[0.4,"#F7F7F7"],[0.6,"#E3E3E3"]]},borderColor:"#B0B0B0",borderRadius:3,borderWidth:1,height:20,hoverBorderColor:"#909090",hoverSymbolFill:"#81A7CF",hoverSymbolStroke:"#4572A5", -symbolFill:"#E0E0E0",symbolStroke:"#A0A0A0",symbolX:11.5,symbolY:10.5,verticalAlign:"top",width:24,y:10}};w.exporting={type:"image/png",url:"http://export.highcharts.com/",width:800,buttons:{exportButton:{symbol:"exportIcon",x:-10,symbolFill:"#A8BF77",hoverSymbolFill:"#768F3E",_id:"exportButton",_titleKey:"exportButtonTitle",menuItems:[{textKey:"downloadPNG",onclick:function(){this.exportChart()}},{textKey:"downloadJPEG",onclick:function(){this.exportChart({type:"image/jpeg"})}},{textKey:"downloadPDF", -onclick:function(){this.exportChart({type:"application/pdf"})}},{textKey:"downloadSVG",onclick:function(){this.exportChart({type:"image/svg+xml"})}}]},printButton:{symbol:"printIcon",x:-36,symbolFill:"#B5C9DF",hoverSymbolFill:"#779ABF",_id:"printButton",_titleKey:"printButtonTitle",onclick:function(){this.print()}}}};e.post=function(a,b){var c,d;d=j("form",{method:"post",action:a,enctype:"multipart/form-data"},{display:"none"},i.body);for(c in b)j("input",{type:"hidden",name:c,value:b[c]},null,d); -d.submit();v(d)};o(z.prototype,{getSVG:function(a){var b=this,c,d,f,g=l(b.options,a);if(!i.createElementNS)i.createElementNS=function(a,b){return i.createElement(b)};a=j("div",null,{position:"absolute",top:"-9999em",width:b.chartWidth+"px",height:b.chartHeight+"px"},i.body);o(g.chart,{renderTo:a,forExport:!0});g.exporting.enabled=!1;g.chart.plotBackgroundImage=null;g.series=[];k(b.series,function(a){f=l(a.options,{animation:!1,showCheckbox:!1,visible:a.visible});f.isInternal||g.series.push(f)});c= -new e.Chart(g);k(["xAxis","yAxis"],function(a){k(b[a],function(b,d){var f=c[a][d],g=b.getExtremes(),e=g.userMin,g=g.userMax;(e!==void 0||g!==void 0)&&f.setExtremes(e,g,!0,!1)})});d=c.container.innerHTML;g=null;c.destroy();v(a);d=d.replace(/zIndex="[^"]+"/g,"").replace(/isShadow="[^"]+"/g,"").replace(/symbolName="[^"]+"/g,"").replace(/jQuery[0-9]+="[^"]+"/g,"").replace(/isTracker="[^"]+"/g,"").replace(/url\([^#]+#/g,"url(#").replace(/.*?$/,"").replace(/ /g," ").replace(/­/g,"­").replace(//g,'xlink:href="$1"/>').replace(/id=([^" >]+)/g,'id="$1"').replace(/class=([^" ]+)/g,'class="$1"').replace(/ transform /g," ").replace(/:(path|rect)/g,"$1").replace(/style="([^"]+)"/g,function(a){return a.toLowerCase()});d=d.replace(/(url\(#highcharts-[0-9]+)"/g, -"$1").replace(/"/g,"'");d.match(/ xmlns="/g).length===2&&(d=d.replace(/xmlns="[^"]+"/,""));return d},exportChart:function(a,b){var c=this.options.exporting,d=this.getSVG(l(c.chartOptions,b)),a=l(c,a);e.post(a.url,{filename:a.filename||"chart",type:a.type,width:a.width,scale:a.scale||2,svg:d})},print:function(){var a=this,b=a.container,c=[],d=b.parentNode,f=i.body,g=f.childNodes;if(!a.isPrinting)a.isPrinting=!0,k(g,function(a,b){if(a.nodeType===1)c[b]=a.style.display,a.style.display="none"}), -f.appendChild(b),D.print(),setTimeout(function(){d.appendChild(b);k(g,function(a,b){if(a.nodeType===1)a.style.display=c[b]});a.isPrinting=!1},1E3)},contextMenu:function(a,b,c,d,f,g){var e=this,p=e.options.navigation,i=p.menuItemStyle,q=e.chartWidth,r=e.chartHeight,s="cache-"+a,h=e[s],m=C(f,g),x,n,l;if(!h)e[s]=h=j("div",{className:"highcharts-"+a},{position:"absolute",zIndex:1E3,padding:m+"px"},e.container),x=j("div",null,o({MozBoxShadow:"3px 3px 10px #888",WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"}, -p.menuStyle),h),n=function(){t(h,{display:"none"})},u(h,"mouseleave",function(){l=setTimeout(n,500)}),u(h,"mouseenter",function(){clearTimeout(l)}),k(b,function(a){if(a){var b=j("div",{onmouseover:function(){t(this,p.menuItemHoverStyle)},onmouseout:function(){t(this,i)},innerHTML:a.text||e.options.lang[a.textKey]},o({cursor:"pointer"},i),x);b.onclick=function(){n();a.onclick.apply(e,arguments)};e.exportDivElements.push(b)}}),e.exportDivElements.push(x,h),e.exportMenuWidth=h.offsetWidth,e.exportMenuHeight= -h.offsetHeight;a={display:"block"};c+e.exportMenuWidth>q?a.right=q-c-f-m+"px":a.left=c-m+"px";d+g+e.exportMenuHeight>r?a.bottom=r-d-m+"px":a.top=d+g-m+"px";t(h,a)},addButton:function(a){function b(){r.attr(k);q.attr(m)}var c=this,d=c.renderer,f=l(c.options.navigation.buttonOptions,a),e=f.onclick,i=f.menuItems,p=f.width,j=f.height,q,r,s,h,a=f.borderWidth,m={stroke:f.borderColor},k={stroke:f.symbolStroke,fill:f.symbolFill},n=f.symbolSize||12;if(!c.btnCount)c.btnCount=0;h=c.btnCount++;if(!c.exportDivElements)c.exportDivElements= -[],c.exportSVGElements=[];f.enabled!==!1&&(q=d.rect(0,0,p,j,f.borderRadius,a).align(f,!0).attr(o({fill:f.backgroundColor,"stroke-width":a,zIndex:19},m)).add(),s=d.rect(0,0,p,j,0).align(f).attr({id:f._id,fill:"rgba(255, 255, 255, 0.001)",title:c.options.lang[f._titleKey],zIndex:21}).css({cursor:"pointer"}).on("mouseover",function(){r.attr({stroke:f.hoverSymbolStroke,fill:f.hoverSymbolFill});q.attr({stroke:f.hoverBorderColor})}).on("mouseout",b).on("click",b).add(),i&&(e=function(){b();var a=s.getBBox(); -c.contextMenu("menu"+h,i,a.x,a.y,p,j)}),s.on("click",function(){e.apply(c,arguments)}),r=d.symbol(f.symbol,f.symbolX-n/2,f.symbolY-n/2,n,n).align(f,!0).attr(o(k,{"stroke-width":f.symbolStrokeWidth||1,zIndex:20})).add(),c.exportSVGElements.push(q,s,r))},destroyExport:function(){var a,b;for(a=0;a.*?$/,"").replace(/ /g," ").replace(/­/g,"­").replace(//g,'xlink:href="$1"/>').replace(/id=([^" >]+)/g,'id="$1"').replace(/class=([^" ]+)/g,'class="$1"').replace(/ transform /g," ").replace(/:(path|rect)/g,"$1").replace(/style="([^"]+)"/g,function(a){return a.toLowerCase()});d=d.replace(/(url\(#highcharts-[0-9]+)"/g,"$1").replace(/"/g,"'");d.match(/ xmlns="/g).length===2&&(d=d.replace(/xmlns="[^"]+"/,""));return d},exportChart:function(a, +b){var c,d=this.getSVG(s(this.options.exporting.chartOptions,b)),a=s(this.options.exporting,a);c=r("form",{method:"post",action:a.url,enctype:"multipart/form-data"},{display:"none"},h.body);k(["filename","type","width","svg"],function(b){r("input",{type:"hidden",name:b,value:{filename:a.filename||"chart",type:a.type,width:a.width,svg:d}[b]},null,c)});c.submit();u(c)},print:function(){var a=this,b=a.container,c=[],d=b.parentNode,e=h.body,f=e.childNodes;if(!a.isPrinting)a.isPrinting=!0,k(f,function(a, +b){if(a.nodeType===1)c[b]=a.style.display,a.style.display="none"}),e.appendChild(b),D.print(),setTimeout(function(){d.appendChild(b);k(f,function(a,b){if(a.nodeType===1)a.style.display=c[b]});a.isPrinting=!1},1E3)},contextMenu:function(a,b,c,d,e,f){var i=this,g=i.options.navigation,h=g.menuItemStyle,o=i.chartWidth,p=i.chartHeight,q="cache-"+a,j=i[q],l=C(e,f),m,w;if(!j)i[q]=j=r("div",{className:"highcharts-"+a},{position:"absolute",zIndex:1E3,padding:l+"px"},i.container),m=r("div",null,n({MozBoxShadow:"3px 3px 10px #888", +WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"},g.menuStyle),j),w=function(){t(j,{display:"none"})},z(j,"mouseleave",w),k(b,function(a){if(a){var b=r("div",{onmouseover:function(){t(this,g.menuItemHoverStyle)},onmouseout:function(){t(this,h)},innerHTML:a.text||i.options.lang[a.textKey]},n({cursor:"pointer"},h),m);b[A?"ontouchstart":"onclick"]=function(){w();a.onclick.apply(i,arguments)};i.exportDivElements.push(b)}}),i.exportDivElements.push(m,j),i.exportMenuWidth=j.offsetWidth, +i.exportMenuHeight=j.offsetHeight;a={display:"block"};c+i.exportMenuWidth>o?a.right=o-c-e-l+"px":a.left=c-l+"px";d+f+i.exportMenuHeight>p?a.bottom=p-d-l+"px":a.top=d+f-l+"px";t(j,a)},addButton:function(a){function b(){p.attr(l);o.attr(j)}var c=this,d=c.renderer,e=s(c.options.navigation.buttonOptions,a),f=e.onclick,g=e.menuItems,h=e.width,k=e.height,o,p,q,a=e.borderWidth,j={stroke:e.borderColor},l={stroke:e.symbolStroke,fill:e.symbolFill},m=e.symbolSize||12;if(!c.exportDivElements)c.exportDivElements= +[],c.exportSVGElements=[];e.enabled!==!1&&(o=d.rect(0,0,h,k,e.borderRadius,a).align(e,!0).attr(n({fill:e.backgroundColor,"stroke-width":a,zIndex:19},j)).add(),q=d.rect(0,0,h,k,0).align(e).attr({id:e._id,fill:"rgba(255, 255, 255, 0.001)",title:c.options.lang[e._titleKey],zIndex:21}).css({cursor:"pointer"}).on("mouseover",function(){p.attr({stroke:e.hoverSymbolStroke,fill:e.hoverSymbolFill});o.attr({stroke:e.hoverBorderColor})}).on("mouseout",b).on("click",b).add(),g&&(f=function(){b();var a=q.getBBox(); +c.contextMenu("export-menu",g,a.x,a.y,h,k)}),q.on("click",function(){f.apply(c,arguments)}),p=d.symbol(e.symbol,e.symbolX-m/2,e.symbolY-m/2,m,m).align(e,!0).attr(n(l,{"stroke-width":e.symbolStrokeWidth||1,zIndex:20})).add(),c.exportSVGElements.push(o,q,p))},destroyExport:function(){var a,b;for(a=0;a Date: Tue, 29 Jan 2013 12:59:23 +0100 Subject: [PATCH 16/37] Added connection between polarsheets front- and backend --- .../domain/common/PolarSheetsData.java | 12 +++++ .../common/impl/PolarSheetsDataImpl.java | 33 ++++++++++++++ .../domain/polarsheets/PerRaceWorker.java | 3 ++ .../PolarSheetGenerationWorker.java | 18 +++++--- .../sailing/gwt/ui/client/SailingService.java | 3 ++ .../gwt/ui/client/SailingServiceAsync.java | 3 ++ .../ui/polarsheets/PolarSheetsChartPanel.java | 20 ++++++++- .../gwt/ui/polarsheets/PolarSheetsPanel.java | 44 ++++++++++++++++--- .../gwt/ui/server/SailingServiceImpl.java | 21 +++++++++ 9 files changed, 144 insertions(+), 13 deletions(-) create mode 100644 java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java create mode 100644 java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java new file mode 100644 index 00000000000..3692addbb18 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java @@ -0,0 +1,12 @@ +package com.sap.sailing.domain.common; + +import java.io.Serializable; +import java.util.Map; + +public interface PolarSheetsData extends Serializable { + + Map getData(); + + boolean isComplete(); + +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java new file mode 100644 index 00000000000..6f48b9ed235 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java @@ -0,0 +1,33 @@ +package com.sap.sailing.domain.common.impl; + +import java.util.Map; + +import com.sap.sailing.domain.common.PolarSheetsData; + +public class PolarSheetsDataImpl implements PolarSheetsData { + + private static final long serialVersionUID = -4649254807341866894L; + + private Map data; + + private boolean complete; + + //For GWT Serialization + PolarSheetsDataImpl() {}; + + public PolarSheetsDataImpl(Map data, boolean complete) { + this.data = data; + this.complete = complete; + } + + @Override + public Map getData() { + return data; + } + + @Override + public boolean isComplete() { + return complete; + } + +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java index 13748eefdba..a472c5985ed 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java @@ -46,6 +46,7 @@ public class PerRaceWorker implements Runnable { @Override public void run() { GPSFixTrack track = race.getTrack(competitor); + track.lockForRead(); Iterator fixesIterator = track.getFixesIterator(startTime, true); // TODO maneuver exclusion // List maneuvers = race.getManeuvers(competitor, startTime, endTime, false); @@ -70,6 +71,8 @@ public class PerRaceWorker implements Runnable { polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed); } + + track.unlockAfterRead(); } }; diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java index 23b550634ab..8e926d843de 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java @@ -42,18 +42,24 @@ public class PolarSheetGenerationWorker { } public void addPolarData(long round, double normalizedSpeed) { - polarData.get(round).add(normalizedSpeed); + if (round >= 0 && round < 360) { + polarData.get((int) round).add(normalizedSpeed); + } } public Map getPolarData() { Map averagedPolarData = new HashMap(); for (Entry> entry : polarData.entrySet()) { - double sum = 0; - for (Double singleData : entry.getValue()) { - sum = sum + singleData; + if (entry.getValue().size() < 1) { + averagedPolarData.put(entry.getKey(), new Double(0)); + } else { + double sum = 0; + for (Double singleData : entry.getValue()) { + sum = sum + singleData; + } + double average = sum / entry.getValue().size(); + averagedPolarData.put(entry.getKey(), average); } - double average = sum / entry.getValue().size(); - averagedPolarData.put(entry.getKey(), average); } return averagedPolarData; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java index af791ee8b47..02bb226dd64 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java @@ -14,6 +14,7 @@ import com.sap.sailing.domain.common.Color; import com.sap.sailing.domain.common.DetailType; import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.NoWindException; +import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.RegattaIdentifier; import com.sap.sailing.domain.common.ScoringSchemeType; @@ -301,4 +302,6 @@ public interface SailingService extends RemoteService { void storeSwissTimingArchiveConfiguration(String swissTimingUrl); String generatePolarSheetForRaces(List selectedRaces); + + PolarSheetsData getPolarSheetsGenerationResults(String id); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java index 45a189f7144..f21ec215331 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java @@ -12,6 +12,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback; import com.sap.sailing.domain.common.Color; import com.sap.sailing.domain.common.DetailType; import com.sap.sailing.domain.common.MaxPointsReason; +import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.RegattaIdentifier; @@ -471,4 +472,6 @@ public interface SailingServiceAsync { void storeSwissTimingArchiveConfiguration(String swissTimingUrl, AsyncCallback asyncCallback); void generatePolarSheetForRaces(List selectedRaces, AsyncCallback asyncCallback); + + void getPolarSheetsGenerationResults(String id, AsyncCallback asyncCallback); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java index baa58f44c5e..7c1cbbc32e1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java @@ -1,5 +1,6 @@ package com.sap.sailing.gwt.ui.polarsheets; +import java.util.HashMap; import java.util.Map; import org.moxieapps.gwt.highcharts.client.Chart; @@ -18,6 +19,7 @@ public class PolarSheetsChartPanel extends SimplePanel { this.stringMessages = stringMessages; setSize("100%", "100%"); chart = createPolarSheetChart(); + seriesMap = new HashMap(); setWidget(chart); } @@ -28,7 +30,7 @@ public class PolarSheetsChartPanel extends SimplePanel { return polarSheetChart; } - public void newSeries(String name) { + private void newSeries(String name) { if (!seriesMap.containsKey(name)) { Number[] forEachDeg = initializeDataForNewSeries(); Series newSeries = chart.createSeries().setPoints(forEachDeg); @@ -45,7 +47,7 @@ public class PolarSheetsChartPanel extends SimplePanel { return forEachDeg; } - public void addDataToSeries(String seriesName, int deg, double value) { + private void addDataToSeries(String seriesName, int deg, double value) { if (seriesMap.containsKey(seriesName)) { Series series = seriesMap.get(seriesName); series.addPoint(deg, value); @@ -65,4 +67,18 @@ public class PolarSheetsChartPanel extends SimplePanel { seriesMap.clear(); } + public void setData(Map data, String id) { + if (data == null) { + //TODO Exception handling + return; + } + if (!seriesMap.containsKey(id)) { + newSeries(id); + } + for (int i = 0; i < 360; i++) { + addDataToSeries(id, i, data.get(i)); + } + chart.redraw(); + } + } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index 899d86994f2..038e298d535 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -1,14 +1,17 @@ package com.sap.sailing.gwt.ui.polarsheets; +import java.util.ArrayList; import java.util.List; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.VerticalPanel; +import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.RaceSelectionChangeListener; @@ -90,22 +93,53 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi } protected void startPolarSheetGeneration() { - sailingService.generatePolarSheetForRaces(selectedRaces, new AsyncCallback() { + //List conversion, to make List serializable + List selectedRacesInArrayList = new ArrayList(); + selectedRacesInArrayList.addAll(selectedRaces); + sailingService.generatePolarSheetForRaces(selectedRacesInArrayList, new AsyncCallback() { @Override public void onSuccess(String result) { - // TODO Auto-generated method stub - + startPullingResults(result); } @Override public void onFailure(Throwable caught) { - // TODO Auto-generated method stub - + errorReporter.reportError(caught.getLocalizedMessage()); } }); } + protected void startPullingResults(final String id) { + + sailingService.getPolarSheetsGenerationResults(id, new AsyncCallback() { + + @Override + public void onSuccess(PolarSheetsData result) { + chartPanel.setData(result.getData(), id); + if (!result.isComplete()) { + Timer timer = new Timer() { + + @Override + public void run() { + startPullingResults(id); + } + }; + + timer.schedule(500); + + } + } + + @Override + public void onFailure(Throwable caught) { + // TODO Exception handling + } + + }); + + } + @Override public void onRaceSelectionChange(List selectedRaces) { this.selectedRaces = selectedRaces; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index b86c7621dbd..9cfa796585d 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -75,6 +75,7 @@ import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.NoWindError; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.Placemark; +import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.RaceFetcher; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; @@ -96,6 +97,7 @@ import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.impl.DegreePosition; import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl; import com.sap.sailing.domain.common.impl.MeterDistance; +import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl; import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Triple; @@ -3219,4 +3221,23 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S genWorker.startPolarSheetGeneration(); return id; } + + @Override + public PolarSheetsData getPolarSheetsGenerationResults(String id) { + PolarSheetsData data = null; + if (polarSheetGenerationWorkers.containsKey(id)) { + PolarSheetGenerationWorker worker = polarSheetGenerationWorkers.get(id); + boolean complete = worker.isFinished(); + Map rawData = worker.getPolarData(); + data = new PolarSheetsDataImpl(rawData, complete); + if (complete) { + polarSheetGenerationWorkers.remove(id); + } + } else { + //TODO Exception handling + } + + return data; + + } } \ No newline at end of file From 298744e141dc8c73aa8a30171137e230829ff1c8 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Tue, 29 Jan 2013 17:07:10 +0100 Subject: [PATCH 17/37] Fixes for Polarsheet generation concerning multi-threading angles Still problem with locks --- .../domain/common/PolarSheetsData.java | 3 +- .../common/impl/PolarSheetsDataImpl.java | 12 ++-- .../domain/polarsheets/PerRaceWorker.java | 56 ++++++++++++++-- .../PolarSheetGenerationWorker.java | 64 +++++++++++++------ .../ui/polarsheets/PolarSheetsChartPanel.java | 30 ++++----- .../gwt/ui/polarsheets/PolarSheetsPanel.java | 4 +- .../gwt/ui/server/SailingServiceImpl.java | 4 +- 7 files changed, 118 insertions(+), 55 deletions(-) diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java index 3692addbb18..33b548a973c 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java @@ -1,11 +1,10 @@ package com.sap.sailing.domain.common; import java.io.Serializable; -import java.util.Map; public interface PolarSheetsData extends Serializable { - Map getData(); + Number[] getValues(); boolean isComplete(); diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java index 6f48b9ed235..04b7a2a835d 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java @@ -1,28 +1,26 @@ package com.sap.sailing.domain.common.impl; -import java.util.Map; - import com.sap.sailing.domain.common.PolarSheetsData; public class PolarSheetsDataImpl implements PolarSheetsData { private static final long serialVersionUID = -4649254807341866894L; - private Map data; + private Number[] values; private boolean complete; //For GWT Serialization PolarSheetsDataImpl() {}; - public PolarSheetsDataImpl(Map data, boolean complete) { - this.data = data; + public PolarSheetsDataImpl(Number[] values, boolean complete) { + this.values = values; this.complete = complete; } @Override - public Map getData() { - return data; + public Number[] getValues() { + return values; } @Override diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java index a472c5985ed..ca60baec52f 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java @@ -1,6 +1,10 @@ package com.sap.sailing.domain.polarsheets; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.RaceDefinition; @@ -28,18 +32,58 @@ public class PerRaceWorker implements Runnable { public void run() { TimePoint startTime = race.getStartOfRace(); TimePoint endTime = race.getEndOfRace(); + if (endTime == null) { + //TODO Figure out if there is an alternative: + endTime = race.getTimePointOfNewestEvent(); + } RaceDefinition raceDefinition = race.getRace(); Iterable competitors = raceDefinition.getCompetitors(); + + final List perCompetitorWorkers = new ArrayList(); + for (Competitor competitor : competitors) { - getPolarDataForCompetitor(startTime, endTime, competitor); + Thread competitorWorkerThread = getPerCompetitorWorkerThread(startTime, endTime, competitor); + competitorWorkerThread.start(); + perCompetitorWorkers.add(competitorWorkerThread); } + + final Timer timer = new Timer(); + + TimerTask threadMonitoringTask = new TimerTask() { + + @Override + public void run() { + boolean perCompetitorWorkersDone = false; + do { + boolean currentWorkerAlive = true; + Thread currentWorker = null; + for (Thread worker : perCompetitorWorkers) { + currentWorker = worker; + if (!worker.isAlive()) { + currentWorkerAlive = false; + } + } + if (!currentWorkerAlive) { + perCompetitorWorkers.remove(currentWorker); + if (perCompetitorWorkers.isEmpty()) { + perCompetitorWorkersDone = true; + } + } + } while (!perCompetitorWorkersDone); - polarSheetGenerationWorker.workerDone(this); + polarSheetGenerationWorker.workerDone(PerRaceWorker.this); + timer.cancel(); + } + }; + + timer.schedule(threadMonitoringTask, 500, 500); + + } - private void getPolarDataForCompetitor(final TimePoint startTime, final TimePoint endTime, + private Thread getPerCompetitorWorkerThread(final TimePoint startTime, final TimePoint endTime, final Competitor competitor) { Runnable perCompetitorWorker = new Runnable() { @@ -62,12 +106,12 @@ public class PerRaceWorker implements Runnable { Bearing bearing = speedWithBearing.getBearing(); Position position = fix.getPosition(); Wind wind = race.getWind(position, fix.getTimePoint()); - Bearing windBearing = wind.getBearing(); + Bearing windBearing = wind.getFrom(); double windSpeed = wind.getMetersPerSecond(); // TODO Figure out if this normalizing is okay concerning different windspeeds and bearings double normalizedSpeed = speed / windSpeed; - double angleToWind = bearing.getDifferenceTo(windBearing).getDegrees(); + double angleToWind = 180 + bearing.getDifferenceTo(windBearing).getDegrees(); polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed); } @@ -77,7 +121,7 @@ public class PerRaceWorker implements Runnable { }; Thread perCompetitorThread = new Thread(perCompetitorWorker); - perCompetitorThread.start(); + return perCompetitorThread; } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java index 8e926d843de..53ac4450649 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java @@ -1,11 +1,8 @@ package com.sap.sailing.domain.polarsheets; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import com.sap.sailing.domain.tracking.TrackedRace; @@ -16,7 +13,9 @@ public class PolarSheetGenerationWorker { private final Set workers; - private final Map> polarData; + private final List> polarData; + + private boolean workerInitDone = false; public PolarSheetGenerationWorker(Set trackedRaces) { polarData = initializePolarDataContainer(); @@ -26,10 +25,10 @@ public class PolarSheetGenerationWorker { } } - private Map> initializePolarDataContainer() { - HashMap> container = new HashMap>(); - for (int i = 0; i < 360; i++) { - container.put(i, new ArrayList()); + private List> initializePolarDataContainer() { + List> container = new ArrayList>(); + for (int i = 0; i < 181; i++) { + container.add(new ArrayList()); } return container; } @@ -39,34 +38,57 @@ public class PolarSheetGenerationWorker { Thread workerThread = new Thread(worker); workerThread.start(); } + workerInitDone = true; } - public void addPolarData(long round, double normalizedSpeed) { - if (round >= 0 && round < 360) { - polarData.get((int) round).add(normalizedSpeed); + public void addPolarData(long roundedAngle, double normalizedSpeed) { + int angle = (int) roundedAngle; + if (angle > 180) { + angle = (360 - angle); } + polarData.get(angle).add(normalizedSpeed); } - public Map getPolarData() { - Map averagedPolarData = new HashMap(); - for (Entry> entry : polarData.entrySet()) { - if (entry.getValue().size() < 1) { - averagedPolarData.put(entry.getKey(), new Double(0)); + public Number[] getPolarData() { + Number[] averagedPolarData = new Number[360]; + for (int i = 0; i < 181; i++) { + // Avoid Concurrent modification, lock would slow things down + Double[] values = polarData.get(i).toArray(new Double[polarData.get(i).size()]); + if (values.length < 20) { + averagedPolarData[i] = 0; } else { double sum = 0; - for (Double singleData : entry.getValue()) { - sum = sum + singleData; + for (Double singleData : values) { + if (singleData != null) { + sum = sum + singleData; + } } - double average = sum / entry.getValue().size(); - averagedPolarData.put(entry.getKey(), average); + double average = sum / values.length; + averagedPolarData[i] = average; } } + for (int i = 1; i < 180; i++) { + if (averagedPolarData[i].doubleValue() == 0) { + double next = 0; + int currentIndex = i; + while (next <= 0 && currentIndex < 181) { + currentIndex++; + if (averagedPolarData[currentIndex] != null) { + next = averagedPolarData[currentIndex].doubleValue(); + } + } + averagedPolarData[i] = (averagedPolarData[i - 1].doubleValue() + next) / 2; + } + + averagedPolarData[360 - i] = averagedPolarData[i]; + } + return averagedPolarData; } public void workerDone(PerRaceWorker worker) { - if (workers.contains(worker)) { + if (workers.contains(worker) && workerInitDone) { workers.remove(worker); if (workers.isEmpty()) { finished = true; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java index 7c1cbbc32e1..8ff31818e43 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java @@ -5,6 +5,7 @@ import java.util.Map; import org.moxieapps.gwt.highcharts.client.Chart; import org.moxieapps.gwt.highcharts.client.Series; +import org.moxieapps.gwt.highcharts.client.plotOptions.LinePlotOptions; import com.google.gwt.user.client.ui.SimplePanel; import com.sap.sailing.gwt.ui.client.StringMessages; @@ -24,9 +25,10 @@ public class PolarSheetsChartPanel extends SimplePanel { } private Chart createPolarSheetChart() { - Chart polarSheetChart = new Chart().setType(Series.Type.LINE).setZoomType(Chart.ZoomType.X_AND_Y) + Chart polarSheetChart = new Chart().setType(Series.Type.LINE).setLinePlotOptions(new LinePlotOptions().setLineWidth(1)).setZoomType(Chart.ZoomType.X_AND_Y) .setPolar(true).setSize(700, 700); polarSheetChart.setChartTitleText(stringMessages.polarSheetChart()); + polarSheetChart.getYAxis().setMin(0); return polarSheetChart; } @@ -47,18 +49,18 @@ public class PolarSheetsChartPanel extends SimplePanel { return forEachDeg; } - private void addDataToSeries(String seriesName, int deg, double value) { - if (seriesMap.containsKey(seriesName)) { - Series series = seriesMap.get(seriesName); - series.addPoint(deg, value); + private void addValuesToSeries(String seriesId, Number[] values) { + if (seriesMap.containsKey(seriesId)) { + Series series = seriesMap.get(seriesId); + series.setPoints(values, false); } } - public void removeSeries(String seriesName) { - if (seriesMap.containsKey(seriesName)) { - Series series = seriesMap.get(seriesName); + public void removeSeries(String seriesId) { + if (seriesMap.containsKey(seriesId)) { + Series series = seriesMap.get(seriesId); chart.removeSeries(series); - seriesMap.remove(seriesName); + seriesMap.remove(seriesId); } } @@ -67,17 +69,15 @@ public class PolarSheetsChartPanel extends SimplePanel { seriesMap.clear(); } - public void setData(Map data, String id) { - if (data == null) { - //TODO Exception handling + public void setData(Number[] values, String id) { + if (values == null) { + // TODO Exception handling return; } if (!seriesMap.containsKey(id)) { newSeries(id); } - for (int i = 0; i < 360; i++) { - addDataToSeries(id, i, data.get(i)); - } + addValuesToSeries(id, values); chart.redraw(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index 038e298d535..62c4b627f09 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -116,7 +116,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi @Override public void onSuccess(PolarSheetsData result) { - chartPanel.setData(result.getData(), id); + chartPanel.setData(result.getValues(), id); if (!result.isComplete()) { Timer timer = new Timer() { @@ -126,7 +126,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi } }; - timer.schedule(500); + timer.schedule(1500); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 9cfa796585d..b501edc7346 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -3228,8 +3228,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S if (polarSheetGenerationWorkers.containsKey(id)) { PolarSheetGenerationWorker worker = polarSheetGenerationWorkers.get(id); boolean complete = worker.isFinished(); - Map rawData = worker.getPolarData(); - data = new PolarSheetsDataImpl(rawData, complete); + Number[] values = worker.getPolarData(); + data = new PolarSheetsDataImpl(values, complete); if (complete) { polarSheetGenerationWorkers.remove(id); } From 43eb0a5e830bc42eb9ab7fe2a1cd0a70e977000d Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Wed, 30 Jan 2013 08:37:36 +0100 Subject: [PATCH 18/37] Fixed missing import and field for last merge --- .../com/sap/sailing/gwt/ui/server/SailingServiceImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index f9baccebf45..602b0fde87a 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -97,6 +97,7 @@ import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.impl.DegreePosition; import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl; import com.sap.sailing.domain.common.impl.MeterDistance; +import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl; import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Triple; @@ -110,6 +111,7 @@ import com.sap.sailing.domain.persistence.DomainObjectFactory; import com.sap.sailing.domain.persistence.MongoFactory; import com.sap.sailing.domain.persistence.MongoObjectFactory; import com.sap.sailing.domain.persistence.MongoWindStoreFactory; +import com.sap.sailing.domain.polarsheets.PolarSheetGenerationWorker; import com.sap.sailing.domain.swisstimingadapter.SwissTimingArchiveConfiguration; import com.sap.sailing.domain.swisstimingadapter.SwissTimingConfiguration; import com.sap.sailing.domain.swisstimingadapter.SwissTimingFactory; @@ -305,6 +307,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S private final DomainFactory tractracDomainFactory; private final com.sap.sailing.domain.base.DomainFactory baseDomainFactory; + + private final Map polarSheetGenerationWorkers = new HashMap(); public SailingServiceImpl() { BundleContext context = Activator.getDefault(); From 8ee3d50d1b3cbc75d05ee46bd4fc19ea6d21830a Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Wed, 30 Jan 2013 14:44:40 +0100 Subject: [PATCH 19/37] Added debugging labels to polarsheetspanel --- .../domain/common/PolarSheetsData.java | 4 ++ .../common/impl/PolarSheetsDataImpl.java | 18 +++++++- .../domain/polarsheets/PerRaceWorker.java | 8 ++-- .../PolarSheetGenerationWorker.java | 43 +++++++------------ .../ui/polarsheets/PolarSheetsChartPanel.java | 37 +++++++++++++--- .../gwt/ui/polarsheets/PolarSheetsPanel.java | 42 ++++++++++++++---- .../gwt/ui/server/SailingServiceImpl.java | 7 +-- 7 files changed, 109 insertions(+), 50 deletions(-) diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java index 33b548a973c..321fcab9ee0 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java @@ -6,6 +6,10 @@ public interface PolarSheetsData extends Serializable { Number[] getValues(); + int getDataCount(); + boolean isComplete(); + + Integer[] getDataCountPerAngle(); } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java index 04b7a2a835d..ad1f2dabb63 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java @@ -10,12 +10,18 @@ public class PolarSheetsDataImpl implements PolarSheetsData { private boolean complete; + private int dataCount; + + private Integer[] dataCountPerAngle; + //For GWT Serialization PolarSheetsDataImpl() {}; - public PolarSheetsDataImpl(Number[] values, boolean complete) { + public PolarSheetsDataImpl(Number[] values, boolean complete, int dataCount, Integer[] dataCountPerAngle) { this.values = values; this.complete = complete; + this.dataCount = dataCount; + this.dataCountPerAngle = dataCountPerAngle; } @Override @@ -28,4 +34,14 @@ public class PolarSheetsDataImpl implements PolarSheetsData { return complete; } + @Override + public int getDataCount() { + return dataCount; + } + + @Override + public Integer[] getDataCountPerAngle() { + return dataCountPerAngle; + } + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java index ca60baec52f..c105ead6741 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java @@ -92,14 +92,16 @@ public class PerRaceWorker implements Runnable { GPSFixTrack track = race.getTrack(competitor); track.lockForRead(); Iterator fixesIterator = track.getFixesIterator(startTime, true); - // TODO maneuver exclusion - // List maneuvers = race.getManeuvers(competitor, startTime, endTime, false); while (fixesIterator.hasNext()) { GPSFixMoving fix = fixesIterator.next(); if (fix.getTimePoint().after(endTime)) { break; } + + if (track.hasDirectionChange(fix.getTimePoint(), race.getRace().getBoatClass().getManeuverDegreeAngleThreshold())) { + continue; + } SpeedWithBearing speedWithBearing = fix.getSpeed(); double speed = speedWithBearing.getMetersPerSecond(); @@ -111,7 +113,7 @@ public class PerRaceWorker implements Runnable { // TODO Figure out if this normalizing is okay concerning different windspeeds and bearings double normalizedSpeed = speed / windSpeed; - double angleToWind = 180 + bearing.getDifferenceTo(windBearing).getDegrees(); + double angleToWind = bearing.getDifferenceTo(windBearing).getDegrees(); polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java index 53ac4450649..e5b7ac77677 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java @@ -5,6 +5,8 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import com.sap.sailing.domain.common.PolarSheetsData; +import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl; import com.sap.sailing.domain.tracking.TrackedRace; public class PolarSheetGenerationWorker { @@ -27,7 +29,7 @@ public class PolarSheetGenerationWorker { private List> initializePolarDataContainer() { List> container = new ArrayList>(); - for (int i = 0; i < 181; i++) { + for (int i = 0; i < 360; i++) { container.add(new ArrayList()); } return container; @@ -43,18 +45,22 @@ public class PolarSheetGenerationWorker { public void addPolarData(long roundedAngle, double normalizedSpeed) { int angle = (int) roundedAngle; - if (angle > 180) { - angle = (360 - angle); + if (angle < 0) { + angle = (360 + angle); } polarData.get(angle).add(normalizedSpeed); } - public Number[] getPolarData() { + public PolarSheetsData getPolarData() { Number[] averagedPolarData = new Number[360]; - for (int i = 0; i < 181; i++) { + Integer[] dataCountPerAngle = new Integer[360]; + int dataCount = 0; + for (int i = 0; i < 360; i++) { // Avoid Concurrent modification, lock would slow things down Double[] values = polarData.get(i).toArray(new Double[polarData.get(i).size()]); - if (values.length < 20) { + dataCount = dataCount + values.length; + dataCountPerAngle[i] = values.length; + if (values.length < 1) { averagedPolarData[i] = 0; } else { double sum = 0; @@ -67,24 +73,11 @@ public class PolarSheetGenerationWorker { averagedPolarData[i] = average; } } + + PolarSheetsData data = new PolarSheetsDataImpl(averagedPolarData, finished, dataCount, dataCountPerAngle); - for (int i = 1; i < 180; i++) { - if (averagedPolarData[i].doubleValue() == 0) { - double next = 0; - int currentIndex = i; - while (next <= 0 && currentIndex < 181) { - currentIndex++; - if (averagedPolarData[currentIndex] != null) { - next = averagedPolarData[currentIndex].doubleValue(); - } - } - averagedPolarData[i] = (averagedPolarData[i - 1].doubleValue() + next) / 2; - } - - averagedPolarData[360 - i] = averagedPolarData[i]; - } - - return averagedPolarData; + + return data; } public void workerDone(PerRaceWorker worker) { @@ -96,8 +89,4 @@ public class PolarSheetGenerationWorker { } } - public boolean isFinished() { - return finished; - } - } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java index 8ff31818e43..0595d95988b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java @@ -1,13 +1,20 @@ package com.sap.sailing.gwt.ui.polarsheets; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.moxieapps.gwt.highcharts.client.Chart; +import org.moxieapps.gwt.highcharts.client.Color; +import org.moxieapps.gwt.highcharts.client.Point; import org.moxieapps.gwt.highcharts.client.Series; import org.moxieapps.gwt.highcharts.client.plotOptions.LinePlotOptions; +import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; import com.google.gwt.user.client.ui.SimplePanel; +import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.gwt.ui.client.StringMessages; public class PolarSheetsChartPanel extends SimplePanel { @@ -25,7 +32,8 @@ public class PolarSheetsChartPanel extends SimplePanel { } private Chart createPolarSheetChart() { - Chart polarSheetChart = new Chart().setType(Series.Type.LINE).setLinePlotOptions(new LinePlotOptions().setLineWidth(1)).setZoomType(Chart.ZoomType.X_AND_Y) + Chart polarSheetChart = new Chart().setType(Series.Type.LINE) + .setLinePlotOptions(new LinePlotOptions().setLineWidth(1)).setZoomType(Chart.ZoomType.X_AND_Y) .setPolar(true).setSize(700, 700); polarSheetChart.setChartTitleText(stringMessages.polarSheetChart()); polarSheetChart.getYAxis().setMin(0); @@ -49,13 +57,30 @@ public class PolarSheetsChartPanel extends SimplePanel { return forEachDeg; } - private void addValuesToSeries(String seriesId, Number[] values) { + private void addValuesToSeries(String seriesId, PolarSheetsData result) { if (seriesMap.containsKey(seriesId)) { Series series = seriesMap.get(seriesId); - series.setPoints(values, false); + series.setPoints(result.getValues(), false); + Point[] points = createPointsWithMarkerAlphaAccordingToDataCount(result); + series.setPoints(points); } } + private Point[] createPointsWithMarkerAlphaAccordingToDataCount(PolarSheetsData result) { + Point[] points = new Point[360]; + List dataCountList = Arrays.asList(result.getDataCountPerAngle()); + Integer max = Collections.max(dataCountList); + if (max > 0) { + for (int i = 0; i < 360; i++) { + points[i] = new Point(result.getValues()[i]); + double alpha = (double) dataCountList.get(i) / (double) max; + // TODO set to series color and change alpha + points[i].setMarker(new Marker().setFillColor(new Color(1, 1, 1, alpha))); + } + } + return points; + } + public void removeSeries(String seriesId) { if (seriesMap.containsKey(seriesId)) { Series series = seriesMap.get(seriesId); @@ -69,15 +94,15 @@ public class PolarSheetsChartPanel extends SimplePanel { seriesMap.clear(); } - public void setData(Number[] values, String id) { - if (values == null) { + public void setData(String id, PolarSheetsData result) { + if (id == null) { // TODO Exception handling return; } if (!seriesMap.containsKey(id)) { newSeries(id); } - addValuesToSeries(id, values); + addValuesToSeries(id, result); chart.redraw(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index 62c4b627f09..582ef0bceff 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -10,6 +10,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.HorizontalPanel; +import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.VerticalPanel; import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; @@ -36,6 +37,9 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi private List selectedRaces; private PolarSheetsChartPanel chartPanel; + private Label polarSheetsGenerationLabel; + private Label dataCountLabel; + public PolarSheetsPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter, StringMessages stringMessages, PolarSheetsEntryPoint polarSheetsEntryPoint) { this.polarSheetsEntryPoint = polarSheetsEntryPoint; @@ -49,11 +53,20 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi mainPanel.setSize("100%", "100%"); setWidget(mainPanel); HorizontalPanel splitPanel = createSplitPanel(); - addFilteredTrackedRacesList(splitPanel); + VerticalPanel leftPanel = addFilteredTrackedRacesList(splitPanel); + polarSheetsGenerationLabel = createPolarSheetGenerationStatusLabel(); + leftPanel.add(polarSheetsGenerationLabel); + dataCountLabel = new Label(); + leftPanel.add(dataCountLabel); addPolarSheetsChartPanel(splitPanel); mainPanel.add(splitPanel); } + private Label createPolarSheetGenerationStatusLabel() { + Label polarSheetsGenerationStatusLabel = new Label(); + return polarSheetsGenerationStatusLabel; + } + private void addPolarSheetsChartPanel(HorizontalPanel splitPanel) { chartPanel = new PolarSheetsChartPanel(stringMessages); splitPanel.add(chartPanel); @@ -66,7 +79,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi return splitPanel; } - private void addFilteredTrackedRacesList(HorizontalPanel splitPanel) { + private VerticalPanel addFilteredTrackedRacesList(HorizontalPanel splitPanel) { VerticalPanel trackedRacesPanel = new VerticalPanel(); trackedRacesPanel.setWidth("100%"); @@ -75,6 +88,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi splitPanel.add(trackedRacesPanel); splitPanel.setCellWidth(trackedRacesPanel, "50%"); + return trackedRacesPanel; } private void createPolarSheetsTrackedRacesList() { @@ -93,13 +107,15 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi } protected void startPolarSheetGeneration() { - //List conversion, to make List serializable + // List conversion, to make List serializable List selectedRacesInArrayList = new ArrayList(); selectedRacesInArrayList.addAll(selectedRaces); sailingService.generatePolarSheetForRaces(selectedRacesInArrayList, new AsyncCallback() { @Override public void onSuccess(String result) { + // TODO string messages + setCompletionLabel("Generating..."); startPullingResults(result); } @@ -116,30 +132,40 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi @Override public void onSuccess(PolarSheetsData result) { - chartPanel.setData(result.getValues(), id); + // TODO string messages + setCompletionLabel("Generating..."); + dataCountLabel.setText("DataCount: " + result.getDataCount()); + chartPanel.setData(id, result); if (!result.isComplete()) { Timer timer = new Timer() { - + @Override public void run() { startPullingResults(id); } }; - + timer.schedule(1500); - + + } else { + // TODO string messages + setCompletionLabel("Generation finished!"); } } @Override public void onFailure(Throwable caught) { - // TODO Exception handling + errorReporter.reportError(caught.getLocalizedMessage()); } }); } + protected void setCompletionLabel(String string) { + polarSheetsGenerationLabel.setText(string); + } + @Override public void onRaceSelectionChange(List selectedRaces) { this.selectedRaces = selectedRaces; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 602b0fde87a..3b72c504ad0 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -97,7 +97,6 @@ import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.impl.DegreePosition; import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl; import com.sap.sailing.domain.common.impl.MeterDistance; -import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl; import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Triple; @@ -3083,10 +3082,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S PolarSheetsData data = null; if (polarSheetGenerationWorkers.containsKey(id)) { PolarSheetGenerationWorker worker = polarSheetGenerationWorkers.get(id); - boolean complete = worker.isFinished(); - Number[] values = worker.getPolarData(); - data = new PolarSheetsDataImpl(values, complete); - if (complete) { + data = worker.getPolarData(); + if (data.isComplete()) { polarSheetGenerationWorkers.remove(id); } } else { From 42127c83fb27eafa313333679f28d72cb982acae Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Thu, 31 Jan 2013 09:03:41 +0100 Subject: [PATCH 20/37] Changed multithreading approach of polar sheets generation to use executor --- .../PerRaceAndCompetitorWorker.java | 75 ++++++++++ .../domain/polarsheets/PerRaceWorker.java | 129 ------------------ .../PolarSheetGenerationWorker.java | 56 +++++--- .../gwt/ui/polarsheets/PolarSheetsPanel.java | 2 + .../PolarSheetsTrackedRacesList.java | 8 ++ .../gwt/ui/server/SailingServiceImpl.java | 2 +- 6 files changed, 122 insertions(+), 150 deletions(-) create mode 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorWorker.java delete mode 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorWorker.java new file mode 100644 index 00000000000..ed1609fa30d --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorWorker.java @@ -0,0 +1,75 @@ +package com.sap.sailing.domain.polarsheets; + +import java.util.Iterator; +import java.util.concurrent.Callable; + +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.SpeedWithBearing; +import com.sap.sailing.domain.common.Bearing; +import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.TimePoint; +import com.sap.sailing.domain.tracking.GPSFixMoving; +import com.sap.sailing.domain.tracking.GPSFixTrack; +import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sailing.domain.tracking.Wind; + +public class PerRaceAndCompetitorWorker implements Callable{ + + private final TrackedRace race; + + private final PolarSheetGenerationWorker polarSheetGenerationWorker; + + private final TimePoint startTime; + + private final TimePoint endTime; + + private final Competitor competitor; + + + + + public PerRaceAndCompetitorWorker(TrackedRace race, PolarSheetGenerationWorker polarSheetGenerationWorker, + TimePoint startTime, TimePoint endTime, Competitor competitor) { + super(); + this.race = race; + this.polarSheetGenerationWorker = polarSheetGenerationWorker; + this.startTime = startTime; + this.endTime = endTime; + this.competitor = competitor; + } + + @Override + public Void call() throws Exception { + GPSFixTrack track = race.getTrack(competitor); + track.lockForRead(); + Iterator fixesIterator = track.getFixesIterator(startTime, true); + + while (fixesIterator.hasNext()) { + GPSFixMoving fix = fixesIterator.next(); + if (fix.getTimePoint().after(endTime)) { + break; + } + + if (track.hasDirectionChange(fix.getTimePoint(), race.getRace().getBoatClass().getManeuverDegreeAngleThreshold())) { + continue; + } + + SpeedWithBearing speedWithBearing = fix.getSpeed(); + double speed = speedWithBearing.getMetersPerSecond(); + Bearing bearing = speedWithBearing.getBearing(); + Position position = fix.getPosition(); + Wind wind = race.getWind(position, fix.getTimePoint()); + Bearing windBearing = wind.getFrom(); + double windSpeed = wind.getMetersPerSecond(); + + // TODO Figure out if this normalizing is okay concerning different windspeeds and bearings + double normalizedSpeed = speed / windSpeed; + double angleToWind = bearing.getDifferenceTo(windBearing).getDegrees(); + + polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed); + } + + track.unlockAfterRead(); + return null; + } +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java deleted file mode 100644 index c105ead6741..00000000000 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceWorker.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.sap.sailing.domain.polarsheets; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; - -import com.sap.sailing.domain.base.Competitor; -import com.sap.sailing.domain.base.RaceDefinition; -import com.sap.sailing.domain.base.SpeedWithBearing; -import com.sap.sailing.domain.common.Bearing; -import com.sap.sailing.domain.common.Position; -import com.sap.sailing.domain.common.TimePoint; -import com.sap.sailing.domain.tracking.GPSFixMoving; -import com.sap.sailing.domain.tracking.GPSFixTrack; -import com.sap.sailing.domain.tracking.TrackedRace; -import com.sap.sailing.domain.tracking.Wind; - -public class PerRaceWorker implements Runnable { - - private final TrackedRace race; - - private final PolarSheetGenerationWorker polarSheetGenerationWorker; - - public PerRaceWorker(PolarSheetGenerationWorker polarSheetGenerationWorker, TrackedRace race) { - this.race = race; - this.polarSheetGenerationWorker = polarSheetGenerationWorker; - } - - @Override - public void run() { - TimePoint startTime = race.getStartOfRace(); - TimePoint endTime = race.getEndOfRace(); - if (endTime == null) { - //TODO Figure out if there is an alternative: - endTime = race.getTimePointOfNewestEvent(); - } - RaceDefinition raceDefinition = race.getRace(); - Iterable competitors = raceDefinition.getCompetitors(); - - final List perCompetitorWorkers = new ArrayList(); - - - for (Competitor competitor : competitors) { - Thread competitorWorkerThread = getPerCompetitorWorkerThread(startTime, endTime, competitor); - competitorWorkerThread.start(); - perCompetitorWorkers.add(competitorWorkerThread); - } - - final Timer timer = new Timer(); - - TimerTask threadMonitoringTask = new TimerTask() { - - @Override - public void run() { - boolean perCompetitorWorkersDone = false; - do { - boolean currentWorkerAlive = true; - Thread currentWorker = null; - for (Thread worker : perCompetitorWorkers) { - currentWorker = worker; - if (!worker.isAlive()) { - currentWorkerAlive = false; - } - } - if (!currentWorkerAlive) { - perCompetitorWorkers.remove(currentWorker); - if (perCompetitorWorkers.isEmpty()) { - perCompetitorWorkersDone = true; - } - } - } while (!perCompetitorWorkersDone); - - polarSheetGenerationWorker.workerDone(PerRaceWorker.this); - timer.cancel(); - } - }; - - timer.schedule(threadMonitoringTask, 500, 500); - - - - } - - private Thread getPerCompetitorWorkerThread(final TimePoint startTime, final TimePoint endTime, - final Competitor competitor) { - Runnable perCompetitorWorker = new Runnable() { - - @Override - public void run() { - GPSFixTrack track = race.getTrack(competitor); - track.lockForRead(); - Iterator fixesIterator = track.getFixesIterator(startTime, true); - - while (fixesIterator.hasNext()) { - GPSFixMoving fix = fixesIterator.next(); - if (fix.getTimePoint().after(endTime)) { - break; - } - - if (track.hasDirectionChange(fix.getTimePoint(), race.getRace().getBoatClass().getManeuverDegreeAngleThreshold())) { - continue; - } - - SpeedWithBearing speedWithBearing = fix.getSpeed(); - double speed = speedWithBearing.getMetersPerSecond(); - Bearing bearing = speedWithBearing.getBearing(); - Position position = fix.getPosition(); - Wind wind = race.getWind(position, fix.getTimePoint()); - Bearing windBearing = wind.getFrom(); - double windSpeed = wind.getMetersPerSecond(); - - // TODO Figure out if this normalizing is okay concerning different windspeeds and bearings - double normalizedSpeed = speed / windSpeed; - double angleToWind = bearing.getDifferenceTo(windBearing).getDegrees(); - - polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed); - } - - track.unlockAfterRead(); - } - }; - - Thread perCompetitorThread = new Thread(perCompetitorWorker); - return perCompetitorThread; - - } -} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java index e5b7ac77677..10459458959 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java @@ -4,26 +4,45 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.FutureTask; +import java.util.concurrent.RunnableFuture; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.common.PolarSheetsData; +import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl; import com.sap.sailing.domain.tracking.TrackedRace; public class PolarSheetGenerationWorker { - private boolean finished = false; - - private final Set workers; + private final Set> workers; private final List> polarData; - private boolean workerInitDone = false; + private final Executor executor; - public PolarSheetGenerationWorker(Set trackedRaces) { + public PolarSheetGenerationWorker(Set trackedRaces, Executor executor) { polarData = initializePolarDataContainer(); - workers = new HashSet(); + this.executor = executor; + workers = new HashSet>(); for (TrackedRace race : trackedRaces) { - workers.add(new PerRaceWorker(this, race)); + TimePoint startTime = race.getStartOfRace(); + TimePoint endTime = race.getEndOfRace(); + if (endTime == null) { + //TODO Figure out if there is an alternative: + endTime = race.getTimePointOfNewestEvent(); + } + RaceDefinition raceDefinition = race.getRace(); + Iterable competitors = raceDefinition.getCompetitors(); + + + for (Competitor competitor : competitors) { + RunnableFuture futureTask = new FutureTask(new PerRaceAndCompetitorWorker(race, this, startTime, endTime, competitor)); + workers.add(futureTask); + } + } } @@ -36,11 +55,9 @@ public class PolarSheetGenerationWorker { } public void startPolarSheetGeneration() { - for (PerRaceWorker worker : workers) { - Thread workerThread = new Thread(worker); - workerThread.start(); + for (RunnableFuture future : workers) { + executor.execute(future); } - workerInitDone = true; } public void addPolarData(long roundedAngle, double normalizedSpeed) { @@ -73,20 +90,19 @@ public class PolarSheetGenerationWorker { averagedPolarData[i] = average; } } + boolean complete = true; + for (RunnableFuture future : workers) { + if (!future.isDone()) { + complete = false; + break; + } + } - PolarSheetsData data = new PolarSheetsDataImpl(averagedPolarData, finished, dataCount, dataCountPerAngle); + PolarSheetsData data = new PolarSheetsDataImpl(averagedPolarData, complete, dataCount, dataCountPerAngle); return data; } - public void workerDone(PerRaceWorker worker) { - if (workers.contains(worker) && workerInitDone) { - workers.remove(worker); - if (workers.isEmpty()) { - finished = true; - } - } - } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index 582ef0bceff..42ad4370fdf 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -110,6 +110,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi // List conversion, to make List serializable List selectedRacesInArrayList = new ArrayList(); selectedRacesInArrayList.addAll(selectedRaces); + polarSheetsTrackedRacesList.changeGenerationButtonState(false); sailingService.generatePolarSheetForRaces(selectedRacesInArrayList, new AsyncCallback() { @Override @@ -150,6 +151,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi } else { // TODO string messages setCompletionLabel("Generation finished!"); + polarSheetsTrackedRacesList.changeGenerationButtonState(true); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java index 233bb8ca3c3..6bec44e3948 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsTrackedRacesList.java @@ -52,4 +52,12 @@ public class PolarSheetsTrackedRacesList extends AbstractFilteredTrackedRacesLis } } + /** + * Changes the state of the generation-start button + * @param enable + */ + public void changeGenerationButtonState(boolean enable) { + btnPolarSheetGeneration.setEnabled(enable); + } + } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 3b72c504ad0..9c76a9af4fb 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -3071,7 +3071,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S for (RegattaAndRaceIdentifier race : selectedRaces) { trackedRaces.add(service.getTrackedRace(race)); } - PolarSheetGenerationWorker genWorker = new PolarSheetGenerationWorker(trackedRaces); + PolarSheetGenerationWorker genWorker = new PolarSheetGenerationWorker(trackedRaces, executor); polarSheetGenerationWorkers.put(id, genWorker); genWorker.startPolarSheetGeneration(); return id; From c2a2d5aded3cdc730f9098c3c8f594dcfcd6bb8b Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Thu, 31 Jan 2013 16:37:26 +0100 Subject: [PATCH 21/37] Added histogram for polarsheet angles --- .../common/PolarSheetsHistogramData.java | 12 ++++ .../impl/PolarSheetsHistogramDataImpl.java | 32 ++++++++++ ...CompetitorPolarSheetGenerationWorker.java} | 10 +-- .../PolarSheetGenerationWorker.java | 6 +- .../GetPolarSheetDataByAngleAction.java | 30 +++++++++ .../sailing/gwt/ui/client/SailingService.java | 3 + .../gwt/ui/client/SailingServiceAsync.java | 21 ++++--- .../ui/polarsheets/PolarSheetsChartPanel.java | 20 +++++- .../PolarSheetsHistogramPanel.java | 61 +++++++++++++++++++ .../gwt/ui/polarsheets/PolarSheetsPanel.java | 54 ++++++++++++++-- .../gwt/ui/server/SailingServiceImpl.java | 52 +++++++++++++++- 11 files changed, 279 insertions(+), 22 deletions(-) create mode 100644 java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsHistogramData.java create mode 100644 java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsHistogramDataImpl.java rename java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/{PerRaceAndCompetitorWorker.java => PerRaceAndCompetitorPolarSheetGenerationWorker.java} (86%) create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/actions/GetPolarSheetDataByAngleAction.java create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsHistogramData.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsHistogramData.java new file mode 100644 index 00000000000..e0bcc714db1 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsHistogramData.java @@ -0,0 +1,12 @@ +package com.sap.sailing.domain.common; + +import java.io.Serializable; + +public interface PolarSheetsHistogramData extends Serializable{ + + public Number[] getyValues(); + + public Number[] getxValues(); + + +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsHistogramDataImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsHistogramDataImpl.java new file mode 100644 index 00000000000..6131457cf6c --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsHistogramDataImpl.java @@ -0,0 +1,32 @@ +package com.sap.sailing.domain.common.impl; + +import com.sap.sailing.domain.common.PolarSheetsHistogramData; + +public class PolarSheetsHistogramDataImpl implements PolarSheetsHistogramData { + + private static final long serialVersionUID = 7492650285773447757L; + + private Number[] yValues; + + private Number[] xValues; + + //For GWT serialization + PolarSheetsHistogramDataImpl() {} + + public PolarSheetsHistogramDataImpl(Number[] xValues, Number[] yValues) { + super(); + this.yValues = yValues; + this.xValues = xValues; + } + + @Override + public Number[] getyValues() { + return yValues; + } + + @Override + public Number[] getxValues() { + return xValues; + } + +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java similarity index 86% rename from java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorWorker.java rename to java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java index ed1609fa30d..7ef8d32a61f 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java @@ -13,7 +13,7 @@ import com.sap.sailing.domain.tracking.GPSFixTrack; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.Wind; -public class PerRaceAndCompetitorWorker implements Callable{ +public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable{ private final TrackedRace race; @@ -28,7 +28,7 @@ public class PerRaceAndCompetitorWorker implements Callable{ - public PerRaceAndCompetitorWorker(TrackedRace race, PolarSheetGenerationWorker polarSheetGenerationWorker, + public PerRaceAndCompetitorPolarSheetGenerationWorker(TrackedRace race, PolarSheetGenerationWorker polarSheetGenerationWorker, TimePoint startTime, TimePoint endTime, Competitor competitor) { super(); this.race = race; @@ -55,15 +55,15 @@ public class PerRaceAndCompetitorWorker implements Callable{ } SpeedWithBearing speedWithBearing = fix.getSpeed(); - double speed = speedWithBearing.getMetersPerSecond(); + double speed = speedWithBearing.getKnots(); Bearing bearing = speedWithBearing.getBearing(); Position position = fix.getPosition(); Wind wind = race.getWind(position, fix.getTimePoint()); Bearing windBearing = wind.getFrom(); - double windSpeed = wind.getMetersPerSecond(); + double windSpeed = wind.getKnots(); // TODO Figure out if this normalizing is okay concerning different windspeeds and bearings - double normalizedSpeed = speed / windSpeed; + double normalizedSpeed = speed/* / windSpeed*/; double angleToWind = bearing.getDifferenceTo(windBearing).getDegrees(); polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java index 10459458959..81a37183757 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java @@ -39,7 +39,7 @@ public class PolarSheetGenerationWorker { for (Competitor competitor : competitors) { - RunnableFuture futureTask = new FutureTask(new PerRaceAndCompetitorWorker(race, this, startTime, endTime, competitor)); + RunnableFuture futureTask = new FutureTask(new PerRaceAndCompetitorPolarSheetGenerationWorker(race, this, startTime, endTime, competitor)); workers.add(futureTask); } @@ -104,5 +104,9 @@ public class PolarSheetGenerationWorker { return data; } + public List> getCompleteData() { + return polarData; + } + } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/actions/GetPolarSheetDataByAngleAction.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/actions/GetPolarSheetDataByAngleAction.java new file mode 100644 index 00000000000..7e30b6e2e5c --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/actions/GetPolarSheetDataByAngleAction.java @@ -0,0 +1,30 @@ +package com.sap.sailing.gwt.ui.actions; + +import com.google.gwt.user.client.rpc.AsyncCallback; +import com.sap.sailing.domain.common.PolarSheetsHistogramData; +import com.sap.sailing.gwt.ui.client.SailingServiceAsync; + +public class GetPolarSheetDataByAngleAction extends DefaultAsyncAction { + + private final SailingServiceAsync sailingService; + private final String polarSheetId; + private final int angle; + + + + public GetPolarSheetDataByAngleAction(SailingServiceAsync sailingService, + String polarSheetId, int angle, AsyncCallback callback) { + super(callback); + this.sailingService = sailingService; + this.polarSheetId = polarSheetId; + this.angle = angle; + } + + + + @Override + public void execute(AsyncActionsExecutor asyncActionsExecutor) { + sailingService.getPolarSheetData(polarSheetId, angle, (AsyncCallback) getWrapperCallback(asyncActionsExecutor)); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java index 93478e282b4..9ba8465061d 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java @@ -15,6 +15,7 @@ import com.sap.sailing.domain.common.DetailType; import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.PolarSheetsData; +import com.sap.sailing.domain.common.PolarSheetsHistogramData; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.RegattaIdentifier; import com.sap.sailing.domain.common.ScoringSchemeType; @@ -288,4 +289,6 @@ public interface SailingService extends RemoteService { String generatePolarSheetForRaces(List selectedRaces); PolarSheetsData getPolarSheetsGenerationResults(String id); + + PolarSheetsHistogramData getPolarSheetData(String polarSheetId, int angle); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java index f769752a24b..dbfffe099cf 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java @@ -11,42 +11,43 @@ import java.util.Set; import com.google.gwt.user.client.rpc.AsyncCallback; import com.sap.sailing.domain.common.Color; import com.sap.sailing.domain.common.DetailType; -import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.domain.common.RegattaIdentifier; import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.PolarSheetsData; +import com.sap.sailing.domain.common.PolarSheetsHistogramData; import com.sap.sailing.domain.common.RaceIdentifier; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.domain.common.RegattaIdentifier; import com.sap.sailing.domain.common.RegattaNameAndRaceName; import com.sap.sailing.domain.common.ScoringSchemeType; import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Triple; -import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationDTO; import com.sap.sailing.gwt.ui.shared.BulkScoreCorrectionDTO; import com.sap.sailing.gwt.ui.shared.CompetitorDTO; +import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO; import com.sap.sailing.gwt.ui.shared.ControlPointDTO; import com.sap.sailing.gwt.ui.shared.CourseDTO; import com.sap.sailing.gwt.ui.shared.EventDTO; -import com.sap.sailing.gwt.ui.shared.RaceCourseMarksDTO; -import com.sap.sailing.gwt.ui.shared.RaceColumnInSeriesDTO; -import com.sap.sailing.gwt.ui.shared.RegattaDTO; import com.sap.sailing.gwt.ui.shared.GPSFixDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardEntryDTO; import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO; import com.sap.sailing.gwt.ui.shared.ManeuverDTO; -import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO; import com.sap.sailing.gwt.ui.shared.QuickRankDTO; +import com.sap.sailing.gwt.ui.shared.RaceColumnInSeriesDTO; +import com.sap.sailing.gwt.ui.shared.RaceCourseMarksDTO; import com.sap.sailing.gwt.ui.shared.RaceDTO; import com.sap.sailing.gwt.ui.shared.RaceMapDataDTO; import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO; -import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO; +import com.sap.sailing.gwt.ui.shared.RegattaDTO; import com.sap.sailing.gwt.ui.shared.RegattaScoreCorrectionDTO; +import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO; import com.sap.sailing.gwt.ui.shared.ScoreCorrectionProviderDTO; import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; -import com.sap.sailing.gwt.ui.shared.SwissTimingReplayRaceDTO; +import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationDTO; import com.sap.sailing.gwt.ui.shared.SwissTimingConfigurationDTO; import com.sap.sailing.gwt.ui.shared.SwissTimingRaceRecordDTO; +import com.sap.sailing.gwt.ui.shared.SwissTimingReplayRaceDTO; import com.sap.sailing.gwt.ui.shared.TracTracConfigurationDTO; import com.sap.sailing.gwt.ui.shared.TracTracRaceRecordDTO; import com.sap.sailing.gwt.ui.shared.VenueDTO; @@ -440,4 +441,6 @@ public interface SailingServiceAsync { void generatePolarSheetForRaces(List selectedRaces, AsyncCallback asyncCallback); void getPolarSheetsGenerationResults(String id, AsyncCallback asyncCallback); + + void getPolarSheetData(String polarSheetId, int angle, AsyncCallback wrapperCallback); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java index 0595d95988b..83fde42f101 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java @@ -10,14 +10,17 @@ import org.moxieapps.gwt.highcharts.client.Chart; import org.moxieapps.gwt.highcharts.client.Color; import org.moxieapps.gwt.highcharts.client.Point; import org.moxieapps.gwt.highcharts.client.Series; +import org.moxieapps.gwt.highcharts.client.events.PointMouseOverEventHandler; import org.moxieapps.gwt.highcharts.client.plotOptions.LinePlotOptions; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; +import org.moxieapps.gwt.highcharts.client.plotOptions.SeriesPlotOptions; +import com.google.gwt.user.client.ui.RequiresResize; import com.google.gwt.user.client.ui.SimplePanel; import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.gwt.ui.client.StringMessages; -public class PolarSheetsChartPanel extends SimplePanel { +public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize{ private StringMessages stringMessages; private Chart chart; @@ -34,7 +37,7 @@ public class PolarSheetsChartPanel extends SimplePanel { private Chart createPolarSheetChart() { Chart polarSheetChart = new Chart().setType(Series.Type.LINE) .setLinePlotOptions(new LinePlotOptions().setLineWidth(1)).setZoomType(Chart.ZoomType.X_AND_Y) - .setPolar(true).setSize(700, 700); + .setPolar(true).setSize(700,700); polarSheetChart.setChartTitleText(stringMessages.polarSheetChart()); polarSheetChart.getYAxis().setMin(0); return polarSheetChart; @@ -73,6 +76,9 @@ public class PolarSheetsChartPanel extends SimplePanel { if (max > 0) { for (int i = 0; i < 360; i++) { points[i] = new Point(result.getValues()[i]); + if (points[i] == null) { + points[i] = new Point(0); + } double alpha = (double) dataCountList.get(i) / (double) max; // TODO set to series color and change alpha points[i].setMarker(new Marker().setFillColor(new Color(1, 1, 1, alpha))); @@ -106,4 +112,14 @@ public class PolarSheetsChartPanel extends SimplePanel { chart.redraw(); } + public void setSeriesPointMouseOverHandler(PointMouseOverEventHandler pointMouseOverHandler) { + chart.setSeriesPlotOptions(new SeriesPlotOptions().setPointMouseOverEventHandler(pointMouseOverHandler)); + } + + @Override + public void onResize() { + chart.setSizeToMatchContainer(); + chart.redraw(); + } + } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java new file mode 100644 index 00000000000..f97d0684a63 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java @@ -0,0 +1,61 @@ +package com.sap.sailing.gwt.ui.polarsheets; + +import org.moxieapps.gwt.highcharts.client.Chart; +import org.moxieapps.gwt.highcharts.client.Legend; +import org.moxieapps.gwt.highcharts.client.Point; +import org.moxieapps.gwt.highcharts.client.Series; +import org.moxieapps.gwt.highcharts.client.Series.Type; +import org.moxieapps.gwt.highcharts.client.labels.XAxisLabels; + +import com.google.gwt.user.client.ui.RequiresResize; +import com.google.gwt.user.client.ui.SimplePanel; +import com.sap.sailing.domain.common.PolarSheetsHistogramData; +import com.sap.sailing.gwt.ui.client.StringMessages; + +public class PolarSheetsHistogramPanel extends SimplePanel implements RequiresResize{ + + private final Chart chart; + private final StringMessages stringMessages; + + public PolarSheetsHistogramPanel(StringMessages stringMessages) { + this.stringMessages = stringMessages; + setSize("100%", "100%"); + chart = createHistogramChart(); + setWidget(chart); + } + + private Chart createHistogramChart() { + Chart histogramChart = new Chart().setType(Type.COLUMN).setZoomType(Chart.ZoomType.X); + //TODO string messages + histogramChart.setChartTitleText("Histogram:"); + histogramChart.getYAxis().setMin(0); + histogramChart.getXAxis().setLabels(new XAxisLabels().setRotation(-90f).setY(20)); + histogramChart.setLegend(new Legend().setEnabled(false)); + return histogramChart; + } + + public void setData(PolarSheetsHistogramData data) { + chart.removeAllSeries(); + Point[] points = toPoints(data); + Series series = chart.createSeries(); + series.setPoints(points); + chart.addSeries(series); + } + + private Point[] toPoints(PolarSheetsHistogramData data) { + Number[] xValues = data.getxValues(); + Number[] yValues = data.getyValues(); + Point[] points = new Point[xValues.length]; + for (int i = 0; i < xValues.length; i++) { + points[i] = new Point(xValues[i], yValues[i]); + } + return points; + } + + @Override + public void onResize() { + chart.setSizeToMatchContainer(); + chart.redraw(); + } + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index 42ad4370fdf..8a5cd4d269a 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -3,6 +3,9 @@ package com.sap.sailing.gwt.ui.polarsheets; import java.util.ArrayList; import java.util.List; +import org.moxieapps.gwt.highcharts.client.events.PointMouseOverEvent; +import org.moxieapps.gwt.highcharts.client.events.PointMouseOverEventHandler; + import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.Timer; @@ -13,7 +16,10 @@ import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.VerticalPanel; import com.sap.sailing.domain.common.PolarSheetsData; +import com.sap.sailing.domain.common.PolarSheetsHistogramData; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor; +import com.sap.sailing.gwt.ui.actions.GetPolarSheetDataByAngleAction; import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.RaceSelectionChangeListener; import com.sap.sailing.gwt.ui.client.RaceSelectionModel; @@ -36,6 +42,8 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi private PolarSheetsEntryPoint polarSheetsEntryPoint; private List selectedRaces; private PolarSheetsChartPanel chartPanel; + private PolarSheetsHistogramPanel histogramPanel; + private AsyncActionsExecutor asyncActionsExecutor; private Label polarSheetsGenerationLabel; private Label dataCountLabel; @@ -58,8 +66,43 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi leftPanel.add(polarSheetsGenerationLabel); dataCountLabel = new Label(); leftPanel.add(dataCountLabel); - addPolarSheetsChartPanel(splitPanel); + VerticalPanel rightPanel = addPolarSheetsChartPanel(splitPanel); + histogramPanel = new PolarSheetsHistogramPanel(stringMessages); + rightPanel.add(histogramPanel); mainPanel.add(splitPanel); + + asyncActionsExecutor = new AsyncActionsExecutor(); + setEventListenersForPolarSheetChart(); + } + + private void setEventListenersForPolarSheetChart() { + PointMouseOverEventHandler pointMouseOverHandler = new PointMouseOverEventHandler() { + + @Override + public boolean onMouseOver(PointMouseOverEvent pointMouseOverEvent) { + int x = (int) pointMouseOverEvent.getXAsLong(); + String polarSheetId = pointMouseOverEvent.getSeriesName(); + GetPolarSheetDataByAngleAction action = new GetPolarSheetDataByAngleAction(sailingService, + polarSheetId, x, new AsyncCallback() { + + @Override + public void onSuccess(PolarSheetsHistogramData result) { + if (result != null) { + histogramPanel.setData(result); + } + } + + @Override + public void onFailure(Throwable caught) { + errorReporter.reportError(caught.getLocalizedMessage()); + } + + }); + asyncActionsExecutor.execute(action); + return true; + } + }; + chartPanel.setSeriesPointMouseOverHandler(pointMouseOverHandler); } private Label createPolarSheetGenerationStatusLabel() { @@ -67,10 +110,13 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi return polarSheetsGenerationStatusLabel; } - private void addPolarSheetsChartPanel(HorizontalPanel splitPanel) { + private VerticalPanel addPolarSheetsChartPanel(HorizontalPanel splitPanel) { + VerticalPanel verticalPanel = new VerticalPanel(); chartPanel = new PolarSheetsChartPanel(stringMessages); - splitPanel.add(chartPanel); - splitPanel.setCellWidth(chartPanel, "50%"); + verticalPanel.add(chartPanel); + splitPanel.add(verticalPanel); + splitPanel.setCellWidth(verticalPanel, "50%"); + return verticalPanel; } private HorizontalPanel createSplitPanel() { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 9c76a9af4fb..685a58c1e42 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -38,6 +38,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; import org.osgi.framework.BundleContext; import org.osgi.util.tracker.ServiceTracker; @@ -76,6 +78,7 @@ import com.sap.sailing.domain.common.NoWindError; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.Placemark; import com.sap.sailing.domain.common.PolarSheetsData; +import com.sap.sailing.domain.common.PolarSheetsHistogramData; import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.RaceFetcher; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; @@ -97,6 +100,7 @@ import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.impl.DegreePosition; import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl; import com.sap.sailing.domain.common.impl.MeterDistance; +import com.sap.sailing.domain.common.impl.PolarSheetsHistogramDataImpl; import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.domain.common.impl.Util.Triple; @@ -3084,14 +3088,60 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S PolarSheetGenerationWorker worker = polarSheetGenerationWorkers.get(id); data = worker.getPolarData(); if (data.isComplete()) { + HttpServletRequest httpServletRequest = this.getThreadLocalRequest(); + HttpSession session = httpServletRequest.getSession(); + session.setAttribute(id, worker.getCompleteData()); polarSheetGenerationWorkers.remove(id); } } else { //TODO Exception handling } - return data; + return data; + } + + @Override + public PolarSheetsHistogramData getPolarSheetData(String polarSheetId, int angle) { + HttpServletRequest httpServletRequest = this.getThreadLocalRequest(); + HttpSession session = httpServletRequest.getSession(); + @SuppressWarnings("unchecked") + List> data = (List>) session.getAttribute(polarSheetId); + if (data == null) { + //TODO exception handling + return null; + } + List dataForAngle = data.get(angle); + if (dataForAngle.size() < 1) { + //TODO exception handling + return null; + } + Double min = Collections.min(dataForAngle); + Double max = Collections.max(dataForAngle); + //TODO make number of columns dynamic to chart size + int numberOfColumns = 20; + double range = (max - min) / numberOfColumns; + Double[] xValues = new Double[numberOfColumns]; + for (int i = 0; i < numberOfColumns; i++) { + xValues[i] = min + i * range + ( 0.5 * range); + } + Integer[] yValues = new Integer[numberOfColumns]; + for (Double dataPoint : dataForAngle) { + int i = (int) (((dataPoint - min) / range)); + if (i == numberOfColumns) { + //For max value + i = 19; + } + if (yValues[i] == null) { + yValues[i] = 0; + } + yValues[i]++; + } + + PolarSheetsHistogramData histogramData = new PolarSheetsHistogramDataImpl(xValues,yValues); + + + return histogramData; } } \ No newline at end of file From 30d5dedcb4a9079eff86e734395766ef1e38eca3 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Fri, 1 Feb 2013 15:49:09 +0100 Subject: [PATCH 22/37] Added some ui-focused functionalities to polarsheetspanel Chartseries now have boatclassname as their name or "mixed" if multiple boat classes were selected +Some axis labels -some bugs --- .../PolarSheetGenerationTriggerResponse.java | 11 ++++++ .../common/PolarSheetsHistogramData.java | 4 ++ ...larSheetGenerationTriggerResponseImpl.java | 30 +++++++++++++++ .../impl/PolarSheetsHistogramDataImpl.java | 18 ++++++++- .../sailing/gwt/ui/client/SailingService.java | 3 +- .../gwt/ui/client/SailingServiceAsync.java | 3 +- .../gwt/ui/client/StringMessages.properties | 2 +- .../ui/client/StringMessages_de.properties | 2 +- .../ui/polarsheets/PolarSheetsChartPanel.java | 30 ++++++++------- .../PolarSheetsHistogramPanel.java | 10 +++-- .../gwt/ui/polarsheets/PolarSheetsPanel.java | 38 ++++++++++++++++--- .../gwt/ui/server/SailingServiceImpl.java | 23 +++++++++-- 12 files changed, 144 insertions(+), 30 deletions(-) create mode 100644 java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetGenerationTriggerResponse.java create mode 100644 java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetGenerationTriggerResponseImpl.java diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetGenerationTriggerResponse.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetGenerationTriggerResponse.java new file mode 100644 index 00000000000..78615496226 --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetGenerationTriggerResponse.java @@ -0,0 +1,11 @@ +package com.sap.sailing.domain.common; + +import java.io.Serializable; + +public interface PolarSheetGenerationTriggerResponse extends Serializable{ + + public String getId(); + + public String getBoatClassName(); + +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsHistogramData.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsHistogramData.java index e0bcc714db1..712962b82f9 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsHistogramData.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsHistogramData.java @@ -4,6 +4,10 @@ import java.io.Serializable; public interface PolarSheetsHistogramData extends Serializable{ + public int getAngle(); + + public int getDataCount(); + public Number[] getyValues(); public Number[] getxValues(); diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetGenerationTriggerResponseImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetGenerationTriggerResponseImpl.java new file mode 100644 index 00000000000..ecd5033359e --- /dev/null +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetGenerationTriggerResponseImpl.java @@ -0,0 +1,30 @@ +package com.sap.sailing.domain.common.impl; + +import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse; + +public class PolarSheetGenerationTriggerResponseImpl implements PolarSheetGenerationTriggerResponse { + + private static final long serialVersionUID = -2160795576114448218L; + private String id; + private String boatClassName; + + // For GWT serialization + PolarSheetGenerationTriggerResponseImpl() { + }; + + public PolarSheetGenerationTriggerResponseImpl(String id, String boatClassName) { + this.id = id; + this.boatClassName = boatClassName; + } + + @Override + public String getId() { + return id; + } + + @Override + public String getBoatClassName() { + return boatClassName; + } + +} diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsHistogramDataImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsHistogramDataImpl.java index 6131457cf6c..c5c321882c0 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsHistogramDataImpl.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsHistogramDataImpl.java @@ -10,13 +10,19 @@ public class PolarSheetsHistogramDataImpl implements PolarSheetsHistogramData { private Number[] xValues; + private int angle; + + private int dataCount; + //For GWT serialization PolarSheetsHistogramDataImpl() {} - public PolarSheetsHistogramDataImpl(Number[] xValues, Number[] yValues) { + public PolarSheetsHistogramDataImpl(int angle, Number[] xValues, Number[] yValues, int dataCount) { super(); + this.angle = angle; this.yValues = yValues; this.xValues = xValues; + this.dataCount = dataCount; } @Override @@ -29,4 +35,14 @@ public class PolarSheetsHistogramDataImpl implements PolarSheetsHistogramData { return xValues; } + @Override + public int getAngle() { + return angle; + } + + @Override + public int getDataCount() { + return dataCount; + } + } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java index 9ba8465061d..d005ff58ef0 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java @@ -14,6 +14,7 @@ import com.sap.sailing.domain.common.Color; import com.sap.sailing.domain.common.DetailType; import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.NoWindException; +import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse; import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.domain.common.PolarSheetsHistogramData; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; @@ -286,7 +287,7 @@ public interface SailingService extends RemoteService { void storeSwissTimingArchiveConfiguration(String swissTimingUrl); - String generatePolarSheetForRaces(List selectedRaces); + PolarSheetGenerationTriggerResponse generatePolarSheetForRaces(List selectedRaces); PolarSheetsData getPolarSheetsGenerationResults(String id); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java index dbfffe099cf..d8b8c5ed397 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java @@ -12,6 +12,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback; import com.sap.sailing.domain.common.Color; import com.sap.sailing.domain.common.DetailType; import com.sap.sailing.domain.common.MaxPointsReason; +import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse; import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.domain.common.PolarSheetsHistogramData; import com.sap.sailing.domain.common.RaceIdentifier; @@ -438,7 +439,7 @@ public interface SailingServiceAsync { void storeSwissTimingArchiveConfiguration(String swissTimingUrl, AsyncCallback asyncCallback); - void generatePolarSheetForRaces(List selectedRaces, AsyncCallback asyncCallback); + void generatePolarSheetForRaces(List selectedRaces, AsyncCallback asyncCallback); void getPolarSheetsGenerationResults(String id, AsyncCallback asyncCallback); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 105cd8aaacf..6209395a70c 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -486,7 +486,7 @@ knotsUnit=kts scoringSchemeHighPointFirstGetsTen=High Point, winner gets 10 points knotsUnit=kts generatePolarSheet=Generate Polar Sheet -polarSheetChart=Polar Sheet: +polarSheetChart=Polar Sheet competitorColumnTooltip=Names of the members of this competitor. sailIdColumnTooltip=Shows the flag of the country and the sail number of the competitor. rankColumnTooltip=The overall rank of this competitor in the regatta. diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index c5be4e5683a..dde0f0c465a 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -486,7 +486,7 @@ racesAreLive=Rennen {0} sind live scoringSchemeHighPointFirstGetsTen=High Point System, Gewinner erhält 10 Punkte knotsUnit=kn generatePolarSheet=Polardiagramm erstellen -polarSheetChart=Polardiagramm: +polarSheetChart=Polardiagramm competitorColumnTooltip=Namen der Segler dieses Teilnehmers sailIdColumnTooltip=Zeigt die Länderflagge und die Segelnummer des Teilnehmers rankColumnTooltip=Der Gesamtplatz des Teilnehmers in der Regatta diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java index 83fde42f101..9b23a66007c 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java @@ -20,7 +20,7 @@ import com.google.gwt.user.client.ui.SimplePanel; import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.gwt.ui.client.StringMessages; -public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize{ +public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize { private StringMessages stringMessages; private Chart chart; @@ -37,7 +37,7 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize private Chart createPolarSheetChart() { Chart polarSheetChart = new Chart().setType(Series.Type.LINE) .setLinePlotOptions(new LinePlotOptions().setLineWidth(1)).setZoomType(Chart.ZoomType.X_AND_Y) - .setPolar(true).setSize(700,700); + .setPolar(true).setSize(800, 800); polarSheetChart.setChartTitleText(stringMessages.polarSheetChart()); polarSheetChart.getYAxis().setMin(0); return polarSheetChart; @@ -65,7 +65,9 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize Series series = seriesMap.get(seriesId); series.setPoints(result.getValues(), false); Point[] points = createPointsWithMarkerAlphaAccordingToDataCount(result); - series.setPoints(points); + if (points != null) { + series.setPoints(points); + } } } @@ -73,17 +75,19 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize Point[] points = new Point[360]; List dataCountList = Arrays.asList(result.getDataCountPerAngle()); Integer max = Collections.max(dataCountList); - if (max > 0) { - for (int i = 0; i < 360; i++) { - points[i] = new Point(result.getValues()[i]); - if (points[i] == null) { - points[i] = new Point(0); - } - double alpha = (double) dataCountList.get(i) / (double) max; - // TODO set to series color and change alpha - points[i].setMarker(new Marker().setFillColor(new Color(1, 1, 1, alpha))); - } + if (max <= 0) { + return null; } + for (int i = 0; i < 360; i++) { + points[i] = new Point(result.getValues()[i]); + if (points[i] == null) { + points[i] = new Point(0); + } + double alpha = (double) dataCountList.get(i) / (double) max; + // TODO set to series color and change alpha + points[i].setMarker(new Marker().setFillColor(new Color(1, 1, 1, alpha))); + } + return points; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java index f97d0684a63..c260b26c022 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java @@ -1,6 +1,9 @@ package com.sap.sailing.gwt.ui.polarsheets; +import org.moxieapps.gwt.highcharts.client.AxisTitle; import org.moxieapps.gwt.highcharts.client.Chart; +import org.moxieapps.gwt.highcharts.client.ChartSubtitle; +import org.moxieapps.gwt.highcharts.client.ChartTitle; import org.moxieapps.gwt.highcharts.client.Legend; import org.moxieapps.gwt.highcharts.client.Point; import org.moxieapps.gwt.highcharts.client.Series; @@ -25,17 +28,18 @@ public class PolarSheetsHistogramPanel extends SimplePanel implements RequiresRe } private Chart createHistogramChart() { - Chart histogramChart = new Chart().setType(Type.COLUMN).setZoomType(Chart.ZoomType.X); + Chart histogramChart = new Chart().setType(Type.COLUMN).setZoomType(Chart.ZoomType.X).setWidth(800); //TODO string messages histogramChart.setChartTitleText("Histogram:"); - histogramChart.getYAxis().setMin(0); - histogramChart.getXAxis().setLabels(new XAxisLabels().setRotation(-90f).setY(20)); + histogramChart.getYAxis().setMin(0).setAxisTitle(new AxisTitle().setText("Number of data-points")); + histogramChart.getXAxis().setLabels(new XAxisLabels().setRotation(-90f).setY(10)).setAxisTitle(new AxisTitle().setText("Speed in knots")); histogramChart.setLegend(new Legend().setEnabled(false)); return histogramChart; } public void setData(PolarSheetsHistogramData data) { chart.removeAllSeries(); + chart.setTitle(new ChartTitle().setText("Histogram"), new ChartSubtitle().setText("Angle: " + data.getAngle() + "; Total number of data-points: " + data.getDataCount())); Point[] points = toPoints(data); Series series = chart.createSeries(); series.setPoints(points); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index 8a5cd4d269a..88d90bb4b08 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -1,7 +1,9 @@ package com.sap.sailing.gwt.ui.polarsheets; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.moxieapps.gwt.highcharts.client.events.PointMouseOverEvent; import org.moxieapps.gwt.highcharts.client.events.PointMouseOverEventHandler; @@ -15,6 +17,7 @@ import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.VerticalPanel; +import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse; import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.domain.common.PolarSheetsHistogramData; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; @@ -47,6 +50,11 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi private Label polarSheetsGenerationLabel; private Label dataCountLabel; + + //Dual mapping. Another solution would be using commons BidiMap. + //But this would require to attach source code for gwt + private Map idNameMapping; + private Map nameIdMapping; public PolarSheetsPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter, StringMessages stringMessages, PolarSheetsEntryPoint polarSheetsEntryPoint) { @@ -54,6 +62,9 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi this.sailingService = sailingService; this.errorReporter = errorReporter; this.stringMessages = stringMessages; + + idNameMapping = new HashMap(); + nameIdMapping = new HashMap(); this.mainPanel = new FlowPanel(); setSize("100%", "100%"); @@ -81,7 +92,8 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi @Override public boolean onMouseOver(PointMouseOverEvent pointMouseOverEvent) { int x = (int) pointMouseOverEvent.getXAsLong(); - String polarSheetId = pointMouseOverEvent.getSeriesName(); + String polarSheetName = pointMouseOverEvent.getSeriesName(); + String polarSheetId = nameIdMapping.get(polarSheetName); GetPolarSheetDataByAngleAction action = new GetPolarSheetDataByAngleAction(sailingService, polarSheetId, x, new AsyncCallback() { @@ -112,6 +124,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi private VerticalPanel addPolarSheetsChartPanel(HorizontalPanel splitPanel) { VerticalPanel verticalPanel = new VerticalPanel(); + verticalPanel.setSize("100%", "100%"); chartPanel = new PolarSheetsChartPanel(stringMessages); verticalPanel.add(chartPanel); splitPanel.add(verticalPanel); @@ -154,16 +167,17 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi protected void startPolarSheetGeneration() { // List conversion, to make List serializable - List selectedRacesInArrayList = new ArrayList(); + final List selectedRacesInArrayList = new ArrayList(); selectedRacesInArrayList.addAll(selectedRaces); polarSheetsTrackedRacesList.changeGenerationButtonState(false); - sailingService.generatePolarSheetForRaces(selectedRacesInArrayList, new AsyncCallback() { + sailingService.generatePolarSheetForRaces(selectedRacesInArrayList, new AsyncCallback() { @Override - public void onSuccess(String result) { + public void onSuccess(PolarSheetGenerationTriggerResponse result) { // TODO string messages setCompletionLabel("Generating..."); - startPullingResults(result); + startPullingResults(result.getId()); + addNameForPolarSheet(result); } @Override @@ -173,6 +187,18 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi }); } + protected void addNameForPolarSheet(PolarSheetGenerationTriggerResponse result) { + String boatClassName = result.getBoatClassName(); + int index = 0; + String name = ""; + do { + index++; + name = boatClassName + "-" + index; + } while (nameIdMapping.containsKey(name)); + idNameMapping.put(result.getId(), name); + nameIdMapping.put(name, result.getId()); + } + protected void startPullingResults(final String id) { sailingService.getPolarSheetsGenerationResults(id, new AsyncCallback() { @@ -182,7 +208,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi // TODO string messages setCompletionLabel("Generating..."); dataCountLabel.setText("DataCount: " + result.getDataCount()); - chartPanel.setData(id, result); + chartPanel.setData(idNameMapping.get(id), result); if (!result.isComplete()) { Timer timer = new Timer() { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 685a58c1e42..5a2060f806e 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -77,6 +77,7 @@ import com.sap.sailing.domain.common.MaxPointsReason; import com.sap.sailing.domain.common.NoWindError; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.Placemark; +import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse; import com.sap.sailing.domain.common.PolarSheetsData; import com.sap.sailing.domain.common.PolarSheetsHistogramData; import com.sap.sailing.domain.common.Position; @@ -100,6 +101,7 @@ import com.sap.sailing.domain.common.impl.DegreeBearingImpl; import com.sap.sailing.domain.common.impl.DegreePosition; import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl; import com.sap.sailing.domain.common.impl.MeterDistance; +import com.sap.sailing.domain.common.impl.PolarSheetGenerationTriggerResponseImpl; import com.sap.sailing.domain.common.impl.PolarSheetsHistogramDataImpl; import com.sap.sailing.domain.common.impl.Util; import com.sap.sailing.domain.common.impl.Util.Pair; @@ -3068,7 +3070,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public String generatePolarSheetForRaces(List selectedRaces) { + public PolarSheetGenerationTriggerResponse generatePolarSheetForRaces(List selectedRaces) { String id = UUID.randomUUID().toString(); RacingEventService service = getService(); Set trackedRaces = new HashSet(); @@ -3078,7 +3080,22 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S PolarSheetGenerationWorker genWorker = new PolarSheetGenerationWorker(trackedRaces, executor); polarSheetGenerationWorkers.put(id, genWorker); genWorker.startPolarSheetGeneration(); - return id; + String name = getCommonBoatClass(trackedRaces); + return new PolarSheetGenerationTriggerResponseImpl(id, name); + } + + private String getCommonBoatClass(Set trackedRaces) { + BoatClass boatClass = null; + for (TrackedRace race : trackedRaces) { + if (boatClass == null) { + boatClass = race.getRace().getBoatClass(); + } + if (!boatClass.getName().matches(race.getRace().getBoatClass().getName())) { + return "Mixed"; + } + } + + return boatClass.getName(); } @Override @@ -3138,7 +3155,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S yValues[i]++; } - PolarSheetsHistogramData histogramData = new PolarSheetsHistogramDataImpl(xValues,yValues); + PolarSheetsHistogramData histogramData = new PolarSheetsHistogramDataImpl(angle, xValues, yValues, dataForAngle.size()); return histogramData; From d2c9b76977a7738a6ebee906bfd7ef7163902d1e Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Mon, 4 Feb 2013 16:41:04 +0100 Subject: [PATCH 23/37] Added test-case for PolarSheet Generation --- .../domain/test/PolarSheetGenerationTest.java | 108 ++++++++++++++++++ ...dCompetitorPolarSheetGenerationWorker.java | 7 +- 2 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java new file mode 100644 index 00000000000..0f11976361f --- /dev/null +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java @@ -0,0 +1,108 @@ +package com.sap.sailing.domain.test; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.UUID; +import java.util.concurrent.Executor; +import java.util.concurrent.FutureTask; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RunnableFuture; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.junit.Test; + +import com.sap.sailing.domain.base.BoatClass; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.RaceDefinition; +import com.sap.sailing.domain.base.Waypoint; +import com.sap.sailing.domain.base.impl.BoatClassImpl; +import com.sap.sailing.domain.base.impl.BoatImpl; +import com.sap.sailing.domain.base.impl.CompetitorImpl; +import com.sap.sailing.domain.base.impl.CourseImpl; +import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl; +import com.sap.sailing.domain.base.impl.MillisecondsTimePoint; +import com.sap.sailing.domain.base.impl.RaceDefinitionImpl; +import com.sap.sailing.domain.base.impl.TeamImpl; +import com.sap.sailing.domain.common.PolarSheetsData; +import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.TimePoint; +import com.sap.sailing.domain.common.impl.DegreeBearingImpl; +import com.sap.sailing.domain.common.impl.DegreePosition; +import com.sap.sailing.domain.polarsheets.PerRaceAndCompetitorPolarSheetGenerationWorker; +import com.sap.sailing.domain.polarsheets.PolarSheetGenerationWorker; +import com.sap.sailing.domain.test.mock.MockedTrackedRace; +import com.sap.sailing.domain.tracking.DynamicGPSFixTrack; +import com.sap.sailing.domain.tracking.GPSFixMoving; +import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sailing.domain.tracking.Wind; +import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl; +import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl; +import com.sap.sailing.domain.tracking.impl.WindImpl; + +public class PolarSheetGenerationTest { + + @Test + public void testPolarSheetRawDataGeneration() throws InterruptedException { + Executor executor = new ThreadPoolExecutor(/* corePoolSize */ 0, + /* maximumPoolSize */ Runtime.getRuntime().availableProcessors(), + /* keepAliveTime */ 60, TimeUnit.SECONDS, + /* workQueue */ new LinkedBlockingQueue()); + + MockTrackedRaceForPolarSheetGeneration race = new MockTrackedRaceForPolarSheetGeneration(); + + TimePoint startTime = new MillisecondsTimePoint(1); + TimePoint endTime = new MillisecondsTimePoint(4); + //Only used for storing and exporting results in this test case: + PolarSheetGenerationWorker resultContainer = new PolarSheetGenerationWorker(new HashSet(), executor); + BoatClass forelle = new BoatClassImpl("Forelle", true); + Competitor competitor = new CompetitorImpl(UUID.randomUUID(), "Hans Frantz", new TeamImpl("SAP", null, null), new BoatImpl("Schnelle Forelle", forelle, "GER000")); + RunnableFuture futureTask = new FutureTask(new PerRaceAndCompetitorPolarSheetGenerationWorker(race, resultContainer, startTime, endTime, competitor)); + + executor.execute(futureTask); + + double timeUntilTimeout = 100; + while (!futureTask.isDone() && timeUntilTimeout > 0) { + Thread.sleep(100); + timeUntilTimeout = timeUntilTimeout - 0.1; + } + + Assert.assertTrue(futureTask.isDone()); + + PolarSheetsData data = resultContainer.getPolarData(); + Assert.assertEquals(4, data.getDataCount()); + Assert.assertEquals(4.0, data.getValues()[45]); + Assert.assertEquals(2.0, data.getValues()[55]); + Assert.assertEquals(6.0, data.getValues()[30]); + + } + + + @SuppressWarnings("serial") + private class MockTrackedRaceForPolarSheetGeneration extends MockedTrackedRace { + @Override + public DynamicGPSFixTrack getTrack(Competitor competitor) { + DynamicGPSFixTrack track = new DynamicGPSFixMovingTrackImpl(competitor, 0); + track.addGPSFix(new GPSFixMovingImpl(new DegreePosition(1.0, 2.0), new MillisecondsTimePoint(1), new KnotSpeedWithBearingImpl(3.0, new DegreeBearingImpl(-45.0)))); + track.addGPSFix(new GPSFixMovingImpl(new DegreePosition(1.0, 2.0), new MillisecondsTimePoint(2), new KnotSpeedWithBearingImpl(5.0, new DegreeBearingImpl(-45.0)))); + track.addGPSFix(new GPSFixMovingImpl(new DegreePosition(1.0, 2.0), new MillisecondsTimePoint(3), new KnotSpeedWithBearingImpl(2.0, new DegreeBearingImpl(-55.0)))); + track.addGPSFix(new GPSFixMovingImpl(new DegreePosition(1.0, 2.0), new MillisecondsTimePoint(4), new KnotSpeedWithBearingImpl(6.0, new DegreeBearingImpl(-30.0)))); + return track; + } + + @Override + public Wind getWind(Position p, TimePoint at) { + Wind wind = new WindImpl(p, at, new KnotSpeedWithBearingImpl(2.0, new DegreeBearingImpl(180.0))); + return wind; + } + + @Override + public RaceDefinition getRace() { + BoatClass forelle = new BoatClassImpl("Forelle", true); + RaceDefinition race = new RaceDefinitionImpl("Forelle1", new CourseImpl("ForelleCourse", new ArrayList()), forelle, new ArrayList()); + return race; + } + } + +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java index 7ef8d32a61f..7194e2f0f04 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java @@ -60,10 +60,9 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< Position position = fix.getPosition(); Wind wind = race.getWind(position, fix.getTimePoint()); Bearing windBearing = wind.getFrom(); - double windSpeed = wind.getKnots(); - - // TODO Figure out if this normalizing is okay concerning different windspeeds and bearings - double normalizedSpeed = speed/* / windSpeed*/; + // TODO windspeed stuff + // double windSpeed = wind.getKnots(); + double normalizedSpeed = speed; double angleToWind = bearing.getDifferenceTo(windBearing).getDegrees(); polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed); From 6a7d95cd4ad5c79151438fba9f6ceffac455844e Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Tue, 5 Feb 2013 14:21:12 +0100 Subject: [PATCH 24/37] Added test for GeneratePolarSheet service --- .../domain/test/PolarSheetGenerationTest.java | 43 +- .../META-INF/MANIFEST.MF | 3 +- .../gwt/ui/test/MockedTrackedRace.java | 727 ++++++++++++++++++ .../test/PolarSheetGenerationServiceTest.java | 203 +++++ .../gwt/ui/server/SailingServiceImpl.java | 10 +- 5 files changed, 975 insertions(+), 11 deletions(-) create mode 100644 java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java create mode 100644 java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/PolarSheetGenerationServiceTest.java diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java index 0f11976361f..e4a95cf9d23 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java @@ -2,6 +2,7 @@ package com.sap.sailing.domain.test; import java.util.ArrayList; import java.util.HashSet; +import java.util.NavigableSet; import java.util.UUID; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; @@ -16,6 +17,7 @@ import org.junit.Test; import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.RaceDefinition; +import com.sap.sailing.domain.base.SpeedWithBearing; import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.base.impl.BoatClassImpl; import com.sap.sailing.domain.base.impl.BoatImpl; @@ -62,7 +64,7 @@ public class PolarSheetGenerationTest { executor.execute(futureTask); - double timeUntilTimeout = 100; + double timeUntilTimeout = 1000; while (!futureTask.isDone() && timeUntilTimeout > 0) { Thread.sleep(100); timeUntilTimeout = timeUntilTimeout - 0.1; @@ -83,11 +85,11 @@ public class PolarSheetGenerationTest { private class MockTrackedRaceForPolarSheetGeneration extends MockedTrackedRace { @Override public DynamicGPSFixTrack getTrack(Competitor competitor) { - DynamicGPSFixTrack track = new DynamicGPSFixMovingTrackImpl(competitor, 0); - track.addGPSFix(new GPSFixMovingImpl(new DegreePosition(1.0, 2.0), new MillisecondsTimePoint(1), new KnotSpeedWithBearingImpl(3.0, new DegreeBearingImpl(-45.0)))); - track.addGPSFix(new GPSFixMovingImpl(new DegreePosition(1.0, 2.0), new MillisecondsTimePoint(2), new KnotSpeedWithBearingImpl(5.0, new DegreeBearingImpl(-45.0)))); - track.addGPSFix(new GPSFixMovingImpl(new DegreePosition(1.0, 2.0), new MillisecondsTimePoint(3), new KnotSpeedWithBearingImpl(2.0, new DegreeBearingImpl(-55.0)))); - track.addGPSFix(new GPSFixMovingImpl(new DegreePosition(1.0, 2.0), new MillisecondsTimePoint(4), new KnotSpeedWithBearingImpl(6.0, new DegreeBearingImpl(-30.0)))); + DynamicGPSFixTrack track = new MockDynamicGPSFixMovinTrackForPolarSheetGeneration(competitor, 0); + track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.0, 1.0), new MillisecondsTimePoint(1), new KnotSpeedWithBearingImpl(3.0, new DegreeBearingImpl(-45.0)))); + track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.001, 1.001), new MillisecondsTimePoint(2), new KnotSpeedWithBearingImpl(5.0, new DegreeBearingImpl(-45.0)))); + track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.002, 1.002), new MillisecondsTimePoint(3), new KnotSpeedWithBearingImpl(2.0, new DegreeBearingImpl(-55.0)))); + track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.003, 1.003), new MillisecondsTimePoint(4), new KnotSpeedWithBearingImpl(6.0, new DegreeBearingImpl(-30.0)))); return track; } @@ -104,5 +106,34 @@ public class PolarSheetGenerationTest { return race; } } + + @SuppressWarnings("serial") + private class MockGPSFixMovingForPolarSheetGeneration extends GPSFixMovingImpl { + + public MockGPSFixMovingForPolarSheetGeneration(Position position, TimePoint timePoint, SpeedWithBearing speed) { + super(position, timePoint, speed); + } + + @Override + public boolean isValid() { + return true; + } + + } + + @SuppressWarnings("serial") + private class MockDynamicGPSFixMovinTrackForPolarSheetGeneration extends DynamicGPSFixMovingTrackImpl { + + public MockDynamicGPSFixMovinTrackForPolarSheetGeneration(ItemType trackedItem, + long millisecondsOverWhichToAverage) { + super(trackedItem, millisecondsOverWhichToAverage); + } + + @Override + protected boolean isValid(NavigableSet rawFixes, GPSFixMoving e) { + return true; + } + + } } diff --git a/java/com.sap.sailing.gwt.ui.test/META-INF/MANIFEST.MF b/java/com.sap.sailing.gwt.ui.test/META-INF/MANIFEST.MF index b2f8e43b4b5..09a8f55521a 100755 --- a/java/com.sap.sailing.gwt.ui.test/META-INF/MANIFEST.MF +++ b/java/com.sap.sailing.gwt.ui.test/META-INF/MANIFEST.MF @@ -7,7 +7,8 @@ Bundle-Vendor: SAP Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Fragment-Host: com.sap.sailing.gwt.ui Require-Bundle: com.sap.sailing.server, - org.hamcrest.core;bundle-version="1.1.0" + org.hamcrest.core;bundle-version="1.1.0", + com.sap.sailing.expeditionconnector Bundle-ClassPath: . Import-Package: javax.jms;version="1.1.0", javax.servlet;version="2.5.0", diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java new file mode 100644 index 00000000000..d18a11b9bc6 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java @@ -0,0 +1,727 @@ +package com.sap.sailing.gwt.ui.test; + +import java.io.Serializable; +import java.util.List; +import java.util.NavigableSet; + +import com.sap.sailing.domain.base.BoatClass; +import com.sap.sailing.domain.base.Mark; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.RaceColumnListener; +import com.sap.sailing.domain.base.Regatta; +import com.sap.sailing.domain.base.RegattaListener; +import com.sap.sailing.domain.base.Leg; +import com.sap.sailing.domain.base.RaceDefinition; +import com.sap.sailing.domain.base.Series; +import com.sap.sailing.domain.base.Waypoint; +import com.sap.sailing.domain.common.Distance; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.domain.common.RegattaIdentifier; +import com.sap.sailing.domain.common.NoWindException; +import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.Tack; +import com.sap.sailing.domain.common.TimePoint; +import com.sap.sailing.domain.common.WindSource; +import com.sap.sailing.domain.common.WindSourceType; +import com.sap.sailing.domain.common.impl.Util.Pair; +import com.sap.sailing.domain.leaderboard.ScoringScheme; +import com.sap.sailing.domain.tracking.DynamicGPSFixTrack; +import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet; +import com.sap.sailing.domain.tracking.DynamicTrackedRegatta; +import com.sap.sailing.domain.tracking.DynamicTrackedRace; +import com.sap.sailing.domain.tracking.GPSFix; +import com.sap.sailing.domain.tracking.GPSFixMoving; +import com.sap.sailing.domain.tracking.Maneuver; +import com.sap.sailing.domain.tracking.MarkPassing; +import com.sap.sailing.domain.tracking.RaceChangeListener; +import com.sap.sailing.domain.tracking.RaceListener; +import com.sap.sailing.domain.tracking.TrackedLeg; +import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; +import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sailing.domain.tracking.TrackedRaceStatus; +import com.sap.sailing.domain.tracking.Wind; +import com.sap.sailing.domain.tracking.WindStore; +import com.sap.sailing.domain.tracking.WindTrack; +import com.sap.sailing.domain.tracking.WindWithConfidence; +import com.sap.sailing.domain.tracking.impl.WindTrackImpl; + +public class MockedTrackedRace implements DynamicTrackedRace { + private static final long serialVersionUID = 5827912985564121181L; + private final WindTrack windTrack = new WindTrackImpl(/* millisecondsOverWhichToAverage */ 30000, /* useSpeed */ true, "TestWindTrack"); + + public WindTrack getWindTrack() { + return windTrack; + } + + @Override + public RaceDefinition getRace() { + // TODO Auto-generated method stub + return null; + } + + @Override + public TimePoint getStartOfRace() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable getTrackedLegs() { + // TODO Auto-generated method stub + return null; + } + + @Override + public TrackedLeg getTrackedLeg(Leg leg) { + // TODO Auto-generated method stub + return null; + } + + @Override + public TrackedLegOfCompetitor getCurrentLeg(Competitor competitor, TimePoint timePoint) { + // TODO Auto-generated method stub + return null; + } + + @Override + public TrackedLeg getCurrentLeg(TimePoint timePoint) { + // TODO Auto-generated method stub + return null; + } + + @Override + public TrackedLeg getTrackedLegFinishingAt(Waypoint endOfLeg) { + // TODO Auto-generated method stub + return null; + } + + @Override + public TrackedLeg getTrackedLegStartingAt(Waypoint startOfLeg) { + // TODO Auto-generated method stub + return null; + } + + @Override + public TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, TimePoint at) { + // TODO Auto-generated method stub + return null; + } + + @Override + public TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, Leg leg) { + // TODO Auto-generated method stub + return null; + } + + @Override + public long getUpdateCount() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getRankDifference(Competitor competitor, Leg leg, TimePoint timePoint) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getRank(Competitor competitor) throws NoWindException { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int getRank(Competitor competitor, TimePoint timePoint) throws NoWindException { + // TODO Auto-generated method stub + return 0; + } + + @Override + public Distance getStartAdvantage(Competitor competitor, double secondsIntoTheRace) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable getMarkPassingsInOrder(Waypoint waypoint) { + // TODO Auto-generated method stub + return null; + } + + @Override + public MarkPassing getMarkPassing(Competitor competitor, Waypoint waypoint) { + // TODO Auto-generated method stub + return null; + } + + @Override + public DynamicGPSFixTrack getOrCreateTrack(Mark mark) { + // TODO Auto-generated method stub + return null; + } + + @Override + public WindTrack getOrCreateWindTrack(WindSource windSource, long delayForWindEstimationCacheInvalidation) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void waitForNextUpdate(int sinceUpdate) throws InterruptedException { + // TODO Auto-generated method stub + + } + + @Override + public TimePoint getStartOfTracking() { + // TODO Auto-generated method stub + return null; + } + + @Override + public TimePoint getTimePointOfNewestEvent() { + // TODO Auto-generated method stub + return null; + } + + @Override + public NavigableSet getMarkPassings(Competitor competitor) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void recordFix(Competitor competitor, GPSFixMoving fix) { + // TODO Auto-generated method stub + + } + + @Override + public void recordWind(Wind wind, WindSource windSource) { + if (windSource.getType() == WindSourceType.EXPEDITION) { + windTrack.add(wind); + } + } + + @Override + public void addListener(RaceChangeListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void updateMarkPassings(Competitor competitor, Iterable markPassings) { + // TODO Auto-generated method stub + + } + + @Override + public void setStartTimeReceived(TimePoint start) { + // TODO Auto-generated method stub + + } + + @Override + public DynamicGPSFixTrack getTrack(Competitor competitor) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void removeWind(Wind wind, WindSource windSource) { + // TODO Auto-generated method stub + + } + + @Override + public TimePoint getTimePointOfLastEvent() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setMillisecondsOverWhichToAverageSpeed(long millisecondsOverWhichToAverageSpeed) { + // TODO Auto-generated method stub + + } + + @Override + public void setMillisecondsOverWhichToAverageWind(long millisecondsOverWhichToAverageWind) { + // TODO Auto-generated method stub + + } + + @Override + public long getMillisecondsOverWhichToAverageSpeed() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public long getMillisecondsOverWhichToAverageWind() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public Wind getEstimatedWindDirection(Position position, TimePoint timePoint) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean hasStarted(TimePoint at) { + // TODO Auto-generated method stub + return false; + } + + @Override + public DynamicTrackedRegatta getTrackedRegatta() { + return new DynamicTrackedRegatta() { + private static final long serialVersionUID = 2651590861333064588L; + + @Override + public Regatta getRegatta() { + return new Regatta() { + private static final long serialVersionUID = -4908774269425170811L; + + @Override + public String getName() { + return "A Mocked Test Regatta"; + } + + @Override + public Serializable getId() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable getAllRaces() { + // TODO Auto-generated method stub + return null; + } + + @Override + public BoatClass getBoatClass() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable getCompetitors() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void addRace(RaceDefinition race) { + // TODO Auto-generated method stub + } + + @Override + public void removeRace(RaceDefinition raceDefinition) { + // TODO Auto-generated method stub + } + + @Override + public RaceDefinition getRaceByName(String raceName) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void addRegattaListener(RegattaListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void removeRegattaListener(RegattaListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public RegattaIdentifier getRegattaIdentifier() { + // TODO Auto-generated method stub + return null; + } + + @Override + public String getBaseName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable getSeries() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Series getSeriesByName(String seriesName) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isPersistent() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void addRaceColumnListener(RaceColumnListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void removeRaceColumnListener(RaceColumnListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public ScoringScheme getScoringScheme() { + // TODO Auto-generated method stub + return null; + } + }; + } + + @Override + public Iterable getTrackedRaces() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable getTrackedRaces(BoatClass boatClass) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void addTrackedRace(TrackedRace trackedRace) { + // TODO Auto-generated method stub + + } + + @Override + public void removeTrackedRace(TrackedRace trackedRace) { + // TODO Auto-generated method stub + + } + + @Override + public void addRaceListener(RaceListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public int getNetPoints(Competitor competitor, TimePoint timePoint) throws NoWindException { + // TODO Auto-generated method stub + return 0; + } + + @Override + public DynamicTrackedRace getTrackedRace(RaceDefinition race) { + // TODO Auto-generated method stub + return null; + } + + @Override + public DynamicTrackedRace getExistingTrackedRace(RaceDefinition race) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void removeTrackedRace(RaceDefinition raceDefinition) { + // TODO Auto-generated method stub + + } + + @Override + public DynamicTrackedRace createTrackedRace(RaceDefinition raceDefinition, WindStore windStore, + long delayToLiveInMillis, long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed, + DynamicRaceDefinitionSet raceDefinitionSetToUpdate) { + // TODO Auto-generated method stub + return null; + } + }; + } + + @Override + public Position getApproximatePosition(Waypoint waypoint, TimePoint timePoint) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Tack getTack(Competitor competitor, TimePoint timePoint) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Wind getDirectionFromStartToNextMark(TimePoint at) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List approximate(Competitor competitor, Distance maxDistance, TimePoint from, TimePoint to) { + // TODO Auto-generated method stub + return null; + } + + @Override + public List getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean raceIsKnownToStartUpwind() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void setRaceIsKnownToStartUpwind(boolean raceIsKnownToStartUpwind) { + // TODO Auto-generated method stub + } + + @Override + public RegattaAndRaceIdentifier getRaceIdentifier() { + // TODO Auto-generated method stub + return null; + } + + @Override + public TimePoint getEndOfRace() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint) + throws NoWindException { + // TODO Auto-generated method stub + return null; + } + + @Override + public Wind getWind(Position p, TimePoint at) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Wind getWind(Position p, TimePoint at, Iterable windSourcesToExclude) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable getWindSources(WindSourceType type) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable getWindSources() { + // TODO Auto-generated method stub + return null; + } + + @Override + public WindWithConfidence> getWindWithConfidence(Position p, TimePoint at, + Iterable windSourcesToExclude) { + // TODO Auto-generated method stub + return null; + } + + @Override + public WindWithConfidence getEstimatedWindDirectionWithConfidence(Position position, TimePoint timePoint) { + // TODO Auto-generated method stub + return null; + } + + @Override + public WindWithConfidence> getWindWithConfidence(Position p, TimePoint at) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable getWindSourcesToExclude() { + // TODO Auto-generated method stub + return null; + } + + @Override + public TimePoint getEndOfTracking() { + // TODO Auto-generated method stub + return null; + } + + @Override + public TimePoint getTimePointOfOldestEvent() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setStartOfTrackingReceived(TimePoint startOfTrackingReceived) { + // TODO Auto-generated method stub + + } + + @Override + public void setEndOfTrackingReceived(TimePoint endOfTrackingReceived) { + // TODO Auto-generated method stub + + } + + @Override + public Iterable>> getMarkPassingsTimes() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Distance getAverageCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException { + // TODO Auto-generated method stub + return null; + } + + @Override + public WindTrack getOrCreateWindTrack(WindSource windSource) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void recordFix(Mark mark, GPSFix fix) { + // TODO Auto-generated method stub + + } + + @Override + public void removeListener(RaceChangeListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public WindStore getWindStore() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setWindSourcesToExclude(Iterable windSourcesToExclude) { + // TODO Auto-generated method stub + } + + @Override + public Competitor getOverallLeader(TimePoint timePoint) throws NoWindException { + // TODO Auto-generated method stub + return null; + } + + @Override + public long getDelayToLiveInMillis() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void setDelayToLiveInMillis(long delayToLiveInMillis) { + // TODO Auto-generated method stub + + } + + @Override + public void setAndFixDelayToLiveInMillis(long delayToLiveInMillis) { + // TODO Auto-generated method stub + + } + + @Override + public List getCompetitorsFromBestToWorst(TimePoint timePoint) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Distance getAverageCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalyses) + throws NoWindException { + // TODO Auto-generated method stub + return null; + } + + @Override + public void waitUntilWindLoadingComplete() throws InterruptedException { + // TODO Auto-generated method stub + } + + @Override + public Iterable getMarks() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean hasWindData() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean hasGPSData() { + // TODO Auto-generated method stub + return false; + } + + @Override + public void lockForRead(Iterable markPassings) { + // TODO Auto-generated method stub + + } + + @Override + public void unlockAfterRead(Iterable markPassings) { + // TODO Auto-generated method stub + + } + + @Override + public TrackedRaceStatus getStatus() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setStatus(TrackedRaceStatus newStatus) { + // TODO Auto-generated method stub + } + + @Override + public void waitUntilNotLoading() { + // TODO Auto-generated method stub + } +} diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/PolarSheetGenerationServiceTest.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/PolarSheetGenerationServiceTest.java new file mode 100644 index 00000000000..a85502ddc14 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/PolarSheetGenerationServiceTest.java @@ -0,0 +1,203 @@ +package com.sap.sailing.gwt.ui.test; + +import java.util.ArrayList; +import java.util.List; +import java.util.NavigableSet; +import java.util.UUID; + +import junit.framework.Assert; + +import org.junit.Test; +import org.osgi.framework.BundleContext; +import org.osgi.util.tracker.ServiceTracker; + +import com.sap.sailing.domain.base.BoatClass; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.RaceDefinition; +import com.sap.sailing.domain.base.SpeedWithBearing; +import com.sap.sailing.domain.base.Waypoint; +import com.sap.sailing.domain.base.impl.BoatClassImpl; +import com.sap.sailing.domain.base.impl.BoatImpl; +import com.sap.sailing.domain.base.impl.CompetitorImpl; +import com.sap.sailing.domain.base.impl.CourseImpl; +import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl; +import com.sap.sailing.domain.base.impl.MillisecondsTimePoint; +import com.sap.sailing.domain.base.impl.RaceDefinitionImpl; +import com.sap.sailing.domain.base.impl.TeamImpl; +import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse; +import com.sap.sailing.domain.common.PolarSheetsData; +import com.sap.sailing.domain.common.Position; +import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; +import com.sap.sailing.domain.common.RegattaNameAndRaceName; +import com.sap.sailing.domain.common.ScoreCorrectionProvider; +import com.sap.sailing.domain.common.TimePoint; +import com.sap.sailing.domain.common.impl.DegreeBearingImpl; +import com.sap.sailing.domain.common.impl.DegreePosition; +import com.sap.sailing.domain.tracking.DynamicGPSFixTrack; +import com.sap.sailing.domain.tracking.GPSFixMoving; +import com.sap.sailing.domain.tracking.TrackedRace; +import com.sap.sailing.domain.tracking.Wind; +import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl; +import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl; +import com.sap.sailing.domain.tracking.impl.WindImpl; +import com.sap.sailing.gwt.ui.client.SailingService; +import com.sap.sailing.gwt.ui.server.SailingServiceImpl; +import com.sap.sailing.server.RacingEventService; +import com.sap.sailing.server.impl.RacingEventServiceImpl; +import com.sap.sailing.server.replication.ReplicationService; + +public class PolarSheetGenerationServiceTest { + + private static final String BOAT_CLASS = "Forelle"; + + @Test + public void testPolarSheetGenerationService() throws InterruptedException { + + SailingService service = new MockSailingServiceForPolarSheetGeneration(); + + List idList = new ArrayList(); + idList.add(new RegattaNameAndRaceName("IrgendeineRegatta", "IrgendeinRennen")); + + PolarSheetGenerationTriggerResponse triggerData = service.generatePolarSheetForRaces(idList); + Assert.assertNotNull(triggerData); + Assert.assertEquals(BOAT_CLASS, triggerData.getBoatClassName()); + Assert.assertNotNull(triggerData.getId()); + + boolean complete = false; + PolarSheetsData results = null; + double timeOut = 10; + while (!complete && timeOut > 0) { + Thread.sleep(200); + timeOut = timeOut - 0.2; + results = service.getPolarSheetsGenerationResults(triggerData.getId()); + complete = results.isComplete(); + } + + Assert.assertTrue(complete); + Assert.assertNotNull(results); + + Assert.assertEquals(4, results.getDataCount()); + Assert.assertEquals(4.0, results.getValues()[45]); + Assert.assertEquals(2.0, results.getValues()[55]); + Assert.assertEquals(6.0, results.getValues()[30]); + + + + + } + + + @SuppressWarnings("serial") + private class MockSailingServiceForPolarSheetGeneration extends SailingServiceImpl { + + @Override + protected RacingEventService getService() { + RacingEventService service = new MockRacingEventServiceForPolarSheetGeneration(); + return service; + } + + @Override + protected ServiceTracker createAndOpenRacingEventServiceTracker( + BundleContext context) { + return null; + } + + @Override + protected ServiceTracker createAndOpenReplicationServiceTracker( + BundleContext context) { + return null; + } + + @Override + protected ServiceTracker createAndOpenScoreCorrectionProviderServiceTracker( + BundleContext bundleContext) {; + return null; + } + + } + + private class MockRacingEventServiceForPolarSheetGeneration extends RacingEventServiceImpl { + + @Override + public TrackedRace getTrackedRace(RegattaAndRaceIdentifier raceIdentifier) { + MockTrackedRaceForPolarSheetGeneration trackedRace = new MockTrackedRaceForPolarSheetGeneration(); + return trackedRace; + } + + } + + @SuppressWarnings("serial") + private class MockTrackedRaceForPolarSheetGeneration extends MockedTrackedRace { + + + @Override + public DynamicGPSFixTrack getTrack(Competitor competitor) { + DynamicGPSFixTrack track = new MockDynamicGPSFixMovinTrackForPolarSheetGeneration(competitor, 0); + track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.0, 1.0), new MillisecondsTimePoint(1), new KnotSpeedWithBearingImpl(3.0, new DegreeBearingImpl(-45.0)))); + track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.001, 1.001), new MillisecondsTimePoint(2), new KnotSpeedWithBearingImpl(5.0, new DegreeBearingImpl(-45.0)))); + track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.002, 1.002), new MillisecondsTimePoint(3), new KnotSpeedWithBearingImpl(2.0, new DegreeBearingImpl(-55.0)))); + track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.003, 1.003), new MillisecondsTimePoint(4), new KnotSpeedWithBearingImpl(6.0, new DegreeBearingImpl(-30.0)))); + + //Should not be taken into consideration because it happens after the race has ended + track.addGPSFix(new GPSFixMovingImpl(new DegreePosition(2.0, 3.0), new MillisecondsTimePoint(7), new KnotSpeedWithBearingImpl(5.0, new DegreeBearingImpl(-45.0)))); + return track; + } + + @Override + public Wind getWind(Position p, TimePoint at) { + Wind wind = new WindImpl(p, at, new KnotSpeedWithBearingImpl(2.0, new DegreeBearingImpl(180.0))); + return wind; + } + + @Override + public RaceDefinition getRace() { + BoatClass forelle = new BoatClassImpl(BOAT_CLASS, true); + Competitor competitor = new CompetitorImpl(UUID.randomUUID(), "Hans Frantz", new TeamImpl("SAP", null, null), new BoatImpl("Schnelle Forelle", forelle, "GER000")); + ArrayList competitors = new ArrayList(); + competitors.add(competitor); + RaceDefinition race = new RaceDefinitionImpl("Forelle1", new CourseImpl("ForelleCourse", new ArrayList()), forelle, competitors); + return race; + } + + @Override + public TimePoint getStartOfRace() { + return new MillisecondsTimePoint(1); + } + + @Override + public TimePoint getEndOfRace() { + return new MillisecondsTimePoint(5); + } + } + + @SuppressWarnings("serial") + private class MockGPSFixMovingForPolarSheetGeneration extends GPSFixMovingImpl { + + public MockGPSFixMovingForPolarSheetGeneration(Position position, TimePoint timePoint, SpeedWithBearing speed) { + super(position, timePoint, speed); + } + + @Override + public boolean isValid() { + return true; + } + + } + + @SuppressWarnings("serial") + private class MockDynamicGPSFixMovinTrackForPolarSheetGeneration extends DynamicGPSFixMovingTrackImpl { + + public MockDynamicGPSFixMovinTrackForPolarSheetGeneration(ItemType trackedItem, + long millisecondsOverWhichToAverage) { + super(trackedItem, millisecondsOverWhichToAverage); + } + + @Override + protected boolean isValid(NavigableSet rawFixes, GPSFixMoving e) { + return true; + } + + } + + +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 1243d2ec235..9546549928d 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -363,7 +363,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S /** * Asks the OSGi system for registered score correction provider services */ - private ServiceTracker createAndOpenScoreCorrectionProviderServiceTracker( + protected ServiceTracker createAndOpenScoreCorrectionProviderServiceTracker( BundleContext bundleContext) { ServiceTracker tracker = new ServiceTracker(bundleContext, ScoreCorrectionProvider.class.getName(), @@ -3133,10 +3133,12 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S PolarSheetGenerationWorker worker = polarSheetGenerationWorkers.get(id); data = worker.getPolarData(); if (data.isComplete()) { - HttpServletRequest httpServletRequest = this.getThreadLocalRequest(); - HttpSession session = httpServletRequest.getSession(); - session.setAttribute(id, worker.getCompleteData()); polarSheetGenerationWorkers.remove(id); + HttpServletRequest httpServletRequest = this.getThreadLocalRequest(); + if (httpServletRequest != null) { + HttpSession session = httpServletRequest.getSession(); + session.setAttribute(id, worker.getCompleteData()); + } } } else { //TODO Exception handling From b75d043a798395f711bb10682d1a186fe06b622f Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Tue, 5 Feb 2013 16:13:46 +0100 Subject: [PATCH 25/37] Added some comments to polar sheet generation logic --- ...dCompetitorPolarSheetGenerationWorker.java | 30 ++++++---- .../PolarSheetGenerationWorker.java | 57 ++++++++++++++++--- 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java index 7194e2f0f04..1eb2e87eec5 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java @@ -13,23 +13,28 @@ import com.sap.sailing.domain.tracking.GPSFixTrack; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.Wind; -public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable{ +/** + * Iterates through the fixes of one competitor in one tracked race and fills the {@link PolarSheetGenerationWorker} + * with datapoints that are found for the speed of the boat and its angle to the wind + * + * @author D054528 Frederik Petersen + * + */ +public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable { private final TrackedRace race; private final PolarSheetGenerationWorker polarSheetGenerationWorker; - + private final TimePoint startTime; - + private final TimePoint endTime; - + private final Competitor competitor; - - - - public PerRaceAndCompetitorPolarSheetGenerationWorker(TrackedRace race, PolarSheetGenerationWorker polarSheetGenerationWorker, - TimePoint startTime, TimePoint endTime, Competitor competitor) { + public PerRaceAndCompetitorPolarSheetGenerationWorker(TrackedRace race, + PolarSheetGenerationWorker polarSheetGenerationWorker, TimePoint startTime, TimePoint endTime, + Competitor competitor) { super(); this.race = race; this.polarSheetGenerationWorker = polarSheetGenerationWorker; @@ -49,8 +54,9 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< if (fix.getTimePoint().after(endTime)) { break; } - - if (track.hasDirectionChange(fix.getTimePoint(), race.getRace().getBoatClass().getManeuverDegreeAngleThreshold())) { + + if (track.hasDirectionChange(fix.getTimePoint(), race.getRace().getBoatClass() + .getManeuverDegreeAngleThreshold())) { continue; } @@ -67,7 +73,7 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed); } - + track.unlockAfterRead(); return null; } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java index 81a37183757..424a1e67e78 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java @@ -15,6 +15,14 @@ import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl; import com.sap.sailing.domain.tracking.TrackedRace; +/** + * Allows extracting data about average speed for each angle creating the foundation of polar-sheet generation. Tasks + * are assigned to the executor per race & per competitor and the results are filled on the go to allow progress + * indication in the polar-sheet itself. + * + * @author D054528 Frederik Petersen + * + */ public class PolarSheetGenerationWorker { private final Set> workers; @@ -23,6 +31,15 @@ public class PolarSheetGenerationWorker { private final Executor executor; + /** + * Will prepare the {@link PerRaceAndCompetitorPolarSheetGenerationWorker}s per race & per competitor. This includes + * determining start and end time. + * + * @param trackedRaces + * from which the data is to be collected + * @param executor + * executes the tasks upon {@link #startPolarSheetGeneration()} + */ public PolarSheetGenerationWorker(Set trackedRaces, Executor executor) { polarData = initializePolarDataContainer(); this.executor = executor; @@ -31,18 +48,18 @@ public class PolarSheetGenerationWorker { TimePoint startTime = race.getStartOfRace(); TimePoint endTime = race.getEndOfRace(); if (endTime == null) { - //TODO Figure out if there is an alternative: + // TODO Figure out if there is an alternative: endTime = race.getTimePointOfNewestEvent(); } RaceDefinition raceDefinition = race.getRace(); Iterable competitors = raceDefinition.getCompetitors(); - for (Competitor competitor : competitors) { - RunnableFuture futureTask = new FutureTask(new PerRaceAndCompetitorPolarSheetGenerationWorker(race, this, startTime, endTime, competitor)); + RunnableFuture futureTask = new FutureTask( + new PerRaceAndCompetitorPolarSheetGenerationWorker(race, this, startTime, endTime, competitor)); workers.add(futureTask); } - + } } @@ -54,20 +71,38 @@ public class PolarSheetGenerationWorker { return container; } + /** + * Starts the {@link PerRaceAndCompetitorPolarSheetGenerationWorker}s + */ public void startPolarSheetGeneration() { for (RunnableFuture future : workers) { executor.execute(future); } } - public void addPolarData(long roundedAngle, double normalizedSpeed) { + /** + * To be called from {@link PerRaceAndCompetitorPolarSheetGenerationWorker} for adding a datapoint to the list of + * results + * + * @param roundedAngle + * boat's angle to the wind + * @param speed + * boat's speed + */ + protected void addPolarData(long roundedAngle, double speed) { int angle = (int) roundedAngle; if (angle < 0) { angle = (360 + angle); } - polarData.get(angle).add(normalizedSpeed); + polarData.get(angle).add(speed); } + /** + * + * @return results already averaged per angle. Also datacount overall and per angle. And a completion flag to show + * if the complete polar sheet has been generated or if the current results are only an intermediate + * product. + */ public PolarSheetsData getPolarData() { Number[] averagedPolarData = new Number[360]; Integer[] dataCountPerAngle = new Integer[360]; @@ -97,16 +132,20 @@ public class PolarSheetGenerationWorker { break; } } - + PolarSheetsData data = new PolarSheetsDataImpl(averagedPolarData, complete, dataCount, dataCountPerAngle); - return data; } + /** + * Can be used to present more detailed data. + * + * @return The complete set of datapoints that have been added. Can be quite big, depending on the amount of races + * and competitors. + */ public List> getCompleteData() { return polarData; } - } From faa30981b00f48469ad5b3030254aed405bfdb88 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Thu, 7 Feb 2013 09:21:20 +0100 Subject: [PATCH 26/37] Added start/stop timepoint optimization to polar sheet generation --- ...dCompetitorPolarSheetGenerationWorker.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java index 1eb2e87eec5..90f8c837e8f 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java @@ -1,6 +1,7 @@ package com.sap.sailing.domain.polarsheets; import java.util.Iterator; +import java.util.NavigableSet; import java.util.concurrent.Callable; import com.sap.sailing.domain.base.Competitor; @@ -10,6 +11,7 @@ import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.tracking.GPSFixMoving; import com.sap.sailing.domain.tracking.GPSFixTrack; +import com.sap.sailing.domain.tracking.MarkPassing; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.Wind; @@ -26,9 +28,9 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< private final PolarSheetGenerationWorker polarSheetGenerationWorker; - private final TimePoint startTime; + private TimePoint startTime; - private final TimePoint endTime; + private TimePoint endTime; private final Competitor competitor; @@ -41,6 +43,32 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< this.startTime = startTime; this.endTime = endTime; this.competitor = competitor; + optimizeStartTime(); + optimizeEndTime(); + } + + private void optimizeEndTime() { + NavigableSet markPassings = race.getMarkPassings(competitor); + if (markPassings.size() < 1) { + return; + } + MarkPassing passedFinish = markPassings.last(); + TimePoint passedFinishTimePoint = passedFinish.getTimePoint(); + if (passedFinishTimePoint.before(endTime)) { + endTime = passedFinishTimePoint; + } + } + + private void optimizeStartTime() { + NavigableSet markPassings = race.getMarkPassings(competitor); + if (markPassings.size() < 1) { + return; + } + MarkPassing passedStart = markPassings.first(); + TimePoint passedStartTimePoint = passedStart.getTimePoint(); + if (passedStartTimePoint.after(startTime)) { + startTime = passedStartTimePoint; + } } @Override From ce80f0e211cbd15cd5d3576886816fdba1a3380b Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Thu, 7 Feb 2013 11:50:44 +0100 Subject: [PATCH 27/37] Changed point marker color range to red/blue for polarsheet --- .../ui/polarsheets/PolarSheetsChartPanel.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java index 9b23a66007c..d5544059be0 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java @@ -84,8 +84,24 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize points[i] = new Point(0); } double alpha = (double) dataCountList.get(i) / (double) max; - // TODO set to series color and change alpha - points[i].setMarker(new Marker().setFillColor(new Color(1, 1, 1, alpha))); + int blue; + int red; + int radius; + if (alpha > 0.2) { + red = (int) (alpha * 255); + blue = 0; + radius = 4; + } else { + blue = (int) ((1 - alpha) * 255); + red = 0; + radius = 2; + } + + // Don't let the markers be invisible + alpha = 0.5 + 0.5 * alpha; + // TODO maybe set to series color. Not sure if this (highcharts-generated color) can be queried before + // rendering + points[i].setMarker(new Marker().setFillColor(new Color(red, 0, blue, alpha)).setRadius(radius)); } return points; From d30aea90ec5d7772a0fd5220465de892cc858128 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Fri, 8 Feb 2013 11:28:58 +0100 Subject: [PATCH 28/37] PolarSheetGeneration is now happening on a per windspeed basis --- .../domain/common/PolarSheetsData.java | 6 +- .../common/impl/PolarSheetsDataImpl.java | 21 +++--- .../domain/test/PolarSheetGenerationTest.java | 6 +- .../domain/polarsheets/BoatAndWindSpeed.java | 11 ++++ .../polarsheets/BoatAndWindSpeedImpl.java | 28 ++++++++ ...dCompetitorPolarSheetGenerationWorker.java | 10 +-- .../PolarSheetGenerationWorker.java | 66 ++++++++++++------- .../test/PolarSheetGenerationServiceTest.java | 6 +- .../GetPolarSheetDataByAngleAction.java | 6 +- .../sailing/gwt/ui/client/SailingService.java | 2 +- .../gwt/ui/client/SailingServiceAsync.java | 2 +- .../ui/polarsheets/PolarSheetsChartPanel.java | 43 +++++++----- .../PolarSheetsHistogramPanel.java | 1 + .../gwt/ui/polarsheets/PolarSheetsPanel.java | 12 +++- .../gwt/ui/server/SailingServiceImpl.java | 29 ++++++-- 15 files changed, 170 insertions(+), 79 deletions(-) create mode 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/BoatAndWindSpeed.java create mode 100644 java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/BoatAndWindSpeedImpl.java diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java index 321fcab9ee0..d435b59acfb 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/PolarSheetsData.java @@ -4,12 +4,12 @@ import java.io.Serializable; public interface PolarSheetsData extends Serializable { - Number[] getValues(); + Number[][] getAveragedPolarDataByWindSpeed(); int getDataCount(); boolean isComplete(); - - Integer[] getDataCountPerAngle(); + + Integer[] getDataCountPerAngleForWindspeed(int beaufort); } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java index ad1f2dabb63..0d38c4920fd 100644 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/PolarSheetsDataImpl.java @@ -1,32 +1,34 @@ package com.sap.sailing.domain.common.impl; +import java.util.Map; + import com.sap.sailing.domain.common.PolarSheetsData; public class PolarSheetsDataImpl implements PolarSheetsData { private static final long serialVersionUID = -4649254807341866894L; - private Number[] values; + private Number[][] averagedPolarDataByWindSpeed; private boolean complete; private int dataCount; - private Integer[] dataCountPerAngle; + private Map dataCountPerAngleForWindspeed; //For GWT Serialization PolarSheetsDataImpl() {}; - public PolarSheetsDataImpl(Number[] values, boolean complete, int dataCount, Integer[] dataCountPerAngle) { - this.values = values; + public PolarSheetsDataImpl(Number[][] averagedPolarDataByWindSpeed, boolean complete, int dataCount, Map dataCountPerAngleForWindspeed) { + this.averagedPolarDataByWindSpeed = averagedPolarDataByWindSpeed; this.complete = complete; this.dataCount = dataCount; - this.dataCountPerAngle = dataCountPerAngle; + this.dataCountPerAngleForWindspeed = dataCountPerAngleForWindspeed; } @Override - public Number[] getValues() { - return values; + public Number[][] getAveragedPolarDataByWindSpeed() { + return averagedPolarDataByWindSpeed; } @Override @@ -39,9 +41,10 @@ public class PolarSheetsDataImpl implements PolarSheetsData { return dataCount; } + @Override - public Integer[] getDataCountPerAngle() { - return dataCountPerAngle; + public Integer[] getDataCountPerAngleForWindspeed(int beaufort) { + return dataCountPerAngleForWindspeed.get(beaufort); } } diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java index e4a95cf9d23..d478a92a0bf 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java @@ -74,9 +74,9 @@ public class PolarSheetGenerationTest { PolarSheetsData data = resultContainer.getPolarData(); Assert.assertEquals(4, data.getDataCount()); - Assert.assertEquals(4.0, data.getValues()[45]); - Assert.assertEquals(2.0, data.getValues()[55]); - Assert.assertEquals(6.0, data.getValues()[30]); + Assert.assertEquals(4.0, data.getAveragedPolarDataByWindSpeed()[1][45]); + Assert.assertEquals(2.0, data.getAveragedPolarDataByWindSpeed()[1][55]); + Assert.assertEquals(6.0, data.getAveragedPolarDataByWindSpeed()[1][30]); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/BoatAndWindSpeed.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/BoatAndWindSpeed.java new file mode 100644 index 00000000000..b28ce358c86 --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/BoatAndWindSpeed.java @@ -0,0 +1,11 @@ +package com.sap.sailing.domain.polarsheets; + +import com.sap.sailing.domain.common.Speed; + +public interface BoatAndWindSpeed { + + public Speed getBoatSpeed(); + + public Speed getWindSpeed(); + +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/BoatAndWindSpeedImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/BoatAndWindSpeedImpl.java new file mode 100644 index 00000000000..0fc2ccc1eff --- /dev/null +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/BoatAndWindSpeedImpl.java @@ -0,0 +1,28 @@ +package com.sap.sailing.domain.polarsheets; + +import com.sap.sailing.domain.common.Speed; + +public class BoatAndWindSpeedImpl implements BoatAndWindSpeed{ + + private Speed boatSpeed; + private Speed windSpeed; + + + + public BoatAndWindSpeedImpl(Speed boatSpeed, Speed windSpeed) { + this.boatSpeed = boatSpeed; + this.windSpeed = windSpeed; + } + + @Override + public Speed getBoatSpeed() { + return boatSpeed; + } + + @Override + public Speed getWindSpeed() { + return windSpeed; + } + + +} diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java index 90f8c837e8f..a70a9f9fc13 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java @@ -49,7 +49,7 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< private void optimizeEndTime() { NavigableSet markPassings = race.getMarkPassings(competitor); - if (markPassings.size() < 1) { + if (markPassings == null || markPassings.size() < 1) { return; } MarkPassing passedFinish = markPassings.last(); @@ -61,7 +61,7 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< private void optimizeStartTime() { NavigableSet markPassings = race.getMarkPassings(competitor); - if (markPassings.size() < 1) { + if (markPassings == null || markPassings.size() < 1) { return; } MarkPassing passedStart = markPassings.first(); @@ -89,17 +89,13 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< } SpeedWithBearing speedWithBearing = fix.getSpeed(); - double speed = speedWithBearing.getKnots(); Bearing bearing = speedWithBearing.getBearing(); Position position = fix.getPosition(); Wind wind = race.getWind(position, fix.getTimePoint()); Bearing windBearing = wind.getFrom(); - // TODO windspeed stuff - // double windSpeed = wind.getKnots(); - double normalizedSpeed = speed; double angleToWind = bearing.getDifferenceTo(windBearing).getDegrees(); - polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), normalizedSpeed); + polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), speedWithBearing, wind); } track.unlockAfterRead(); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java index 424a1e67e78..6ee4848960f 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java @@ -1,8 +1,10 @@ package com.sap.sailing.domain.polarsheets; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; @@ -11,6 +13,7 @@ import java.util.concurrent.RunnableFuture; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.common.PolarSheetsData; +import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.TimePoint; import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl; import com.sap.sailing.domain.tracking.TrackedRace; @@ -27,7 +30,7 @@ public class PolarSheetGenerationWorker { private final Set> workers; - private final List> polarData; + private final List> polarData; private final Executor executor; @@ -63,10 +66,10 @@ public class PolarSheetGenerationWorker { } } - private List> initializePolarDataContainer() { - List> container = new ArrayList>(); + private List> initializePolarDataContainer() { + List> container = new ArrayList>(); for (int i = 0; i < 360; i++) { - container.add(new ArrayList()); + container.add(new ArrayList()); } return container; } @@ -86,15 +89,18 @@ public class PolarSheetGenerationWorker { * * @param roundedAngle * boat's angle to the wind - * @param speed - * boat's speed + * @param boatSpeed + * boat's speed in knots + * @param windSpeed + * wind's speed in knots */ - protected void addPolarData(long roundedAngle, double speed) { + protected void addPolarData(long roundedAngle, Speed boatSpeed, Speed windSpeed) { int angle = (int) roundedAngle; if (angle < 0) { angle = (360 + angle); } - polarData.get(angle).add(speed); + BoatAndWindSpeed speeds = new BoatAndWindSpeedImpl(boatSpeed, windSpeed); + polarData.get(angle).add(speeds); } /** @@ -104,26 +110,41 @@ public class PolarSheetGenerationWorker { * product. */ public PolarSheetsData getPolarData() { - Number[] averagedPolarData = new Number[360]; + Number[][] averagedPolarDataByWindSpeed = new Number[13][360]; Integer[] dataCountPerAngle = new Integer[360]; int dataCount = 0; + Map dataCountPerAngleForWindspeed = new HashMap(); + for (int i = 0; i < 13; i++) { + dataCountPerAngleForWindspeed.put(i, new Integer[360]); + } for (int i = 0; i < 360; i++) { // Avoid Concurrent modification, lock would slow things down - Double[] values = polarData.get(i).toArray(new Double[polarData.get(i).size()]); + BoatAndWindSpeed[] values = polarData.get(i).toArray(new BoatAndWindSpeed[polarData.get(i).size()]); dataCount = dataCount + values.length; dataCountPerAngle[i] = values.length; - if (values.length < 1) { - averagedPolarData[i] = 0; - } else { - double sum = 0; - for (Double singleData : values) { - if (singleData != null) { - sum = sum + singleData; - } + double[] sumsPerWindSpeed = new double[13]; + int[] dataCountPerWindSpeed = new int[13]; + for (BoatAndWindSpeed singleDataPoint : values) { + if (singleDataPoint != null) { + int windSpeed = (int) singleDataPoint.getWindSpeed().getBeaufort(); + //TODO enable different kinds of metrics for boats speed + sumsPerWindSpeed[windSpeed] = sumsPerWindSpeed[windSpeed] + singleDataPoint.getBoatSpeed().getKnots(); + dataCountPerWindSpeed[windSpeed]++; } - double average = sum / values.length; - averagedPolarData[i] = average; } + + for (int j = 0; j < 13; j++) { + Double average = sumsPerWindSpeed[j] / dataCountPerWindSpeed[j]; + if (average.isNaN()) { + average = new Double(0); + } + averagedPolarDataByWindSpeed[j][i] = average; + dataCountPerAngleForWindspeed.get(j)[i] = dataCountPerWindSpeed[j]; + } + + + + } boolean complete = true; for (RunnableFuture future : workers) { @@ -133,7 +154,8 @@ public class PolarSheetGenerationWorker { } } - PolarSheetsData data = new PolarSheetsDataImpl(averagedPolarData, complete, dataCount, dataCountPerAngle); + PolarSheetsData data = new PolarSheetsDataImpl(averagedPolarDataByWindSpeed, complete, dataCount, + dataCountPerAngleForWindspeed); return data; } @@ -144,7 +166,7 @@ public class PolarSheetGenerationWorker { * @return The complete set of datapoints that have been added. Can be quite big, depending on the amount of races * and competitors. */ - public List> getCompleteData() { + public List> getCompleteData() { return polarData; } diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/PolarSheetGenerationServiceTest.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/PolarSheetGenerationServiceTest.java index a85502ddc14..80535f1975f 100644 --- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/PolarSheetGenerationServiceTest.java +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/PolarSheetGenerationServiceTest.java @@ -77,9 +77,9 @@ public class PolarSheetGenerationServiceTest { Assert.assertNotNull(results); Assert.assertEquals(4, results.getDataCount()); - Assert.assertEquals(4.0, results.getValues()[45]); - Assert.assertEquals(2.0, results.getValues()[55]); - Assert.assertEquals(6.0, results.getValues()[30]); + Assert.assertEquals(4.0, results.getAveragedPolarDataByWindSpeed()[1][45]); + Assert.assertEquals(2.0, results.getAveragedPolarDataByWindSpeed()[1][55]); + Assert.assertEquals(6.0, results.getAveragedPolarDataByWindSpeed()[1][30]); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/actions/GetPolarSheetDataByAngleAction.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/actions/GetPolarSheetDataByAngleAction.java index 7e30b6e2e5c..6d4ecaab442 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/actions/GetPolarSheetDataByAngleAction.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/actions/GetPolarSheetDataByAngleAction.java @@ -9,22 +9,24 @@ public class GetPolarSheetDataByAngleAction extends DefaultAsyncAction callback) { + String polarSheetId, int angle, int windSpeed, AsyncCallback callback) { super(callback); this.sailingService = sailingService; this.polarSheetId = polarSheetId; this.angle = angle; + this.windSpeed = windSpeed; } @Override public void execute(AsyncActionsExecutor asyncActionsExecutor) { - sailingService.getPolarSheetData(polarSheetId, angle, (AsyncCallback) getWrapperCallback(asyncActionsExecutor)); + sailingService.getPolarSheetData(polarSheetId, angle, windSpeed, (AsyncCallback) getWrapperCallback(asyncActionsExecutor)); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java index 079925a15c9..147378933f2 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java @@ -291,5 +291,5 @@ public interface SailingService extends RemoteService { PolarSheetsData getPolarSheetsGenerationResults(String id); - PolarSheetsHistogramData getPolarSheetData(String polarSheetId, int angle); + PolarSheetsHistogramData getPolarSheetData(String polarSheetId, int angle, int windSpeed); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java index c7342b06d61..bf1b258b2ab 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java @@ -443,5 +443,5 @@ public interface SailingServiceAsync { void getPolarSheetsGenerationResults(String id, AsyncCallback asyncCallback); - void getPolarSheetData(String polarSheetId, int angle, AsyncCallback wrapperCallback); + void getPolarSheetData(String polarSheetId, int angle, int windSpeed, AsyncCallback wrapperCallback); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java index d5544059be0..0e8d12ead1c 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java @@ -24,13 +24,13 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize private StringMessages stringMessages; private Chart chart; - private Map seriesMap; + private Map seriesMap; public PolarSheetsChartPanel(StringMessages stringMessages) { this.stringMessages = stringMessages; - setSize("100%", "100%"); + setPixelSize(800, 800); chart = createPolarSheetChart(); - seriesMap = new HashMap(); + seriesMap = new HashMap(); setWidget(chart); } @@ -45,11 +45,14 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize private void newSeries(String name) { if (!seriesMap.containsKey(name)) { - Number[] forEachDeg = initializeDataForNewSeries(); - Series newSeries = chart.createSeries().setPoints(forEachDeg); - newSeries.setName(name); - chart.addSeries(newSeries); - seriesMap.put(name, newSeries); + Series[] seriesPerWindSpeed = new Series[13]; + for (int i = 0; i < 13; i++) { + Number[] forEachDeg = initializeDataForNewSeries(); + seriesPerWindSpeed[i] = chart.createSeries().setPoints(forEachDeg); + seriesPerWindSpeed[i].setName(name+"-"+(i)); + chart.addSeries(seriesPerWindSpeed[i]); + } + seriesMap.put(name, seriesPerWindSpeed); } else { // TODO exception handling } @@ -62,24 +65,26 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize private void addValuesToSeries(String seriesId, PolarSheetsData result) { if (seriesMap.containsKey(seriesId)) { - Series series = seriesMap.get(seriesId); - series.setPoints(result.getValues(), false); - Point[] points = createPointsWithMarkerAlphaAccordingToDataCount(result); - if (points != null) { - series.setPoints(points); + for (int i = 0; i < 13; i++) { + Series series = seriesMap.get(seriesId)[i]; + series.setPoints(result.getAveragedPolarDataByWindSpeed()[i], false); + Point[] points = createPointsWithMarkerAlphaAccordingToDataCount(result, i); + if (points != null) { + series.setPoints(points); + } } } } - private Point[] createPointsWithMarkerAlphaAccordingToDataCount(PolarSheetsData result) { + private Point[] createPointsWithMarkerAlphaAccordingToDataCount(PolarSheetsData result, int beaufort) { Point[] points = new Point[360]; - List dataCountList = Arrays.asList(result.getDataCountPerAngle()); + List dataCountList = Arrays.asList(result.getDataCountPerAngleForWindspeed(beaufort)); Integer max = Collections.max(dataCountList); if (max <= 0) { return null; } for (int i = 0; i < 360; i++) { - points[i] = new Point(result.getValues()[i]); + points[i] = new Point(result.getAveragedPolarDataByWindSpeed()[beaufort][i]); if (points[i] == null) { points[i] = new Point(0); } @@ -109,8 +114,10 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize public void removeSeries(String seriesId) { if (seriesMap.containsKey(seriesId)) { - Series series = seriesMap.get(seriesId); - chart.removeSeries(series); + Series[] seriesPerWindSpeed = seriesMap.get(seriesId); + for (Series series : seriesPerWindSpeed) { + chart.removeSeries(series); + } seriesMap.remove(seriesId); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java index c260b26c022..2b669d3d8c8 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java @@ -24,6 +24,7 @@ public class PolarSheetsHistogramPanel extends SimplePanel implements RequiresRe this.stringMessages = stringMessages; setSize("100%", "100%"); chart = createHistogramChart(); + chart.getElement().setAttribute("align", "top"); setWidget(chart); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java index 88d90bb4b08..9c3180feb06 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsPanel.java @@ -79,6 +79,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi leftPanel.add(dataCountLabel); VerticalPanel rightPanel = addPolarSheetsChartPanel(splitPanel); histogramPanel = new PolarSheetsHistogramPanel(stringMessages); + histogramPanel.getElement().setAttribute("align", "top"); rightPanel.add(histogramPanel); mainPanel.add(splitPanel); @@ -91,11 +92,15 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi @Override public boolean onMouseOver(PointMouseOverEvent pointMouseOverEvent) { - int x = (int) pointMouseOverEvent.getXAsLong(); - String polarSheetName = pointMouseOverEvent.getSeriesName(); + int angle = (int) pointMouseOverEvent.getXAsLong(); + String polarSheetNameWithWind = pointMouseOverEvent.getSeriesName(); + String[] split = polarSheetNameWithWind.split("-"); + String polarSheetName = split[0] + "-" + split[1]; String polarSheetId = nameIdMapping.get(polarSheetName); + int windSpeed = Integer.parseInt(split[2]); + GetPolarSheetDataByAngleAction action = new GetPolarSheetDataByAngleAction(sailingService, - polarSheetId, x, new AsyncCallback() { + polarSheetId, angle, windSpeed, new AsyncCallback() { @Override public void onSuccess(PolarSheetsHistogramData result) { @@ -127,6 +132,7 @@ public class PolarSheetsPanel extends FormPanel implements RaceSelectionChangeLi verticalPanel.setSize("100%", "100%"); chartPanel = new PolarSheetsChartPanel(stringMessages); verticalPanel.add(chartPanel); + verticalPanel.setCellHeight(chartPanel, "800px"); splitPanel.add(verticalPanel); splitPanel.setCellWidth(verticalPanel, "50%"); return verticalPanel; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index 418b9fff240..11248bbfcd3 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -116,6 +116,7 @@ import com.sap.sailing.domain.persistence.DomainObjectFactory; import com.sap.sailing.domain.persistence.MongoFactory; import com.sap.sailing.domain.persistence.MongoObjectFactory; import com.sap.sailing.domain.persistence.MongoWindStoreFactory; +import com.sap.sailing.domain.polarsheets.BoatAndWindSpeed; import com.sap.sailing.domain.polarsheets.PolarSheetGenerationWorker; import com.sap.sailing.domain.swisstimingadapter.SwissTimingArchiveConfiguration; import com.sap.sailing.domain.swisstimingadapter.SwissTimingConfiguration; @@ -3156,22 +3157,36 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } @Override - public PolarSheetsHistogramData getPolarSheetData(String polarSheetId, int angle) { + public PolarSheetsHistogramData getPolarSheetData(String polarSheetId, int angle, int windSpeed) { HttpServletRequest httpServletRequest = this.getThreadLocalRequest(); HttpSession session = httpServletRequest.getSession(); @SuppressWarnings("unchecked") - List> data = (List>) session.getAttribute(polarSheetId); + List> data = (List>) session.getAttribute(polarSheetId); if (data == null) { //TODO exception handling return null; } - List dataForAngle = data.get(angle); + List dataForAngle = data.get(angle); if (dataForAngle.size() < 1) { //TODO exception handling return null; } - Double min = Collections.min(dataForAngle); - Double max = Collections.max(dataForAngle); + + List dataForAngleAndWindSpeed = new ArrayList(); + + for (BoatAndWindSpeed dataPoint: dataForAngle) { + if (((int) dataPoint.getWindSpeed().getBeaufort()) == windSpeed) { + dataForAngleAndWindSpeed.add(dataPoint.getBoatSpeed().getKnots()); + } + } + + if (dataForAngleAndWindSpeed.size() < 1) { + //TODO exception handling + return null; + } + + Double min = Collections.min(dataForAngleAndWindSpeed); + Double max = Collections.max(dataForAngleAndWindSpeed); //TODO make number of columns dynamic to chart size int numberOfColumns = 20; double range = (max - min) / numberOfColumns; @@ -3181,7 +3196,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S } Integer[] yValues = new Integer[numberOfColumns]; - for (Double dataPoint : dataForAngle) { + for (Double dataPoint : dataForAngleAndWindSpeed) { int i = (int) (((dataPoint - min) / range)); if (i == numberOfColumns) { //For max value @@ -3193,7 +3208,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S yValues[i]++; } - PolarSheetsHistogramData histogramData = new PolarSheetsHistogramDataImpl(angle, xValues, yValues, dataForAngle.size()); + PolarSheetsHistogramData histogramData = new PolarSheetsHistogramDataImpl(angle, xValues, yValues, dataForAngleAndWindSpeed.size()); return histogramData; From 31a5d7f9ff8a5bdb4f40ab7b8bc18d6ee5ba7bf2 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Fri, 8 Feb 2013 12:04:02 +0100 Subject: [PATCH 29/37] Only windspeeds with 5% or more of the total datapoint count are shown --- .../com.google.gwt.eclipse.core.prefs | 2 +- .../ui/polarsheets/PolarSheetsChartPanel.java | 47 +++++++++++++------ 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs b/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs index b7c685f44e7..7c0fb0f2a1a 100755 --- a/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs +++ b/java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs @@ -1,4 +1,4 @@ eclipse.preferences.version=1 entryPointModules= filesCopiedToWebInfLib=gwt-servlet.jar -gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDEwMjRtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5BZG1pbkNvbnNvbGU8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmRFZGl0aW5nPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlJhY2VCb2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVHZWaWV3PC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlZpZGVvUG9wdXA8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuWW91dHViZVBvcHVwPC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\= +gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDEwMjRtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5BZG1pbkNvbnNvbGU8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmRFZGl0aW5nPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlJhY2VCb2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVHZWaWV3PC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlZpZGVvUG9wdXA8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuWW91dHViZVBvcHVwPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlBvbGFyU2hlZXRzPC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\= diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java index 0e8d12ead1c..a782c9d1eaf 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsChartPanel.java @@ -43,21 +43,23 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize return polarSheetChart; } - private void newSeries(String name) { + private void newSeriesArray(String name) { if (!seriesMap.containsKey(name)) { - Series[] seriesPerWindSpeed = new Series[13]; - for (int i = 0; i < 13; i++) { - Number[] forEachDeg = initializeDataForNewSeries(); - seriesPerWindSpeed[i] = chart.createSeries().setPoints(forEachDeg); - seriesPerWindSpeed[i].setName(name+"-"+(i)); - chart.addSeries(seriesPerWindSpeed[i]); - } + Series[] seriesPerWindSpeed = new Series[13]; seriesMap.put(name, seriesPerWindSpeed); } else { // TODO exception handling } } + private void createSeriesForWindspeed(String name, int windSpeed) { + Series[] seriesPerWindSpeed = seriesMap.get(name); + Number[] forEachDeg = initializeDataForNewSeries(); + seriesPerWindSpeed[windSpeed] = chart.createSeries().setPoints(forEachDeg); + seriesPerWindSpeed[windSpeed].setName(name + "-" + (windSpeed)); + chart.addSeries(seriesPerWindSpeed[windSpeed]); + } + private Number[] initializeDataForNewSeries() { Number[] forEachDeg = new Number[360]; return forEachDeg; @@ -66,16 +68,33 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize private void addValuesToSeries(String seriesId, PolarSheetsData result) { if (seriesMap.containsKey(seriesId)) { for (int i = 0; i < 13; i++) { - Series series = seriesMap.get(seriesId)[i]; - series.setPoints(result.getAveragedPolarDataByWindSpeed()[i], false); - Point[] points = createPointsWithMarkerAlphaAccordingToDataCount(result, i); - if (points != null) { - series.setPoints(points); + if (hasSufficientDataForWindspeed(result.getDataCountPerAngleForWindspeed(i), result.getDataCount())) { + if (seriesMap.get(seriesId)[i] == null) { + createSeriesForWindspeed(seriesId, i); + } + Series series = seriesMap.get(seriesId)[i]; + series.setPoints(result.getAveragedPolarDataByWindSpeed()[i], false); + Point[] points = createPointsWithMarkerAlphaAccordingToDataCount(result, i); + if (points != null) { + series.setPoints(points); + } } } } } + private boolean hasSufficientDataForWindspeed(Integer[] dataCountPerAngleForWindspeed, int countOverall) { + int sum = 0; + for (int count : dataCountPerAngleForWindspeed) { + sum = sum + count; + } + //TODO make configurable + if (sum >= (0.05 * countOverall)) { + return true; + } + return false; + } + private Point[] createPointsWithMarkerAlphaAccordingToDataCount(PolarSheetsData result, int beaufort) { Point[] points = new Point[360]; List dataCountList = Arrays.asList(result.getDataCountPerAngleForWindspeed(beaufort)); @@ -133,7 +152,7 @@ public class PolarSheetsChartPanel extends SimplePanel implements RequiresResize return; } if (!seriesMap.containsKey(id)) { - newSeries(id); + newSeriesArray(id); } addValuesToSeries(id, result); chart.redraw(); From 8fd2e7f7e39a2e42a2cebf8f1a83d5c9d1ea4803 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Fri, 8 Feb 2013 15:35:35 +0100 Subject: [PATCH 30/37] Changed PolarSheetGeneration workers to be simple Runnables rather than FutureTasks, since the results are continuosly pushed to the result container --- .../domain/test/PolarSheetGenerationTest.java | 10 ++++---- ...dCompetitorPolarSheetGenerationWorker.java | 13 +++++++---- .../PolarSheetGenerationWorker.java | 23 ++++++++++--------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java index d478a92a0bf..0ec3cb3e87d 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PolarSheetGenerationTest.java @@ -5,9 +5,7 @@ import java.util.HashSet; import java.util.NavigableSet; import java.util.UUID; import java.util.concurrent.Executor; -import java.util.concurrent.FutureTask; import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.RunnableFuture; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -60,17 +58,17 @@ public class PolarSheetGenerationTest { PolarSheetGenerationWorker resultContainer = new PolarSheetGenerationWorker(new HashSet(), executor); BoatClass forelle = new BoatClassImpl("Forelle", true); Competitor competitor = new CompetitorImpl(UUID.randomUUID(), "Hans Frantz", new TeamImpl("SAP", null, null), new BoatImpl("Schnelle Forelle", forelle, "GER000")); - RunnableFuture futureTask = new FutureTask(new PerRaceAndCompetitorPolarSheetGenerationWorker(race, resultContainer, startTime, endTime, competitor)); + PerRaceAndCompetitorPolarSheetGenerationWorker task = new PerRaceAndCompetitorPolarSheetGenerationWorker(race, resultContainer, startTime, endTime, competitor); - executor.execute(futureTask); + executor.execute(task); double timeUntilTimeout = 1000; - while (!futureTask.isDone() && timeUntilTimeout > 0) { + while (!task.isDone() && timeUntilTimeout > 0) { Thread.sleep(100); timeUntilTimeout = timeUntilTimeout - 0.1; } - Assert.assertTrue(futureTask.isDone()); + Assert.assertTrue(task.isDone()); PolarSheetsData data = resultContainer.getPolarData(); Assert.assertEquals(4, data.getDataCount()); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java index a70a9f9fc13..f44c8b176d9 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PerRaceAndCompetitorPolarSheetGenerationWorker.java @@ -2,7 +2,6 @@ package com.sap.sailing.domain.polarsheets; import java.util.Iterator; import java.util.NavigableSet; -import java.util.concurrent.Callable; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.SpeedWithBearing; @@ -22,7 +21,7 @@ import com.sap.sailing.domain.tracking.Wind; * @author D054528 Frederik Petersen * */ -public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable { +public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Runnable{ private final TrackedRace race; @@ -34,6 +33,8 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< private final Competitor competitor; + private boolean done = false; + public PerRaceAndCompetitorPolarSheetGenerationWorker(TrackedRace race, PolarSheetGenerationWorker polarSheetGenerationWorker, TimePoint startTime, TimePoint endTime, Competitor competitor) { @@ -72,7 +73,7 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< } @Override - public Void call() throws Exception { + public void run() { GPSFixTrack track = race.getTrack(competitor); track.lockForRead(); Iterator fixesIterator = track.getFixesIterator(startTime, true); @@ -99,6 +100,10 @@ public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Callable< } track.unlockAfterRead(); - return null; + done = true; + } + + public boolean isDone() { + return done; } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java index 6ee4848960f..276590f0fde 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/polarsheets/PolarSheetGenerationWorker.java @@ -7,8 +7,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Executor; -import java.util.concurrent.FutureTask; -import java.util.concurrent.RunnableFuture; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.RaceDefinition; @@ -28,7 +26,7 @@ import com.sap.sailing.domain.tracking.TrackedRace; */ public class PolarSheetGenerationWorker { - private final Set> workers; + private final Set workers; private final List> polarData; @@ -46,7 +44,7 @@ public class PolarSheetGenerationWorker { public PolarSheetGenerationWorker(Set trackedRaces, Executor executor) { polarData = initializePolarDataContainer(); this.executor = executor; - workers = new HashSet>(); + workers = new HashSet(); for (TrackedRace race : trackedRaces) { TimePoint startTime = race.getStartOfRace(); TimePoint endTime = race.getEndOfRace(); @@ -58,9 +56,8 @@ public class PolarSheetGenerationWorker { Iterable competitors = raceDefinition.getCompetitors(); for (Competitor competitor : competitors) { - RunnableFuture futureTask = new FutureTask( - new PerRaceAndCompetitorPolarSheetGenerationWorker(race, this, startTime, endTime, competitor)); - workers.add(futureTask); + PerRaceAndCompetitorPolarSheetGenerationWorker task = new PerRaceAndCompetitorPolarSheetGenerationWorker(race, this, startTime, endTime, competitor); + workers.add(task); } } @@ -78,8 +75,8 @@ public class PolarSheetGenerationWorker { * Starts the {@link PerRaceAndCompetitorPolarSheetGenerationWorker}s */ public void startPolarSheetGeneration() { - for (RunnableFuture future : workers) { - executor.execute(future); + for (Runnable task : workers) { + executor.execute(task); } } @@ -127,6 +124,10 @@ public class PolarSheetGenerationWorker { for (BoatAndWindSpeed singleDataPoint : values) { if (singleDataPoint != null) { int windSpeed = (int) singleDataPoint.getWindSpeed().getBeaufort(); + //Somehow beaufort sometimes gets bigger than twelve. TODO: Investigation + if (windSpeed > 12) { + windSpeed = 12; + } //TODO enable different kinds of metrics for boats speed sumsPerWindSpeed[windSpeed] = sumsPerWindSpeed[windSpeed] + singleDataPoint.getBoatSpeed().getKnots(); dataCountPerWindSpeed[windSpeed]++; @@ -147,8 +148,8 @@ public class PolarSheetGenerationWorker { } boolean complete = true; - for (RunnableFuture future : workers) { - if (!future.isDone()) { + for (PerRaceAndCompetitorPolarSheetGenerationWorker task : workers) { + if (!task.isDone()) { complete = false; break; } From 5d6a5ddc580ea099d66f7a1a6f118fa390703263 Mon Sep 17 00:00:00 2001 From: fmittag Date: Thu, 14 Feb 2013 10:40:53 +0100 Subject: [PATCH 31/37] removed double implementation of attribute displayName in RegattaLeaderboard --- .../leaderboard/impl/RegattaLeaderboardImpl.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java index e167ac671d8..e167982678b 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java @@ -29,12 +29,6 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R private static final long serialVersionUID = 2370461218294770084L; private final Regatta regatta; - /** - * If this member is null, {@link #getName()} will use the regatta name as the default name for this - * leaderboard. Otherwise, the {@link #displayName} is used. - */ - private String displayName; - public RegattaLeaderboardImpl(Regatta regatta, SettableScoreCorrection scoreCorrection, ThresholdBasedResultDiscardingRule resultDiscardingRule) { super(scoreCorrection, resultDiscardingRule); @@ -47,7 +41,7 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R */ @Override public void setName(String newName) { - displayName = newName; + setDisplayName(newName); } @Override @@ -58,8 +52,8 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R @Override public String getName() { String result; - if (displayName != null) { - result = displayName; + if (getDisplayName() != null) { + result = getDisplayName(); } else { result = getRegatta().getName(); } From 74df3cc829014bd565fa4b157ab6907c7e760622 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Sun, 17 Feb 2013 14:00:55 +0100 Subject: [PATCH 32/37] use StringMessages in polar sheet view --- .../com/sap/sailing/gwt/ui/client/StringMessages.java | 3 +++ .../sailing/gwt/ui/client/StringMessages.properties | 3 +++ .../gwt/ui/client/StringMessages_de.properties | 5 ++++- .../gwt/ui/polarsheets/PolarSheetsHistogramPanel.java | 11 ++++++----- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index f0069acbf1f..179d125a37f 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -499,4 +499,7 @@ public interface StringMessages extends Messages { String overallRankTooltip(); String noDataFound(); String displayName(); + String histogram(); + String numberOfDataPoints(); + String angleAndTotalNumberOfDataPoints(int angle, int numberOfDataPoints); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 428a802f143..a3d5192f8b0 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -501,3 +501,6 @@ gpsData=GPS data status=Status noDataFound=No data found displayName=Display name +histogram=Histogram +numberOfDataPoints=Number of data points +angleAndTotalNumberOfDataPoints=Angle: {0}; Total number of data-points: {1} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index 124a0615991..5bdb10bdc08 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -500,4 +500,7 @@ windData=Winddaten gpsData=GPS-Daten status=Status noDataFound=Keine Daten gefunden -displayName=Anzeigename \ No newline at end of file +displayName=Anzeigename +histogram=Histogramm +numberOfDataPoints=Anzahl Datenpunkte +angleAndTotalNumberOfDataPoints=Winkel: {0}; Anzahl Datenpunkte: {1} \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java index 2b669d3d8c8..251bc69423c 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/polarsheets/PolarSheetsHistogramPanel.java @@ -30,17 +30,18 @@ public class PolarSheetsHistogramPanel extends SimplePanel implements RequiresRe private Chart createHistogramChart() { Chart histogramChart = new Chart().setType(Type.COLUMN).setZoomType(Chart.ZoomType.X).setWidth(800); - //TODO string messages - histogramChart.setChartTitleText("Histogram:"); - histogramChart.getYAxis().setMin(0).setAxisTitle(new AxisTitle().setText("Number of data-points")); - histogramChart.getXAxis().setLabels(new XAxisLabels().setRotation(-90f).setY(10)).setAxisTitle(new AxisTitle().setText("Speed in knots")); + histogramChart.setChartTitleText(stringMessages.histogram()); + histogramChart.getYAxis().setMin(0).setAxisTitle(new AxisTitle().setText(stringMessages.numberOfDataPoints())); + histogramChart.getXAxis().setLabels(new XAxisLabels().setRotation(-90f).setY(10)).setAxisTitle(new AxisTitle().setText( + stringMessages.speedInKnots())); histogramChart.setLegend(new Legend().setEnabled(false)); return histogramChart; } public void setData(PolarSheetsHistogramData data) { chart.removeAllSeries(); - chart.setTitle(new ChartTitle().setText("Histogram"), new ChartSubtitle().setText("Angle: " + data.getAngle() + "; Total number of data-points: " + data.getDataCount())); + chart.setTitle(new ChartTitle().setText(stringMessages.histogram()), + new ChartSubtitle().setText(stringMessages.angleAndTotalNumberOfDataPoints(data.getAngle(), data.getDataCount()))); Point[] points = toPoints(data); Series series = chart.createSeries(); series.setPoints(points); From ac84e6f1a8afe25bb31dd5dc095af5a454b4b62e Mon Sep 17 00:00:00 2001 From: "Axel Uhl (Server)" Date: Sun, 17 Feb 2013 15:09:26 +0100 Subject: [PATCH 33/37] Preserving old build log --- configuration/buildAndUpdateProduct.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configuration/buildAndUpdateProduct.sh b/configuration/buildAndUpdateProduct.sh index c524eef8479..2dfa8c3313f 100755 --- a/configuration/buildAndUpdateProduct.sh +++ b/configuration/buildAndUpdateProduct.sh @@ -90,6 +90,10 @@ MAVEN_SETTINGS=$ACDIR/maven-settings.xml if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then # yield build so that we get updated product + + # preserve old build log + cp $ACDIR/build.log $ACDIR/build.log.old + cd $PROJECT_HOME/java if [ $gwtcompile -eq 1 ]; then echo "INFO: Compiling GWT (rm -rf com.sap.sailing.gwt.ui/com.sap.sailing.*)" @@ -116,7 +120,7 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then extra="$extra -P no-debug.without-proxy" fi - echo "Using following command: mvn $extra -P no-debug.without-proxy -fae -s $MAVEN_SETTINGS $clean install" + echo "Using following command: mvn $extra -fae -s $MAVEN_SETTINGS $clean install" mvn $extra -fae -s $MAVEN_SETTINGS $clean install 2>&1 | tee $ACDIR/build.log echo "Build complete. Do not forget to install product..." From 0d78d4e7bcc2c1cf60421183dcbaa80b3396f3dc Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Mon, 18 Feb 2013 12:35:36 +0100 Subject: [PATCH 34/37] Added test for regatta race association, also removing association when regatta gets removed --- .../persistence/MongoObjectFactory.java | 2 ++ .../impl/MongoObjectFactoryImpl.java | 7 +++++ ...estStoringAndLoadingEventsAndRegattas.java | 27 +++++++++++++++++++ .../server/impl/RacingEventServiceImpl.java | 2 ++ 4 files changed, 38 insertions(+) diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/MongoObjectFactory.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/MongoObjectFactory.java index fdfc9f0bb77..bf55a8d43ce 100755 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/MongoObjectFactory.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/MongoObjectFactory.java @@ -84,4 +84,6 @@ public interface MongoObjectFactory { void storeRegattaForRaceID(String id, Regatta regatta); + void removeRegattaForRaceID(String raceIDAsString, Regatta regatta); + } diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java index 8467eac8c96..c18ca5fda3d 100755 --- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java +++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java @@ -467,4 +467,11 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory { entry.put(FieldNames.REGATTA_NAME.name(), regatta.getName()); regattaForRaceIDCollection.update(query, entry, /* upsrt */ true, /* multi */ false); } + + @Override + public void removeRegattaForRaceID(String raceIDAsString, Regatta regatta) { + DBCollection regattaForRaceIDCollection = database.getCollection(CollectionNames.REGATTA_FOR_RACE_ID.name()); + DBObject query = new BasicDBObject(FieldNames.RACE_ID_AS_STRING.name(), raceIDAsString); + regattaForRaceIDCollection.remove(query); + } } diff --git a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndLoadingEventsAndRegattas.java b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndLoadingEventsAndRegattas.java index 930eac1d317..cc94325b1ee 100755 --- a/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndLoadingEventsAndRegattas.java +++ b/java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndLoadingEventsAndRegattas.java @@ -21,20 +21,26 @@ import org.junit.Test; import com.mongodb.MongoException; import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.Course; import com.sap.sailing.domain.base.CourseArea; import com.sap.sailing.domain.base.DomainFactory; import com.sap.sailing.domain.base.Event; import com.sap.sailing.domain.base.Fleet; import com.sap.sailing.domain.base.RaceColumn; import com.sap.sailing.domain.base.RaceColumnInSeries; +import com.sap.sailing.domain.base.RaceDefinition; import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.base.Series; import com.sap.sailing.domain.base.Venue; +import com.sap.sailing.domain.base.Waypoint; +import com.sap.sailing.domain.base.impl.CompetitorImpl; import com.sap.sailing.domain.base.impl.CourseAreaImpl; +import com.sap.sailing.domain.base.impl.CourseImpl; import com.sap.sailing.domain.base.impl.EventImpl; import com.sap.sailing.domain.base.impl.FleetImpl; import com.sap.sailing.domain.base.impl.MillisecondsTimePoint; import com.sap.sailing.domain.base.impl.RaceColumnInSeriesImpl; +import com.sap.sailing.domain.base.impl.RaceDefinitionImpl; import com.sap.sailing.domain.base.impl.RegattaImpl; import com.sap.sailing.domain.base.impl.SeriesImpl; import com.sap.sailing.domain.base.impl.VenueImpl; @@ -386,4 +392,25 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest } } + @Test + public void testRegattaRaceAssociationStore() throws Exception { + BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("112er", /* typicallyStartsUpwind */ true); + Regatta regatta = createRegatta("Cologne Masters", boatClass, /* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT)); + + List competitors = new ArrayList(); + competitors.add(new CompetitorImpl("Axel", "Axel Uhl", null, null)); + Iterable waypoints = Collections.emptyList(); + Course course = new CourseImpl("Course", waypoints); + + RaceDefinition racedef = new RaceDefinitionImpl("M1", course, boatClass, competitors); + regatta.addRace(racedef); + + RacingEventServiceImpl evs = new RacingEventServiceImpl(getMongoService()); + assertNull(evs.getRememberedRegattaForRace(racedef.getId())); + evs.raceAdded(regatta, racedef); + assertNotNull(evs.getRememberedRegattaForRace(racedef.getId())); + evs.removeRegatta(regatta); + assertNull(evs.getRememberedRegattaForRace(racedef.getId())); + } + } diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java index 94d389b231d..bd27e8cabf5 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java @@ -1080,6 +1080,8 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen public void removeRegatta(Regatta regatta) throws MalformedURLException, IOException, InterruptedException { for (RaceDefinition race : regatta.getAllRaces()) { removeRace(regatta, race); + mongoObjectFactory.removeRegattaForRaceID(race.getName(), regatta); + persistentRegattasForRaceIDs.remove(race.getId().toString()); } if (regatta.isPersistent()) { mongoObjectFactory.removeRegatta(regatta); From e0d4d643814dc561a5438a4fa23e9c17a0b09a93 Mon Sep 17 00:00:00 2001 From: fmittag Date: Mon, 18 Feb 2013 12:51:48 +0100 Subject: [PATCH 35/37] added the folder /extras to .gitignore for the main gwt project. Such a folder is created when you use the gwt compiler with the -compileReport flag --- java/com.sap.sailing.gwt.ui/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/java/com.sap.sailing.gwt.ui/.gitignore b/java/com.sap.sailing.gwt.ui/.gitignore index 609a3512f53..e93253c29d3 100755 --- a/java/com.sap.sailing.gwt.ui/.gitignore +++ b/java/com.sap.sailing.gwt.ui/.gitignore @@ -2,4 +2,5 @@ /.gwt /.generated /gwt-unitCache +/extras /com.sap.sailing.gwt.ui.* From 5d8eca285d8f869950943ec75e7442b138d820cd Mon Sep 17 00:00:00 2001 From: Marcus Kammer Date: Mon, 18 Feb 2013 13:24:32 +0100 Subject: [PATCH 36/37] Change pixel dimension of iOS Homescreen Icon. --- .../images/sap-sailing-app-icon.png | Bin 101225 -> 18172 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/images/sap-sailing-app-icon.png b/java/com.sap.sailing.gwt.ui/images/sap-sailing-app-icon.png index 9ad08955f9f0cb2a37307facafe812b5ae2ec7a8..a7efa78aedcbea9180917a32787007d57692d5a9 100644 GIT binary patch literal 18172 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
    aPM|i7I#Fp`c zW77a8T#J&Mbs3SD;lw*N85{MJ8)LT(HaXjbA?H?2ebp|-M&sNzZ0s$Q)~f7~R6d%x zH@=}q_eCI%VrsRNdc8rKrmS>UJ{RlwZzgf_?Ln4}47;l#6rutUTNlotR@m)R?$>Y}^D<0b6$9CVk zn%SY$wri=<0NZ+>5iuD{?ceHkY}qZ_{Q44j)5;rdazWOd_@z#F{qw75SAXNFQ%^m1 naQ{K>x#R9Kvb1}I>i-)6xdqTZl#pc#00000NkvXXu0mjfc519r literal 101225 zcmXVXWmuHY_xJ8nOLq#gbTAwyh%61#-K_!w(y_p@ z`}qC+pBMKv_p3SAoa+;3&den0KUXIvU?2bh0K}RaDuw_6=-)300LJ|{Tn5kG{Tt{5 zRLuj7yj=o<#Acoc-k(z@J%GeRF+2(5YWd#YLqnA*HG^|I2aB@dUuV zgO^W?PmEP`BNP*Q0*evBeW7i&vh&yG(Kl8{cl#%Gz?*{zQ=Q($OO%l5h$$8WVbYVRTOJl>JwN}qsC+I#*bIsFr^+o z4>r}HsmeOUy9X;1+{_q+HhpAT_>m)%khKvG#PiAs5t!oC(G~ye{xK+%ne8?T>u%KZ z2Jj;*>CV5V6=0iR`u*R`W!19`9;?s4%CE&U2BV;$rm~BK2foswrEEv%uD~+qToqf= zY7xs%Uk@g){9+ffcP~$jT_%yu=kw~i5UQPb+b)ktKYdkVm6{`|n7(PWhHU3YZ#s91KC zSKm%sK%-WzPKok<3|iFm^!rh*4s^TLb?@_M^sj=4yG68oTS$(AC)g0D@GW-4B2u0s z)<#|P#iE_{Qlr(U+y62>vv9j0@A0#}N{xjLLx9~KF1NF0${B7*t}lQU$X$OsPuRGG zJ99_QZcH#@=8F2wCnPxW5i<@&{;rJxS^DEk8AKWbm%4WgFmIvPT9oo?9h`$KtM3wZ z_m;wqy58tnTas=rPW#+}9F>MF3ugbzp;rmEjMeukm#TqHhia(yy8z$A@YrNO_akof zoF=ebj54m!Y*SS5{7kx0KiVEcE%?^rutoL^iJ`v`Q!MyiWvtu3Y4^?bQ$jy%0DApr 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
    4TxW%;e+DgdrAqxMZ{2(;9$B9q<4qap!d1A?j= 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 Ug?dPsb^rhX07*qoM6N<$g5l4K82|tP From 12bd4b2ca24b4a429bda19f47c04a46135c18f70 Mon Sep 17 00:00:00 2001 From: Simon Pamies Date: Mon, 18 Feb 2013 17:15:35 +0100 Subject: [PATCH 37/37] Destroyed test-simon-2 (markdown) --- wiki/test-simon-2.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 wiki/test-simon-2.md diff --git a/wiki/test-simon-2.md b/wiki/test-simon-2.md deleted file mode 100644 index 793aa682b06..00000000000 --- a/wiki/test-simon-2.md +++ /dev/null @@ -1 +0,0 @@ -This is a test \ No newline at end of file