From 012476f9e736c19252ccab10914c79f4a9e4789c Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 29 Mar 2018 13:47:44 +1100 Subject: [PATCH 01/38] Added statistic getNormalizedDistanceToStarboardSideAtStartVsRankAtFirstMark with return type Pair --- java/com.google.gwt.dev/spartanizer.xml | 178 ++++++++++++++++++ .../Sailing_StringMessages.properties | 1 + .../Sailing_StringMessages_de.properties | 1 + .../data/HasRaceOfCompetitorContext.java | 4 + .../data/RaceOfCompetitorWithContext.java | 6 + 5 files changed, 190 insertions(+) create mode 100644 java/com.google.gwt.dev/spartanizer.xml diff --git a/java/com.google.gwt.dev/spartanizer.xml b/java/com.google.gwt.dev/spartanizer.xml new file mode 100644 index 00000000000..b432c016b32 --- /dev/null +++ b/java/com.google.gwt.dev/spartanizer.xml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index bdb6b361c45..00cc5cfc943 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -70,6 +70,7 @@ NumberOfJibes=Number of Jibes NumberOfPenaltyCircles=Number of Penalty Circles RankGainsOrLosses=Rank Gains or Losses DistanceToStarboardSideAtStart=Distance to Starboard Side (% of Length) +DistanceToStarboardSideAtStartVsRankAtFirstMark=Distance to Starboard Side (% of Length) vs. Rank at First Mark NumberOfPodiumFinish=Number of Podium Finishes NumberOfWins=Number of Wins RankGainsOrLossesBetweenFirstMarkAndFinish=Rank Gains or Losses (1st Mark -> Finish) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index 134179d2064..cccb6af75fb 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -70,6 +70,7 @@ NumberOfJibes=Anzahl der Halsen NumberOfPenaltyCircles=Anzahl der Straf-Kreise RankGainsOrLosses=Positions-Verluste oder -Gewinne DistanceToStarboardSideAtStart=Distanz zur Steuerbordseite (% der Länge) +DistanceToStarboardSideAtStartVsRankAtFirstMark=Distanz zur Steuerbordseite (% der Länge) vs. Position beim ersten Wegpunkt NumberOfPodiumFinish=Azahl der Podium-Siege NumberOfWins=Anzahl der Siege RankGainsOrLossesBetweenFirstMarkAndFinish=Positions-Verluste oder -Gewinne (1ter Wegpunkt -> Ziel) diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java index ea9d2c50ccb..eb16414fd36 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java @@ -5,6 +5,7 @@ import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.NoWindException; import com.sap.sailing.domain.common.Speed; import com.sap.sailing.domain.common.Tack; +import com.sap.sse.common.Util.Pair; import com.sap.sse.datamining.annotations.Connector; import com.sap.sse.datamining.annotations.Dimension; import com.sap.sse.datamining.annotations.Statistic; @@ -34,6 +35,9 @@ public interface HasRaceOfCompetitorContext { @Statistic(messageKey="DistanceToStarboardSideAtStart", resultDecimals=2, ordinal=1) public Double getNormalizedDistanceToStarboardSideAtStart(); + @Statistic(messageKey="DistanceToStarboardSideAtStartVsRankAtFirstMark", resultDecimals=2, ordinal=1) + public Pair getNormalizedDistanceToStarboardSideAtStartVsRankAtFirstMark(); + @Statistic(messageKey="WindwardDistanceToAdvantageousEndOfLine", resultDecimals=2, ordinal=2) public Distance getWindwardDistanceToAdvantageousLineEndAtStart(); diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java index ff51b9e67ab..7ddb365b32e 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java @@ -27,6 +27,7 @@ import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.WindPositionMode; import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util.Pair; import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.datamining.data.Cluster; import com.sap.sse.datamining.shared.impl.dto.ClusterDTO; @@ -92,6 +93,11 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { return distance / length; } + @Override + public Pair getNormalizedDistanceToStarboardSideAtStartVsRankAtFirstMark(){ + return new Pair (getNormalizedDistanceToStarboardSideAtStart(), getRankAtFirstMark()); + } + @Override public Distance getWindwardDistanceToAdvantageousLineEndAtStart() { TrackedRace trackedRace = getTrackedRace(); From 65de62c5db642ef1842613aa29085643ac4350cd Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 3 Apr 2018 11:13:09 +1000 Subject: [PATCH 02/38] Removed my spartanizer.xml --- java/com.google.gwt.dev/spartanizer.xml | 178 ------------------------ 1 file changed, 178 deletions(-) delete mode 100644 java/com.google.gwt.dev/spartanizer.xml diff --git a/java/com.google.gwt.dev/spartanizer.xml b/java/com.google.gwt.dev/spartanizer.xml deleted file mode 100644 index b432c016b32..00000000000 --- a/java/com.google.gwt.dev/spartanizer.xml +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From fb7a2ac090c65039c4bd49dee5a48de7cc1677c4 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 10 Apr 2018 10:39:05 +1000 Subject: [PATCH 03/38] Added AveragePairWithStats and parallelGroupedNumberPairDataAverageAggregationProcessor --- .../shared/data/AveragePairWithStats.java | 29 ++++ .../shared/impl/AveragePairWithStatsImpl.java | 125 ++++++++++++++++++ .../stringmessages/StringMessages.properties | 1 + .../StringMessages_de.properties | 1 + .../impl/DataMiningFrameworkActivator.java | 2 + ...erPairDataAverageAggregationProcessor.java | 101 ++++++++++++++ 6 files changed, 259 insertions(+) create mode 100644 java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java create mode 100644 java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java create mode 100644 java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java diff --git a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java new file mode 100644 index 00000000000..3a83c9cf555 --- /dev/null +++ b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java @@ -0,0 +1,29 @@ +package com.sap.sse.datamining.shared.data; + +import java.io.Serializable; + +import com.sap.sse.common.Util.Pair; + +/** + * Result of an averaging operation, augmented by statistical data explaining a bit more about how the average was + * computed, including minimum and maximum values, count, median, as well as standard deviation. All but count will have + * the same type of the average value whereas the count is an integer-like data type. + * + * @author Axel Uhl (d043530) + * + * @param + */ +public interface AveragePairWithStats extends Serializable { + Pair getAverage(); + Pair getMin(); + Pair getMax(); + Pair getMedian(); + Pair getStandardDeviation(); + long getCount(); + + /** + * @return the fully-qualified type name of the {@code T} type argument; may be used by + * the results presenter to choose an applicable data provider. + */ + String getResultType(); +} diff --git a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java new file mode 100644 index 00000000000..acca706b087 --- /dev/null +++ b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java @@ -0,0 +1,125 @@ +package com.sap.sse.datamining.shared.impl; + +import com.sap.sse.common.Util.Pair; +import com.sap.sse.datamining.shared.data.AveragePairWithStats; + +public class AveragePairWithStatsImpl implements AveragePairWithStats { + private static final long serialVersionUID = -3094183173270210846L; + private final Pair average; + private final Pair min; + private final Pair max; + private final Pair median; + private final Pair standardDeviation; + private final long count; + private final String resultType; + + public AveragePairWithStatsImpl(Pair average, Pair min, Pair max, Pair median, Pair standardDeviation, long count, String resultType) { + super(); + this.average = average; + this.min = min; + this.max = max; + this.median = median; + this.standardDeviation = standardDeviation; + this.count = count; + this.resultType = resultType; + } + + @Override + public Pair getAverage() { + return average; + } + + @Override + public Pair getMin() { + return min; + } + + @Override + public Pair getMax() { + return max; + } + + @Override + public Pair getMedian() { + return median; + } + + @Override + public Pair getStandardDeviation() { + return standardDeviation; + } + + @Override + public long getCount() { + return count; + } + + @Override + public String getResultType() { + return resultType; + } + + @Override + public String toString() { + return "AverageWithStatsImpl [average=" + average + ", min=" + min + ", max=" + max + ", median=" + median + + ", standardDeviation=" + standardDeviation + ", count=" + count + ", resultType=" + resultType + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((average == null) ? 0 : average.hashCode()); + result = prime * result + (int) (count ^ (count >>> 32)); + result = prime * result + ((max == null) ? 0 : max.hashCode()); + result = prime * result + ((median == null) ? 0 : median.hashCode()); + result = prime * result + ((min == null) ? 0 : min.hashCode()); + result = prime * result + ((resultType == null) ? 0 : resultType.hashCode()); + result = prime * result + ((standardDeviation == null) ? 0 : standardDeviation.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AveragePairWithStatsImpl other = (AveragePairWithStatsImpl) obj; + if (average == null) { + if (other.average != null) + return false; + } else if (!average.equals(other.average)) + return false; + if (count != other.count) + return false; + if (max == null) { + if (other.max != null) + return false; + } else if (!max.equals(other.max)) + return false; + if (median == null) { + if (other.median != null) + return false; + } else if (!median.equals(other.median)) + return false; + if (min == null) { + if (other.min != null) + return false; + } else if (!min.equals(other.min)) + return false; + if (resultType == null) { + if (other.resultType != null) + return false; + } else if (!resultType.equals(other.resultType)) + return false; + if (standardDeviation == null) { + if (other.standardDeviation != null) + return false; + } else if (!standardDeviation.equals(other.standardDeviation)) + return false; + return true; + } +} diff --git a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties index 3f09729ac71..7b7effd1b9d 100644 --- a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties +++ b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties @@ -1,4 +1,5 @@ Average=Average +PairAverage=Average (Pair) Median=Median Sum=Sum Maximum=Maximum diff --git a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties index 81e0c2120ab..1bed0dd1324 100644 --- a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties +++ b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties @@ -1,4 +1,5 @@ Average=Durchschnitt +PairAverage=Durchschnitt (Paar) Median=Median Sum=Summe Maximum=Maximum diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java index 9b636c4c8d0..9284d175f8f 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java @@ -33,6 +33,7 @@ import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberD import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberDataMedianAggregationProcessor; import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberDataMinAggregationProcessor; import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberDataSumAggregationProcessor; +import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberPairDataAverageAggregationProcessor; import com.sap.sse.datamining.impl.components.management.AggregationProcessorDefinitionManager; import com.sap.sse.datamining.impl.components.management.DataRetrieverChainDefinitionManager; import com.sap.sse.datamining.impl.components.management.DataSourceProviderManager; @@ -86,6 +87,7 @@ public class DataMiningFrameworkActivator implements BundleActivator { defaultAggregationProcessors.add(ParallelGroupedDataCountDistinctAggregationProcessor.getDefinition()); defaultAggregationProcessors.add(ParallelGroupedDataCountAggregationProcessor.getDefinition()); defaultAggregationProcessors.add(ParallelGroupedNumberDataAverageAggregationProcessor.getDefinition()); + defaultAggregationProcessors.add(ParallelGroupedNumberPairDataAverageAggregationProcessor.getDefinition()); defaultAggregationProcessors.add(ParallelGroupedNumberDataMaxAggregationProcessor.getDefinition()); defaultAggregationProcessors.add(ParallelGroupedNumberDataMedianAggregationProcessor.getDefinition()); defaultAggregationProcessors.add(ParallelGroupedNumberDataMinAggregationProcessor.getDefinition()); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java new file mode 100644 index 00000000000..45f6d6f19d9 --- /dev/null +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java @@ -0,0 +1,101 @@ +package com.sap.sse.datamining.impl.components.aggregators; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicLong; + +import org.omg.CORBA.DoubleHolder; + +import com.sap.sse.common.Util.Pair; +import com.sap.sse.datamining.components.AggregationProcessorDefinition; +import com.sap.sse.datamining.components.Processor; +import com.sap.sse.datamining.impl.components.GroupedDataEntry; +import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition; +import com.sap.sse.datamining.shared.GroupKey; +import com.sap.sse.datamining.shared.data.AverageWithStats; +import com.sap.sse.datamining.shared.data.AveragePairWithStats; +import com.sap.sse.datamining.shared.impl.AveragePairWithStatsImpl; +import com.sap.sse.datamining.shared.impl.AverageWithStatsImpl; + +public class ParallelGroupedNumberPairDataAverageAggregationProcessor + extends AbstractParallelGroupedDataStoringAggregationProcessor> { + private static final Class _c = AveragePairWithStats.class; + @SuppressWarnings("unchecked") + private static final Class> _cc = (Class>) _c; + + private static final AggregationProcessorDefinition> DEFINITION = + new SimpleAggregationProcessorDefinition<>(Pair.class, + _cc, "PairAverage", ParallelGroupedNumberPairDataAverageAggregationProcessor.class); + + public static AggregationProcessorDefinition> getDefinition() { + return DEFINITION; + } + + private final Map> sumPerKey; + private final Map> minPerKey; + private final Map> maxPerKey; + private final Map elementAmountPerKey; + + public ParallelGroupedNumberPairDataAverageAggregationProcessor(ExecutorService executor, + Collection>, ?>> resultReceivers) { + super(executor, resultReceivers, "PairAverage"); + elementAmountPerKey = new HashMap<>(); + sumPerKey = new HashMap<>(); + minPerKey = new HashMap<>(); + maxPerKey = new HashMap<>(); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + protected void storeElement(GroupedDataEntry element) { + if (element.getDataEntry() != null) { + incrementElementAmount(element); + // concurrency is not an issue here; needsSynchronization() returns true + Pair aggregate = sumPerKey.get(element.getKey()); + final double doubleValueA = ((Number) element.getDataEntry().getA()).doubleValue(); + final double doubleValueB = ((Number) element.getDataEntry().getA()).doubleValue(); + if (aggregate == null) { + aggregate = new Pair<>(doubleValueA, doubleValueB); + sumPerKey.put(element.getKey(), aggregate); + } else { + sumPerKey.put(element.getKey(), new Pair<>(((Number) element.getDataEntry().getA()).doubleValue() + doubleValueA,((Number) element.getDataEntry().getB()).doubleValue() + doubleValueB)); + } + if (!minPerKey.containsKey(element.getKey()) || doubleValueA < minPerKey.get(element.getKey()).getA().doubleValue() && doubleValueB < minPerKey.get(element.getKey()).getB().doubleValue()) { + minPerKey.put(element.getKey(), new Pair<>(doubleValueA, doubleValueB)); + } + if (!maxPerKey.containsKey(element.getKey()) || doubleValueA > maxPerKey.get(element.getKey()).getA().doubleValue() && doubleValueB > maxPerKey.get(element.getKey()).getB().doubleValue()) { + maxPerKey.put(element.getKey(), new Pair<>(doubleValueA, doubleValueB)); + } + } + } + + private void incrementElementAmount(GroupedDataEntry element) { + GroupKey key = element.getKey(); + // concurrency is not an issue here; needsSynchronization() returns true + AtomicLong currentAmount = elementAmountPerKey.get(key); + if (currentAmount == null) { + elementAmountPerKey.put(key, new AtomicLong(1)); + } else { + currentAmount.incrementAndGet(); + } + } + + @Override + protected Map> aggregateResult() { + Map> result = new HashMap<>(); + for (Entry> sumAggregationEntry : sumPerKey.entrySet()) { + GroupKey key = sumAggregationEntry.getKey(); + result.put(key, new AveragePairWithStatsImpl(new Pair<>(sumAggregationEntry.getValue().getA().doubleValue() / elementAmountPerKey.get(key).get(),sumAggregationEntry.getValue().getB().doubleValue() / elementAmountPerKey.get(key).get()), + minPerKey.get(key), maxPerKey.get(key), + /* median */ null, + /* standardDeviation */ null, + /* count */ elementAmountPerKey.get(key).get(), + Number.class.getName())); + } + return result; + } + +} From 918f3ab900a3cdd562b2d0330819969d0f43e435 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Mon, 16 Apr 2018 15:19:15 +1000 Subject: [PATCH 04/38] Added NumberPairResultsPresenter --- .../presentation/TabbedResultsPresenter.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/TabbedResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/TabbedResultsPresenter.java index 412cb2d99de..298ebc132b1 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/TabbedResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/TabbedResultsPresenter.java @@ -88,7 +88,15 @@ public class TabbedResultsPresenter extends AbstractComponent implemen addTabAndFocus(new ManeuverSpeedDetailsResultsPresenter(TabbedResultsPresenter.this, getComponentContext(), stringMessages)); removeTab(oldHeader); - } else { + } + else if (result.getResultType() + .equals("com.sap.sse.datamining.shared.data.AveragePairWithStats")) { + CloseableTabHeader oldHeader = getSelectedHeader(); + addTabAndFocus(new NumberPairResultsPresenter(TabbedResultsPresenter.this, + getComponentContext(), stringMessages)); + removeTab(oldHeader); + } + else { if (!(getSelectedPresenter() instanceof MultiResultsPresenter)) { CloseableTabHeader oldHeader = getSelectedHeader(); addTabAndFocus(new MultiResultsPresenter(this, getComponentContext(), drillDownCallback, stringMessages)); From 4c7f9c21701b7e7e2aa28b97ee634781a5b09214 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Mon, 16 Apr 2018 15:19:36 +1000 Subject: [PATCH 05/38] Removed comments --- .../sse/datamining/shared/data/AveragePairWithStats.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java index 3a83c9cf555..32537d2084b 100644 --- a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java +++ b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java @@ -4,15 +4,6 @@ import java.io.Serializable; import com.sap.sse.common.Util.Pair; -/** - * Result of an averaging operation, augmented by statistical data explaining a bit more about how the average was - * computed, including minimum and maximum values, count, median, as well as standard deviation. All but count will have - * the same type of the average value whereas the count is an integer-like data type. - * - * @author Axel Uhl (d043530) - * - * @param - */ public interface AveragePairWithStats extends Serializable { Pair getAverage(); Pair getMin(); From 26fc468f0bf67085fec9244a47e7b62d6e186b45 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Mon, 16 Apr 2018 15:20:02 +1000 Subject: [PATCH 06/38] Changed serialVersionUID and toString() method --- .../sse/datamining/shared/impl/AveragePairWithStatsImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java index acca706b087..51bc8afda69 100644 --- a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java +++ b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java @@ -4,7 +4,7 @@ import com.sap.sse.common.Util.Pair; import com.sap.sse.datamining.shared.data.AveragePairWithStats; public class AveragePairWithStatsImpl implements AveragePairWithStats { - private static final long serialVersionUID = -3094183173270210846L; + private static final long serialVersionUID = -2643300186690471524L; private final Pair average; private final Pair min; private final Pair max; @@ -61,7 +61,7 @@ public class AveragePairWithStatsImpl implements AveragePairWithStats { @Override public String toString() { - return "AverageWithStatsImpl [average=" + average + ", min=" + min + ", max=" + max + ", median=" + median + return "AveragePairWithStatsImpl [average=" + average + ", min=" + min + ", max=" + max + ", median=" + median + ", standardDeviation=" + standardDeviation + ", count=" + count + ", resultType=" + resultType + "]"; } From 78a331c597fe986993dcc6d8ed0000bdeed52cc2 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Mon, 16 Apr 2018 15:22:01 +1000 Subject: [PATCH 07/38] Adjusted storeElement() method of ParallelGroupedNumberPairDataAverageAggregationProcessor --- ...erPairDataAverageAggregationProcessor.java | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java index 45f6d6f19d9..6ccbd7b9614 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java @@ -7,18 +7,14 @@ import java.util.Map.Entry; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicLong; -import org.omg.CORBA.DoubleHolder; - import com.sap.sse.common.Util.Pair; import com.sap.sse.datamining.components.AggregationProcessorDefinition; import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.impl.components.GroupedDataEntry; import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition; import com.sap.sse.datamining.shared.GroupKey; -import com.sap.sse.datamining.shared.data.AverageWithStats; import com.sap.sse.datamining.shared.data.AveragePairWithStats; import com.sap.sse.datamining.shared.impl.AveragePairWithStatsImpl; -import com.sap.sse.datamining.shared.impl.AverageWithStatsImpl; public class ParallelGroupedNumberPairDataAverageAggregationProcessor extends AbstractParallelGroupedDataStoringAggregationProcessor> { @@ -55,20 +51,27 @@ public class ParallelGroupedNumberPairDataAverageAggregationProcessor incrementElementAmount(element); // concurrency is not an issue here; needsSynchronization() returns true Pair aggregate = sumPerKey.get(element.getKey()); - final double doubleValueA = ((Number) element.getDataEntry().getA()).doubleValue(); - final double doubleValueB = ((Number) element.getDataEntry().getA()).doubleValue(); - if (aggregate == null) { - aggregate = new Pair<>(doubleValueA, doubleValueB); - sumPerKey.put(element.getKey(), aggregate); - } else { - sumPerKey.put(element.getKey(), new Pair<>(((Number) element.getDataEntry().getA()).doubleValue() + doubleValueA,((Number) element.getDataEntry().getB()).doubleValue() + doubleValueB)); - } - if (!minPerKey.containsKey(element.getKey()) || doubleValueA < minPerKey.get(element.getKey()).getA().doubleValue() && doubleValueB < minPerKey.get(element.getKey()).getB().doubleValue()) { - minPerKey.put(element.getKey(), new Pair<>(doubleValueA, doubleValueB)); - } - if (!maxPerKey.containsKey(element.getKey()) || doubleValueA > maxPerKey.get(element.getKey()).getA().doubleValue() && doubleValueB > maxPerKey.get(element.getKey()).getB().doubleValue()) { - maxPerKey.put(element.getKey(), new Pair<>(doubleValueA, doubleValueB)); - } + Number a = ((Number) element.getDataEntry().getA()); + Number b = ((Number) element.getDataEntry().getB()); + + final Double doubleValueA = a == null ? null : a.doubleValue(); + final Double doubleValueB = b == null ? null : b.doubleValue(); + + if (doubleValueA != null && doubleValueB != null) { + if(aggregate == null) { + aggregate = new Pair<>(doubleValueA, doubleValueB); + sumPerKey.put(element.getKey(), aggregate); + } + else { + sumPerKey.put(element.getKey(), new Pair<>(doubleValueA + aggregate.getA().doubleValue(),doubleValueB + aggregate.getB().doubleValue())); + } + if (!minPerKey.containsKey(element.getKey()) || doubleValueA < minPerKey.get(element.getKey()).getA().doubleValue() && doubleValueB < minPerKey.get(element.getKey()).getB().doubleValue()) { + minPerKey.put(element.getKey(), new Pair<>(doubleValueA, doubleValueB)); + } + if (!maxPerKey.containsKey(element.getKey()) || doubleValueA > maxPerKey.get(element.getKey()).getA().doubleValue() && doubleValueB > maxPerKey.get(element.getKey()).getB().doubleValue()) { + maxPerKey.put(element.getKey(), new Pair<>(doubleValueA, doubleValueB)); + } + } } } @@ -88,12 +91,12 @@ public class ParallelGroupedNumberPairDataAverageAggregationProcessor Map> result = new HashMap<>(); for (Entry> sumAggregationEntry : sumPerKey.entrySet()) { GroupKey key = sumAggregationEntry.getKey(); - result.put(key, new AveragePairWithStatsImpl(new Pair<>(sumAggregationEntry.getValue().getA().doubleValue() / elementAmountPerKey.get(key).get(),sumAggregationEntry.getValue().getB().doubleValue() / elementAmountPerKey.get(key).get()), + result.put(key, new AveragePairWithStatsImpl(new Pair<>(sumAggregationEntry.getValue().getA() != null ? sumAggregationEntry.getValue().getA().doubleValue() / elementAmountPerKey.get(key).get() : null, sumAggregationEntry.getValue().getB() != null ? sumAggregationEntry.getValue().getB().doubleValue() / elementAmountPerKey.get(key).get() : null) , minPerKey.get(key), maxPerKey.get(key), /* median */ null, /* standardDeviation */ null, /* count */ elementAmountPerKey.get(key).get(), - Number.class.getName())); + Pair.class.getName())); } return result; } From 40c70057c8d39c059c8a0cc2dc3c01b16fd4afc4 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Mon, 16 Apr 2018 15:23:15 +1000 Subject: [PATCH 08/38] Added AveragePairWithStatsImpl_CustomFieldSerializer --- ...irWithStatsImpl_CustomFieldSerializer.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java new file mode 100644 index 00000000000..316cb922708 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java @@ -0,0 +1,59 @@ +package com.google.gwt.user.client.rpc.core.com.sap.sse.datamining.shared.impl; + +import com.google.gwt.user.client.rpc.CustomFieldSerializer; +import com.google.gwt.user.client.rpc.SerializationException; +import com.google.gwt.user.client.rpc.SerializationStreamReader; +import com.google.gwt.user.client.rpc.SerializationStreamWriter; +import com.sap.sse.common.Util.Pair; +import com.sap.sse.datamining.shared.impl.AveragePairWithStatsImpl; + +@SuppressWarnings("rawtypes") +public class AveragePairWithStatsImpl_CustomFieldSerializer extends CustomFieldSerializer { + @Override + public boolean hasCustomInstantiateInstance() { + return true; + } + + @Override + public AveragePairWithStatsImpl instantiateInstance(SerializationStreamReader streamReader) throws SerializationException { + return instantiate(streamReader); + } + + public static AveragePairWithStatsImpl instantiate(SerializationStreamReader streamReader) throws SerializationException { + final Pair average = (Pair) streamReader.readObject(); + final Pair min = (Pair) streamReader.readObject(); + final Pair max = (Pair) streamReader.readObject(); + final Pair median = (Pair) streamReader.readObject(); + final Pair standardDeviation = (Pair) streamReader.readObject(); + final String resultType = streamReader.readString(); + final long count = streamReader.readLong(); + return new AveragePairWithStatsImpl(average, min, max, median, standardDeviation, count, resultType); + } + + @Override + public void deserializeInstance(SerializationStreamReader streamReader, AveragePairWithStatsImpl instance) + throws SerializationException { + deserialize(streamReader, instance); + } + + public static void deserialize(SerializationStreamReader streamReader, AveragePairWithStatsImpl instance) { + // handled by instantiate + } + + @Override + public void serializeInstance(SerializationStreamWriter streamWriter, AveragePairWithStatsImpl instance) + throws SerializationException { + serialize(streamWriter, instance); + } + + public static void serialize(SerializationStreamWriter streamWriter, AveragePairWithStatsImpl instance) + throws SerializationException { + streamWriter.writeObject(instance.getAverage()); + streamWriter.writeObject(instance.getMin()); + streamWriter.writeObject(instance.getMax()); + streamWriter.writeObject(instance.getMedian()); + streamWriter.writeObject(instance.getStandardDeviation()); + streamWriter.writeString(instance.getResultType()); + streamWriter.writeLong(instance.getCount()); + } +} From ce79b971cc0c990f45d655aa9ebf44d52fe604ac Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Mon, 16 Apr 2018 15:23:33 +1000 Subject: [PATCH 09/38] Added NumberPairResultsPresenter.java --- .../NumberPairResultsPresenter.java | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java new file mode 100644 index 00000000000..18323df3edb --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -0,0 +1,148 @@ +package com.sap.sailing.gwt.ui.datamining.presentation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.moxieapps.gwt.highcharts.client.Chart; +import org.moxieapps.gwt.highcharts.client.ChartTitle; +import org.moxieapps.gwt.highcharts.client.Color; +import org.moxieapps.gwt.highcharts.client.Credits; +import org.moxieapps.gwt.highcharts.client.Exporting; +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.AxisLabelsData; +import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsFormatter; +import org.moxieapps.gwt.highcharts.client.labels.YAxisLabels; + +import com.google.gwt.user.client.ui.SimpleLayoutPanel; +import com.google.gwt.user.client.ui.Widget; +import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sse.common.Util.Pair; +import com.sap.sse.common.Util.Triple; +import com.sap.sse.common.settings.Settings; +import com.sap.sse.datamining.shared.GroupKey; +import com.sap.sse.datamining.shared.data.AveragePairWithStats; +import com.sap.sse.datamining.shared.impl.CompoundGroupKey; +import com.sap.sse.datamining.shared.impl.GenericGroupKey; +import com.sap.sse.datamining.shared.impl.dto.QueryResultDTO; +import com.sap.sse.gwt.client.shared.components.Component; +import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent; +import com.sap.sse.gwt.client.shared.settings.ComponentContext; + +public class NumberPairResultsPresenter extends AbstractResultsPresenter { + private QueryResultDTO result; + private final SimpleLayoutPanel chartPanel; + private final Chart chart; + private final ArrayList series; + + + public NumberPairResultsPresenter(Component parent, ComponentContext context, StringMessages stringMessages) { + super(parent, context, stringMessages); + + chartPanel = new SimpleLayoutPanel() { + @Override + public void onResize() { + chart.setSizeToMatchContainer(); + chart.redraw(); + } + }; + chart = createChart(); + chartPanel.setWidget(chart); + series = new ArrayList<>(); +// redrawAllCharts(); + + } + + private Chart createChart() { + Chart chart = new Chart() + .setType(Series.Type.SCATTER) + .setMarginLeft(100) + .setMarginRight(45) + .setWidth100() + .setHeight100() + .setBorderColor(new Color("#F0AB00")) + .setPlotBorderWidth(0) + .setCredits(new Credits().setEnabled(false)) + .setChartTitle(new ChartTitle().setText(getStringMessages().dataMiningResult())); + chart.setExporting(new Exporting().setEnabled(false)); + chart.getXAxis().setAllowDecimals(false); + chart.getYAxis().setAxisTitleText("Result").setLabels(new YAxisLabels().setFormatter(new AxisLabelsFormatter() { + @Override + public String format(AxisLabelsData axisLabelsData) { + try { + return axisLabelsData.getValueAsDouble() + ""; + } catch (Exception e) { + return ""; + } + } + })); + return chart; + } + + private void redrawAllCharts() { + internalShowResults(result); + } + + @Override + protected Widget getPresentationWidget() { + return chartPanel; + } + + + @Override + protected void internalShowResults(QueryResultDTO r) { + result = r; +// createAndAddSeriesToChart(); + for (Entry resultEntry : result.getResults().entrySet()) { + AveragePairWithStats value = (AveragePairWithStats) resultEntry.getValue(); + + Point point = new Point(value.getAverage().getA(), value.getAverage().getB()); + series.add(point); + } + + chart.addSeries(chart.createSeries().setType(Type.SCATTER).setPoints(series.toArray(new Point[series.size()]))); + chart.redraw(); + } + + + @Override + public String getLocalizedShortName() { + return "NumberPair"; + } + + @Override + public boolean hasSettings() { + return false; + } + + @Override + public SettingsDialogComponent getSettingsDialogComponent(Settings settings) { + return null; + } + + @Override + public void updateSettings(Settings newSettings) { + // no-op + } + + @Override + public String getDependentCssClassName() { + return "NumberPair"; + } + + @Override + public Settings getSettings() { + return null; + } + + @Override + public String getId() { + return "NumberPairResultsPresenter"; + } + +} From 6fcff01dc5b608b8f25b76ddd22cb52f64a0cdf2 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Mon, 16 Apr 2018 15:35:54 +1000 Subject: [PATCH 10/38] Removed comment and method. --- .../datamining/presentation/NumberPairResultsPresenter.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index 18323df3edb..6e7ed1c90df 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -54,7 +54,6 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter(); -// redrawAllCharts(); } @@ -84,10 +83,6 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter Date: Mon, 16 Apr 2018 15:38:03 +1000 Subject: [PATCH 11/38] Removed getDependentCssClassName method --- .../presentation/NumberPairResultsPresenter.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index 6e7ed1c90df..5d110eff7da 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -125,11 +125,6 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter Date: Mon, 16 Apr 2018 16:23:00 +1000 Subject: [PATCH 12/38] Changed stringMessage for average pair: --- .../resources/stringmessages/StringMessages.properties | 2 +- .../resources/stringmessages/StringMessages_de.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties index 7b7effd1b9d..610d6ee1633 100644 --- a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties +++ b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties @@ -1,5 +1,5 @@ Average=Average -PairAverage=Average (Pair) +PairAverage=Average Median=Median Sum=Sum Maximum=Maximum diff --git a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties index 1bed0dd1324..06c7ea39d67 100644 --- a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties +++ b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties @@ -1,5 +1,5 @@ Average=Durchschnitt -PairAverage=Durchschnitt (Paar) +PairAverage=Durchschnitt Median=Median Sum=Summe Maximum=Maximum From 689844b9333d95c18a3a05c8bb93e8a4fdece597 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 17 Apr 2018 10:52:44 +1000 Subject: [PATCH 13/38] Adjusted stringMessages --- .../main/java/com/sap/sailing/gwt/ui/client/StringMessages.java | 1 + .../java/com/sap/sailing/gwt/ui/client/StringMessages.properties | 1 + .../com/sap/sailing/gwt/ui/client/StringMessages_de.properties | 1 + 3 files changed, 3 insertions(+) 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 8103ee9e021..2a21502fd84 100644 --- 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 @@ -1532,6 +1532,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, String tabbedResultsPresenter(); String polarResultsPresenter(); String maneuverSpeedDetailsResultsPresenter(); + String numberPairResultsPresenter(); String dataMiningRetrieval(); String actionWatch(); String actionAnalyze(); 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 77047229f3f..70c2d809915 100644 --- 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 @@ -9,6 +9,7 @@ trackedBefore=History of tracked events general=General listRaces=List Races listRegattas=List Regattas +numberPairResultsPresenter=Scatterplot wind=Wind maneuverType=Maneuver windPanelLabel=This is the Wind Panel which so far is completely empty. 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 9b5650c3975..7d069ea87ac 100644 --- 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 @@ -1489,6 +1489,7 @@ resultsChart=Ergebnis-Diagramm tabbedResultsPresenter=Tab Ergebnis-Darsteller polarResultsPresenter=Polar Ergebnis-Darsteller maneuverSpeedDetailsResultsPresenter=Manöver Geschwindigkeitsdetails Ergebnis-Darsteller +numberPairResultsPresenter=Scatterplot dataMiningRetrieval=Datenbeschaffung actionWatch=Verfolgen actionAnalyze=Analysieren From 717ec0a644004ed01d3efb3fb51fdfa6741dc4d8 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 17 Apr 2018 10:52:58 +1000 Subject: [PATCH 14/38] Adjusted Scatterplot Chart --- .../NumberPairResultsPresenter.java | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index 5d110eff7da..95691e7b805 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -1,12 +1,9 @@ package com.sap.sailing.gwt.ui.datamining.presentation; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.Map.Entry; +import org.moxieapps.gwt.highcharts.client.AxisTitle; import org.moxieapps.gwt.highcharts.client.Chart; import org.moxieapps.gwt.highcharts.client.ChartTitle; import org.moxieapps.gwt.highcharts.client.Color; @@ -22,13 +19,9 @@ import org.moxieapps.gwt.highcharts.client.labels.YAxisLabels; import com.google.gwt.user.client.ui.SimpleLayoutPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sse.common.Util.Pair; -import com.sap.sse.common.Util.Triple; import com.sap.sse.common.settings.Settings; import com.sap.sse.datamining.shared.GroupKey; import com.sap.sse.datamining.shared.data.AveragePairWithStats; -import com.sap.sse.datamining.shared.impl.CompoundGroupKey; -import com.sap.sse.datamining.shared.impl.GenericGroupKey; import com.sap.sse.datamining.shared.impl.dto.QueryResultDTO; import com.sap.sse.gwt.client.shared.components.Component; import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent; @@ -70,16 +63,7 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter r) { result = r; -// createAndAddSeriesToChart(); for (Entry resultEntry : result.getResults().entrySet()) { AveragePairWithStats value = (AveragePairWithStats) resultEntry.getValue(); Point point = new Point(value.getAverage().getA(), value.getAverage().getB()); + point.setName(resultEntry.getKey().asString()); series.add(point); } + chart.getXAxis().setAxisTitleText(result.getResultSignifier()); - chart.addSeries(chart.createSeries().setType(Type.SCATTER).setPoints(series.toArray(new Point[series.size()]))); - chart.redraw(); + chart.addSeries(chart.createSeries().setName("Test").setType(Type.SCATTER).setPoints(series.toArray(new Point[series.size()]))); } @Override public String getLocalizedShortName() { - return "NumberPair"; + return getStringMessages().numberPairResultsPresenter(); } @Override From 1a35348a15c9867c381e10922979d913641c205c Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 17 Apr 2018 11:36:14 +1000 Subject: [PATCH 15/38] Added line length at time of competitor start as statistic --- .../stringmessages/Sailing_StringMessages.properties | 1 + .../Sailing_StringMessages_de.properties | 1 + .../datamining/data/HasRaceOfCompetitorContext.java | 2 ++ .../impl/data/RaceOfCompetitorWithContext.java | 10 ++++++++++ 4 files changed, 14 insertions(+) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index e009d9cc966..926b3a5b2ea 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -32,6 +32,7 @@ RaceResultSailingDomainRetrieverChain=Race Results RaceOfCompetitorSailingDomainRetrieverChain=Races of Competitors ManeuverSailingDomainRetrieverChain=Maneuver LeaderboardGroup=Leaderboard Group +LineLengthAtStart=Length of Startline at Start of Race Leaderboard=Leaderboard Leg=Leg MarkPassing=Mark Passing diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index c97e309c525..48374a53bcd 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -36,6 +36,7 @@ MarkPassing=Tonnenrundung LegOfCompetitor=Schenkel eines Teilnehmers GpsFix=GPS-Fix BravoFix=Bravo-Fix +LineLengthAtStart=Länge der Startlinie zum Startzeitpunkt BravoFixTrack=Bravo-Messreihe WindFix=Windmessung Maneuver=Manöver diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java index eb16414fd36..fa1db182fa2 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java @@ -77,4 +77,6 @@ public interface HasRaceOfCompetitorContext { @Statistic(messageKey="DistanceTraveled", resultDecimals=1) public Distance getDistanceTraveled(); + @Statistic(messageKey="LineLengthAtStart", resultDecimals=1) + public Distance getLineLengthAtStart(); } diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java index 7ddb365b32e..dae7f393690 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java @@ -250,4 +250,14 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { return getTrackedRace().getDistanceTraveledIncludingGateStart(getCompetitor(), MillisecondsTimePoint.now()); } + @Override + public Distance getLineLengthAtStart() { + TrackedLegOfCompetitor firstTrackedLegOfCompetitor = getTrackedRace().getTrackedLeg(competitor, getTrackedRace().getRace().getCourse().getFirstLeg()); + TimePoint competitorStartTime = firstTrackedLegOfCompetitor.getStartTime(); + if (competitorStartTime == null) { + return null; + } + return getTrackedRace().getStartLine(competitorStartTime).getLength(); + } + } \ No newline at end of file From 34cbd620ce3ce5f2eef948d5a3e43391ed1481d9 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 17 Apr 2018 11:45:40 +1000 Subject: [PATCH 16/38] Added statistic windward distance to starboard side at start --- .../Sailing_StringMessages.properties | 1 + .../Sailing_StringMessages_de.properties | 1 + .../data/HasRaceOfCompetitorContext.java | 3 +++ .../data/RaceOfCompetitorWithContext.java | 20 +++++++++++++++++++ 4 files changed, 25 insertions(+) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index 926b3a5b2ea..901b8a9802b 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -93,6 +93,7 @@ TackAtStart=Tack at Start SpeedTenSecondsAfterStart=Speed 10s After Start RankThirtySecondsAfterStart=Rank 30s After Start WindwardDistanceToAdvantageousEndOfLine=Windward Distance to Advantageous End of Line +WindwardDistanceToStarboardSideAtStart=Windward Distance to Starboardside of Line RankAfterHalfOfTheFirstLeg=Rank after the half of the first leg AdvantageousEndOfLine=Advantageous End of Line TimeSpentInSeconds=Time Spent in Seconds diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index 48374a53bcd..88b1e5c9806 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -93,6 +93,7 @@ TackAtStart=Startbug SpeedTenSecondsAfterStart=Geschwindigkeit 10s nach dem Startzeitpunkt RankThirtySecondsAfterStart=Absolute Platzierung 30s nach dem Startzeitpunkt WindwardDistanceToAdvantageousEndOfLine=Windwärtige Distanz zum Bevorteilten Ende der Startlinie +WindwardDistanceToStarboardSideAtStart=Windwärtige Distanz zur Steuerbordseite beim Start RankAfterHalfOfTheFirstLeg=Platzierung nach der Hälfte des ersten Schenkels AdvantageousEndOfLine=Bevorteiltes Ende der Startlinie TimeSpentInSeconds=Benötigte Zeit in Sekunden diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java index fa1db182fa2..c4ad0a89d64 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java @@ -79,4 +79,7 @@ public interface HasRaceOfCompetitorContext { @Statistic(messageKey="LineLengthAtStart", resultDecimals=1) public Distance getLineLengthAtStart(); + + @Statistic(messageKey="WindwardDistanceToStarboardSideAtStart", resultDecimals=2) + Distance getWindwardDistanceToStarboardSideAtStart(); } diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java index dae7f393690..5099942592c 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java @@ -126,6 +126,26 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { return distance; } + @Override + public Distance getWindwardDistanceToStarboardSideAtStart() { + TrackedRace trackedRace = getTrackedRace(); + TimePoint startOfRace = trackedRace.getStartOfRace(); + LineDetails startLine = trackedRace.getStartLine(startOfRace); + Mark starboardMark = startLine.getStarboardMarkWhileApproachingLine(); + if (starboardMark == null) { + return null; + } + + GPSFixTrack starboardMarkTrack = trackedRace.getOrCreateTrack(starboardMark); + Position advantageousMarkPosition = starboardMarkTrack.getEstimatedPosition(startOfRace, false); + GPSFixTrack competitorTrack = trackedRace.getTrack(getCompetitor()); + Position competitorPosition = competitorTrack.getEstimatedPosition(startOfRace, false); + + TrackedLeg trackedLeg = trackedRace.getTrackedLeg(trackedRace.getRace().getCourse().getFirstLeg()); + Distance distance = trackedLeg.getWindwardDistance(competitorPosition, advantageousMarkPosition, startOfRace, WindPositionMode.LEG_MIDDLE); + return distance; + } + @Override public ClusterDTO getPercentageClusterForRelativeScore() { Double relativeScore = getTrackedRaceContext().getRelativeScoreForCompetitor(getCompetitor()); From ad1d3864cb3f9cf4833290ba852495f7c2aeea62 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 17 Apr 2018 11:49:21 +1000 Subject: [PATCH 17/38] Changed statistic to be absolute --- .../stringmessages/Sailing_StringMessages.properties | 2 +- .../stringmessages/Sailing_StringMessages_de.properties | 2 +- .../sailing/datamining/data/HasRaceOfCompetitorContext.java | 4 ++-- .../datamining/impl/data/RaceOfCompetitorWithContext.java | 5 +++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index 901b8a9802b..3473b854ecc 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -93,7 +93,7 @@ TackAtStart=Tack at Start SpeedTenSecondsAfterStart=Speed 10s After Start RankThirtySecondsAfterStart=Rank 30s After Start WindwardDistanceToAdvantageousEndOfLine=Windward Distance to Advantageous End of Line -WindwardDistanceToStarboardSideAtStart=Windward Distance to Starboardside of Line +AbsoluteWindwardDistanceToStarboardSideAtStart=Absolute Windward Distance to Starboardside of Line RankAfterHalfOfTheFirstLeg=Rank after the half of the first leg AdvantageousEndOfLine=Advantageous End of Line TimeSpentInSeconds=Time Spent in Seconds diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index 88b1e5c9806..e18761b988a 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -93,7 +93,7 @@ TackAtStart=Startbug SpeedTenSecondsAfterStart=Geschwindigkeit 10s nach dem Startzeitpunkt RankThirtySecondsAfterStart=Absolute Platzierung 30s nach dem Startzeitpunkt WindwardDistanceToAdvantageousEndOfLine=Windwärtige Distanz zum Bevorteilten Ende der Startlinie -WindwardDistanceToStarboardSideAtStart=Windwärtige Distanz zur Steuerbordseite beim Start +AbsoluteWindwardDistanceToStarboardSideAtStart=Absolute Windwärtige Distanz zur Steuerbordseite beim Start RankAfterHalfOfTheFirstLeg=Platzierung nach der Hälfte des ersten Schenkels AdvantageousEndOfLine=Bevorteiltes Ende der Startlinie TimeSpentInSeconds=Benötigte Zeit in Sekunden diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java index c4ad0a89d64..b54b84f3d7e 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java @@ -80,6 +80,6 @@ public interface HasRaceOfCompetitorContext { @Statistic(messageKey="LineLengthAtStart", resultDecimals=1) public Distance getLineLengthAtStart(); - @Statistic(messageKey="WindwardDistanceToStarboardSideAtStart", resultDecimals=2) - Distance getWindwardDistanceToStarboardSideAtStart(); + @Statistic(messageKey="AbsoluteWindwardDistanceToStarboardSideAtStart", resultDecimals=2) + Distance getAbsoluteWindwardDistanceToStarboardSideAtStart(); } diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java index 5099942592c..8d21272de21 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java @@ -127,7 +127,7 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { } @Override - public Distance getWindwardDistanceToStarboardSideAtStart() { + public Distance getAbsoluteWindwardDistanceToStarboardSideAtStart() { TrackedRace trackedRace = getTrackedRace(); TimePoint startOfRace = trackedRace.getStartOfRace(); LineDetails startLine = trackedRace.getStartLine(startOfRace); @@ -142,7 +142,8 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { Position competitorPosition = competitorTrack.getEstimatedPosition(startOfRace, false); TrackedLeg trackedLeg = trackedRace.getTrackedLeg(trackedRace.getRace().getCourse().getFirstLeg()); - Distance distance = trackedLeg.getWindwardDistance(competitorPosition, advantageousMarkPosition, startOfRace, WindPositionMode.LEG_MIDDLE); + Distance distance = trackedLeg.getAbsoluteWindwardDistance(competitorPosition, advantageousMarkPosition, startOfRace, WindPositionMode.LEG_MIDDLE); + return distance; } From 99b55b2a3d245c49caa286d7aa0072352f31ae76 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 17 Apr 2018 12:01:38 +1000 Subject: [PATCH 18/38] Cleaned some warnings --- .../impl/AveragePairWithStatsImpl_CustomFieldSerializer.java | 3 ++- .../datamining/presentation/NumberPairResultsPresenter.java | 5 +---- ...llelGroupedNumberPairDataAverageAggregationProcessor.java | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java index 316cb922708..eadc3f0a7c6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java @@ -19,6 +19,7 @@ public class AveragePairWithStatsImpl_CustomFieldSerializer extends CustomFieldS return instantiate(streamReader); } + @SuppressWarnings("unchecked") public static AveragePairWithStatsImpl instantiate(SerializationStreamReader streamReader) throws SerializationException { final Pair average = (Pair) streamReader.readObject(); final Pair min = (Pair) streamReader.readObject(); @@ -27,7 +28,7 @@ public class AveragePairWithStatsImpl_CustomFieldSerializer extends CustomFieldS final Pair standardDeviation = (Pair) streamReader.readObject(); final String resultType = streamReader.readString(); final long count = streamReader.readLong(); - return new AveragePairWithStatsImpl(average, min, max, median, standardDeviation, count, resultType); + return new AveragePairWithStatsImpl(average, min, max, median, standardDeviation, count, resultType); } @Override diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index 95691e7b805..dce1d1bd2c1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -3,7 +3,6 @@ package com.sap.sailing.gwt.ui.datamining.presentation; import java.util.ArrayList; import java.util.Map.Entry; -import org.moxieapps.gwt.highcharts.client.AxisTitle; import org.moxieapps.gwt.highcharts.client.Chart; import org.moxieapps.gwt.highcharts.client.ChartTitle; import org.moxieapps.gwt.highcharts.client.Color; @@ -12,9 +11,6 @@ import org.moxieapps.gwt.highcharts.client.Exporting; 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.AxisLabelsData; -import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsFormatter; -import org.moxieapps.gwt.highcharts.client.labels.YAxisLabels; import com.google.gwt.user.client.ui.SimpleLayoutPanel; import com.google.gwt.user.client.ui.Widget; @@ -77,6 +73,7 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter r) { result = r; for (Entry resultEntry : result.getResults().entrySet()) { + @SuppressWarnings("unchecked") AveragePairWithStats value = (AveragePairWithStats) resultEntry.getValue(); Point point = new Point(value.getAverage().getA(), value.getAverage().getB()); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java index 6ccbd7b9614..35f4c1d837c 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java @@ -16,6 +16,7 @@ import com.sap.sse.datamining.shared.GroupKey; import com.sap.sse.datamining.shared.data.AveragePairWithStats; import com.sap.sse.datamining.shared.impl.AveragePairWithStatsImpl; +@SuppressWarnings("rawtypes") public class ParallelGroupedNumberPairDataAverageAggregationProcessor extends AbstractParallelGroupedDataStoringAggregationProcessor> { private static final Class _c = AveragePairWithStats.class; @@ -44,7 +45,6 @@ public class ParallelGroupedNumberPairDataAverageAggregationProcessor maxPerKey = new HashMap<>(); } - @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected void storeElement(GroupedDataEntry element) { if (element.getDataEntry() != null) { From 4f2bad67032ab1935b8007a4e31130ba01ade3a2 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 17 Apr 2018 12:59:24 +1000 Subject: [PATCH 19/38] Adjusted stringMessage of statistic. --- .../resources/stringmessages/Sailing_StringMessages.properties | 2 +- .../stringmessages/Sailing_StringMessages_de.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index e009d9cc966..9da86895b9a 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -70,7 +70,7 @@ NumberOfJibes=Number of Jibes NumberOfPenaltyCircles=Number of Penalty Circles RankGainsOrLosses=Rank Gains or Losses DistanceToStarboardSideAtStart=Distance to Starboard Side (% of Length) -DistanceToStarboardSideAtStartVsRankAtFirstMark=Distance to Starboard Side (% of Length) vs. Rank at First Mark +DistanceToStarboardSideAtStartVsRankAtFirstMark=Relative Distance to Starboard Side (X) vs. Rank at First Mark (Y) NumberOfPodiumFinish=Number of Podium Finishes NumberOfWins=Number of Wins RankGainsOrLossesBetweenFirstMarkAndFinish=Rank Gains or Losses (1st Mark -> Finish) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index c97e309c525..065af0f5f28 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -70,7 +70,7 @@ NumberOfJibes=Anzahl der Halsen NumberOfPenaltyCircles=Anzahl der Straf-Kreise RankGainsOrLosses=Positions-Verluste oder -Gewinne DistanceToStarboardSideAtStart=Distanz zur Steuerbordseite (% der Länge) -DistanceToStarboardSideAtStartVsRankAtFirstMark=Distanz zur Steuerbordseite (% der Länge) vs. Position beim ersten Wegpunkt +DistanceToStarboardSideAtStartVsRankAtFirstMark=Relative Distanz zur Steuerbordseite (X) vs. Position beim ersten Wegpunkt (Y) NumberOfPodiumFinish=Azahl der Podium-Siege NumberOfWins=Anzahl der Siege RankGainsOrLossesBetweenFirstMarkAndFinish=Positions-Verluste oder -Gewinne (1ter Wegpunkt -> Ziel) From f7e4b47f777729b39543a1efca24091bce0314e2 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 17 Apr 2018 13:43:16 +1000 Subject: [PATCH 20/38] Adjusted metrics --- .../stringmessages/Sailing_StringMessages.properties | 1 + .../Sailing_StringMessages_de.properties | 1 + .../datamining/data/HasRaceOfCompetitorContext.java | 3 +++ .../impl/data/RaceOfCompetitorWithContext.java | 11 +++++++++++ 4 files changed, 16 insertions(+) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index 3473b854ecc..f06bbd0b281 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -106,6 +106,7 @@ speedInKnots=Speed (kts) bearing=Direction (°T) WindTrack=Wind Track timeSpentFoiling=Time spent foiling +DistanceToStarboadSideAtStartVsFinalRank=Relative Distance to Starboardside at Start (X) vs. Final Rank (Y) yaw=Yaw pitch=Pitch heel=Heel diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index e18761b988a..da7a1270791 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -73,6 +73,7 @@ RankGainsOrLosses=Positions-Verluste oder -Gewinne DistanceToStarboardSideAtStart=Distanz zur Steuerbordseite (% der Länge) DistanceToStarboardSideAtStartVsRankAtFirstMark=Distanz zur Steuerbordseite (% der Länge) vs. Position beim ersten Wegpunkt NumberOfPodiumFinish=Azahl der Podium-Siege +DistanceToStarboadSideAtStartVsFinalRank=Relative Distanz zur Steuerbordseite zum Start (X) vs. finale Platzierung (Y) NumberOfWins=Anzahl der Siege RankGainsOrLossesBetweenFirstMarkAndFinish=Positions-Verluste oder -Gewinne (1ter Wegpunkt -> Ziel) IsTracked=Ist getracked diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java index b54b84f3d7e..aef0b16aac5 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java @@ -82,4 +82,7 @@ public interface HasRaceOfCompetitorContext { @Statistic(messageKey="AbsoluteWindwardDistanceToStarboardSideAtStart", resultDecimals=2) Distance getAbsoluteWindwardDistanceToStarboardSideAtStart(); + + @Statistic(messageKey="DistanceToStarboadSideAtStartVsFinalRank", resultDecimals=2) + Pair getRelativeDistanceToStarboardSideAtStartVsFinalRank(); } diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java index 8d21272de21..d7552bb4714 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java @@ -128,6 +128,12 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { @Override public Distance getAbsoluteWindwardDistanceToStarboardSideAtStart() { + TrackedLegOfCompetitor firstTrackedLegOfCompetitor = getTrackedRace().getTrackedLeg(competitor, getTrackedRace().getRace().getCourse().getFirstLeg()); + TimePoint competitorStartTime = firstTrackedLegOfCompetitor.getStartTime(); + if(competitorStartTime == null) { + return null; + } + TrackedRace trackedRace = getTrackedRace(); TimePoint startOfRace = trackedRace.getStartOfRace(); LineDetails startLine = trackedRace.getStartLine(startOfRace); @@ -281,4 +287,9 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { return getTrackedRace().getStartLine(competitorStartTime).getLength(); } + @Override + public Pair getRelativeDistanceToStarboardSideAtStartVsFinalRank(){ + return new Pair<>(getNormalizedDistanceToStarboardSideAtStart(), getTrackedRaceContext().getRankAtFinishForCompetitor(getCompetitor())); + } + } \ No newline at end of file From c481b75c237402647fa28d96aed9c6a7dabb0bf9 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Tue, 17 Apr 2018 14:50:47 +1000 Subject: [PATCH 21/38] Removed legend for more space. Gave points groupkey name. Always use circle as a marker for now. --- .../NumberPairResultsPresenter.java | 51 ++++++++++++++++--- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index dce1d1bd2c1..541d7411dd1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -1,6 +1,10 @@ package com.sap.sailing.gwt.ui.datamining.presentation; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; import org.moxieapps.gwt.highcharts.client.Chart; @@ -10,14 +14,19 @@ import org.moxieapps.gwt.highcharts.client.Credits; import org.moxieapps.gwt.highcharts.client.Exporting; 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.plotOptions.Marker; +import org.moxieapps.gwt.highcharts.client.plotOptions.Marker.Symbol; +import org.moxieapps.gwt.highcharts.client.plotOptions.SeriesPlotOptions; +import com.google.gwt.maps.client.overlays.Circle; import com.google.gwt.user.client.ui.SimpleLayoutPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sse.common.settings.Settings; import com.sap.sse.datamining.shared.GroupKey; import com.sap.sse.datamining.shared.data.AveragePairWithStats; +import com.sap.sse.datamining.shared.impl.CompoundGroupKey; +import com.sap.sse.datamining.shared.impl.GenericGroupKey; import com.sap.sse.datamining.shared.impl.dto.QueryResultDTO; import com.sap.sse.gwt.client.shared.components.Component; import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent; @@ -27,12 +36,13 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter result; private final SimpleLayoutPanel chartPanel; private final Chart chart; - private final ArrayList series; + private final Map seriesMappedByGroupKey; + private final GroupKey simpleResultSeriesKey; public NumberPairResultsPresenter(Component parent, ComponentContext context, StringMessages stringMessages) { super(parent, context, stringMessages); - + seriesMappedByGroupKey = new HashMap<>(); chartPanel = new SimpleLayoutPanel() { @Override public void onResize() { @@ -40,10 +50,9 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter(stringMessages.results()); chart = createChart(); chartPanel.setWidget(chart); - series = new ArrayList<>(); - } private Chart createChart() { @@ -67,22 +76,48 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter subKeys = GroupKey.Util.getSubKeys(groupKey); + return subKeys.size() == 1 ? subKeys.get(0) : new CompoundGroupKey(subKeys); + } else { + return groupKey; + } + } + + private void createAndAddSeriesToChart() { + for (GroupKey groupKey : getCurrentResult().getResults().keySet()) { + GroupKey seriesKey = groupKeyToSeriesKey(groupKey); + if (!seriesMappedByGroupKey.containsKey(seriesKey)) { + seriesMappedByGroupKey.put(seriesKey, chart.createSeries().setPlotOptions(new SeriesPlotOptions().setShowInLegend(false).setMarker(new Marker().setSymbol(Symbol.CIRCLE))).setName(seriesKey.asString())); + } + } + List sortedSeriesKeys = new ArrayList<>(seriesMappedByGroupKey.keySet()); + Collections.sort(sortedSeriesKeys); + for (GroupKey seriesKey : sortedSeriesKeys) { + chart.addSeries(seriesMappedByGroupKey.get(seriesKey), false, false); + } + } @Override protected void internalShowResults(QueryResultDTO r) { result = r; + createAndAddSeriesToChart(); for (Entry resultEntry : result.getResults().entrySet()) { @SuppressWarnings("unchecked") AveragePairWithStats value = (AveragePairWithStats) resultEntry.getValue(); - Point point = new Point(value.getAverage().getA(), value.getAverage().getB()); point.setName(resultEntry.getKey().asString()); - series.add(point); + seriesMappedByGroupKey.get(groupKeyToSeriesKey(resultEntry.getKey())) + .addPoint(point, false, false, false); + } chart.getXAxis().setAxisTitleText(result.getResultSignifier()); - chart.addSeries(chart.createSeries().setName("Test").setType(Type.SCATTER).setPoints(series.toArray(new Point[series.size()]))); +// chart.addSeries(chart.createSeries().setName("Test").setType(Type.SCATTER).setPoints(series.toArray(new Point[series.size()]))); + chart.redraw(); } From 2970e72d1cd98bf53c2f729c76818f6af4137b8e Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 19 Apr 2018 11:46:42 +1000 Subject: [PATCH 22/38] Changed variable name --- .../datamining/impl/data/RaceOfCompetitorWithContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java index d7552bb4714..9ea783a2d5c 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java @@ -143,12 +143,12 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { } GPSFixTrack starboardMarkTrack = trackedRace.getOrCreateTrack(starboardMark); - Position advantageousMarkPosition = starboardMarkTrack.getEstimatedPosition(startOfRace, false); + Position starboardMarkPosition = starboardMarkTrack.getEstimatedPosition(startOfRace, false); GPSFixTrack competitorTrack = trackedRace.getTrack(getCompetitor()); Position competitorPosition = competitorTrack.getEstimatedPosition(startOfRace, false); TrackedLeg trackedLeg = trackedRace.getTrackedLeg(trackedRace.getRace().getCourse().getFirstLeg()); - Distance distance = trackedLeg.getAbsoluteWindwardDistance(competitorPosition, advantageousMarkPosition, startOfRace, WindPositionMode.LEG_MIDDLE); + Distance distance = trackedLeg.getAbsoluteWindwardDistance(competitorPosition, starboardMarkPosition, startOfRace, WindPositionMode.LEG_MIDDLE); return distance; } From 519a2f6c1f47fcbaa3447b3a29873a8adbbb744d Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 19 Apr 2018 12:07:42 +1000 Subject: [PATCH 23/38] Removed unnecessary variables for the current purpose. --- .../NumberPairResultsPresenter.java | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index 541d7411dd1..ffacb1f9f7b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -1,7 +1,5 @@ package com.sap.sailing.gwt.ui.datamining.presentation; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -18,7 +16,6 @@ import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker.Symbol; import org.moxieapps.gwt.highcharts.client.plotOptions.SeriesPlotOptions; -import com.google.gwt.maps.client.overlays.Circle; import com.google.gwt.user.client.ui.SimpleLayoutPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.ui.client.StringMessages; @@ -37,8 +34,6 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter seriesMappedByGroupKey; - private final GroupKey simpleResultSeriesKey; - public NumberPairResultsPresenter(Component parent, ComponentContext context, StringMessages stringMessages) { super(parent, context, stringMessages); @@ -50,7 +45,6 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter(stringMessages.results()); chart = createChart(); chartPanel.setWidget(chart); } @@ -90,20 +84,17 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter sortedSeriesKeys = new ArrayList<>(seriesMappedByGroupKey.keySet()); - Collections.sort(sortedSeriesKeys); - for (GroupKey seriesKey : sortedSeriesKeys) { - chart.addSeries(seriesMappedByGroupKey.get(seriesKey), false, false); - } } @Override - protected void internalShowResults(QueryResultDTO r) { - result = r; + protected void internalShowResults(QueryResultDTO res) { + result = res; createAndAddSeriesToChart(); for (Entry resultEntry : result.getResults().entrySet()) { @SuppressWarnings("unchecked") @@ -115,9 +106,6 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter Date: Thu, 19 Apr 2018 13:08:09 +1000 Subject: [PATCH 24/38] Overwrite tooltip to be able to create series with multiple points whilst displaying the points name in the tooltip and not the series name. --- .../NumberPairResultsPresenter.java | 44 +++++++------------ 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index ffacb1f9f7b..82a832b2328 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -12,6 +12,9 @@ import org.moxieapps.gwt.highcharts.client.Credits; import org.moxieapps.gwt.highcharts.client.Exporting; import org.moxieapps.gwt.highcharts.client.Point; import org.moxieapps.gwt.highcharts.client.Series; +import org.moxieapps.gwt.highcharts.client.ToolTip; +import org.moxieapps.gwt.highcharts.client.ToolTipData; +import org.moxieapps.gwt.highcharts.client.ToolTipFormatter; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker.Symbol; import org.moxieapps.gwt.highcharts.client.plotOptions.SeriesPlotOptions; @@ -33,11 +36,10 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter result; private final SimpleLayoutPanel chartPanel; private final Chart chart; - private final Map seriesMappedByGroupKey; public NumberPairResultsPresenter(Component parent, ComponentContext context, StringMessages stringMessages) { super(parent, context, stringMessages); - seriesMappedByGroupKey = new HashMap<>(); + chartPanel = new SimpleLayoutPanel() { @Override public void onResize() { @@ -63,6 +65,15 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter"+toolTipData.getPointName()+"
("+toolTipData.getPoint().getX()+","+toolTipData.getYAsString()+")"; + } + })); + return chart; } @@ -70,42 +81,21 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter subKeys = GroupKey.Util.getSubKeys(groupKey); - return subKeys.size() == 1 ? subKeys.get(0) : new CompoundGroupKey(subKeys); - } else { - return groupKey; - } - } - - private void createAndAddSeriesToChart() { - for (GroupKey groupKey : getCurrentResult().getResults().keySet()) { - GroupKey seriesKey = groupKeyToSeriesKey(groupKey); - if (!seriesMappedByGroupKey.containsKey(seriesKey)) { - Series series = chart.createSeries().setPlotOptions(new SeriesPlotOptions().setShowInLegend(false).setMarker(new Marker().setSymbol(Symbol.CIRCLE))).setName(seriesKey.asString()); - seriesMappedByGroupKey.put(seriesKey, series); - chart.addSeries(series, false, false); - } - } - } - @Override protected void internalShowResults(QueryResultDTO res) { result = res; - createAndAddSeriesToChart(); + + Series series = chart.createSeries().setPlotOptions(new SeriesPlotOptions().setMarker(new Marker().setSymbol(Symbol.CIRCLE))); for (Entry resultEntry : result.getResults().entrySet()) { @SuppressWarnings("unchecked") AveragePairWithStats value = (AveragePairWithStats) resultEntry.getValue(); Point point = new Point(value.getAverage().getA(), value.getAverage().getB()); point.setName(resultEntry.getKey().asString()); - seriesMappedByGroupKey.get(groupKeyToSeriesKey(resultEntry.getKey())) - .addPoint(point, false, false, false); - + series.addPoint(point); } chart.getXAxis().setAxisTitleText(result.getResultSignifier()); + chart.addSeries(series, false, false); } From 87f5333723e3e2a284b12df4d5d070fa63b9f898 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 19 Apr 2018 13:09:08 +1000 Subject: [PATCH 25/38] Remove
of tooltip as it does not work --- .../ui/datamining/presentation/NumberPairResultsPresenter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index 82a832b2328..5cd62b7d9b9 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -70,7 +70,7 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter"+toolTipData.getPointName()+"
("+toolTipData.getPoint().getX()+","+toolTipData.getYAsString()+")"; + return ""+toolTipData.getPointName()+"
("+toolTipData.getPoint().getX()+","+toolTipData.getYAsString()+")"; } })); From c1a30ca632e24f96b42703ddd972d94fef5d08cc Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 19 Apr 2018 13:26:45 +1000 Subject: [PATCH 26/38] Create multiple series according to group keys --- .../NumberPairResultsPresenter.java | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index 5cd62b7d9b9..f54fc551923 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -1,5 +1,7 @@ package com.sap.sailing.gwt.ui.datamining.presentation; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,6 +17,7 @@ import org.moxieapps.gwt.highcharts.client.Series; import org.moxieapps.gwt.highcharts.client.ToolTip; import org.moxieapps.gwt.highcharts.client.ToolTipData; import org.moxieapps.gwt.highcharts.client.ToolTipFormatter; +import org.moxieapps.gwt.highcharts.client.Series.Type; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker.Symbol; import org.moxieapps.gwt.highcharts.client.plotOptions.SeriesPlotOptions; @@ -36,10 +39,11 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter result; private final SimpleLayoutPanel chartPanel; private final Chart chart; + private final Map seriesMappedByGroupKey; public NumberPairResultsPresenter(Component parent, ComponentContext context, StringMessages stringMessages) { super(parent, context, stringMessages); - + seriesMappedByGroupKey = new HashMap<>(); chartPanel = new SimpleLayoutPanel() { @Override public void onResize() { @@ -85,17 +89,37 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter res) { result = res; - - Series series = chart.createSeries().setPlotOptions(new SeriesPlotOptions().setMarker(new Marker().setSymbol(Symbol.CIRCLE))); + createAndAddSeriesToChart(); + for (Entry resultEntry : result.getResults().entrySet()) { @SuppressWarnings("unchecked") AveragePairWithStats value = (AveragePairWithStats) resultEntry.getValue(); Point point = new Point(value.getAverage().getA(), value.getAverage().getB()); point.setName(resultEntry.getKey().asString()); - series.addPoint(point); + seriesMappedByGroupKey.get(groupKeyToSeriesKey(resultEntry.getKey())) + .addPoint(point, false, false, false); } chart.getXAxis().setAxisTitleText(result.getResultSignifier()); - chart.addSeries(series, false, false); + } + + private void createAndAddSeriesToChart() { + for (GroupKey groupKey : result.getResults().keySet()) { + GroupKey seriesKey = groupKeyToSeriesKey(groupKey); + if (!seriesMappedByGroupKey.containsKey(seriesKey)) { + seriesMappedByGroupKey.put(seriesKey, chart.createSeries().setPlotOptions(new SeriesPlotOptions().setMarker(new Marker().setSymbol(Symbol.CIRCLE))).setName(seriesKey.asString())); + chart.addSeries(seriesMappedByGroupKey.get(seriesKey), false, false); + } + } + + } + + private GroupKey groupKeyToSeriesKey(GroupKey groupKey) { + if (groupKey.hasSubKeys()) { + List subKeys = GroupKey.Util.getSubKeys(groupKey); + return subKeys.size() == 1 ? subKeys.get(0) : new CompoundGroupKey(subKeys); + } else { + return new GenericGroupKey<>(stringMessages.results()); + } } From d7ecc7894f37efc0f5fab7fbc1f4512b66b8a93f Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Fri, 20 Apr 2018 13:41:32 +1000 Subject: [PATCH 27/38] Changed tooltip --- .../ui/datamining/presentation/NumberPairResultsPresenter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index f54fc551923..a26d1ac2673 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -74,7 +74,7 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter"+toolTipData.getPointName()+"
("+toolTipData.getPoint().getX()+","+toolTipData.getYAsString()+")"; + return ""+toolTipData.getPointName()+"
X: "+toolTipData.getPoint().getX()+"
Y: "+toolTipData.getYAsString(); } })); From 907387bf438d2a75152ea07cd2df37a13660f6da Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Fri, 20 Apr 2018 14:17:09 +1000 Subject: [PATCH 28/38] Added WindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine and RelativeDistanceToAdvantageousEndOfLine as metrics --- .../Sailing_StringMessages.properties | 2 ++ .../Sailing_StringMessages_de.properties | 2 ++ .../data/HasRaceOfCompetitorContext.java | 6 ++++ .../data/RaceOfCompetitorWithContext.java | 36 +++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index 245219c6eba..1f457be98fd 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -98,8 +98,10 @@ RankAfterHalfOfTheFirstLeg=Rank after the half of the first leg AdvantageousEndOfLine=Advantageous End of Line TimeSpentInSeconds=Time Spent in Seconds MedalRace=Medal Race +WindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine=Windward Distance to Advantageous End of Line (X) vs. Relative Distance to Advantageous End of Line (Y) WindSourceType=Wind Source Type WindSourceName=Wind Source Name +RelativeDistanceToAdvantageousEndOfLine=Relative Distance to Advantageous End of Line windFrom=True Wind Direction (TWD) windSpeedKnots=True Wind Speed (kts) speedInKnots=Speed (kts) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index 2d70b537095..6e1595c4edd 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -110,6 +110,8 @@ timeSpentFoiling=Zeit auf Foils yaw=Gierung pitch=Neigung heel=Krängung +WindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine=Windwärtige Distanz zum Bevorteilten Ende der Startlinie (X) vs. Relative Distanz zum Bevorteilten Ende der Startlinie (Y) +RelativeDistanceToAdvantageousEndOfLine=Relative Distanz zum Bevorteilten Ende der Startlinie rideHeight=Foiling-Höhe rideHeightPort=Foiling-Höhe Backbord-Rumpf rideHeightStarboard=Foiling-Höhe Steuerbord-Rumpf diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java index aef0b16aac5..4785bcc000f 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java @@ -85,4 +85,10 @@ public interface HasRaceOfCompetitorContext { @Statistic(messageKey="DistanceToStarboadSideAtStartVsFinalRank", resultDecimals=2) Pair getRelativeDistanceToStarboardSideAtStartVsFinalRank(); + + @Statistic(messageKey="WindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine", resultDecimals=2) + Pair getWindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine(); + + @Statistic(messageKey="RelativeDistanceToAdvantageousEndOfLine", resultDecimals=2) + Double getRelativeDistanceToAdvantageousEndOfLine(); } diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java index 9ea783a2d5c..77547f3eea6 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java @@ -292,4 +292,40 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { return new Pair<>(getNormalizedDistanceToStarboardSideAtStart(), getTrackedRaceContext().getRankAtFinishForCompetitor(getCompetitor())); } + @Override + public Pair getWindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine(){ + return new Pair<>(getWindwardDistanceToAdvantageousLineEndAtStart().getMeters(), getRelativeDistanceToAdvantageousEndOfLine()); + } + + @Override + public Double getRelativeDistanceToAdvantageousEndOfLine() { + TrackedRace trackedRace = getTrackedRace(); + TimePoint startOfRace = trackedRace.getStartOfRace(); + LineDetails startLine = trackedRace.getStartLine(startOfRace); + Mark advantageousMark = null; + switch (startLine.getAdvantageousSideWhileApproachingLine()) { + case PORT: + advantageousMark = startLine.getPortMarkWhileApproachingLine(); + break; + case STARBOARD: + advantageousMark = startLine.getStarboardMarkWhileApproachingLine(); + break; + } + if (advantageousMark == null) { + return null; + } + + GPSFixTrack advantageousMarkTrack = trackedRace.getOrCreateTrack(advantageousMark); + Position advantageousMarkPosition = advantageousMarkTrack.getEstimatedPosition(startOfRace, false); + GPSFixTrack competitorTrack = trackedRace.getTrack(getCompetitor()); + Position competitorPosition = competitorTrack.getEstimatedPosition(startOfRace, false); + + Double distance = competitorPosition.getDistance(advantageousMarkPosition).getMeters(); + + TrackedLegOfCompetitor firstTrackedLegOfCompetitor = getTrackedRace().getTrackedLeg(competitor, trackedRace.getRace().getCourse().getFirstLeg()); + TimePoint competitorStartTime = firstTrackedLegOfCompetitor.getStartTime(); + Double length = trackedRace.getStartLine(competitorStartTime).getLength().getMeters(); + return distance / length; + } + } \ No newline at end of file From 4495e6836702bc4ce52dfd1f44f3d0103f121f07 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 20 Apr 2018 15:06:18 +0200 Subject: [PATCH 29/38] consolidated imports to avoid warnings Change-Id: I1c4a39f0d458cadc6ec48a70f1e2dd99c3d9fea6 --- .../ui/datamining/presentation/NumberPairResultsPresenter.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index a26d1ac2673..9cfc996ae20 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -1,7 +1,5 @@ package com.sap.sailing.gwt.ui.datamining.presentation; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -17,7 +15,6 @@ import org.moxieapps.gwt.highcharts.client.Series; import org.moxieapps.gwt.highcharts.client.ToolTip; import org.moxieapps.gwt.highcharts.client.ToolTipData; import org.moxieapps.gwt.highcharts.client.ToolTipFormatter; -import org.moxieapps.gwt.highcharts.client.Series.Type; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker.Symbol; import org.moxieapps.gwt.highcharts.client.plotOptions.SeriesPlotOptions; From edf922dfb6d9cd67373849bd1c3748b581f9001f Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 26 Apr 2018 16:39:20 +1000 Subject: [PATCH 30/38] Added ParallelGroupedNumberPairCollectingProcessor. Renamed AveragePairWithStats to PairWithStats to express that this class is now not only used for aggregating an average but also to collect all individual pairs of a group when combined with ParallelGroupedNumberPairCollectingProcessor. Adjusted NumberPairResultsPresenter. Changed default series name to groupKey. --- ...rWithStatsImpl_CustomFieldSerializer.java} | 22 +++-- .../NumberPairResultsPresenter.java | 29 ++++-- .../presentation/TabbedResultsPresenter.java | 2 +- ...ePairWithStats.java => PairWithStats.java} | 4 +- ...hStatsImpl.java => PairWithStatsImpl.java} | 29 ++++-- .../stringmessages/StringMessages.properties | 1 + .../StringMessages_de.properties | 1 + .../impl/DataMiningFrameworkActivator.java | 6 +- ...umberPairAverageAggregationProcessor.java} | 29 +++--- ...lGroupedNumberPairCollectingProcessor.java | 99 +++++++++++++++++++ 10 files changed, 180 insertions(+), 42 deletions(-) rename java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/{AveragePairWithStatsImpl_CustomFieldSerializer.java => PairWithStatsImpl_CustomFieldSerializer.java} (69%) rename java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/{AveragePairWithStats.java => PairWithStats.java} (79%) rename java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/{AveragePairWithStatsImpl.java => PairWithStatsImpl.java} (75%) rename java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/{ParallelGroupedNumberPairDataAverageAggregationProcessor.java => ParallelGroupedNumberPairAverageAggregationProcessor.java} (74%) create mode 100644 java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairCollectingProcessor.java diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/PairWithStatsImpl_CustomFieldSerializer.java similarity index 69% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/PairWithStatsImpl_CustomFieldSerializer.java index eadc3f0a7c6..7321b9fa4a7 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl_CustomFieldSerializer.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/datamining/shared/impl/PairWithStatsImpl_CustomFieldSerializer.java @@ -1,59 +1,63 @@ package com.google.gwt.user.client.rpc.core.com.sap.sse.datamining.shared.impl; +import java.util.HashSet; + import com.google.gwt.user.client.rpc.CustomFieldSerializer; import com.google.gwt.user.client.rpc.SerializationException; import com.google.gwt.user.client.rpc.SerializationStreamReader; import com.google.gwt.user.client.rpc.SerializationStreamWriter; import com.sap.sse.common.Util.Pair; -import com.sap.sse.datamining.shared.impl.AveragePairWithStatsImpl; +import com.sap.sse.datamining.shared.impl.PairWithStatsImpl; @SuppressWarnings("rawtypes") -public class AveragePairWithStatsImpl_CustomFieldSerializer extends CustomFieldSerializer { +public class PairWithStatsImpl_CustomFieldSerializer extends CustomFieldSerializer { @Override public boolean hasCustomInstantiateInstance() { return true; } @Override - public AveragePairWithStatsImpl instantiateInstance(SerializationStreamReader streamReader) throws SerializationException { + public PairWithStatsImpl instantiateInstance(SerializationStreamReader streamReader) throws SerializationException { return instantiate(streamReader); } @SuppressWarnings("unchecked") - public static AveragePairWithStatsImpl instantiate(SerializationStreamReader streamReader) throws SerializationException { + public static PairWithStatsImpl instantiate(SerializationStreamReader streamReader) throws SerializationException { final Pair average = (Pair) streamReader.readObject(); final Pair min = (Pair) streamReader.readObject(); final Pair max = (Pair) streamReader.readObject(); final Pair median = (Pair) streamReader.readObject(); final Pair standardDeviation = (Pair) streamReader.readObject(); + final HashSet individualPairs = (HashSet) streamReader.readObject(); final String resultType = streamReader.readString(); final long count = streamReader.readLong(); - return new AveragePairWithStatsImpl(average, min, max, median, standardDeviation, count, resultType); + return new PairWithStatsImpl(average, min, max, median, standardDeviation, individualPairs, count, resultType); } @Override - public void deserializeInstance(SerializationStreamReader streamReader, AveragePairWithStatsImpl instance) + public void deserializeInstance(SerializationStreamReader streamReader, PairWithStatsImpl instance) throws SerializationException { deserialize(streamReader, instance); } - public static void deserialize(SerializationStreamReader streamReader, AveragePairWithStatsImpl instance) { + public static void deserialize(SerializationStreamReader streamReader, PairWithStatsImpl instance) { // handled by instantiate } @Override - public void serializeInstance(SerializationStreamWriter streamWriter, AveragePairWithStatsImpl instance) + public void serializeInstance(SerializationStreamWriter streamWriter, PairWithStatsImpl instance) throws SerializationException { serialize(streamWriter, instance); } - public static void serialize(SerializationStreamWriter streamWriter, AveragePairWithStatsImpl instance) + public static void serialize(SerializationStreamWriter streamWriter, PairWithStatsImpl instance) throws SerializationException { streamWriter.writeObject(instance.getAverage()); streamWriter.writeObject(instance.getMin()); streamWriter.writeObject(instance.getMax()); streamWriter.writeObject(instance.getMedian()); streamWriter.writeObject(instance.getStandardDeviation()); + streamWriter.writeObject(instance.getIndividualPairs()); streamWriter.writeString(instance.getResultType()); streamWriter.writeLong(instance.getCount()); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index 9cfc996ae20..ac4515be21e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -22,9 +22,10 @@ import org.moxieapps.gwt.highcharts.client.plotOptions.SeriesPlotOptions; import com.google.gwt.user.client.ui.SimpleLayoutPanel; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.ui.client.StringMessages; +import com.sap.sse.common.Util.Pair; import com.sap.sse.common.settings.Settings; import com.sap.sse.datamining.shared.GroupKey; -import com.sap.sse.datamining.shared.data.AveragePairWithStats; +import com.sap.sse.datamining.shared.data.PairWithStats; import com.sap.sse.datamining.shared.impl.CompoundGroupKey; import com.sap.sse.datamining.shared.impl.GenericGroupKey; import com.sap.sse.datamining.shared.impl.dto.QueryResultDTO; @@ -87,18 +88,30 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter res) { result = res; createAndAddSeriesToChart(); - + for (Entry resultEntry : result.getResults().entrySet()) { @SuppressWarnings("unchecked") - AveragePairWithStats value = (AveragePairWithStats) resultEntry.getValue(); - Point point = new Point(value.getAverage().getA(), value.getAverage().getB()); - point.setName(resultEntry.getKey().asString()); - seriesMappedByGroupKey.get(groupKeyToSeriesKey(resultEntry.getKey())) - .addPoint(point, false, false, false); + PairWithStats value = (PairWithStats) resultEntry.getValue(); + + if(value.getIndividualPairs() != null) { + for(Pair pair : value.getIndividualPairs()) { + createAndAddPoint(resultEntry.getKey(), pair.getA(), pair.getB()); + } + } + else { + createAndAddPoint(resultEntry.getKey(), value.getAverage().getA(), value.getAverage().getB()); + } + } chart.getXAxis().setAxisTitleText(result.getResultSignifier()); } + private void createAndAddPoint(GroupKey key, Number x, Number y) { + Point point = new Point(x, y); + point.setName(key.asString()); + seriesMappedByGroupKey.get(groupKeyToSeriesKey(key)).addPoint(point, false, false, false); + } + private void createAndAddSeriesToChart() { for (GroupKey groupKey : result.getResults().keySet()) { GroupKey seriesKey = groupKeyToSeriesKey(groupKey); @@ -115,7 +128,7 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter subKeys = GroupKey.Util.getSubKeys(groupKey); return subKeys.size() == 1 ? subKeys.get(0) : new CompoundGroupKey(subKeys); } else { - return new GenericGroupKey<>(stringMessages.results()); + return groupKey; } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/TabbedResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/TabbedResultsPresenter.java index 298ebc132b1..7b489ac74b6 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/TabbedResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/TabbedResultsPresenter.java @@ -90,7 +90,7 @@ public class TabbedResultsPresenter extends AbstractComponent implemen removeTab(oldHeader); } else if (result.getResultType() - .equals("com.sap.sse.datamining.shared.data.AveragePairWithStats")) { + .equals("com.sap.sse.datamining.shared.data.PairWithStats")) { CloseableTabHeader oldHeader = getSelectedHeader(); addTabAndFocus(new NumberPairResultsPresenter(TabbedResultsPresenter.this, getComponentContext(), stringMessages)); diff --git a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/PairWithStats.java similarity index 79% rename from java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java rename to java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/PairWithStats.java index 32537d2084b..51c78ed6d52 100644 --- a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/AveragePairWithStats.java +++ b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/data/PairWithStats.java @@ -1,15 +1,17 @@ package com.sap.sse.datamining.shared.data; import java.io.Serializable; +import java.util.HashSet; import com.sap.sse.common.Util.Pair; -public interface AveragePairWithStats extends Serializable { +public interface PairWithStats extends Serializable { Pair getAverage(); Pair getMin(); Pair getMax(); Pair getMedian(); Pair getStandardDeviation(); + HashSet> getIndividualPairs(); long getCount(); /** diff --git a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/PairWithStatsImpl.java similarity index 75% rename from java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java rename to java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/PairWithStatsImpl.java index 51bc8afda69..5d09ed47fac 100644 --- a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/AveragePairWithStatsImpl.java +++ b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/PairWithStatsImpl.java @@ -1,25 +1,29 @@ package com.sap.sse.datamining.shared.impl; -import com.sap.sse.common.Util.Pair; -import com.sap.sse.datamining.shared.data.AveragePairWithStats; +import java.util.HashSet; -public class AveragePairWithStatsImpl implements AveragePairWithStats { +import com.sap.sse.common.Util.Pair; +import com.sap.sse.datamining.shared.data.PairWithStats; + +public class PairWithStatsImpl implements PairWithStats { private static final long serialVersionUID = -2643300186690471524L; private final Pair average; private final Pair min; private final Pair max; private final Pair median; private final Pair standardDeviation; + private final HashSet> individualPairs; private final long count; private final String resultType; - public AveragePairWithStatsImpl(Pair average, Pair min, Pair max, Pair median, Pair standardDeviation, long count, String resultType) { + public PairWithStatsImpl(Pair average, Pair min, Pair max, Pair median, Pair standardDeviation, HashSet> individualPairs, long count, String resultType) { super(); this.average = average; this.min = min; this.max = max; this.median = median; this.standardDeviation = standardDeviation; + this.individualPairs = individualPairs; this.count = count; this.resultType = resultType; } @@ -58,11 +62,16 @@ public class AveragePairWithStatsImpl implements AveragePairWithStats { public String getResultType() { return resultType; } + + @Override + public HashSet> getIndividualPairs() { + return individualPairs; + } @Override public String toString() { - return "AveragePairWithStatsImpl [average=" + average + ", min=" + min + ", max=" + max + ", median=" + median - + ", standardDeviation=" + standardDeviation + ", count=" + count + ", resultType=" + resultType + "]"; + return "PairWithStatsImpl [average=" + average + ", min=" + min + ", max=" + max + ", median=" + median + + ", standardDeviation=" + standardDeviation + ", individualPairs=" + individualPairs + ", count=" + count + ", resultType=" + resultType + "]"; } @Override @@ -76,6 +85,7 @@ public class AveragePairWithStatsImpl implements AveragePairWithStats { result = prime * result + ((min == null) ? 0 : min.hashCode()); result = prime * result + ((resultType == null) ? 0 : resultType.hashCode()); result = prime * result + ((standardDeviation == null) ? 0 : standardDeviation.hashCode()); + result = prime * result + ((individualPairs == null) ? 0 : individualPairs.hashCode()); return result; } @@ -87,7 +97,7 @@ public class AveragePairWithStatsImpl implements AveragePairWithStats { return false; if (getClass() != obj.getClass()) return false; - AveragePairWithStatsImpl other = (AveragePairWithStatsImpl) obj; + PairWithStatsImpl other = (PairWithStatsImpl) obj; if (average == null) { if (other.average != null) return false; @@ -120,6 +130,11 @@ public class AveragePairWithStatsImpl implements AveragePairWithStats { return false; } else if (!standardDeviation.equals(other.standardDeviation)) return false; + if (individualPairs == null) { + if (other.individualPairs != null) + return false; + } else if (!individualPairs.equals(other.individualPairs)) + return false; return true; } } diff --git a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties index 610d6ee1633..00ef0cb6874 100644 --- a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties +++ b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages.properties @@ -1,6 +1,7 @@ Average=Average PairAverage=Average Median=Median +PairCollecting=Identity Sum=Sum Maximum=Maximum Minimum=Minimum diff --git a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties index 06c7ea39d67..24bf33e5faf 100644 --- a/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties +++ b/java/com.sap.sse.datamining/resources/stringmessages/StringMessages_de.properties @@ -1,5 +1,6 @@ Average=Durchschnitt PairAverage=Durchschnitt +PairCollecting=Identität Median=Median Sum=Summe Maximum=Maximum diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java index 9284d175f8f..fc1c1d53684 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java @@ -28,12 +28,13 @@ import com.sap.sse.datamining.components.management.FunctionRegistry; import com.sap.sse.datamining.components.management.QueryDefinitionDTORegistry; import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedDataCountAggregationProcessor; import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedDataCountDistinctAggregationProcessor; +import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberPairCollectingProcessor; import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberDataAverageAggregationProcessor; import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberDataMaxAggregationProcessor; import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberDataMedianAggregationProcessor; import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberDataMinAggregationProcessor; import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberDataSumAggregationProcessor; -import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberPairDataAverageAggregationProcessor; +import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedNumberPairAverageAggregationProcessor; import com.sap.sse.datamining.impl.components.management.AggregationProcessorDefinitionManager; import com.sap.sse.datamining.impl.components.management.DataRetrieverChainDefinitionManager; import com.sap.sse.datamining.impl.components.management.DataSourceProviderManager; @@ -87,7 +88,8 @@ public class DataMiningFrameworkActivator implements BundleActivator { defaultAggregationProcessors.add(ParallelGroupedDataCountDistinctAggregationProcessor.getDefinition()); defaultAggregationProcessors.add(ParallelGroupedDataCountAggregationProcessor.getDefinition()); defaultAggregationProcessors.add(ParallelGroupedNumberDataAverageAggregationProcessor.getDefinition()); - defaultAggregationProcessors.add(ParallelGroupedNumberPairDataAverageAggregationProcessor.getDefinition()); + defaultAggregationProcessors.add(ParallelGroupedNumberPairAverageAggregationProcessor.getDefinition()); + defaultAggregationProcessors.add(ParallelGroupedNumberPairCollectingProcessor.getDefinition()); defaultAggregationProcessors.add(ParallelGroupedNumberDataMaxAggregationProcessor.getDefinition()); defaultAggregationProcessors.add(ParallelGroupedNumberDataMedianAggregationProcessor.getDefinition()); defaultAggregationProcessors.add(ParallelGroupedNumberDataMinAggregationProcessor.getDefinition()); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairAverageAggregationProcessor.java similarity index 74% rename from java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java rename to java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairAverageAggregationProcessor.java index 35f4c1d837c..55db47ed770 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairDataAverageAggregationProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairAverageAggregationProcessor.java @@ -13,21 +13,21 @@ import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.impl.components.GroupedDataEntry; import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition; import com.sap.sse.datamining.shared.GroupKey; -import com.sap.sse.datamining.shared.data.AveragePairWithStats; -import com.sap.sse.datamining.shared.impl.AveragePairWithStatsImpl; +import com.sap.sse.datamining.shared.data.PairWithStats; +import com.sap.sse.datamining.shared.impl.PairWithStatsImpl; @SuppressWarnings("rawtypes") -public class ParallelGroupedNumberPairDataAverageAggregationProcessor - extends AbstractParallelGroupedDataStoringAggregationProcessor> { - private static final Class _c = AveragePairWithStats.class; +public class ParallelGroupedNumberPairAverageAggregationProcessor + extends AbstractParallelGroupedDataStoringAggregationProcessor> { + private static final Class _c = PairWithStats.class; @SuppressWarnings("unchecked") - private static final Class> _cc = (Class>) _c; + private static final Class> _cc = (Class>) _c; - private static final AggregationProcessorDefinition> DEFINITION = + private static final AggregationProcessorDefinition> DEFINITION = new SimpleAggregationProcessorDefinition<>(Pair.class, - _cc, "PairAverage", ParallelGroupedNumberPairDataAverageAggregationProcessor.class); + _cc, "PairAverage", ParallelGroupedNumberPairAverageAggregationProcessor.class); - public static AggregationProcessorDefinition> getDefinition() { + public static AggregationProcessorDefinition> getDefinition() { return DEFINITION; } @@ -36,8 +36,8 @@ public class ParallelGroupedNumberPairDataAverageAggregationProcessor private final Map> maxPerKey; private final Map elementAmountPerKey; - public ParallelGroupedNumberPairDataAverageAggregationProcessor(ExecutorService executor, - Collection>, ?>> resultReceivers) { + public ParallelGroupedNumberPairAverageAggregationProcessor(ExecutorService executor, + Collection>, ?>> resultReceivers) { super(executor, resultReceivers, "PairAverage"); elementAmountPerKey = new HashMap<>(); sumPerKey = new HashMap<>(); @@ -87,14 +87,15 @@ public class ParallelGroupedNumberPairDataAverageAggregationProcessor } @Override - protected Map> aggregateResult() { - Map> result = new HashMap<>(); + protected Map> aggregateResult() { + Map> result = new HashMap<>(); for (Entry> sumAggregationEntry : sumPerKey.entrySet()) { GroupKey key = sumAggregationEntry.getKey(); - result.put(key, new AveragePairWithStatsImpl(new Pair<>(sumAggregationEntry.getValue().getA() != null ? sumAggregationEntry.getValue().getA().doubleValue() / elementAmountPerKey.get(key).get() : null, sumAggregationEntry.getValue().getB() != null ? sumAggregationEntry.getValue().getB().doubleValue() / elementAmountPerKey.get(key).get() : null) , + result.put(key, new PairWithStatsImpl(new Pair<>(sumAggregationEntry.getValue().getA() != null ? sumAggregationEntry.getValue().getA().doubleValue() / elementAmountPerKey.get(key).get() : null, sumAggregationEntry.getValue().getB() != null ? sumAggregationEntry.getValue().getB().doubleValue() / elementAmountPerKey.get(key).get() : null) , minPerKey.get(key), maxPerKey.get(key), /* median */ null, /* standardDeviation */ null, + /* individualPairs */ null, /* count */ elementAmountPerKey.get(key).get(), Pair.class.getName())); } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairCollectingProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairCollectingProcessor.java new file mode 100644 index 00000000000..8a7aa40855f --- /dev/null +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairCollectingProcessor.java @@ -0,0 +1,99 @@ +package com.sap.sse.datamining.impl.components.aggregators; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicLong; + +import com.sap.sse.common.Util.Pair; +import com.sap.sse.datamining.components.AggregationProcessorDefinition; +import com.sap.sse.datamining.components.Processor; +import com.sap.sse.datamining.impl.components.GroupedDataEntry; +import com.sap.sse.datamining.impl.components.SimpleAggregationProcessorDefinition; +import com.sap.sse.datamining.shared.GroupKey; +import com.sap.sse.datamining.shared.data.PairWithStats; +import com.sap.sse.datamining.shared.impl.PairWithStatsImpl; + + +@SuppressWarnings("rawtypes") +public class ParallelGroupedNumberPairCollectingProcessor + extends AbstractParallelGroupedDataStoringAggregationProcessor> { + + private static final Class _c = PairWithStats.class; + @SuppressWarnings("unchecked") + private static final Class> _cc = (Class>) _c; + + private static final AggregationProcessorDefinition> DEFINITION = + new SimpleAggregationProcessorDefinition<>(Pair.class, + _cc, "PairCollecting", ParallelGroupedNumberPairCollectingProcessor.class); + + public static AggregationProcessorDefinition> getDefinition() { + return DEFINITION; + } + + private final Map>> individualPairs; + private final Map elementAmountPerKey; + + public ParallelGroupedNumberPairCollectingProcessor(ExecutorService executor, + Collection>, ?>> resultReceivers) { + super(executor, resultReceivers, "PairCollecting"); + individualPairs = new HashMap<>(); + elementAmountPerKey = new HashMap<>(); + } + + @Override + protected void storeElement(GroupedDataEntry element) { + if (element.getDataEntry() != null) { + incrementElementAmount(element); + HashSet> aggregate = individualPairs.get(element.getKey()); + Number a = ((Number) element.getDataEntry().getA()); + Number b = ((Number) element.getDataEntry().getB()); + + final Double doubleValueA = a == null ? null : a.doubleValue(); + final Double doubleValueB = b == null ? null : b.doubleValue(); + + if (doubleValueA != null && doubleValueB != null) { + if(aggregate == null) { + aggregate = new HashSet<>(); + aggregate.add(new Pair<>(doubleValueA, doubleValueB)); + individualPairs.put(element.getKey(), aggregate); + } + else { + individualPairs.get(element.getKey()).add(new Pair<>(doubleValueA, doubleValueB)); + } + } + } + } + + private void incrementElementAmount(GroupedDataEntry element) { + GroupKey key = element.getKey(); + // concurrency is not an issue here; needsSynchronization() returns true + AtomicLong currentAmount = elementAmountPerKey.get(key); + if (currentAmount == null) { + elementAmountPerKey.put(key, new AtomicLong(1)); + } else { + currentAmount.incrementAndGet(); + } + } + + @Override + protected Map> aggregateResult() { + Map> result = new HashMap<>(); + for (Entry>> sumAggregationEntry : individualPairs.entrySet()) { + GroupKey key = sumAggregationEntry.getKey(); + result.put(key, new PairWithStatsImpl(null, + /* min */ null, + /* max */ null, + /* median */ null, + /* standardDeviation */ null, + /* individualPairs */ individualPairs.get(key), + /* count */ elementAmountPerKey.get(key).get(), + Pair.class.getName())); + } + return result; + } + +} From 3e8acf2723bfc6cf3a71e7f1f733da037a0dcca3 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 26 Apr 2018 16:40:29 +1000 Subject: [PATCH 31/38] Removed unused imports --- .../ui/datamining/presentation/NumberPairResultsPresenter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index ac4515be21e..1c94beb3104 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -16,8 +16,8 @@ import org.moxieapps.gwt.highcharts.client.ToolTip; import org.moxieapps.gwt.highcharts.client.ToolTipData; import org.moxieapps.gwt.highcharts.client.ToolTipFormatter; import org.moxieapps.gwt.highcharts.client.plotOptions.Marker; -import org.moxieapps.gwt.highcharts.client.plotOptions.Marker.Symbol; import org.moxieapps.gwt.highcharts.client.plotOptions.SeriesPlotOptions; +import org.moxieapps.gwt.highcharts.client.plotOptions.Marker.Symbol; import com.google.gwt.user.client.ui.SimpleLayoutPanel; import com.google.gwt.user.client.ui.Widget; @@ -27,7 +27,6 @@ import com.sap.sse.common.settings.Settings; import com.sap.sse.datamining.shared.GroupKey; import com.sap.sse.datamining.shared.data.PairWithStats; import com.sap.sse.datamining.shared.impl.CompoundGroupKey; -import com.sap.sse.datamining.shared.impl.GenericGroupKey; import com.sap.sse.datamining.shared.impl.dto.QueryResultDTO; import com.sap.sse.gwt.client.shared.components.Component; import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent; From fa325c38af52c0622538969a1b4df0024daa6b0b Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Mon, 30 Apr 2018 10:41:09 +1000 Subject: [PATCH 32/38] Changed grouping visualization back to default. --- .../datamining/presentation/NumberPairResultsPresenter.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index 1c94beb3104..e39d28874dd 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -27,6 +27,7 @@ import com.sap.sse.common.settings.Settings; import com.sap.sse.datamining.shared.GroupKey; import com.sap.sse.datamining.shared.data.PairWithStats; import com.sap.sse.datamining.shared.impl.CompoundGroupKey; +import com.sap.sse.datamining.shared.impl.GenericGroupKey; import com.sap.sse.datamining.shared.impl.dto.QueryResultDTO; import com.sap.sse.gwt.client.shared.components.Component; import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent; @@ -37,6 +38,7 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter seriesMappedByGroupKey; + private final GroupKey simpleResultSeriesKey; public NumberPairResultsPresenter(Component parent, ComponentContext context, StringMessages stringMessages) { super(parent, context, stringMessages); @@ -48,6 +50,7 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter(stringMessages.results()); chart = createChart(); chartPanel.setWidget(chart); } @@ -119,7 +122,6 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter subKeys = GroupKey.Util.getSubKeys(groupKey); return subKeys.size() == 1 ? subKeys.get(0) : new CompoundGroupKey(subKeys); } else { - return groupKey; + return simpleResultSeriesKey; } } From 5518523c4910c311c21ff64b87182d9e1d5c2e68 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Mon, 30 Apr 2018 12:25:07 +1000 Subject: [PATCH 33/38] Added statistics SpeedAverage and SpeedAverageVsDistanceTraveled --- .../Sailing_StringMessages.properties | 2 ++ .../Sailing_StringMessages_de.properties | 2 ++ .../HasTrackedLegOfCompetitorContext.java | 7 +++++ .../TrackedLegOfCompetitorWithContext.java | 28 +++++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index 1f457be98fd..9658df2452e 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -1,8 +1,10 @@ Speed=Speed +SpeedAverage=Average Speed SpeedTenSecondsBefore=Speed 10s before DistanceTraveled=Distance Traveled Name=Name LegType=Leg Type +SpeedAverageVsDistanceTraveled=Average Speed in Knots (X) Vs. Distance Traveled in Meters (Y) SailID=Sail Number Year=Year LegNumber=Leg Number diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index 6e1595c4edd..f01e023ae09 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -133,6 +133,8 @@ AverageAbsoluteTrueWindAngle=Durchschnittlicher absoluter Winkel zum wahren Wind AbsoluteTrueWindAngle=Absoluter Winkel zum wahren Wind (TWA) TrueWindAngle=Winkel zum wahren Wind (TWA) Wind=Wind +SpeedAverageVsDistanceTraveled=Durschnittliche Geschwindigkeit in Knoten (X) Vs. zurückgelegte Distanz in Meter (Y) +SpeedAverage=Durchschnittliche Geschwindigkeit VMG=Luv-/Leegeschwindigkeit (VMG) MaxTurningRateInDegreesPerSecond=Max. Drehrate in deg/s ManeuverEnteringAbsTWA=Absolutes TWA vor Manöver diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedLegOfCompetitorContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedLegOfCompetitorContext.java index 3958b151812..cbbb4ad4bf1 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedLegOfCompetitorContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedLegOfCompetitorContext.java @@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; import com.sap.sse.common.Duration; +import com.sap.sse.common.Util.Pair; import com.sap.sse.datamining.annotations.Connector; import com.sap.sse.datamining.annotations.Dimension; import com.sap.sse.datamining.annotations.Statistic; @@ -24,6 +25,12 @@ public interface HasTrackedLegOfCompetitorContext extends HasWindOnTrackedLeg { @Statistic(messageKey="DistanceTraveled", resultDecimals=0, ordinal=0) public Distance getDistanceTraveled(); + @Statistic(messageKey="SpeedAverage", resultDecimals=0, ordinal=0) + public Double getSpeedAverage(); + + @Statistic(messageKey="SpeedAverageVsDistanceTraveled", resultDecimals=0, ordinal=0) + public Pair getSpeedAverageVsDistanceTraveled(); + @Statistic(messageKey="RankGainsOrLosses", resultDecimals=2, ordinal=1) public Double getRankGainsOrLosses(); diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedLegOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedLegOfCompetitorWithContext.java index a4f9ec3b7b8..85cb74f06cd 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedLegOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedLegOfCompetitorWithContext.java @@ -1,5 +1,6 @@ package com.sap.sailing.datamining.impl.data; +import java.util.List; import java.util.function.BiFunction; import com.sap.sailing.datamining.Activator; @@ -7,17 +8,21 @@ import com.sap.sailing.datamining.SailingClusterGroups; import com.sap.sailing.datamining.data.HasTrackedLegContext; import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext; import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.Leg; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.Position; import com.sap.sailing.domain.common.Wind; +import com.sap.sailing.domain.common.tracking.GPSFixMoving; import com.sap.sailing.domain.leaderboard.Leaderboard; import com.sap.sailing.domain.tracking.BravoFixTrack; +import com.sap.sailing.domain.tracking.GPSFixTrack; import com.sap.sailing.domain.tracking.TrackedLeg; import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sse.common.Duration; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; +import com.sap.sse.common.Util.Pair; import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.datamining.data.Cluster; import com.sap.sse.datamining.shared.impl.dto.ClusterDTO; @@ -111,6 +116,29 @@ public class TrackedLegOfCompetitorWithContext implements HasTrackedLegOfCompeti return getTrackedLegOfCompetitor().getDistanceTraveled(timePoint); } + @Override + public Double getSpeedAverage() { + if (getTrackedRace() == null) { + return null; + } else { + final List legs = getTrackedRace().getRace().getCourse().getLegs(); + if (legs.isEmpty()) { + return null; + } else { + final Leg lastLeg = legs.get(legs.size() - 1); + GPSFixTrack track = getTrackedRace().getTrack(getCompetitor()); + TimePoint finished = getTrackedRace().getTrackedLeg(getCompetitor(), lastLeg).getFinishTime(); + return getTrackedRace().getAverageSpeedOverGround(getCompetitor(), finished).getKnots(); + } + } + } + + @Override + public Pair getSpeedAverageVsDistanceTraveled(){ + return new Pair(getSpeedAverage(), getDistanceTraveled().getMeters()); + } + + @Override public Double getRankGainsOrLosses() { Double rankAtStart = getRankAtStart(); From 0a30ccee1defae458d79a68952ab322acda04176 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Mon, 30 Apr 2018 14:06:57 +1000 Subject: [PATCH 34/38] Distinguish metrics that depend on start of race or start of competitor by naming them accordingly. --- .../Sailing_StringMessages.properties | 15 +++--- .../Sailing_StringMessages_de.properties | 15 +++--- .../data/HasRaceOfCompetitorContext.java | 37 +++++++------- .../data/RaceOfCompetitorWithContext.java | 49 ++++++++++++------- 4 files changed, 66 insertions(+), 50 deletions(-) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index 9658df2452e..257e3255ecb 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -72,8 +72,8 @@ NumberOfTacks=Number of Tacks NumberOfJibes=Number of Jibes NumberOfPenaltyCircles=Number of Penalty Circles RankGainsOrLosses=Rank Gains or Losses -DistanceToStarboardSideAtStart=Distance to Starboard Side (% of Length) -DistanceToStarboardSideAtStartVsRankAtFirstMark=Relative Distance to Starboard Side (X) vs. Rank at First Mark (Y) +DistanceToStarboardSideAtStartOfCompetitor=Relative Distance to Starboard Side at Start of Competitor +DistanceToStarboardSideAtStartOfCompetitorVsRankAtFirstMark=Relative Distance to Starboard Side at Start of Competitor (X) vs. Rank at First Mark (Y) NumberOfPodiumFinish=Number of Podium Finishes NumberOfWins=Number of Wins RankGainsOrLossesBetweenFirstMarkAndFinish=Rank Gains or Losses (1st Mark -> Finish) @@ -94,23 +94,24 @@ PassingSide=Passing Side TackAtStart=Tack at Start SpeedTenSecondsAfterStart=Speed 10s After Start RankThirtySecondsAfterStart=Rank 30s After Start -WindwardDistanceToAdvantageousEndOfLine=Windward Distance to Advantageous End of Line -AbsoluteWindwardDistanceToStarboardSideAtStart=Absolute Windward Distance to Starboardside of Line +WindwardDistanceToAdvantageousEndOfLineAtStartOfRace=Windward Distance to Advantageous End of Line at Start of Race +WindwardDistanceToAdvantageousEndOfLineAtStartOfCompetitor=Windward Distance to Starboard Side of Line at Start of Competitor RankAfterHalfOfTheFirstLeg=Rank after the half of the first leg AdvantageousEndOfLine=Advantageous End of Line TimeSpentInSeconds=Time Spent in Seconds MedalRace=Medal Race -WindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine=Windward Distance to Advantageous End of Line (X) vs. Relative Distance to Advantageous End of Line (Y) +WindwardDistanceToAdvantageousEndOfLineAtStartOfRaceVsRelativeDistanceToAdvantageousEndOfLine=Windward Distance to Advantageous End of Line at Start of Race (X) vs. Relative Distance to Advantageous End of Line at Start of Race (Y) WindSourceType=Wind Source Type +AbsoluteWindwardDistanceToStarboardSideAtStartOfCompetitor=Absolute Windward Distance to Starboardside of Line at Start of Competitor WindSourceName=Wind Source Name -RelativeDistanceToAdvantageousEndOfLine=Relative Distance to Advantageous End of Line +RelativeDistanceToAdvantageousEndOfLineAtStartOfRace=Relative Distance to Advantageous End of Line at Start of Race windFrom=True Wind Direction (TWD) windSpeedKnots=True Wind Speed (kts) speedInKnots=Speed (kts) bearing=Direction (°T) WindTrack=Wind Track timeSpentFoiling=Time spent foiling -DistanceToStarboadSideAtStartVsFinalRank=Relative Distance to Starboardside at Start (X) vs. Final Rank (Y) +DistanceToStarboardSideAtStartOfCompetitorVsFinalRank=Relative Distance to Starboard Side at Start of Competitor (X) vs. Final Rank (Y) yaw=Yaw pitch=Pitch heel=Heel diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index f01e023ae09..083af2b4533 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -70,10 +70,10 @@ NumberOfTacks=Anzahl der Wenden NumberOfJibes=Anzahl der Halsen NumberOfPenaltyCircles=Anzahl der Straf-Kreise RankGainsOrLosses=Positions-Verluste oder -Gewinne -DistanceToStarboardSideAtStart=Distanz zur Steuerbordseite (% der Länge) -DistanceToStarboardSideAtStartVsRankAtFirstMark=Relative Distanz zur Steuerbordseite (X) vs. Position beim ersten Wegpunkt (Y) +DistanceToStarboardSideAtStartOfCompetitor=Relative Distanz zur Steuerbordseite beim Start des Teilnehmers +DistanceToStarboardSideAtStartOfCompetitorVsRankAtFirstMark=Relative Distanz zur Steuerbordseite beim Start des Teilnehmers (X) vs. Position beim ersten Wegpunkt (Y) NumberOfPodiumFinish=Azahl der Podium-Siege -DistanceToStarboadSideAtStartVsFinalRank=Relative Distanz zur Steuerbordseite zum Start (X) vs. finale Platzierung (Y) +DistanceToStarboardSideAtStartOfCompetitorVsFinalRank=Relative Distanz zur Steuerbordseite zum Start des Teilnehmers (X) vs. finale Platzierung (Y) NumberOfWins=Anzahl der Siege RankGainsOrLossesBetweenFirstMarkAndFinish=Positions-Verluste oder -Gewinne (1ter Wegpunkt -> Ziel) IsTracked=Ist getracked @@ -93,8 +93,9 @@ PassingSide=Passierende Seite TackAtStart=Startbug SpeedTenSecondsAfterStart=Geschwindigkeit 10s nach dem Startzeitpunkt RankThirtySecondsAfterStart=Absolute Platzierung 30s nach dem Startzeitpunkt -WindwardDistanceToAdvantageousEndOfLine=Windwärtige Distanz zum Bevorteilten Ende der Startlinie -AbsoluteWindwardDistanceToStarboardSideAtStart=Absolute Windwärtige Distanz zur Steuerbordseite beim Start +WindwardDistanceToAdvantageousEndOfLineAtStartOfRace=Windwärtige Distanz zum Bevorteilten Ende der Startlinie zum Start des Rennens +WindwardDistanceToAdvantageousEndOfLineAtStartOfCompetitor=Windwärtige Distanz zum Bevorteilten Ende der Startlinie zum Start des Teilnehmers +AbsoluteWindwardDistanceToStarboardSideAtStartOfCompetitor=Absolute Windwärtige Distanz zur Steuerbordseite beim Start des Teilnehmers RankAfterHalfOfTheFirstLeg=Platzierung nach der Hälfte des ersten Schenkels AdvantageousEndOfLine=Bevorteiltes Ende der Startlinie TimeSpentInSeconds=Benötigte Zeit in Sekunden @@ -110,8 +111,8 @@ timeSpentFoiling=Zeit auf Foils yaw=Gierung pitch=Neigung heel=Krängung -WindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine=Windwärtige Distanz zum Bevorteilten Ende der Startlinie (X) vs. Relative Distanz zum Bevorteilten Ende der Startlinie (Y) -RelativeDistanceToAdvantageousEndOfLine=Relative Distanz zum Bevorteilten Ende der Startlinie +WindwardDistanceToAdvantageousEndOfLineAtStartOfRaceVsRelativeDistanceToAdvantageousEndOfLine=Windwärtige Distanz zum Bevorteilten Ende der Startlinie zum Start des Rennens (X) vs. Relative Distanz zum Bevorteilten Ende der Startlinie zum Start des Rennens (Y) +RelativeDistanceToAdvantageousEndOfLineAtStartOfRace=Relative Distanz zum Bevorteilten Ende der Startlinie zum Start des Rennens rideHeight=Foiling-Höhe rideHeightPort=Foiling-Höhe Backbord-Rumpf rideHeightStarboard=Foiling-Höhe Steuerbord-Rumpf diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java index 4785bcc000f..b0e873a9d10 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java @@ -23,7 +23,7 @@ public interface HasRaceOfCompetitorContext { @Dimension(messageKey="TackAtStart", ordinal=12) public Tack getTackAtStart() throws NoWindException; - @Dimension(messageKey="DistanceToStarboardSideAtStart", ordinal=13) + @Dimension(messageKey="DistanceToStarboardSideAtStartOfCompetitor", ordinal=13) public ClusterDTO getPercentageClusterForDistanceToStarboardSideAtStart(); @Dimension(messageKey="RelativeScoreInPercent", ordinal=14) @@ -32,14 +32,17 @@ public interface HasRaceOfCompetitorContext { @Statistic(messageKey="DistanceAtStart", resultDecimals=2, ordinal=0) public Distance getDistanceToStartLineAtStart(); - @Statistic(messageKey="DistanceToStarboardSideAtStart", resultDecimals=2, ordinal=1) - public Double getNormalizedDistanceToStarboardSideAtStart(); + @Statistic(messageKey="DistanceToStarboardSideAtStartOfCompetitor", resultDecimals=2, ordinal=1) + public Double getNormalizedDistanceToStarboardSideAtStartOfCompetitor(); - @Statistic(messageKey="DistanceToStarboardSideAtStartVsRankAtFirstMark", resultDecimals=2, ordinal=1) - public Pair getNormalizedDistanceToStarboardSideAtStartVsRankAtFirstMark(); + @Statistic(messageKey="DistanceToStarboardSideAtStartOfCompetitorVsRankAtFirstMark", resultDecimals=2, ordinal=1) + public Pair getNormalizedDistanceToStarboardSideAtStartOfCompetitorVsRankAtFirstMark(); - @Statistic(messageKey="WindwardDistanceToAdvantageousEndOfLine", resultDecimals=2, ordinal=2) - public Distance getWindwardDistanceToAdvantageousLineEndAtStart(); + @Statistic(messageKey="WindwardDistanceToAdvantageousEndOfLineAtStartOfRace", resultDecimals=2, ordinal=2) + public Distance getWindwardDistanceToAdvantageousLineEndAtStartofRace(); + + @Statistic(messageKey="WindwardDistanceToAdvantageousEndOfLineAtStartOfCompetitor", resultDecimals=2, ordinal=2) + public Distance getWindwardDistanceToAdvantageousLineEndAtStartofCompetitor(); @Connector(messageKey="SpeedWhenStarting", ordinal=3) public Speed getSpeedWhenStarting(); @@ -48,10 +51,10 @@ public interface HasRaceOfCompetitorContext { public Speed getSpeedTenSecondsBeforeStart(); @Connector(messageKey="SpeedTenSecondsAfterStart", ordinal=5) - public Speed getSpeedTenSecondsAfterStart(); + public Speed getSpeedTenSecondsAfterStartOfRace(); @Statistic(messageKey="RankThirtySecondsAfterStart", resultDecimals=2, ordinal=6) - public Double getRankThirtySecondsAfterStart(); + public Double getRankThirtySecondsAfterStartOfRace(); @Statistic(messageKey="RankAfterHalfOfTheFirstLeg", resultDecimals=2, ordinal=7) public Double getRankAfterHalfOfTheFirstLeg(); @@ -80,15 +83,15 @@ public interface HasRaceOfCompetitorContext { @Statistic(messageKey="LineLengthAtStart", resultDecimals=1) public Distance getLineLengthAtStart(); - @Statistic(messageKey="AbsoluteWindwardDistanceToStarboardSideAtStart", resultDecimals=2) - Distance getAbsoluteWindwardDistanceToStarboardSideAtStart(); + @Statistic(messageKey="AbsoluteWindwardDistanceToStarboardSideAtStartOfCompetitor", resultDecimals=2) + Distance getAbsoluteWindwardDistanceToStarboardSideAtStartOfCompetitor(); - @Statistic(messageKey="DistanceToStarboadSideAtStartVsFinalRank", resultDecimals=2) - Pair getRelativeDistanceToStarboardSideAtStartVsFinalRank(); + @Statistic(messageKey="DistanceToStarboardSideAtStartOfCompetitorVsFinalRank", resultDecimals=2) + Pair getRelativeDistanceToStarboardSideAtStartOfCompetitorVsFinalRank(); - @Statistic(messageKey="WindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine", resultDecimals=2) - Pair getWindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine(); + @Statistic(messageKey="WindwardDistanceToAdvantageousEndOfLineAtStartOfRaceVsRelativeDistanceToAdvantageousEndOfLine", resultDecimals=2) + Pair getWindwardDistanceToAdvantageousEndOfLineAtStartOfRaceVsRelativeDistanceToAdvantageousEndOfLineAtStartOfRace(); - @Statistic(messageKey="RelativeDistanceToAdvantageousEndOfLine", resultDecimals=2) - Double getRelativeDistanceToAdvantageousEndOfLine(); + @Statistic(messageKey="RelativeDistanceToAdvantageousEndOfLineAtStartOfRace", resultDecimals=2) + Double getRelativeDistanceToAdvantageousEndOfLineAtStartOfRace(); } diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java index 77547f3eea6..f40ffb6049a 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java @@ -64,7 +64,7 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { @Override public ClusterDTO getPercentageClusterForDistanceToStarboardSideAtStart() { - Double normalizedDistance = getNormalizedDistanceToStarboardSideAtStart(); + Double normalizedDistance = getNormalizedDistanceToStarboardSideAtStartOfCompetitor(); if (normalizedDistance == null) { return null; } @@ -80,7 +80,7 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { } @Override - public Double getNormalizedDistanceToStarboardSideAtStart() { + public Double getNormalizedDistanceToStarboardSideAtStartOfCompetitor() { TrackedRace trackedRace = getTrackedRace(); TrackedLegOfCompetitor firstTrackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, trackedRace.getRace().getCourse().getFirstLeg()); TimePoint competitorStartTime = firstTrackedLegOfCompetitor.getStartTime(); @@ -94,15 +94,16 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { } @Override - public Pair getNormalizedDistanceToStarboardSideAtStartVsRankAtFirstMark(){ - return new Pair (getNormalizedDistanceToStarboardSideAtStart(), getRankAtFirstMark()); + public Pair getNormalizedDistanceToStarboardSideAtStartOfCompetitorVsRankAtFirstMark(){ + return new Pair (getNormalizedDistanceToStarboardSideAtStartOfCompetitor(), getRankAtFirstMark()); } - @Override - public Distance getWindwardDistanceToAdvantageousLineEndAtStart() { + public Distance getWindwardDistanceToAdvantageousLineEndAtStartOf(TimePoint timepoint) { + if(timepoint == null) { + return null; + } TrackedRace trackedRace = getTrackedRace(); - TimePoint startOfRace = trackedRace.getStartOfRace(); - LineDetails startLine = trackedRace.getStartLine(startOfRace); + LineDetails startLine = trackedRace.getStartLine(timepoint); Mark advantageousMark = null; switch (startLine.getAdvantageousSideWhileApproachingLine()) { case PORT: @@ -117,17 +118,27 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { } GPSFixTrack advantageousMarkTrack = trackedRace.getOrCreateTrack(advantageousMark); - Position advantageousMarkPosition = advantageousMarkTrack.getEstimatedPosition(startOfRace, false); + Position advantageousMarkPosition = advantageousMarkTrack.getEstimatedPosition(timepoint, false); GPSFixTrack competitorTrack = trackedRace.getTrack(getCompetitor()); - Position competitorPosition = competitorTrack.getEstimatedPosition(startOfRace, false); + Position competitorPosition = competitorTrack.getEstimatedPosition(timepoint, false); TrackedLeg trackedLeg = trackedRace.getTrackedLeg(trackedRace.getRace().getCourse().getFirstLeg()); - Distance distance = trackedLeg.getWindwardDistance(competitorPosition, advantageousMarkPosition, startOfRace, WindPositionMode.LEG_MIDDLE); + Distance distance = trackedLeg.getWindwardDistance(competitorPosition, advantageousMarkPosition, timepoint, WindPositionMode.LEG_MIDDLE); return distance; } @Override - public Distance getAbsoluteWindwardDistanceToStarboardSideAtStart() { + public Distance getWindwardDistanceToAdvantageousLineEndAtStartofRace() { + return getWindwardDistanceToAdvantageousLineEndAtStartOf(getTrackedRace().getStartOfRace()); + } + + @Override + public Distance getWindwardDistanceToAdvantageousLineEndAtStartofCompetitor() { + return getWindwardDistanceToAdvantageousLineEndAtStartOf(getTrackedRace().getTrackedLeg(getCompetitor(), getTrackedRace().getRace().getCourse().getFirstLeg()).getStartTime()); + } + + @Override + public Distance getAbsoluteWindwardDistanceToStarboardSideAtStartOfCompetitor() { TrackedLegOfCompetitor firstTrackedLegOfCompetitor = getTrackedRace().getTrackedLeg(competitor, getTrackedRace().getRace().getCourse().getFirstLeg()); TimePoint competitorStartTime = firstTrackedLegOfCompetitor.getStartTime(); if(competitorStartTime == null) { @@ -176,7 +187,7 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { } @Override - public Speed getSpeedTenSecondsAfterStart() { + public Speed getSpeedTenSecondsAfterStartOfRace() { TimePoint startOfRace = getTrackedRace().getStartOfRace(); if (startOfRace == null) { return null; @@ -185,7 +196,7 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { } @Override - public Double getRankThirtySecondsAfterStart() { + public Double getRankThirtySecondsAfterStartOfRace() { TimePoint startOfRace = getTrackedRace().getStartOfRace(); if (startOfRace == null) { return null; @@ -288,17 +299,17 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { } @Override - public Pair getRelativeDistanceToStarboardSideAtStartVsFinalRank(){ - return new Pair<>(getNormalizedDistanceToStarboardSideAtStart(), getTrackedRaceContext().getRankAtFinishForCompetitor(getCompetitor())); + public Pair getRelativeDistanceToStarboardSideAtStartOfCompetitorVsFinalRank(){ + return new Pair<>(getNormalizedDistanceToStarboardSideAtStartOfCompetitor(), getTrackedRaceContext().getRankAtFinishForCompetitor(getCompetitor())); } @Override - public Pair getWindwardDistanceToAdvantageousEndOfLineVsRelativeDistanceToAdvantageousEndOfLine(){ - return new Pair<>(getWindwardDistanceToAdvantageousLineEndAtStart().getMeters(), getRelativeDistanceToAdvantageousEndOfLine()); + public Pair getWindwardDistanceToAdvantageousEndOfLineAtStartOfRaceVsRelativeDistanceToAdvantageousEndOfLineAtStartOfRace(){ + return new Pair<>(getWindwardDistanceToAdvantageousLineEndAtStartofRace().getMeters(), getRelativeDistanceToAdvantageousEndOfLineAtStartOfRace()); } @Override - public Double getRelativeDistanceToAdvantageousEndOfLine() { + public Double getRelativeDistanceToAdvantageousEndOfLineAtStartOfRace() { TrackedRace trackedRace = getTrackedRace(); TimePoint startOfRace = trackedRace.getStartOfRace(); LineDetails startLine = trackedRace.getStartLine(startOfRace); From 5ed0f14196c2bea1d96e049772eb1c0f8e6c1be9 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Wed, 2 May 2018 14:57:46 +1000 Subject: [PATCH 35/38] Adjusted release_notes_admin.html --- java/com.sap.sailing.www/release_notes_admin.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/com.sap.sailing.www/release_notes_admin.html b/java/com.sap.sailing.www/release_notes_admin.html index cf105cfbc0e..745afc92082 100755 --- a/java/com.sap.sailing.www/release_notes_admin.html +++ b/java/com.sap.sailing.www/release_notes_admin.html @@ -35,6 +35,8 @@ Previously it was only possible to import a new event structure.
  • The Expedition log file import now prefers "GPS Time" for time stamping over "Utc" and over other date / time formats, making it more consistent with the Expedition live connector which uses column 146 for time stamping which is GPS Time.
  • +
  • Two dimensional metrics can now be displayed by using a scatter plot presenter within the data mining tool. + Select a metric that returns a pair of numbers and choose "Average" or "Identity" as an aggregator.
  • March 2018

    From d81dbc5acc0a037ad1ddcaa6a360ea683ac57555 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 3 May 2018 12:54:09 +1000 Subject: [PATCH 36/38] Added statistic ManeuverLossVsWindSpeed. Removed unused variable. --- .../stringmessages/Sailing_StringMessages.properties | 1 + .../stringmessages/Sailing_StringMessages_de.properties | 1 + .../sap/sailing/datamining/data/HasManeuverContext.java | 4 ++++ .../sailing/datamining/impl/data/ManeuverWithContext.java | 7 +++++++ .../impl/data/TrackedLegOfCompetitorWithContext.java | 1 - 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index 257e3255ecb..ead318c8ec3 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -82,6 +82,7 @@ NumberOfCompetitorFixes=Number of Competitor Fixes NumberOfMarkFixes=Number of Mark Fixes ManeuverType=Maneuver Type Tack=Tack +ManeuverLossVsWindSpeed=Maneuver Loss in Meters (X) vs. Wind Speed in Knots (Y) SpeedBefore=Speed Before Maneuver SpeedAfter=Speed After Maneuver DirectionChange=Direction Change in Degrees diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index 083af2b4533..f5c566f705d 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -100,6 +100,7 @@ RankAfterHalfOfTheFirstLeg=Platzierung nach der Hälfte des ersten Schenkels AdvantageousEndOfLine=Bevorteiltes Ende der Startlinie TimeSpentInSeconds=Benötigte Zeit in Sekunden MedalRace=Medaillenrennen +ManeuverLossVsWindSpeed=Manöververlust in Meter (X) vs. Windgeschwindigkeit in Knoten (Y) WindSourceType=Art der Windmessung WindSourceName=Name der Windmessreihe windFrom=Wind aus Richtung (TWD) diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasManeuverContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasManeuverContext.java index 80a1ba25114..57da75631bf 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasManeuverContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasManeuverContext.java @@ -4,6 +4,7 @@ import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.ManeuverType; import com.sap.sailing.domain.common.Tack; import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util.Pair; import com.sap.sse.datamining.annotations.Connector; import com.sap.sse.datamining.annotations.Dimension; import com.sap.sse.datamining.annotations.Statistic; @@ -26,6 +27,9 @@ public interface HasManeuverContext extends HasManeuver, HasTrackedLegOfCompetit @Statistic(messageKey = "ManeuverLoss", resultDecimals = 0, ordinal = 4) Distance getManeuverLoss(); + + @Statistic(messageKey = "ManeuverLossVsWindSpeed", resultDecimals = 2, ordinal = 4) + Pair getManeuverLossVsWindSpeed(); @Statistic(messageKey = "AbsTWAAtManeuverClimax", ordinal = 7) Double getAbsTWAAtManeuverClimax(); diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/ManeuverWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/ManeuverWithContext.java index f7190c98f7d..b94202dfe54 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/ManeuverWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/ManeuverWithContext.java @@ -14,6 +14,7 @@ import com.sap.sailing.domain.tracking.Maneuver; import com.sap.sailing.domain.tracking.ManeuverCurveBoundaries; import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sse.common.TimePoint; +import com.sap.sse.common.Util.Pair; /** * @@ -64,6 +65,7 @@ public class ManeuverWithContext implements HasManeuverContext { public ManeuverType getTypeOfNextManeuver() { return nextManeuver != null ? nextManeuver.getType() : ManeuverType.UNKNOWN; } + @Override public Double getManeuverEnteringSpeed() { @@ -142,6 +144,11 @@ public class ManeuverWithContext implements HasManeuverContext { } return null; } + + public Pair getManeuverLossVsWindSpeed(){ + Wind wind = getTrackedLegOfCompetitorContext().getTrackedRace().getWind(maneuver.getPosition(), getTimePointBeforeForAnalysis()); + return new Pair<>(getManeuverLoss().getMeters(), wind.getKnots()); + } @Override public Double getEnteringManeuverSpeedMinusExitingSpeed() { diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedLegOfCompetitorWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedLegOfCompetitorWithContext.java index 85cb74f06cd..cb44dacb1d4 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedLegOfCompetitorWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedLegOfCompetitorWithContext.java @@ -126,7 +126,6 @@ public class TrackedLegOfCompetitorWithContext implements HasTrackedLegOfCompeti return null; } else { final Leg lastLeg = legs.get(legs.size() - 1); - GPSFixTrack track = getTrackedRace().getTrack(getCompetitor()); TimePoint finished = getTrackedRace().getTrackedLeg(getCompetitor(), lastLeg).getFinishTime(); return getTrackedRace().getAverageSpeedOverGround(getCompetitor(), finished).getKnots(); } From fa1e88227ebf55041ced8164a1ab5c25a8d03097 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 3 May 2018 13:40:16 +1000 Subject: [PATCH 37/38] Reflect grouping to selected dimensions. --- .../presentation/NumberPairResultsPresenter.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java index e39d28874dd..37f805ddf22 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/NumberPairResultsPresenter.java @@ -125,12 +125,7 @@ public class NumberPairResultsPresenter extends AbstractResultsPresenter subKeys = GroupKey.Util.getSubKeys(groupKey); - return subKeys.size() == 1 ? subKeys.get(0) : new CompoundGroupKey(subKeys); - } else { - return simpleResultSeriesKey; - } + return new CompoundGroupKey(groupKey.getKeys()); } From 3222a73ce8e86cc7548395b74a8c3696df2f5238 Mon Sep 17 00:00:00 2001 From: Leon Radeck Date: Thu, 3 May 2018 15:56:40 +1000 Subject: [PATCH 38/38] Changed metric ManeuverLossVsWindSpeed to WindSpeedVsManeuverLoss --- .../stringmessages/Sailing_StringMessages.properties | 2 +- .../stringmessages/Sailing_StringMessages_de.properties | 2 +- .../com/sap/sailing/datamining/data/HasManeuverContext.java | 4 ++-- .../sap/sailing/datamining/impl/data/ManeuverWithContext.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties index ead318c8ec3..65084d8084a 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties @@ -82,7 +82,7 @@ NumberOfCompetitorFixes=Number of Competitor Fixes NumberOfMarkFixes=Number of Mark Fixes ManeuverType=Maneuver Type Tack=Tack -ManeuverLossVsWindSpeed=Maneuver Loss in Meters (X) vs. Wind Speed in Knots (Y) +WindSpeedVsManeuverLoss=Wind Speed in Knots (X) vs. Maneuver Loss in Meters (Y) SpeedBefore=Speed Before Maneuver SpeedAfter=Speed After Maneuver DirectionChange=Direction Change in Degrees diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties index f5c566f705d..2ef0edf2761 100644 --- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties +++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties @@ -100,7 +100,7 @@ RankAfterHalfOfTheFirstLeg=Platzierung nach der Hälfte des ersten Schenkels AdvantageousEndOfLine=Bevorteiltes Ende der Startlinie TimeSpentInSeconds=Benötigte Zeit in Sekunden MedalRace=Medaillenrennen -ManeuverLossVsWindSpeed=Manöververlust in Meter (X) vs. Windgeschwindigkeit in Knoten (Y) +WindSpeedVsManeuverLoss=Windgeschwindigkeit in Knoten (X) vs. Manöververlust in Meter (Y) WindSourceType=Art der Windmessung WindSourceName=Name der Windmessreihe windFrom=Wind aus Richtung (TWD) diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasManeuverContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasManeuverContext.java index 57da75631bf..4f2b52a5fbb 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasManeuverContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasManeuverContext.java @@ -28,8 +28,8 @@ public interface HasManeuverContext extends HasManeuver, HasTrackedLegOfCompetit @Statistic(messageKey = "ManeuverLoss", resultDecimals = 0, ordinal = 4) Distance getManeuverLoss(); - @Statistic(messageKey = "ManeuverLossVsWindSpeed", resultDecimals = 2, ordinal = 4) - Pair getManeuverLossVsWindSpeed(); + @Statistic(messageKey = "WindSpeedVsManeuverLoss", resultDecimals = 2, ordinal = 4) + Pair getWindSpeedVsManeuverLoss(); @Statistic(messageKey = "AbsTWAAtManeuverClimax", ordinal = 7) Double getAbsTWAAtManeuverClimax(); diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/ManeuverWithContext.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/ManeuverWithContext.java index b94202dfe54..8c6d72f6325 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/ManeuverWithContext.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/ManeuverWithContext.java @@ -145,9 +145,9 @@ public class ManeuverWithContext implements HasManeuverContext { return null; } - public Pair getManeuverLossVsWindSpeed(){ + public Pair getWindSpeedVsManeuverLoss(){ Wind wind = getTrackedLegOfCompetitorContext().getTrackedRace().getWind(maneuver.getPosition(), getTimePointBeforeForAnalysis()); - return new Pair<>(getManeuverLoss().getMeters(), wind.getKnots()); + return new Pair<>(wind.getKnots(), getManeuverLoss().getMeters()); } @Override