Merge branch 'highcharts_version_update' of ssh://kielweek.web4sap.com/home/trac/git into highcharts_version_update

This commit is contained in:
Marcus Kammer committed 2012-05-23 15:03:25 +02:00
commit e08dbc5cd4
9 files changed
+408 -53

No files matched your search

@@ -61,12 +61,14 @@ public class TrackedRacesManagementPanel extends AbstractEventManagementPanel im
selectedRacePanel.setContentWidget(vPanel);
selectedRacePanel.setVisible(false);
raceDataGrid = new Grid(3,2);
raceDataGrid = new Grid(5,2);
vPanel.add(raceDataGrid);
raceDataGrid.setText(0, 0, "StartTime:");
raceDataGrid.setText(1, 0, "EndTime:");
raceDataGrid.setText(2, 0, "Duration:");
raceDataGrid.setText(3, 0, "Start of tracking:");
raceDataGrid.setText(4, 0, "End of tracking:");
}
@Override
@@ -117,6 +119,12 @@ public class TrackedRacesManagementPanel extends AbstractEventManagementPanel im
} else {
raceDataGrid.setText(2, 1, "");
}
if(selectedRaceDTO.startOfTracking != null) {
raceDataGrid.setText(3, 1, dateFormatter.render(selectedRaceDTO.startOfTracking) + " "
+ timeFormatter.render(selectedRaceDTO.startOfTracking));
} else {
raceDataGrid.setText(3, 1, "");
}
}
}
@@ -75,6 +75,14 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
}
}
@Override
public void onTimeZoom(Date zoomStartTimepoint, Date zoomEndTimepoint) {
}
@Override
public void onTimeZoomReset() {
}
@Override
protected boolean isLiveModeToBeMadePossible() {
long livePlayDelayInMillis = timer.getLivePlayDelayInMillis();
@@ -28,8 +28,10 @@ import com.sap.sailing.gwt.ui.shared.components.Component;
import com.sap.sailing.gwt.ui.shared.components.SettingsDialog;
import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent;
import com.sap.sailing.gwt.ui.shared.controls.slider.SliderBar;
import com.sap.sailing.gwt.ui.shared.controls.slider.TimeSlider;
public class TimePanel<T extends TimePanelSettings> extends FormPanel implements Component<T>, TimeListener, PlayStateListener, RequiresResize {
public class TimePanel<T extends TimePanelSettings> extends FormPanel implements Component<T>, TimeListener, TimeZoomChangeListener,
PlayStateListener, RequiresResize {
protected final Timer timer;
/**
@@ -105,7 +107,7 @@ public class TimePanel<T extends TimePanelSettings> extends FormPanel implements
playModeInactiveImg = resources.timesliderPlayStateLiveInactiveIcon();
playModeImage = new Image(playModeInactiveImg);
sliderBar = new SliderBar();
sliderBar = new TimeSlider();
sliderBar.setEnabled(true);
sliderBar.setLabelFormatter(new SliderBar.LabelFormatter() {
final DateTimeFormat formatter = DateTimeFormat.getFormat("HH:mm");
@@ -306,6 +308,7 @@ public class TimePanel<T extends TimePanelSettings> extends FormPanel implements
*/
public void setMinMax(Date min, Date max, boolean fireEvent) {
assert min != null && max != null;
boolean changed = false;
int numTicks = 8;
if (!max.equals(this.max)) {
@@ -381,6 +384,14 @@ public class TimePanel<T extends TimePanelSettings> extends FormPanel implements
}
}
@Override
public void onTimeZoom(Date zoomStartTimepoint, Date zoomEndTimepoint) {
}
@Override
public void onTimeZoomReset() {
}
protected boolean isLiveModeToBeMadePossible() {
return false;
}
@@ -1,7 +1,6 @@
package com.sap.sailing.gwt.ui.raceboard;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -12,7 +11,6 @@ import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.sap.sailing.domain.common.DefaultLeaderboardName;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.impl.Util.Pair;
import com.sap.sailing.gwt.ui.client.AbstractEntryPoint;
import com.sap.sailing.gwt.ui.client.ParallelExecutionCallback;
import com.sap.sailing.gwt.ui.client.ParallelExecutionHolder;
@@ -25,7 +23,6 @@ import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RaceDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.UserDTO;
import com.sap.sailing.gwt.ui.shared.panels.BreadcrumbPanel;
public class RaceBoardEntryPoint extends AbstractEntryPoint {
private RaceDTO selectedRace;
@@ -154,35 +151,6 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
return null;
}
private FlowPanel createBreadcrumbPanel() {
FlowPanel raceBoardHeaderPanel = new FlowPanel();
raceBoardHeaderPanel.addStyleName("RaceBoardHeaderPanel");
List<Pair<String, String>> links = new ArrayList<Pair<String, String>>();
String debugParam = Window.Location.getParameter("gwt.codesvr");
String root = Window.Location.getParameter("root");
if (leaderboardGroupName != null && !leaderboardGroupName.isEmpty()) {
if (root.equals("overview")) {
String link = "/gwt/Spectator.html"
+ (debugParam != null && !debugParam.isEmpty() ? "?gwt.codesvr=" + debugParam : "");
links.add(new Pair<String, String>(link, stringMessages.home()));
}
String link = "/gwt/Spectator.html?leaderboardGroupName=" + leaderboardGroupName
+ (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : "");
links.add(new Pair<String, String>(link, leaderboardGroupName));
}
if (leaderboardName != null && !leaderboardName.isEmpty()) {
String link = "/gwt/Leaderboard.html?name=" + leaderboardName
+ (leaderboardGroupName != null ? "&leaderboardGroupName=" + leaderboardGroupName : "")
+ "&root=" + root + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : "");
links.add(new Pair<String, String>(link, leaderboardName));
}
BreadcrumbPanel breadcrumbPanel = new BreadcrumbPanel(links, raceName);
raceBoardHeaderPanel.add(breadcrumbPanel);
return raceBoardHeaderPanel;
}
private FlowPanel createTimePanel(RaceBoardPanel raceBoardPanel) {
FlowPanel timeLineInnerBgPanel = new FlowPanel();
timeLineInnerBgPanel.addStyleName("timeLineInnerBgPanel");
@@ -261,8 +261,7 @@ public class RaceBoardPanel extends FormPanel implements RegattaDisplayer, RaceS
componentsNavigationPanel.add(checkBox);
}
private void addComponentAsToogleButtonToNavigationMenu(final ComponentViewer componentViewer,
public void addComponentAsToogleButtonToNavigationMenu(final ComponentViewer componentViewer,
final Component<?> component) {
final ToggleButton toggleButton = new ToggleButton(component.getLocalizedShortName(),
"\u2713 " + component.getLocalizedShortName());
@@ -136,8 +136,7 @@ public class WindChart extends RaceChart implements Component<WindChartSettings>
chart.getXAxis().setType(Axis.Type.DATE_TIME)
.setMaxZoom(60 * 1000) // 1 minute
.setAxisTitleText(stringMessages.time())
.setTickInterval(1000 * 60 * 10);
.setAxisTitleText(stringMessages.time());
chart.getXAxis().setLabels(new XAxisLabels().setFormatter(new AxisLabelsFormatter() {
@Override
public String format(AxisLabelsData axisLabelsData) {
@@ -322,7 +321,6 @@ public class WindChart extends RaceChart implements Component<WindChartSettings>
for (WindDTO wind : windTrackInfo.windFixes) {
Date windDate = new Date(wind.originTimepoint.longValue());
if (timeOfEarliestRequestInMillis == null || wind.timepoint<timeOfEarliestRequestInMillis) {
timeOfEarliestRequestInMillis = wind.originTimepoint;
}
@@ -210,37 +210,37 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
/**
* The elements used to display labels above the ticks.
*/
private List<Element> tickLabelElements = new ArrayList<Element>();
protected List<Element> tickLabelElements = new ArrayList<Element>();
/**
* The elements used to display the marker labels.
*/
private List<Element> markerLabelElements = new ArrayList<Element>();
protected List<Element> markerLabelElements = new ArrayList<Element>();
/**
* The formatter used to generate label text.
*/
private LabelFormatter tickLabelFormatter;
protected LabelFormatter tickLabelFormatter;
/**
* The line that the knob moves over.
*/
private Element lineElement;
protected Element lineElement;
/**
* The offset between the edge of the shell and the line.
*/
private int lineLeftOffset = 0;
protected int lineLeftOffset = 0;
/**
* The maximum slider value.
*/
private Double maxValue;
protected Double maxValue;
/**
* The minimum slider value.
*/
private Double minValue;
protected Double minValue;
/**
* The number of labels to show.
@@ -250,7 +250,7 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
/**
* The number of tick marks to show.
*/
private int numTicks = 0;
protected int numTicks = 0;
/**
* A bit indicating whether or not we are currently sliding the slider bar due to keyboard events.
@@ -265,7 +265,7 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
/**
* A bit indicating whether or not the slider is enabled
*/
private boolean enabled = true;
protected boolean enabled = true;
/**
* The images used with the sliding bar.
@@ -280,7 +280,7 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
/**
* The elements used to display tick marks, which are the vertical lines along the slider bar.
*/
private List<Element> tickElements = new ArrayList<Element>();
protected List<Element> tickElements = new ArrayList<Element>();
/**
* The elements used to display additional markers on the slider bar.
@@ -863,7 +863,7 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
/**
* Draw the labels along the line.
*/
private void drawTickLabels() {
protected void drawTickLabels() {
if (!isAttached() || !isMinMaxInitialized())
return;
@@ -921,7 +921,7 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
/**
* Draw the tick along the line.
*/
private void drawTicks() {
protected void drawTicks() {
if (!isAttached() || !isMinMaxInitialized())
return;
@@ -1099,7 +1099,7 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
* the mouse event
*/
private void slideKnob(Event event) {
//Adding scrollLeft to adjust the position, if the user had scrolled with the lower scroll bar
// Adding scrollLeft to adjust the position, if the user had scrolled with the lower scroll bar
int x = DOM.eventGetClientX(event) + Window.getScrollLeft();
if (x > 0) {
int lineWidth = lineElement.getOffsetWidth();
@@ -0,0 +1,120 @@
package com.sap.sailing.gwt.ui.shared.controls.slider;
import java.util.List;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.sap.sailing.gwt.ui.shared.controls.slider.TimeTicksCalculator.NormalizedInterval;
import com.sap.sailing.gwt.ui.shared.controls.slider.TimeTicksCalculator.TickPosition;
public class TimeSlider extends SliderBar {
private final TimeTicksCalculator calc = new TimeTicksCalculator();
/**
* Draw the tick along the line.
*/
protected void drawTicks() {
if (!isAttached() || !isMinMaxInitialized())
return;
NormalizedInterval normalizedTimeTickInterval = calc.normalizeTimeTickInterval((maxValue.longValue() - minValue.longValue()) / 8);
List<TickPosition> calculatedTimeTicks = calc.calculateTimeTicks(normalizedTimeTickInterval, minValue.longValue(), maxValue.longValue(), 1);
// Draw the ticks
int lineWidth = lineElement.getOffsetWidth();
// Create the ticks or make them visible
for (int i = 0; i < calculatedTimeTicks.size(); i++) {
TickPosition tickPosition = calculatedTimeTicks.get(i);
Element tick = null;
if (i < tickElements.size()) {
tick = tickElements.get(i);
} else { // Create the new tick
tick = DOM.createDiv();
DOM.setStyleAttribute(tick, "position", "absolute");
DOM.setStyleAttribute(tick, "display", "none");
DOM.appendChild(getElement(), tick);
tickElements.add(tick);
}
if (enabled) {
DOM.setElementProperty(tick, "className", "gwt-SliderBar-tick");
} else {
DOM.setElementProperty(tick, "className", "gwt-SliderBar-tick gwt-SliderBar-tick-disabled");
}
// Position the tick and make it visible
DOM.setStyleAttribute(tick, "visibility", "hidden");
DOM.setStyleAttribute(tick, "display", "");
int tickWidth = tick.getOffsetWidth();
long pos = (tickPosition.time.getTime() - minValue.longValue()) * lineWidth / (maxValue.longValue() - minValue.longValue());
int tickLeftOffset = lineLeftOffset + (int) pos - (tickWidth / 2);
tickLeftOffset = Math.min(tickLeftOffset, lineLeftOffset + lineWidth - tickWidth);
DOM.setStyleAttribute(tick, "left", tickLeftOffset + "px");
DOM.setStyleAttribute(tick, "visibility", "visible");
}
// Hide unused ticks
for (int i = (calculatedTimeTicks.size() + 1); i < tickElements.size(); i++) {
DOM.setStyleAttribute(tickElements.get(i), "display", "none");
}
}
/**
* Draw the labels along the line.
*/
protected void drawTickLabels() {
if (!isAttached() || !isMinMaxInitialized())
return;
NormalizedInterval normalizedTimeTickInterval = calc.normalizeTimeTickInterval((maxValue.longValue() - minValue.longValue()) / 8);
List<TickPosition> calculatedTimeTicks = calc.calculateTimeTicks(normalizedTimeTickInterval, minValue.longValue(), maxValue.longValue(), 1);
// Draw the tick labels
int lineWidth = lineElement.getOffsetWidth();
// Create the labels or make them visible
for (int i = 0; i < calculatedTimeTicks.size(); i++) {
TickPosition tickPosition = calculatedTimeTicks.get(i);
Element label = null;
if (i < tickLabelElements.size()) {
label = tickLabelElements.get(i);
} else { // Create the new label
label = DOM.createDiv();
DOM.setStyleAttribute(label, "position", "absolute");
DOM.setStyleAttribute(label, "display", "none");
if (enabled) {
DOM.setElementProperty(label, "className", "gwt-SliderBar-ticklabel");
} else {
DOM.setElementProperty(label, "className", "gwt-SliderBar-ticklabel-disabled");
}
DOM.appendChild(getElement(), label);
tickLabelElements.add(label);
}
// Set the label text
double value = tickPosition.time.getTime();
DOM.setStyleAttribute(label, "visibility", "hidden");
DOM.setStyleAttribute(label, "display", "");
DOM.setElementProperty(label, "innerHTML", formatTickLabel(value));
// Move to the left so the label width is not clipped by the
// shell
DOM.setStyleAttribute(label, "left", "0px");
// Position the label and make it visible
int labelWidth = label.getOffsetWidth();
long pos = (tickPosition.time.getTime() - minValue.longValue()) * lineWidth / (maxValue.longValue() - minValue.longValue());
int labelLeftOffset = lineLeftOffset + (int) pos - (labelWidth / 2);
labelLeftOffset = Math.min(labelLeftOffset, lineLeftOffset + lineWidth - labelWidth);
labelLeftOffset = Math.max(labelLeftOffset, lineLeftOffset);
DOM.setStyleAttribute(label, "left", labelLeftOffset + "px");
DOM.setStyleAttribute(label, "visibility", "visible");
}
// Hide unused labels
for (int i = (calculatedTimeTicks.size() + 1); i < tickLabelElements.size(); i++) {
DOM.setStyleAttribute(tickLabelElements.get(i), "display", "none");
}
}
}
@@ -0,0 +1,243 @@
package com.sap.sailing.gwt.ui.shared.controls.slider;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class TimeTicksCalculator {
public TimeTicksCalculator() {
}
/**
* Get a normalized tick interval for dates. Returns a configuration object with unit range (interval), count and
* name. Used to prepare data for getTimeTicks. Previously this logic was part of getTimeTicks, but as getTimeTicks
* now runs of segments in stock charts, the normalizing logic was extracted in order to prevent it for running over
* again for each segment having the same interval.
*/
public NormalizedInterval normalizeTimeTickInterval(long tickInterval) {
TimeUnits[] units = TimeUnits.values();
TimeUnits unit = units[units.length - 1]; // default unit is years
long interval = unit.unitInMs;
int[] multiples = unit.allowedMultiples;
int count;
// loop through the units to find the one that best fits the tickInterval
for (int i = 0; i < units.length; i++) {
unit = units[i];
interval = unit.unitInMs;
multiples = unit.allowedMultiples;
if (i + 1 < units.length) {
// lessThan is in the middle between the highest multiple and the next unit.
long lessThan = (interval * multiples[multiples.length - 1] + units[i + 1].unitInMs) / 2;
// break and keep the current unit
if (tickInterval <= lessThan) {
break;
}
}
}
// prevent 2.5 years intervals, though 25, 250 etc. are allowed
if (interval == TimeUnits.YEAR.unitInMs && tickInterval < 5 * interval) {
multiples = new int[] { 1, 2, 5 };
}
// get the count
count = (int) normalizeTickInterval(tickInterval / interval, multiples, 1);
return new NormalizedInterval(unit.name(), interval, count);
}
/**
* Take an interval and normalize it to multiples of 1, 2, 2.5 and 5
*
* @param {Number} interval
* @param {Array} multiples
* @param {Number} magnitude
* @param {Object} options
*/
public long normalizeTickInterval(long interval, int[] multiples, int magnitude) {
long normalized;
// round to a tenfold of 1, 2, 2.5 or 5
normalized = interval / magnitude;
// multiples for a linear scale
if (magnitude == 1) {
multiples = new int[] { 1, 2, 5, 10 };
}
// normalize the interval to the nearest multiple
for (int i = 0; i < multiples.length; i++) {
interval = multiples[i];
int addedValue = i + 1 < multiples.length ? multiples[i + 1] : multiples[i];
if (normalized <= (multiples[i] + addedValue) / 2) {
break;
}
}
// multiply back to the correct magnitude
interval *= magnitude;
return interval;
}
private long makeTime(int year, int month) {
return makeTime(year, month, 1, 0, 0, 0);
}
private long makeTime(int year, int month, int date) {
return makeTime(year, month, date, 0, 0, 0);
}
@SuppressWarnings("deprecation")
private long makeTime(int year, int month, int date, int hours, int minutes, int seconds) {
return new Date(year, month, date, hours, minutes, seconds).getTime();
}
/**
* Set the tick positions to a time unit that makes sense, for example on the first of each month or on every
* Monday. Return an array with the time positions. Used in datetime axes as well as for grouping data on a datetime
* axis.
*
* @param {Object} normalizedInterval The interval in axis values (ms) and the count
* @param {Number} min The minimum in axis values
* @param {Number} max The maximum in axis values
* @param {Number} startOfWeek
*/
@SuppressWarnings("deprecation")
public List<TickPosition> calculateTimeTicks(NormalizedInterval normalizedInterval, long min, long max,
long startOfWeek) {
List<TickPosition> tickPositions = new ArrayList<TickPosition>();
int i;
boolean useUTC = true;
int minYear = 0; // used in months and years as a basis for Date.UTC()
Date minDate = new Date(min);
long interval = normalizedInterval.unitRange;
int count = (int) normalizedInterval.count;
if (interval >= TimeUnits.SECOND.unitInMs) { // second
minDate.setTime(min - (min % 1000));
minDate.setSeconds(interval >= TimeUnits.MINUTE.unitInMs ? 0 : count
* Math.round(minDate.getSeconds() / count));
}
if (interval >= TimeUnits.MINUTE.unitInMs) { // minute
minDate.setMinutes(interval >= TimeUnits.HOUR.unitInMs ? 0 : count
* Math.round(minDate.getMinutes() / count));
}
if (interval >= TimeUnits.HOUR.unitInMs) { // hour
minDate.setHours(interval >= TimeUnits.DAY.unitInMs ? 0 : count * Math.round(minDate.getHours() / count));
}
if (interval >= TimeUnits.DAY.unitInMs) { // day
minDate.setDate(interval >= TimeUnits.MONTH.unitInMs ? 1 : count * Math.round(minDate.getDate() / count));
}
if (interval >= TimeUnits.MONTH.unitInMs) { // month
minDate.setMonth(interval >= TimeUnits.YEAR.unitInMs ? 0 : count * Math.round(minDate.getMonth() + 1 / count) - 1);
minYear = minDate.getYear() + 1900;
}
if (interval >= TimeUnits.YEAR.unitInMs) { // year
minYear -= minYear % count;
minDate.setYear(minYear - 1900);
}
// week is a special case that runs outside the hierarchy
if (interval == TimeUnits.WEEK.unitInMs) {
// get start of current week, independent of count
long value = minDate.getDate() - minDate.getDay() + startOfWeek;
minDate.setDate((int) value);
}
// get tick positions
i = 1;
minYear = minDate.getYear() + 1900;
int minMonth = minDate.getMonth() + 1;
int minDateDate = minDate.getDate();
long time = minDate.getTime();
// iterate and add tick positions at appropriate values
while (time < max) {
if(time > min)
tickPositions.add(new TickPosition(time));
// if the interval is years, use Date.UTC to increase years
if (interval == TimeUnits.YEAR.unitInMs) {
time = makeTime(minYear + i * count, 0);
// if the interval is months, use Date.UTC to increase months
} else if (interval == TimeUnits.MONTH.unitInMs) {
time = makeTime(minYear, minMonth + i * count);
// if we're using global time, the interval is not fixed as it jumps
// one hour at the DST crossover
} else if (!useUTC && (interval == TimeUnits.DAY.unitInMs || interval == TimeUnits.WEEK.unitInMs)) {
time = makeTime(minYear, minMonth, minDateDate + i * count * (interval == TimeUnits.DAY.unitInMs ? 1 : 7));
// else, the interval is fixed and we use simple addition
} else {
time += interval * count;
}
i++;
}
// push the last time
if(time < max)
tickPositions.add(new TickPosition(time));
// record information on the chosen unit - for dynamic label formatter
// tickPositions.info = extend(normalizedInterval, {
// totalRange: interval * count
// });
return tickPositions;
}
public class NormalizedInterval {
public String unitName;
public long unitRange;
public int count;
public NormalizedInterval(String unitName, long unitRange, int count) {
this.unitName = unitName;
this.unitRange = unitRange;
this.count = count;
}
}
public class TickPosition {
public TickPosition(long time) {
this.time = new Date(time);
}
Date time;
}
enum TimeUnits {
MILLISECOND(1, new int[] { 1, 2, 5, 10, 20, 25, 50, 100, 200, 500 }),
SECOND(1000, new int[] { 1, 2, 5, 10, 15, 30 }),
MINUTE(60 * 1000, new int[] { 1, 2, 5, 10, 15, 30 }),
HOUR(60 * 60 * 1000, new int[] { 1, 2, 3, 4, 6, 8, 12 }),
DAY(24 * 3600000l, new int[] { 1, 2 }),
WEEK(7 * 24 * 3600000l, new int[] { 1, 2 }),
MONTH(30 * 24 * 3600000l, new int[] { 1, 2, 3, 4, 6 }),
YEAR(31556952000l, new int[] {});
int[] allowedMultiples;
long unitInMs;
TimeUnits(long unitInMs, int[] allowedMultiples) {
this.unitInMs = unitInMs;
this.allowedMultiples = allowedMultiples;
}
}
}