Added error messages with helping hints

This commit is contained in:
Lennart Hensler committed 2013-10-07 13:01:36 +02:00
1 parent 8604cf83e6
commit 2035eb3832
14 files changed
+147 -78

No files matched your search

@@ -8,7 +8,7 @@ public interface QueryResult<AggregatedType> extends Serializable {
int getRetrievedDataAmount();
public int getFilteredDataAmount();
public double getCalculationTimeInSeconds();
public boolean isEmpty();
/**
* @return a description what kind of results are contained.
@@ -11,8 +11,8 @@ public class QueryResultImpl<AggregatedType> implements QueryResult<AggregatedTy
private long calculationTimeInNanos;
private String resultSignifier;
private Unit unit;
private int valueDecimals;
private Unit unit;
private int valueDecimals;
private Map<GroupKey, AggregatedType> results;
@@ -50,6 +50,11 @@ public class QueryResultImpl<AggregatedType> implements QueryResult<AggregatedTy
this.calculationTimeInNanos = calculationTimeInNanos;
}
@Override
public boolean isEmpty() {
return results.isEmpty();
}
@Override
public String getResultSignifier() {
return resultSignifier;
+1 -1
View File
@@ -167,7 +167,7 @@ input.magnifier {
height: 70px;
margin: 0 auto;
padding: 49px 0 0 80px;
width: 300px;
width: 400px;
color: #7c7c7c;
background: url(images/important-message.png) left center no-repeat;
}
@@ -769,4 +769,9 @@ public interface StringMessages extends Messages {
String queryResultsChartSubtitle(int retrievedDataAmount, int filteredDataAmount, double calculationTime);
String noQuerySelected();
String runAutomatically();
String noStatisticSelectedError();
String noCustomGrouperScriptTextError();
String noDimensionToGroupBySelectedError();
String noGrouperSelectedError();
String queryNotValidBecause();
}
@@ -762,4 +762,9 @@ groupBy=Group by
statisticToCalculate=Calculate statistic
queryResultsChartSubtitle=Worked through {1}/{0} data entries in {2} seconds
noQuerySelected=No query selected
runAutomatically=Run automatically
runAutomatically=Run automatically
noStatisticSelectedError=No statistic to calculate is selected
noCustomGrouperScriptTextError=The grouper script is empty
noDimensionToGroupBySelectedError=No dimension to group by is selected
noGrouperSelectedError=No grouper type is selected
queryNotValidBecause=No query possible, because
@@ -758,4 +758,9 @@ groupBy=Gruppieren nach
statisticToCalculate=Berechne Kennzahl
queryResultsChartSubtitle=Es wurden {1}/{0} Datensätze in {2} Sekunden verarbeitet
noQuerySelected=Keine Abfrage ausgewählt
runAutomatically=Automatisch ausführen
runAutomatically=Automatisch ausführen
noStatisticSelectedError=Keine zu berechnende Kennzahl ausgewählt ist
noCustomGrouperScriptTextError=Das Grouper-Skript leer ist
noDimensionToGroupBySelectedError=Keine Gruppierungs-Dimension ausgewählt ist
noGrouperSelectedError=Kein Gruppierungs-Typ ausgewählt ist
queryNotValidBecause=Keine Datenabfrage möglich, da
@@ -1,5 +1,7 @@
package com.sap.sailing.gwt.ui.datamining;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
@@ -25,25 +27,34 @@ public abstract class AbstractQueryComponentsProvider<DimensionType> extends Flo
listeners = new HashSet<QueryComponentsChangedListener<DimensionType>>();
}
@Override
public boolean areComponentsValid() {
return isGrouperValid() && isStatisticToCalculateValid() && isAggregatorValid();
public Iterable<String> validateComponents() {
Collection<String> errorMessages = new ArrayList<String>();
String grouperError = validateGrouper();
if (grouperError != null && !grouperError.isEmpty()) {
errorMessages.add(grouperError);
}
String statisticError = validateStatisticAndAggregator();
if (statisticError != null && !statisticError.isEmpty()) {
errorMessages.add(statisticError);
}
return errorMessages;
}
private boolean isAggregatorValid() {
return getAggregatorType() != null;
}
private boolean isStatisticToCalculateValid() {
return getStatisticToCalculate() != null;
}
private boolean isGrouperValid() {
ValidateGrouper: switch (getGrouperType()) {
private String validateGrouper() {
GrouperType grouper = getGrouperType();
if (grouper == null) {
return stringMessages.noGrouperSelectedError();
}
ValidateGrouper: switch (grouper) {
case Custom:
if (getCustomGrouperScriptText().isEmpty()) {
return false;
return stringMessages.noCustomGrouperScriptTextError();
}
break;
case Dimensions:
@@ -52,14 +63,20 @@ public abstract class AbstractQueryComponentsProvider<DimensionType> extends Flo
break ValidateGrouper;
}
}
return false;
return stringMessages.noDimensionToGroupBySelectedError();
default:
return false;
return stringMessages.noGrouperSelectedError();
}
return true;
return null;
}
private String validateStatisticAndAggregator() {
return getStatisticAndAggregatorType() == null ? stringMessages.noStatisticSelectedError() : null;
}
protected abstract StatisticAndAggregatorType getStatisticAndAggregatorType();
@Override
public void addListener(QueryComponentsChangedListener<DimensionType> listener) {
listeners.add(listener);
@@ -23,45 +23,48 @@ public abstract class AbstractResultsPanel<DimensionType, ResultType> extends Fl
private QueryComponentsProvider<DimensionType> queryComponentsProvider;
private Label queryStatusLabel;
private ResultsPresentator<ResultType> presentator;
private ResultsPresenter<ResultType> presenter;
private Button runQueryButton;
public AbstractResultsPanel(StringMessages stringMessages, SailingServiceAsync sailingService,
ErrorReporter errorReporter, QueryComponentsProvider<DimensionType> queryComponentsProvider, ResultsPresentator<ResultType> presentator) {
ErrorReporter errorReporter, QueryComponentsProvider<DimensionType> queryComponentsProvider, ResultsPresenter<ResultType> presenter) {
super();
this.stringMessages = stringMessages;
this.sailingService = sailingService;
this.errorReporter = errorReporter;
this.queryComponentsProvider = queryComponentsProvider;
this.presenter = presenter;
add(createFunctionsPanel());
this.presentator = presentator;
add(this.presentator.getWidget());
add(this.presenter.getWidget());
runQuery();
}
@Override
public void queryComponentsChanged(QueryComponentsProvider<DimensionType> componentsProvider) {
if (componentsProvider.areComponentsValid()) {
runQuery();
} else {
//TODO Display error message
}
runQuery();
}
private void runQuery() {
queryStatusLabel.setText(" | " + stringMessages.running());
sendServerRequest(new AsyncCallback<QueryResult<ResultType>>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error running the query: " + caught.getMessage());
}
@Override
public void onSuccess(QueryResult<ResultType> result) {
queryStatusLabel.setText(" | " + stringMessages.done());
presentator.showResult(result);
}
});
Iterable<String> errorMessages = queryComponentsProvider.validateComponents();
if (errorMessages == null || !errorMessages.iterator().hasNext()) {
queryStatusLabel.setText(" | " + stringMessages.running());
sendServerRequest(new AsyncCallback<QueryResult<ResultType>>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error running the query: " + caught.getMessage());
}
@Override
public void onSuccess(QueryResult<ResultType> result) {
queryStatusLabel.setText(" | " + stringMessages.done());
presenter.showResult(result);
}
});
} else {
presenter.showError(stringMessages.queryNotValidBecause(), errorMessages);
}
}
protected abstract void sendServerRequest(AsyncCallback<QueryResult<ResultType>> asyncCallback);
@@ -12,7 +12,7 @@ public class DataMiningPanel extends FlowPanel {
GPSFixQueryComponentsPanel selectionPanel = new GPSFixQueryComponentsPanel(stringMessages, sailingService, errorReporter);
this.add(selectionPanel);
ResultsPresentator<Number> resultsChart = new ResultsChart(stringMessages);
ResultsPresenter<Number> resultsChart = new ResultsChart(stringMessages);
GPSFixResultsPanel queryPanel = new GPSFixResultsPanel(stringMessages, sailingService, errorReporter, selectionPanel, resultsChart);
this.add(queryPanel);
@@ -112,6 +112,11 @@ public class GPSFixQueryComponentsPanel extends AbstractQueryComponentsProvider<
return dimensionsToGroupBy;
}
@Override
protected StatisticAndAggregatorType getStatisticAndAggregatorType() {
return statisticsListBox.getValue();
}
@Override
public StatisticType getStatisticToCalculate() {
return statisticsListBox.getValue().getStatisticType();
@@ -266,13 +271,15 @@ public class GPSFixQueryComponentsPanel extends AbstractQueryComponentsProvider<
grouperTypeListBox.addValueChangeHandler(new ValueChangeHandler<GrouperType>() {
@Override
public void onValueChange(ValueChangeEvent<GrouperType> event) {
switch (event.getValue()) {
case Custom:
groupByOptionsPanel.showWidget(1);
break;
case Dimensions:
groupByOptionsPanel.showWidget(0);
break;
if (event.getValue() != null) {
switch (event.getValue()) {
case Custom:
groupByOptionsPanel.showWidget(1);
break;
case Dimensions:
groupByOptionsPanel.showWidget(0);
break;
}
}
notifyQueryComponentsChanged();
}
@@ -17,8 +17,8 @@ import com.sap.sailing.gwt.ui.datamining.QueryComponentsProvider.GrouperType;
public class GPSFixResultsPanel extends AbstractResultsPanel<SharedDimensions.GPSFix, Number> {
public GPSFixResultsPanel(StringMessages stringMessages, SailingServiceAsync sailingService,
ErrorReporter errorReporter, QueryComponentsProvider<SharedDimensions.GPSFix> queryComponentsProvider, ResultsPresentator<Number> presentator) {
super(stringMessages, sailingService, errorReporter, queryComponentsProvider, presentator);
ErrorReporter errorReporter, QueryComponentsProvider<SharedDimensions.GPSFix> queryComponentsProvider, ResultsPresenter<Number> presenter) {
super(stringMessages, sailingService, errorReporter, queryComponentsProvider, presenter);
}
@Override
@@ -10,7 +10,7 @@ public interface QueryComponentsProvider<DimensionType> {
public enum GrouperType { Dimensions, Custom }
public boolean areComponentsValid();
public Iterable<String> validateComponents();
public Map<DimensionType, Collection<?>> getSelection();
@@ -20,7 +20,7 @@ import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsFormatter;
import org.moxieapps.gwt.highcharts.client.labels.XAxisLabels;
import org.moxieapps.gwt.highcharts.client.labels.YAxisLabels;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
@@ -28,7 +28,7 @@ import com.sap.sailing.datamining.shared.GroupKey;
import com.sap.sailing.datamining.shared.QueryResult;
import com.sap.sailing.gwt.ui.client.StringMessages;
public class ResultsChart implements ResultsPresentator<Number>, RequiresResize {
public class ResultsChart implements ResultsPresenter<Number>, RequiresResize {
private StringMessages stringMessages;
private SimplePanel mainPanel;
@@ -39,37 +39,56 @@ public class ResultsChart implements ResultsPresentator<Number>, RequiresResize
private Map<GroupKey, Integer> mainKeyToValueMap;
private Map<Integer, GroupKey> valueToGroupKeyMap;
private Label noQuerySelectedLabel;
private HTML errorLabel;
public ResultsChart(StringMessages stringMessages) {
super();
this.stringMessages = stringMessages;
mainPanel = new SimplePanel();
series = new HashMap<GroupKey, Series>();
noQuerySelectedLabel = new Label(this.stringMessages.noQuerySelected() + ".");
noQuerySelectedLabel.setStyleName("chart-importantMessage");
errorLabel = new HTML();
errorLabel.setStyleName("chart-importantMessage");
createChart();
mainPanel.setWidget(noQuerySelectedLabel);
mainPanel.setWidget(chart);
}
@Override
public void showError(String error) {
errorLabel.setHTML(error);
mainPanel.setWidget(errorLabel);
}
@Override
public void showError(String mainError, Iterable<String> detailedErrors) {
StringBuilder errorBuilder = new StringBuilder(mainError + ":<br /><ul>");
for (String detailedError : detailedErrors) {
errorBuilder.append("<li>" + detailedError + "</li>");
}
errorBuilder.append("</ul>");
showError(errorBuilder.toString());
}
@Override
public void showResult(QueryResult<Number> result) {
reset();
updateYAxisLabels(result);
updateChartSubtitleAndSetChartAsWidget(result);
List<GroupKey> sortedKeys = getSortedKeysFrom(result);
buildGroupKeyValueMaps(sortedKeys);
if (resultHasComplexKeys(result)) {
displayComplexResult(result, sortedKeys);
if (!result.isEmpty()) {
resetChart();
updateYAxisLabels(result);
updateChartSubtitleAndSetChartAsWidget(result);
List<GroupKey> sortedKeys = getSortedKeysFrom(result);
buildGroupKeyValueMaps(sortedKeys);
if (resultHasComplexKeys(result)) {
displayComplexResult(result, sortedKeys);
} else {
displaySimpleResult(result, sortedKeys);
}
chart.redraw();
} else {
displaySimpleResult(result, sortedKeys);
showError(stringMessages.noDataFound() + ".");
}
chart.redraw();
}
private void updateYAxisLabels(QueryResult<? extends Number> result) {
@@ -152,7 +171,7 @@ public class ResultsChart implements ResultsPresentator<Number>, RequiresResize
return series.get(key);
}
private void reset() {
private void resetChart() {
chart.removeAllSeries(false);
series = new HashMap<GroupKey, Series>();
}
@@ -3,10 +3,13 @@ package com.sap.sailing.gwt.ui.datamining;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.datamining.shared.QueryResult;
public interface ResultsPresentator<ResultType> {
public interface ResultsPresenter<ResultType> {
public Widget getWidget();
public void showResult(QueryResult<ResultType> result);
public Widget getWidget();
public void showError(String error);
public void showError(String mainError, Iterable<String> detailedErrors);
}