mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-07 12:51:02 +00:00
Merge branch 'highcharts_version_update' of ssh://kielweek.web4sap.com/home/trac/git into highcharts_version_update
This commit is contained in:
commit
e08dbc5cd4
9 files changed
+408
-53
No files matched your search
+9
-1
@@ -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, "");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -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();
|
||||
|
||||
+13
-2
@@ -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;
|
||||
}
|
||||
|
||||
-32
@@ -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");
|
||||
|
||||
+1
-2
@@ -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());
|
||||
|
||||
+1
-3
@@ -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;
|
||||
}
|
||||
|
||||
+13
-13
@@ -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();
|
||||
|
||||
+120
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+243
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user