Merge remote-tracking branch 'origin/bug4614'

This commit is contained in:
Alessandro Stoltenberg
2018-07-06 10:51:20 +02:00
3 changed files with 124 additions and 93 deletions
@@ -9,11 +9,9 @@ import java.util.function.Function;
import java.util.function.Supplier;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell.Context;
import com.google.gwt.cell.client.DateCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.i18n.shared.DateTimeFormat;
import com.google.gwt.i18n.shared.DateTimeFormat.PredefinedFormat;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
@@ -42,14 +40,11 @@ import com.sap.sailing.gwt.ui.actions.GetManeuversForCompetitorsAction;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider;
import com.sap.sailing.gwt.ui.client.ManeuverTypeFormatter;
import com.sap.sailing.gwt.ui.client.NumberFormatterFactory;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.controls.AbstractSortableColumnWithMinMax;
import com.sap.sailing.gwt.ui.client.shared.controls.SortableColumn;
import com.sap.sailing.gwt.ui.leaderboard.HasStringAndDoubleValue;
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel.LeaderBoardStyle;
import com.sap.sailing.gwt.ui.leaderboard.MinMaxRenderer;
import com.sap.sailing.gwt.ui.leaderboard.SortedCellTableWithStylableHeaders;
import com.sap.sailing.gwt.ui.shared.ManeuverDTO;
import com.sap.sse.common.TimeRange;
@@ -82,8 +77,6 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable
private final StringMessages stringMessages;
private final CompetitorSelectionProvider competitorSelectionModel;
private final NumberFormat towDigitAccuracy = NumberFormatterFactory.getDecimalFormat(2);
private final SimplePanel contentPanel = new SimplePanel();
private final Label importantMessageLabel = new Label();
private final SortedCellTableWithStylableHeaders<ManeuverTableData> maneuverCellTable;
@@ -162,84 +155,31 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable
this.stringMessages.avgTurningRate(), this.stringMessages.degreesPerSecondUnit()));
this.maneuverCellTable.addColumn(createSortableMinMaxColumn(ManeuverTableData::getManeuverLoss,
this.stringMessages.maneuverLoss(), stringMessages.metersUnit()));
this.maneuverCellTable.addColumn(createSortableMinMaxColumn(ManeuverTableData::getDirectionChange,
this.maneuverCellTable.addColumn(createSortableAbsMinMaxColumn(ManeuverTableData::getDirectionChange,
stringMessages.directionChange(), this.stringMessages.degreesShort()));
initWidget(rootPanel);
setVisible(false);
}
/**
* Creates a sortable column with the absolute value. Whereas {@link #createSortableMinMaxColumn()} creates a
* sortable column with signed values.
*/
private SortableColumn<ManeuverTableData, String> createSortableAbsMinMaxColumn(
Function<ManeuverTableData, Double> extractor, String title, String unit) {
return new SortableMinMaxColumn(extractor, title, unit, maneuverCellTable.getDataProvider(), /* absolute */ true);
}
/**
* Creates a sortable column with signed values.
*/
private SortableColumn<ManeuverTableData, String> createSortableMinMaxColumn(
Function<ManeuverTableData, Double> extractor, String title, String unit) {
final SortableColumn<ManeuverTableData, String> col = new AbstractSortableColumnWithMinMax<ManeuverTableData, String>(
new TextCell(), SortingOrder.ASCENDING) {
final InvertibleComparator<ManeuverTableData> comparatorWithAbs = new InvertibleComparatorAdapter<ManeuverTableData>() {
@Override
public int compare(ManeuverTableData o1, ManeuverTableData o2) {
Double o1v = extractor.apply(o1);
Double o2v = extractor.apply(o2);
if (o1v == null && o2v == null) {
return 0;
}
if (o1v == null && o2v != null) {
return -1;
}
if (o1v != null && o2v == null) {
return 1;
}
return Double.compare(Math.abs(o1v), Math.abs(o2v));
}
};
final HasStringAndDoubleValue<ManeuverTableData> dataProvider = new HasStringAndDoubleValue<ManeuverTableData>() {
@Override
public String getStringValueToRender(ManeuverTableData row) {
Double value = extractor.apply(row);
if (value == null) {
return null;
}
return towDigitAccuracy.format(value);
}
@Override
public Double getDoubleValue(ManeuverTableData row) {
Double value = extractor.apply(row);
return value == null ? null : Math.abs(value);
}
};
final MinMaxRenderer<ManeuverTableData> renderer = new MinMaxRenderer<ManeuverTableData>(dataProvider, comparatorWithAbs);
@Override
public InvertibleComparator<ManeuverTableData> getComparator() {
return comparatorWithAbs;
}
@Override
public void render(Context context, ManeuverTableData object, SafeHtmlBuilder sb) {
renderer.render(context, object, title, sb);
}
@Override
public Header<?> getHeader() {
return new TextHeader(title + " [" + unit + "]");
}
@Override
public String getValue(ManeuverTableData object) {
return dataProvider.getStringValueToRender(object);
}
@Override
public void updateMinMax() {
renderer.updateMinMax(maneuverCellTable.getDataProvider().getList());
}
};
col.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
return col;
return new SortableMinMaxColumn(extractor, title, unit, maneuverCellTable.getDataProvider(), /* absolute */ false);
}
private SortableColumn<ManeuverTableData, String> createManeuverTypeColumn() {
return new SortableColumn<ManeuverTableData, String>(new TextCell(), SortingOrder.ASCENDING) {
@Override
public InvertibleComparator<ManeuverTableData> getComparator() {
return new InvertibleComparatorAdapter<ManeuverTableData>() {
@@ -269,7 +209,6 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable
return o1.getTimePoint().compareTo(o2.getTimePoint());
}
};
final SortableColumn<ManeuverTableData, Date> col = new SortableColumn<ManeuverTableData, Date>(
new DateCell(DateTimeFormat.getFormat(PredefinedFormat.TIME_LONG)), SortingOrder.ASCENDING) {
@Override
@@ -297,7 +236,6 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable
return -Boolean.compare(o1.isMarkPassing(), o2.isMarkPassing());
}
};
final SortableColumn<ManeuverTableData, Boolean> column = new SortableColumn<ManeuverTableData, Boolean>(
new AbstractCell<Boolean>() {
@Override
@@ -332,9 +270,7 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable
return o1.getCompetitorName().compareTo(o2.getCompetitorName());
}
};
return new SortableColumn<ManeuverTableData, String>(new TextCell(), SortingOrder.ASCENDING) {
@Override
public InvertibleComparator<ManeuverTableData> getComparator() {
return comparator;
@@ -0,0 +1,94 @@
package com.sap.sailing.gwt.ui.client.shared.racemap.maneuver;
import java.util.Comparator;
import java.util.function.Function;
import com.google.gwt.cell.client.Cell.Context;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.Header;
import com.google.gwt.user.cellview.client.TextHeader;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.view.client.ListDataProvider;
import com.sap.sailing.domain.common.InvertibleComparator;
import com.sap.sailing.domain.common.SortingOrder;
import com.sap.sailing.domain.common.impl.InvertibleComparatorAdapter;
import com.sap.sailing.gwt.ui.client.NumberFormatterFactory;
import com.sap.sailing.gwt.ui.client.shared.controls.AbstractSortableColumnWithMinMax;
import com.sap.sailing.gwt.ui.leaderboard.HasStringAndDoubleValue;
import com.sap.sailing.gwt.ui.leaderboard.MinMaxRenderer;
public class SortableMinMaxColumn extends AbstractSortableColumnWithMinMax<ManeuverTableData, String> {
private final static NumberFormat TWO_DIGIT_ACCURACY = NumberFormatterFactory.getDecimalFormat(2);
private final String title;
private final String unit;
final InvertibleComparator<ManeuverTableData> comparator;
final HasStringAndDoubleValue<ManeuverTableData> dataProvider;
final MinMaxRenderer<ManeuverTableData> renderer;
final ListDataProvider<ManeuverTableData> maneuverTableListDataProvider;
public SortableMinMaxColumn(final Function<ManeuverTableData, Double> extractor, String title, String unit,
ListDataProvider<ManeuverTableData> maneuverTableListDataProvider, boolean absolute) {
super(new TextCell(), SortingOrder.ASCENDING);
this.title = title;
this.unit = unit;
this.maneuverTableListDataProvider = maneuverTableListDataProvider;
this.comparator = new InvertibleComparatorAdapter<ManeuverTableData>() {
@Override
public int compare(ManeuverTableData o1, ManeuverTableData o2) {
Double o1v = extractor.apply(o1);
Double o2v = extractor.apply(o2);
return Comparator.nullsFirst((Double v1, Double v2)->Double.compare(absolute?Math.abs(v1):v1, absolute?Math.abs(v2):v2)).compare(o1v, o2v);
}
};
this.dataProvider = new HasStringAndDoubleValue<ManeuverTableData>() {
@Override
public String getStringValueToRender(ManeuverTableData row) {
Double value = extractor.apply(row);
if (value == null) {
return null;
}
return TWO_DIGIT_ACCURACY.format(value);
}
@Override
public Double getDoubleValue(ManeuverTableData row) {
Double value = extractor.apply(row);
return value == null ? null : absolute ? Math.abs(value) : value;
}
};
this.renderer = new MinMaxRenderer<ManeuverTableData>(dataProvider, comparator);
this.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
}
@Override
public InvertibleComparator<ManeuverTableData> getComparator() {
return comparator;
}
@Override
public void render(Context context, ManeuverTableData object, SafeHtmlBuilder sb) {
renderer.render(context, object, title, sb);
}
@Override
public Header<?> getHeader() {
return new TextHeader(title + " [" + unit + "]");
}
@Override
public String getValue(ManeuverTableData object) {
return dataProvider.getStringValueToRender(object);
}
@Override
public void updateMinMax() {
renderer.updateMinMax(maneuverTableListDataProvider.getList());
}
}
@@ -26,6 +26,7 @@ public class MinMaxRenderer<T> {
protected static final String BACKGROUND_BAR_STYLE_GOOD = "minMaxBackgroundBarGood";
private final HasStringAndDoubleValue<T> valueProvider;
/** used to determine minimum and maximum values for the rendered bars.*/
private final Comparator<T> comparator;
private Double minimumValue;
private Double maximumValue;
@@ -119,7 +120,8 @@ public class MinMaxRenderer<T> {
* @param row
* The row to get the percentage for.
*/
protected int getPercentage(T row) {
protected int getPercentage(T row) {
int percentage = 0;
Double value = valueProvider.getDoubleValue(row);
if (value != null) {
@@ -128,10 +130,8 @@ public class MinMaxRenderer<T> {
percentage = (int) (minBarLength + (100. - minBarLength) * (value - getMinimumDouble())
/ (getMaximumDouble() - getMinimumDouble()));
}
}
}
return percentage;
}
private Double getMinimumDouble() {
@@ -149,23 +149,24 @@ public class MinMaxRenderer<T> {
* The values of {@link LeaderboardRowDTO}s to determine the minimum and maximum values for.
*/
public void updateMinMax(Iterable<T> displayedLeaderboardRowsProvider) {
T minimumRow = null;
T maximumRow = null;
T minimumOrderRow = null;
T maximumOrderRow = null;
for (T row : displayedLeaderboardRowsProvider) {
if (valueProvider.getDoubleValue(row) != null
&& (minimumRow == null || comparator.compare(minimumRow, row) > 0)) {
minimumRow = row;
&& (minimumOrderRow == null || comparator.compare(minimumOrderRow, row) > 0)) {
minimumOrderRow = row;
}
if (valueProvider.getDoubleValue(row) != null
&& (maximumRow == null || comparator.compare(maximumRow, row) < 0)) {
maximumRow = row;
&& (maximumOrderRow == null || comparator.compare(maximumOrderRow, row) < 0)) {
maximumOrderRow = row;
}
}
if (minimumOrderRow != null) {
minimumValue = valueProvider.getDoubleValue(minimumOrderRow);
}
if (minimumRow != null) {
minimumValue = valueProvider.getDoubleValue(minimumRow);
}
if (maximumRow != null) {
maximumValue = valueProvider.getDoubleValue(maximumRow);
if (maximumOrderRow != null) {
maximumValue = valueProvider.getDoubleValue(maximumOrderRow);
}
}