Java tutorial
package com.vaadin.addon.timeline.gwt.client; /* * #%L * Vaadin Charts * %% * Copyright (C) 2014 Vaadin Ltd * %% * This program is available under Commercial Vaadin Add-On License 3.0 * (CVALv3). * * See the file licensing.txt distributed with this software for more * information about licensing. * * You should have received a copy of the CVALv3 along with this program. * If not, see <https://vaadin.com/license/cval-3>. * #L% */ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.KeyEvent; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.i18n.client.NumberFormat; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FocusPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.TextBox; import com.vaadin.addon.timeline.gwt.client.VTimelineDisplay.PlotMode; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.DateTimeService; import com.vaadin.client.Focusable; import com.vaadin.client.LocaleNotLoadedException; import com.vaadin.client.Paintable; import com.vaadin.client.UIDL; import com.vaadin.client.Util; import com.vaadin.client.VConsole; import com.vaadin.client.ValueMap; /** * VTimelineWidget * */ @SuppressWarnings("deprecation") public class VTimelineWidget extends FocusPanel implements Paintable, KeyDownHandler, KeyUpHandler, KeyPressHandler, Focusable { // Style names public static final String TAGNAME = "timeline-widget"; public static final String CLASSNAME = "v-" + TAGNAME; public static final String DISPLAY_CLASSNAME = CLASSNAME + "-display"; public static final String BROWSER_CLASSNAME = CLASSNAME + "-browser"; public static final String CAPTION_CLASSNAME = CLASSNAME + "-caption"; private static final String CLASSNAME_TOPBAR = CLASSNAME + "-topbar"; private static final String CLASSNAME_ZOOMBAR = CLASSNAME + "-zoombar"; private static final String CLASSNAME_ZOOMBARLABEL = CLASSNAME_ZOOMBAR + "-label"; private static final String CLASSNAME_DATEFIELD = CLASSNAME + "-datefield"; private static final String CLASSNAME_DATEFIELDEDIT = CLASSNAME_DATEFIELD + "-edit"; private static final String CLASSNAME_DATERANGE = CLASSNAME + "-daterange"; private static final String CLASSNAME_LEGEND = CLASSNAME + "-legend"; private static final String CLASSNAME_LEGENDLABEL = CLASSNAME_LEGEND + "-label"; private static final String CLASSNAME_LEGENDLABELVALUE = CLASSNAME_LEGEND + "-value"; private static final String CLASSNAME_CHARTMODE = CLASSNAME + "-chartmode"; private static final String CLASSNAME_CHARTMODELINE = CLASSNAME_CHARTMODE + "-line"; private static final String CLASSNAME_CHARTMODESCATTER = CLASSNAME_CHARTMODE + "-scatter"; private static final String CLASSNAME_CHARTMODEBAR = CLASSNAME_CHARTMODE + "-bar"; private static final String CLASSNAME_MODELEGEND_ROW = CLASSNAME + "-modelegend"; private final ClickHandler modeClickHandler = new ClickHandler() { @Override public void onClick(ClickEvent event) { if (event.getSource() == lineModeBtn) { setChartMode(PlotMode.LINE, true); } else if (event.getSource() == barModeBtn) { setChartMode(PlotMode.BAR, true); } else if (event.getSource() == scatterModeBtn) { setChartMode(PlotMode.SCATTER, true); } } }; private final ClickHandler zoomClickHandler = new ClickHandler() { @Override public void onClick(ClickEvent event) { zoomLevelClicked(event); } }; // Panels private final HorizontalPanel topBar; private final HorizontalPanel zoomBar; private final HorizontalPanel dateRangeBar; private final HorizontalPanel chartModeBar; private final HorizontalPanel modeLegendBar; // Legend private final HorizontalPanel legend; private final List<Label> legendCaptions = new ArrayList<Label>(); private final List<HTML> legendColors = new ArrayList<HTML>(); private final List<Label> legendValues = new ArrayList<Label>(); // Date selection private final TextBox dateFrom; private final TextBox dateTo; private Date intervalStartDate, intervalEndDate; // Default UIDL stuff private ApplicationConnection client; private String uidlId; // Initialization private boolean initStage1Done = false; private boolean initStage2Done = false; private boolean initDone = false; private boolean noDataAvailable = false; private Date selectedStartDate, selectedEndDate; // Components private VDateFormatInfo dateFormatInfo = new VDateFormatInfo(); private VTimelineDisplay display; private VTimelineBrowser browser; private final Map<Integer, VClientCache> multiLevelCache = new HashMap<Integer, VClientCache>(); // Base private final FlowPanel root = new FlowPanel(); private final Label caption; private boolean isIdle = true; private boolean clientCacheEnabled = true; private PlotMode initPlotMode = PlotMode.LINE; private String initGridColor = "rgb(200,200,200)"; private boolean selectionLock = true; private boolean graphStacking = false; private boolean uniformBarThickness = false; private String currentLocale; private DateTimeService dts; private boolean dateRangeChangeEventsEnabled = false; private boolean eventClickListenersEnabled = false; // Data handling private long requestCounter = 0L; private final Map<Long, VDataListener> waitingForData = new HashMap<Long, VDataListener>(); private final Map<Long, Integer> requestGraphMap = new HashMap<Long, Integer>(); private final Map<Integer, Boolean> graphVisibilites = new HashMap<Integer, Boolean>(); private final Map<Long, Integer> densityMap = new HashMap<Long, Integer>(); private final List<Integer> containerSizes = new ArrayList<Integer>(); private int offscreenPoints = 100; // Graph specific properties private Date startDate = null; private Date endDate = null; private int numGraphs = 0; // Graph colors private final Map<Integer, String> colors = new HashMap<Integer, String>(); private final Map<Integer, String> fillcolors = new HashMap<Integer, String>(); private final Map<Integer, Double> thicknesses = new HashMap<Integer, Double>(); private final Map<Integer, Boolean> caps = new HashMap<Integer, Boolean>(); // Browser colors private final Map<Integer, String> browserColors = new HashMap<Integer, String>(); private final Map<Integer, String> browserFillColors = new HashMap<Integer, String>(); // Legend values private final Map<Integer, String> captions = new HashMap<Integer, String>(); private final Map<Integer, String> units = new HashMap<Integer, String>(); // Zoom levels private final Map<HTML, Long> zoomLevels = new HashMap<HTML, Long>(); // Chart mode private final Button lineModeBtn; private final Button scatterModeBtn; private final Button barModeBtn; // Component visibilities private boolean browserIsVisible = true; private boolean zoomIsVisible = true; private boolean dateSelectVisible = true; private boolean dateSelectEnabled = true; private boolean chartModeVisible = true; private boolean lineChartModeVisible = true; private boolean barChartModeVisible = true; private boolean scatterChartModeVisible = true; private boolean legendVisible = true; private boolean graphShadows = true; private List<HandlerRegistration> handlers = new LinkedList<HandlerRegistration>(); public VTimelineWidget() { setWidget(root); getElement().setClassName("v-timeline"); dts = new DateTimeService(); root.setStyleName(CLASSNAME); root.setSize("100%", "100%"); caption = new Label(""); caption.setStyleName(CAPTION_CLASSNAME); caption.setVisible(false); root.add(caption); endDate = new Date(); startDate = new Date(endDate.getTime() - VDateFormatInfo.MONTH); topBar = new HorizontalPanel(); topBar.setStyleName(CLASSNAME_TOPBAR); topBar.setVisible(zoomIsVisible || dateSelectVisible); root.add(topBar); zoomBar = new HorizontalPanel(); zoomBar.setStyleName(CLASSNAME_ZOOMBAR); zoomBar.setVisible(zoomIsVisible); Label zoomLbl = new Label("Zoom:"); zoomLbl.setStyleName(CLASSNAME_ZOOMBARLABEL); zoomBar.add(zoomLbl); topBar.add(zoomBar); dateRangeBar = new HorizontalPanel(); dateRangeBar.setStyleName(CLASSNAME_DATERANGE); dateRangeBar.setHorizontalAlignment(HorizontalPanel.ALIGN_RIGHT); dateRangeBar.setVisible(dateSelectVisible); dateFrom = new TextBox(); dateFrom.addValueChangeHandler(new ValueChangeHandler<String>() { @Override public void onValueChange(ValueChangeEvent<String> event) { try { Date newDate = dts.parseDate(event.getValue(), dateFormatInfo.getEditFormat().getPattern(), true); if ((newDate.equals(startDate) || newDate.after(startDate)) && (newDate.equals(endDate) || newDate.before(endDate))) { intervalStartDate = newDate; setBrowserRange(intervalStartDate, intervalEndDate); setDisplayRange(intervalStartDate, intervalEndDate); dateFrom.setFocus(false); } else { dateFrom.setText( dts.formatDate(intervalStartDate, dateFormatInfo.getEditFormat().getPattern())); } } catch (IllegalArgumentException iae) { dateFrom.setText( dts.formatDate(intervalStartDate, dateFormatInfo.getEditFormat().getPattern())); } } }); dateFrom.addFocusHandler(new FocusHandler() { @Override public void onFocus(FocusEvent event) { dateFrom.setStyleName(CLASSNAME_DATEFIELDEDIT); dateFrom.setText(dts.formatDate(intervalStartDate, dateFormatInfo.getEditFormat().getPattern())); dateFrom.selectAll(); } }); dateFrom.addBlurHandler(new BlurHandler() { @Override public void onBlur(BlurEvent event) { dateFrom.setStyleName(CLASSNAME_DATEFIELD); dateFrom.setText(dts.formatDate(intervalStartDate, dateFormatInfo.getDisplayFormat().getPattern())); } }); dateFrom.setReadOnly(!dateSelectEnabled); dateFrom.setStyleName(CLASSNAME_DATEFIELD); dateRangeBar.add(dateFrom); Label dash = new Label(); dash.setText("-"); dateRangeBar.add(dash); dateTo = new TextBox(); dateTo.addValueChangeHandler(new ValueChangeHandler<String>() { @Override public void onValueChange(ValueChangeEvent<String> event) { try { Date newDate = dts.parseDate(event.getValue(), dateFormatInfo.getEditFormat().getPattern(), true); if ((newDate.equals(startDate) || newDate.after(startDate)) && (newDate.equals(endDate) || newDate.before(endDate))) { intervalEndDate = newDate; setBrowserRange(intervalStartDate, intervalEndDate); setDisplayRange(intervalStartDate, intervalEndDate); dateTo.setFocus(false); } else { dateTo.setText( dts.formatDate(intervalEndDate, dateFormatInfo.getEditFormat().getPattern())); } } catch (IllegalArgumentException iae) { dateTo.setText(dts.formatDate(intervalEndDate, dateFormatInfo.getEditFormat().getPattern())); } } }); dateTo.addFocusHandler(new FocusHandler() { @Override public void onFocus(FocusEvent event) { dateTo.setStyleName(CLASSNAME_DATEFIELDEDIT); dateTo.setText(dts.formatDate(intervalEndDate, dateFormatInfo.getEditFormat().getPattern())); dateTo.selectAll(); } }); dateTo.addBlurHandler(new BlurHandler() { @Override public void onBlur(BlurEvent event) { dateTo.setStyleName(CLASSNAME_DATEFIELD); dateTo.setText(dts.formatDate(intervalEndDate, dateFormatInfo.getDisplayFormat().getPattern())); } }); dateTo.setReadOnly(!dateSelectEnabled); dateTo.setStyleName(CLASSNAME_DATEFIELD); dateRangeBar.add(dateTo); topBar.add(dateRangeBar); topBar.setCellHorizontalAlignment(dateRangeBar, HorizontalPanel.ALIGN_RIGHT); legend = new HorizontalPanel(); legend.setVisible(legendVisible); legend.setHeight("30px"); legend.setStyleName(CLASSNAME_LEGEND); chartModeBar = new HorizontalPanel(); chartModeBar.setVisible(chartModeVisible); chartModeBar.setStyleName(CLASSNAME_CHARTMODE); Label modelbl = new Label("Chart mode:"); chartModeBar.add(modelbl); lineModeBtn = new Button("", modeClickHandler); lineModeBtn.setTabIndex(-1); lineModeBtn.setVisible(lineChartModeVisible); lineModeBtn.setStyleName(CLASSNAME_CHARTMODELINE); lineModeBtn.setTitle("Line Graph"); chartModeBar.add(lineModeBtn); barModeBtn = new Button("", modeClickHandler); barModeBtn.setTabIndex(-1); barModeBtn.setVisible(barChartModeVisible); barModeBtn.setStyleName(CLASSNAME_CHARTMODEBAR); barModeBtn.setTitle("Bar Graph"); chartModeBar.add(barModeBtn); scatterModeBtn = new Button("", modeClickHandler); scatterModeBtn.setTabIndex(-1); scatterModeBtn.setVisible(scatterChartModeVisible); scatterModeBtn.setStyleName(CLASSNAME_CHARTMODESCATTER); scatterModeBtn.setTitle("Scatter Graph"); chartModeBar.add(scatterModeBtn); modeLegendBar = new HorizontalPanel(); modeLegendBar.setVisible(chartModeVisible || legendVisible); modeLegendBar.setWidth("100%"); modeLegendBar.setHeight("31px"); modeLegendBar.setStyleName(CLASSNAME_MODELEGEND_ROW); modeLegendBar.add(chartModeBar); modeLegendBar.add(legend); modeLegendBar.setCellHorizontalAlignment(legend, HorizontalPanel.ALIGN_RIGHT); root.add(modeLegendBar); // Add the display display = new VTimelineDisplay(this); root.add(display); // Add the browser browser = new VTimelineBrowser(this); browser.setVisible(browserIsVisible); root.add(browser); } /** * Returns the {@link DateTimeService} used by timezone calculations * * @return */ public DateTimeService getDateTimeService() { return dts; } /* * (non-Javadoc) * * @see com.google.gwt.user.client.ui.Widget#onLoad() */ @Override protected void onLoad() { super.onLoad(); // Keyboard listeners handlers.add(addDomHandler(this, KeyPressEvent.getType())); handlers.add(addDomHandler(this, KeyDownEvent.getType())); handlers.add(addDomHandler(this, KeyUpEvent.getType())); } /* * (non-Javadoc) * * @see com.google.gwt.user.client.ui.Widget#onUnload() */ @Override protected void onUnload() { super.onUnload(); for (HandlerRegistration handler : handlers) { handler.removeHandler(); } handlers.clear(); } void recalculateHeights(int height) { int captionHeight = getCaptionHeight(); int topBarHeight = topBar.isVisible() ? Util.getRequiredHeight(topBar) : 0; int modeLegendBarHeight = modeLegendBar.isVisible() ? Util.getRequiredHeight(modeLegendBar) : 0; int browserHeight = browser.isVisible() ? Util.getRequiredHeight(browser) : 0; int displayHeight = height - captionHeight - topBarHeight - modeLegendBarHeight - browserHeight; display.setHeight(displayHeight + "px"); if (isInitDone()) { display.redraw(); browser.redraw(); } } void recalculateWidths(int width) { caption.setWidth((width - 5) + "px"); topBar.setWidth(width + "px"); modeLegendBar.setWidth(width + "px"); browser.setWidth(width + "px"); display.setWidth(width + "px"); if (isInitDone()) { display.redraw(); browser.redraw(); } } /** * Adds a zoom level to the zoom bar * * @param caption * The caption of the zoom level * @param time * The time in milliseconds of the zoom level */ private void addZoomLevel(String caption, Long time) { HTML level = new HTML(caption); level.setStyleName("zoom-level"); level.addClickHandler(zoomClickHandler); zoomLevels.put(level, time); zoomBar.add(level); } /** * Initializes the widget */ private boolean init1(UIDL uidl) { clearCache(); setCache(uidl); // Set initial data setStartDate(uidl); setEndDate(uidl); setNumGraphs(uidl); setCaption(uidl); setZoomCaption(uidl); setChartModeCaption(uidl); setNoDataSourceCaption(uidl); setSelectionLock(uidl); setDateFormatInfo(uidl); setLocale(uidl); setVerticalFitting(uidl); setVerticalGraphLines(uidl); // Component UI setZoomVisibility(uidl); setChartModeVisibility(uidl); setDateSelectEnabled(uidl); setDateSelectVisibility(uidl); setBarChartModeVisible(uidl); setLineChartModeVisible(uidl); setScatterChartModeVisible(uidl); setBrowserVisibility(uidl); setLegendVisibility(uidl); handleDateRangeChangeEventEnabled(uidl); handleOffscreeRendering(uidl); setSelectionRange(uidl); handleVerticalAxisNumberFormat(uidl); return true; } private boolean init2(UIDL uidl) { init1(uidl); handleEventClickListenersEnabled(uidl); handleGraphShadows(uidl); setGraphOutlineColors(uidl); setGraphFillColors(uidl); setBrowserFillColors(uidl); setBrowserOutlineColors(uidl); setLineCaps(uidl); setLineGraphThickness(uidl); setGridColor(uidl); setZoomLevels(uidl); setZoomCaption(uidl); setChartModeCaption(uidl); setNoDataSourceCaption(uidl); setGraphCaptions(uidl); setGraphUnits(uidl); setGraphVisibilities(uidl); handleOnePointGraph(); setChartMode(uidl); // Refresh the browser part if (browserIsVisible) { browser.refresh(); } // If no data is present, then show "No data" label setNoData(uidl); return true; } private void setLineGraphThickness(UIDL uidl) { if (uidl.hasVariable(TimelineConstants.VARIABLE_LINE_GRAPH_THICKNESS)) { String[] ts = uidl.getStringArrayVariable(TimelineConstants.VARIABLE_LINE_GRAPH_THICKNESS); thicknesses.clear(); for (int t = 0; t < ts.length; t++) { double thickness = Double.parseDouble(ts[t]); thicknesses.put(t, thickness); } if (isInitDone()) { display.redraw(); } } } private void setStartDate(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_START_DATE)) { startDate = new Date(uidl.getLongAttribute(TimelineConstants.ATTRIBUTE_START_DATE)); } } private void setEndDate(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_END_DATE)) { endDate = new Date(uidl.getLongAttribute(TimelineConstants.ATTRIBUTE_END_DATE)); } } private void setNumGraphs(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_NUMBER_OF_GRAPHS)) { numGraphs = uidl.getIntAttribute(TimelineConstants.ATTRIBUTE_NUMBER_OF_GRAPHS); } } private void setCaption(UIDL uidl) { if (uidl.hasAttribute("caption")) { String captionText = uidl.getStringAttribute("caption"); setCaption(captionText); } } void setCaption(String captionText) { boolean captionWasVisible = caption.isVisible(); if (captionText == null || captionText.equals("")) { caption.setText(""); caption.setVisible(false); } else { caption.setText(captionText); caption.setVisible(true); } if (captionWasVisible != caption.isVisible()) { if (isInitDone()) { recalculateHeights(getOffsetHeight()); display.redraw(); browser.redraw(); } } } private void setSelectionLock(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_LOCK)) { selectionLock = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_LOCK); } else { selectionLock = false; } } private void setZoomLevels(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_ZOOM_LEVELS)) { ValueMap levelMap = uidl.getMapAttribute(TimelineConstants.ATTRIBUTE_ZOOM_LEVELS); if (zoomBar != null) { for (HTML lvl : zoomLevels.keySet()) { zoomBar.remove(lvl); } } zoomLevels.clear(); for (String caption : levelMap.getKeySet()) { Long time = Long.parseLong(levelMap.getString(caption)); addZoomLevel(caption, time); } } } private void setZoomVisibility(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_UI_ZOOMBAR_VISIBILITY)) { zoomIsVisible = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_UI_ZOOMBAR_VISIBILITY); if (zoomBar != null) { zoomBar.setVisible(zoomIsVisible); setTopBarVisibility(zoomIsVisible || dateSelectVisible); } } } private void setZoomCaption(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_ZOOM_LEVEL_CAPTION)) { String caption = uidl.getStringAttribute(TimelineConstants.ATTRIBUTE_ZOOM_LEVEL_CAPTION); Label lbl = (Label) zoomBar.getWidget(0); lbl.setText(caption); } } private void setNoDataSourceCaption(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_NO_DS_CAPTION)) { String caption = uidl.getStringAttribute(TimelineConstants.ATTRIBUTE_NO_DS_CAPTION); display.setNoDataSourceCaption(caption); } } private void setModeLegendBarVisibility(boolean visibility) { boolean isVisible = modeLegendBar.isVisible(); if (isVisible != visibility) { modeLegendBar.setVisible(visibility); if (isInitDone()) { display.redraw(); browser.redraw(); } } } private void setTopBarVisibility(boolean visibility) { if (topBar != null) { boolean isVisible = topBar.isVisible(); if (isVisible != visibility) { topBar.setVisible(visibility); if (isInitDone()) { display.redraw(); browser.redraw(); } } } } private Timer refreshTimer = new Timer() { @Override public void run() { // Clear the cache from old data clearCache(); // Render the browser canvas (refreshes the selection after loading // the data) browser.refresh(); /* * Refresh display */ display.resetVerticalScaleFitting(); display.resetDisplayCache(); display.refresh(); } }; public boolean isSelectionLocked() { return selectionLock; } private void setDirty(UIDL uidl) { if (uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_DIRTY) && isInitDone()) { refreshTimer.cancel(); refreshTimer.schedule(500); } } private void clearCache() { multiLevelCache.clear(); multiLevelCache.put(1, new VClientCache(VTimelineWidget.this)); display.clearCache(); } private void setGraphStacking(UIDL uidl) { graphStacking = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_STACKED); } private void setUniformBarThicknessEnabled(UIDL uidl) { uniformBarThickness = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_UNIFORM_BARCHART); } private void setContainerSizes(UIDL uidl) { if (uidl.hasVariable(TimelineConstants.VARIABLE_CONTAINER_SIZES)) { int[] sizes = uidl.getIntArrayVariable(TimelineConstants.VARIABLE_CONTAINER_SIZES); containerSizes.clear(); int maxSize = 0; for (int size : sizes) { containerSizes.add(size); maxSize = size > maxSize ? size : maxSize; } // Cache is not up to date so empty it clearCache(); } } private void setCache(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_CACHE)) { clientCacheEnabled = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_CACHE); // Clear current cache clearCache(); } } private void setVerticalFitting(UIDL uidl) { if (uidl.hasVariable(TimelineConstants.VARIABLE_VERTICAL_FITTING)) { boolean auto = uidl.getBooleanVariable(TimelineConstants.VARIABLE_VERTICAL_FITTING); float min = 0f; float max = 0f; if (uidl.hasVariable(TimelineConstants.VARIABLE_VERTICAL_FITTING_MIN) && uidl.hasVariable(TimelineConstants.VARIABLE_VERTICAL_FITTING_MAX)) { min = uidl.getFloatVariable(TimelineConstants.VARIABLE_VERTICAL_FITTING_MIN); max = uidl.getFloatVariable(TimelineConstants.VARIABLE_VERTICAL_FITTING_MAX); } display.setVerticalFitting(auto, min, max); } } private void setVerticalGraphLines(UIDL uidl) { if (uidl.hasVariable(TimelineConstants.VARIABLE_VERTICAL_GRID_LINES)) { String[] linesStr = uidl.getStringArrayVariable(TimelineConstants.VARIABLE_VERTICAL_GRID_LINES); float[] values = new float[linesStr.length]; for (int i = 0; i < linesStr.length; i++) { values[i] = Float.parseFloat(linesStr[i]); } display.setVerticalScaleLines(values); } else if (uidl.hasVariable(TimelineConstants.VARIABLE_NO_VERTICAL_GRID) && uidl.getBooleanVariable(TimelineConstants.VARIABLE_NO_VERTICAL_GRID)) { display.setVerticalScaleLines(null); } } private void setGraphCaptions(UIDL uidl) { if (uidl.hasVariable(TimelineConstants.VARIABLE_CAPTIONS)) { String[] caps = uidl.getStringArrayVariable(TimelineConstants.VARIABLE_CAPTIONS); captions.clear(); for (int g = 0; g < caps.length; g++) { captions.put(g, caps[g]); } // Create the legend labels if (!captions.isEmpty()) { legend.clear(); legendColors.clear(); legendCaptions.clear(); legendValues.clear(); for (Integer graph : captions.keySet()) { String caption = captions.get(graph); if (colors.get(graph) != null) { HTML color = new HTML("<B></B>"); color.setHeight("15px"); String cc = colors.get(graph); DOM.setStyleAttribute(color.getElement(), "color", cc); legend.add(color); legendColors.add(color); } HTML html = new HTML(); legend.add(html); Label lbl = new Label(caption); lbl.setHeight("15px"); lbl.setStyleName(CLASSNAME_LEGENDLABEL); html.getElement().appendChild(lbl.getElement()); legendCaptions.add(lbl); Label val = new Label(); val.setHeight("15px"); val.setStyleName(CLASSNAME_LEGENDLABELVALUE); html.getElement().appendChild(val.getElement()); legendValues.add(val); } } } } private void setSelectionRange(UIDL uidl) { if (uidl.hasVariable(TimelineConstants.VARIABLE_SELECTION_START) && uidl.hasVariable(TimelineConstants.VARIABLE_SELECTION_END)) { selectedStartDate = new Date(uidl.getLongVariable(TimelineConstants.VARIABLE_SELECTION_START)); selectedEndDate = new Date(uidl.getLongVariable(TimelineConstants.VARIABLE_SELECTION_END)); if (selectedStartDate.before(startDate)) { selectedStartDate = startDate; } if (selectedEndDate.after(endDate)) { selectedEndDate = endDate; } if (browser.isVisible()) { browser.setRange(selectedStartDate, selectedEndDate); selectedStartDate = browser.getSelectionStart(); selectedEndDate = browser.getSelectionEnd(); } display.setRange(selectedStartDate, selectedEndDate); if (!isInitDone()) { selectedStartDate = display.getSelectionStartDate(); selectedEndDate = display.getSelectionEndDate(); } } } private void setGraphVisibilities(UIDL uidl) { if (uidl.hasVariable(TimelineConstants.VARIABLE_VISIBILITIES)) { String[] v = uidl.getStringArrayVariable(TimelineConstants.VARIABLE_VISIBILITIES); for (int i = 0; i < v.length; i++) { setLegendCaptionVisibility(i, Boolean.parseBoolean(v[i])); } } } private void setGraphUnits(UIDL uidl) { if (uidl.hasVariable(TimelineConstants.VARIABLE_VERTICAL_UNIT)) { String[] gUnits = uidl.getStringArrayVariable(TimelineConstants.VARIABLE_VERTICAL_UNIT); for (int g = 0; g < gUnits.length; g++) { units.put(g, gUnits[g]); } } } private void setGridColor(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_GRID_COLOR)) { String color = uidl.getStringAttribute(TimelineConstants.ATTRIBUTE_GRID_COLOR); if (color == null || color.equals("")) { initGridColor = null; } else { initGridColor = color; } display.setGridColor(initGridColor); } } private void setBarChartModeVisible(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_UI_CHARTMODE_BARCHART_VISIBILITY)) { barChartModeVisible = uidl .getBooleanAttribute(TimelineConstants.ATTRIBUTE_UI_CHARTMODE_BARCHART_VISIBILITY); if (barModeBtn != null) { barModeBtn.setVisible(barChartModeVisible); chartModeBar.setVisible(chartModeVisible && (lineChartModeVisible || barChartModeVisible || scatterChartModeVisible)); } } } private void setScatterChartModeVisible(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_UI_CHARTMODE_SCATTERCHART_VISIBILITY)) { scatterChartModeVisible = uidl .getBooleanAttribute(TimelineConstants.ATTRIBUTE_UI_CHARTMODE_SCATTERCHART_VISIBILITY); if (scatterModeBtn != null) { scatterModeBtn.setVisible(scatterChartModeVisible); chartModeBar.setVisible(chartModeVisible && (lineChartModeVisible || barChartModeVisible || scatterChartModeVisible)); } } } private void setChartModeVisibility(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_UI_CHARTMODE_VISIBILITY)) { chartModeVisible = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_UI_CHARTMODE_VISIBILITY); if (chartModeBar != null) { chartModeBar.setVisible(chartModeVisible); } } } private void setChartMode(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_CHART_MODE)) { setChartMode(PlotMode.valueOf(uidl.getStringAttribute(TimelineConstants.ATTRIBUTE_CHART_MODE)), initStage2Done); } } void setChartMode(PlotMode mode, boolean plot) { initPlotMode = mode; display.setChartMode(initPlotMode, plot); browser.setChartMode(initPlotMode, plot); } private void setChartModeCaption(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_CHART_MODE_CAPTION)) { String caption = uidl.getStringAttribute(TimelineConstants.ATTRIBUTE_CHART_MODE_CAPTION); Label lbl = (Label) chartModeBar.getWidget(0); lbl.setText(caption); } } private void setDateSelectEnabled(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_UI_DATESELECT_ENABLED)) { dateSelectEnabled = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_UI_DATESELECT_ENABLED); dateFrom.setReadOnly(!dateSelectEnabled); dateTo.setReadOnly(!dateSelectEnabled); } } private void setDateSelectVisibility(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_UI_DATESELECT_VISIBILITY)) { dateSelectVisible = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_UI_DATESELECT_VISIBILITY); if (dateRangeBar != null) { dateRangeBar.setVisible(dateSelectVisible); setTopBarVisibility(zoomIsVisible || dateSelectVisible); } } } private void setLegendVisibility(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIUBTE_UI_LEGEND_VISIBILITY)) { legendVisible = uidl.getBooleanAttribute(TimelineConstants.ATTRIUBTE_UI_LEGEND_VISIBILITY); if (legend != null) { legend.setVisible(legendVisible); setModeLegendBarVisibility(legendVisible || chartModeBar.isVisible()); } } } private void setBrowserVisibility(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_UI_BROWSER_VISIBLITY)) { boolean browserWasVisible = browserIsVisible; browserIsVisible = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_UI_BROWSER_VISIBLITY); if (browser != null && browserWasVisible != browserIsVisible) { browser.setVisible(browserIsVisible); if (isInitDone()) { display.redraw(); browser.redraw(); } } } } private void setBrowserOutlineColors(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_BROWSER_COLORS)) { browserColors.clear(); String[] colorStrings = uidl.getStringArrayAttribute(TimelineConstants.ATTRIBUTE_BROWSER_COLORS); for (int s = 0; s < colorStrings.length; s++) { browserColors.put(s, colorStrings[s]); } if (isInitDone()) { browser.redraw(); } } } private void setBrowserFillColors(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_BROWSER_FILLCOLORS)) { browserFillColors.clear(); String[] colorStrings = uidl.getStringArrayAttribute(TimelineConstants.ATTRIBUTE_BROWSER_FILLCOLORS); for (int s = 0; s < colorStrings.length; s++) { browserFillColors.put(s, colorStrings[s]); } if (isInitDone()) { browser.redraw(); } } } private void setGraphOutlineColors(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_COLORS)) { colors.clear(); String[] colorStrings = uidl.getStringArrayAttribute(TimelineConstants.ATTRIBUTE_COLORS); for (int s = 0; s < colorStrings.length; s++) { colors.put(s, colorStrings[s]); } if (isInitDone()) { display.redraw(); } } } private void setGraphFillColors(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_FILLCOLORS)) { fillcolors.clear(); String[] colorStrings = uidl.getStringArrayAttribute(TimelineConstants.ATTRIBUTE_FILLCOLORS); for (int s = 0; s < colorStrings.length; s++) { fillcolors.put(s, colorStrings[s]); } if (isInitDone()) { display.redraw(); } } } private void setLineCaps(UIDL uidl) { if (uidl.hasVariable(TimelineConstants.VARIABLE_CAPS) && display != null) { caps.clear(); String[] cs = uidl.getStringArrayVariable(TimelineConstants.VARIABLE_CAPS); for (int c = 0; c < cs.length; c++) { caps.put(c, Integer.parseInt(cs[c]) == 1 ? true : false); } if (isInitDone()) { display.redraw(); } } } private void setLineChartModeVisible(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_UI_CHARTMODE_LINECHART_VISIBILITY)) { lineChartModeVisible = uidl .getBooleanAttribute(TimelineConstants.ATTRIBUTE_UI_CHARTMODE_LINECHART_VISIBILITY); if (lineModeBtn != null) { lineModeBtn.setVisible(lineChartModeVisible); chartModeBar.setVisible(chartModeVisible && (lineChartModeVisible || barChartModeVisible || scatterChartModeVisible)); } } } private void setLocale(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_LOCALE)) { final String locale = uidl.getStringAttribute(TimelineConstants.ATTRIBUTE_LOCALE); try { dts.setLocale(locale); currentLocale = locale; } catch (final LocaleNotLoadedException e) { currentLocale = dts.getLocale(); VConsole.error("Tried to use an unloaded locale \"" + locale + "\". Using default locale (" + currentLocale + ")."); VConsole.error(e); } } } private void handleOnePointGraph() { if (startDate.equals(endDate)) { long halfDay = VDateFormatInfo.DAY / 2L; startDate = new Date(startDate.getTime() - halfDay); endDate = new Date(endDate.getTime() + halfDay); selectedStartDate = startDate; selectedEndDate = endDate; setBrowserRange(selectedStartDate, selectedEndDate); setDisplayRange(selectedStartDate, selectedEndDate); } } /* * (non-Javadoc) * * @see * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection) */ @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { // Check parent components if (client.updateComponent(this, uidl, true)) { return; } // Store reference variables for later usage this.client = client; uidlId = uidl.getId(); // Initialization stage 1 if (!initStage1Done) { initStage1Done = init1(uidl); // Send init flag back to server along with the canvas width client.updateVariable(uidlId, TimelineConstants.VARIABLE_INIT, true, false); client.updateVariable(uidlId, TimelineConstants.VARIABLE_CANVAS_WIDTH, getOffsetWidth(), true); return; // Initialization done } else if (!initStage2Done) { initStage2Done = init2(uidl); return; } else if (!isInitDone()) { initDone = true; } handleOffscreeRendering(uidl); handleDateRangeChangeEventEnabled(uidl); handleEventClickListenersEnabled(uidl); handleGraphShadows(uidl); handleVerticalAxisNumberFormat(uidl); // Basic setCaption(uidl); setLocale(uidl); setNoData(uidl); setSelectionLock(uidl); setGraphStacking(uidl); setUniformBarThicknessEnabled(uidl); setContainerSizes(uidl); setCache(uidl); // Dates setStartDate(uidl); setEndDate(uidl); handleOnePointGraph(); // Graphs setNumGraphs(uidl); setGraphOutlineColors(uidl); setBrowserOutlineColors(uidl); setBrowserFillColors(uidl); setGraphFillColors(uidl); setGraphCaptions(uidl); setGraphVisibilities(uidl); setSelectionRange(uidl); setVerticalFitting(uidl); setVerticalGraphLines(uidl); setGraphUnits(uidl); setLineCaps(uidl); setLineGraphThickness(uidl); // Browser UI setBrowserVisibility(uidl); setZoomVisibility(uidl); setDateSelectVisibility(uidl); setDateSelectEnabled(uidl); setChartModeVisibility(uidl); setLineChartModeVisible(uidl); setBarChartModeVisible(uidl); setScatterChartModeVisible(uidl); setLegendVisibility(uidl); setZoomLevels(uidl); // Chrat modes and colors setChartMode(uidl); setGridColor(uidl); setZoomCaption(uidl); setChartModeCaption(uidl); setNoDataSourceCaption(uidl); setDateFormatInfo(uidl); // Data received if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_DATA)) { ValueMap map = uidl.getMapAttribute(TimelineConstants.ATTRIBUTE_DATA); ValueMap changedDensitiesMap = uidl.getMapAttribute(TimelineConstants.ATTRIBUTE_DENSITIES); List<Long> removableRequests = new LinkedList<Long>(); Set<Long> currentlyWaitingData = new HashSet<Long>(waitingForData.keySet()); // Check waiting data list for (Long req : currentlyWaitingData) { for (String req2 : map.getKeySet()) { if (req2.equals(req.toString())) { // Process the request processRequest(req, map, changedDensitiesMap, uidl); // Remove the request removableRequests.add(req); } } } // Remove recieved requests for (Long requestToRemove : removableRequests) { waitingForData.remove(requestToRemove); requestGraphMap.remove(requestToRemove); densityMap.remove(requestToRemove); } isIdle = waitingForData.isEmpty(); } // Handle cache cleaning setDirty(uidl); } private void handleGraphShadows(UIDL uidl) { boolean hadShadows = graphShadows; graphShadows = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_GRAPH_SHADOWS); if (hadShadows != graphShadows) { browser.redraw(); } } private void handleDateRangeChangeEventEnabled(UIDL uidl) { dateRangeChangeEventsEnabled = uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_CHANGE_EVENT_ENABLED); } private void handleOffscreeRendering(UIDL uidl) { offscreenPoints = uidl.getIntAttribute(TimelineConstants.ATTRIBUTE_OFFSCREEN_RENDERING); } private void handleEventClickListenersEnabled(UIDL uidl) { eventClickListenersEnabled = uidl .getBooleanAttribute(TimelineConstants.ATTRIBUTE_EVENT_CLICK_LISTENER_ENABLED); } private void setNoData(UIDL uidl) { // Disable component since no data source has been defined on the server if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_NODATA)) { setWidgetNoData(uidl.getBooleanAttribute(TimelineConstants.ATTRIBUTE_NODATA)); } else { setWidgetNoData(false); } } private void handleVerticalAxisNumberFormat(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_VERTICAL_NUMBER_FORMAT)) { NumberFormat format = NumberFormat .getFormat(uidl.getStringAttribute(TimelineConstants.ATTRIBUTE_VERTICAL_NUMBER_FORMAT)); display.setVerticalAxisNumberFormat(format); } } private void processRequest(Long req, ValueMap map, ValueMap changedDensitiesMap, UIDL uidl) { VDataListener comp = waitingForData.get(req); // Get the values. List<String> values = new ArrayList<String>(); String valuesString = map.getString(String.valueOf(req)); if (valuesString != null && !valuesString.equals("")) { for (String val : map.getString(String.valueOf(req)).split(";")) { values.add(val); } } List<Float> fvalues = new ArrayList<Float>(); List<Date> dvalues = new ArrayList<Date>(); Integer density = densityMap.get(req); if (changedDensitiesMap != null) { String d = changedDensitiesMap.getString(String.valueOf(req)); if (d != null) { density = Integer.valueOf(d); } } Long lastTime = null; Long lastIncrement = null; for (String val : values) { // Values and timestamps are separated with a '_' // character String[] v = val.split("_"); // Get the value Float value = Float.parseFloat(v[0]); // Get the time/increment Long time = v.length < 2 ? lastIncrement : Long.parseLong(v[1]); // If last time is null then we have the first point // with a complete timestamp if (lastTime == null) { dvalues.add(new Date(time)); lastTime = time; // Else the time is the difference between the // last points time and this points time. } else { dvalues.add(new Date(lastTime + time)); lastTime += time; lastIncrement = time; } // Add the value to the value list fvalues.add(value); } // Get markers Set<String> markers = null; if (uidl.hasVariable(TimelineConstants.VARIABLE_MARKERS)) { markers = uidl.getStringArrayVariableAsSet(TimelineConstants.VARIABLE_MARKERS); } // Get events Set<String> events = null; if (uidl.hasVariable(TimelineConstants.VARIABLE_EVENTS)) { events = uidl.getStringArrayVariableAsSet(TimelineConstants.VARIABLE_EVENTS); } // Put data in cache int graph = requestGraphMap.get(req); if (dvalues.size() > 0 && clientCacheEnabled) { // Only add visible graphs to cache if (graphIsVisible(graph)) { VClientCache densityCache = multiLevelCache.get(density); // Create new cache if it does not exist if (densityCache == null) { densityCache = new VClientCache(this); multiLevelCache.put(density, densityCache); } // Add points to cache densityCache.addToCache(graph, dvalues.get(0), dvalues.get(dvalues.size() - 1), fvalues, dvalues, markers, events); } } // Notify component of the data comp.dataRecieved(req, fvalues, dvalues, markers, events, density); } /** * Set the not data state * * @param enabled */ private void setWidgetNoData(boolean enabled) { noDataAvailable = enabled; display.displayNoDataMessage(enabled); browser.displayNoDataMessage(enabled); display.setEnabled(!enabled); browser.setEnabled(!enabled); barModeBtn.setEnabled(!enabled); lineModeBtn.setEnabled(!enabled); scatterModeBtn.setEnabled(!enabled); dateFrom.setEnabled(!enabled); dateTo.setEnabled(!enabled); if (enabled) { legend.clear(); legendColors.clear(); legendCaptions.clear(); legendValues.clear(); captions.clear(); } } /** * Get data points from server * * @param component * The component which need the points * @param graphIndex * From which graph should the data points be fetched * @param startDate * The start date of the data points * @param endDate * The end date of the data points * @return Was the data fetched from the cache */ public boolean getDateData(VDataListener component, int graphIndex, Date startDate, Date endDate, int density) { if (component.isVisible()) { isIdle = false; requestCounter++; component.setCurrentRequestId(Long.valueOf(requestCounter), graphIndex); waitingForData.put(requestCounter, component); requestGraphMap.put(requestCounter, graphIndex); densityMap.put(requestCounter, density); client.updateVariable(uidlId, TimelineConstants.VARIABLE_DATA_PREFIX + requestCounter, new String[] { String.valueOf(requestCounter), String.valueOf(graphIndex), String.valueOf(startDate.getTime()), String.valueOf(endDate.getTime()), String.valueOf(density) }, false); } return false; } /** * Tries to get the data points from the cache, if that fails then gets the * points from the server * * @param component * The component which need the points * @param startDate * The start date * @param endDate * The end date * @param density * The density of the points * @return Was the data fetched from the cache * */ @SuppressWarnings("unchecked") public boolean getDateDataAll(VDataListener component, Date startDate, Date endDate, int density) { if (clientCacheEnabled) { boolean allRetrievedFromCache = true; List<Long> requests = new ArrayList<Long>(); Map<Integer, List<Float>> values = new HashMap<Integer, List<Float>>(); Map<Integer, List<Date>> dates = new HashMap<Integer, List<Date>>(); Set<String> markers = new HashSet<String>(); Set<String> events = new HashSet<String>(); Map<Integer, Float> min = new HashMap<Integer, Float>(); Map<Integer, Float> max = new HashMap<Integer, Float>(); Float totalMinimum = Float.MAX_VALUE; Float totalMaximum = Float.MIN_VALUE; int numGraphs = getNumGraphs(); for (int g = 0; g < numGraphs; g++) { // Abort if graph is not visible if (!graphIsVisible(g)) { continue; } requestCounter++; component.setCurrentRequestId(Long.valueOf(requestCounter), g); requests.add(Long.valueOf(requestCounter)); VClientCache densityCache = multiLevelCache.get(density); int cacheDensity = density; /* * We didn't find the correct density cache, try to find a lower * level to use */ if (densityCache == null) { cacheDensity = (int) Math.floor(density / 2f); while (cacheDensity >= 1) { densityCache = multiLevelCache.get(cacheDensity); if (densityCache != null) { break; } cacheDensity = (int) Math.floor(cacheDensity / 2f); } } Object[] obj = null; if (densityCache != null) { obj = densityCache.getFromCache(g, startDate, endDate); } if (obj == null) { allRetrievedFromCache = false; break; } else { List<Date> dvalues = (List<Date>) obj[1]; List<Float> fvalues = (List<Float>) obj[0]; Float minvalue = (Float) obj[4]; Float maxvalue = (Float) obj[5]; /* * Ensures we got enough points from cache to cover the * display area */ Date realStartDate = dvalues.get(0); Date realEndDate = dvalues.get(dvalues.size() - 1); if (realStartDate.after(startDate) || realEndDate.before(endDate)) { allRetrievedFromCache = false; break; } /* * If we are using a higher density cache then we need to * remove some points */ if (cacheDensity < density) { int cachediff = density - cacheDensity; List<Float> newValues = new ArrayList<Float>(); List<Date> newDates = new ArrayList<Date>(); float newMin = fvalues.get(0); float newMax = fvalues.get(0); for (int i = 0; i < fvalues.size(); i += cachediff + 1) { float value = fvalues.get(i); newValues.add(value); newMin = value < newMin ? value : newMin; newMax = value > newMax ? value : newMax; newDates.add(dvalues.get(i)); } dvalues = newDates; fvalues = newValues; minvalue = newMin; maxvalue = newMax; } values.put(g, fvalues); dates.put(g, dvalues); min.put(g, minvalue); max.put(g, maxvalue); if (minvalue < totalMinimum) { totalMinimum = minvalue; } if (maxvalue > totalMaximum) { totalMaximum = maxvalue; } if (obj[2] != null) { markers.addAll((Set<String>) obj[2]); } if (obj[3] != null) { events.addAll((Set<String>) obj[3]); } } } // Everything was fetched from the cache if (allRetrievedFromCache && getNumGraphs() > 0) { component.dataRecievedAll(requests, values, dates, markers, events, min, max, totalMinimum, totalMaximum, density); return true; } } // Some data not found in cache, get it from the server for (int g = 0; g < getNumGraphs(); g++) { getDateData(component, g, startDate, endDate, density); } // Issue request getFromServer(); return false; } /** * @param graphIndex * * @return Returns how many points a graph has */ public int getContainerSize(int graphIndex) { if (graphIndex >= containerSizes.size()) { return 0; } return containerSizes.get(graphIndex); } /** * Set the displayed date range * * @param start * The start date * @param end * The end date */ public void setDisplayRange(Date start, Date end) { display.setRange(start, end); } /** * Set the selected date range * * @param start * The start date * @param end * The end date */ public void setBrowserRange(Date start, Date end) { if (browser.isVisible()) { browser.setRange(start, end); } } /** * Calculates the maximum value of a list of values * * @param values * The list of values * @return The maximum value */ public static float getMaxValue(List<Float> values) { if (values == null || values.size() == 0) { return 0; } float max = values.get(0); for (Float value : values) { max = max < value.floatValue() ? value.floatValue() : max; } return max; } /** * Calculates the minimum value of a list of values * * @param values * The list of values * @return The minimum value */ public static float getMinValue(List<Float> values) { if (values == null || values.size() == 0) { return 0; } float min = values.get(0); for (Float value : values) { min = min > value.floatValue() ? value.floatValue() : min; } return min; } /** * Normalizes a list of values using the minimum value as reference * * @param values * A list of values * @param minimum * The reference value * @return A normilized list */ public static List<Float> normalizeValues(List<Float> values, float minimum) { if (minimum == 0f) { return values; } List<Float> normValues = new ArrayList<Float>(); if (values != null) { for (Float val : values) { normValues.add(new Float(val - minimum)); } } return normValues; } /** * Get the ISO week date week number */ public static int getWeek(Date date) { Date onejan = new Date(date.getYear(), 0, 1); Long t1 = onejan.getTime(); Long t2 = date.getTime(); Long diff = t2 - t1; Float d = diff.floatValue() / 86400000f; Float d2 = (onejan.getDay() + 1f); return (int) Math.floor((d + d2) / 7f); } /** * Returns the number of days of a given month * * @param month * The month 0-11 * @param year * The year * @return Days in the month */ public static int getDaysInMonth(int month, int year) { return 32 - new Date(year, month, 32).getDate(); } /** * Returns the start date * * @return The start date */ public Date getStartDate() { return startDate; } /** * Returns the end date * * @return The end date */ public Date getEndDate() { return endDate; } /** * Returns the amount of graphs * * @return The amount of grafs */ public int getNumGraphs() { return numGraphs; } /** * Issues a get request to fetch the requested data points */ public void getFromServer() { client.updateVariable(uidlId, TimelineConstants.VARIABLE_SEND, true, true); } /** * Returns the colormap where the graph colors are stored * * @return A map of colors */ Map<Integer, String> getColorMap() { return colors; } /** * Returns the thicknesses for the graphs * * @return */ Map<Integer, Double> getThicknessMap() { return thicknesses; } /** * Returns the caps for the graphs * * @return */ Map<Integer, Boolean> getCapsMap() { return caps; } /** * Get the colormap used in the browser * * @return */ public Map<Integer, String> getBrowserColorMap() { return browserColors; } /** * Returns the colormap where the graph fill colors are stored * * @return A map of colors */ public Map<Integer, String> getFillColorMap() { return fillcolors; } public Map<Integer, String> getBrowserFillColorMap() { return browserFillColors; } /** * Set the starting date text field * * @param date * The date */ public void setFromDateTextField(Date date) { intervalStartDate = date; if (dateSelectVisible) { if (date != null) { dateFrom.setText(dts.formatDate(date, dateFormatInfo.getDisplayFormat().getPattern())); } else { dateFrom.setText(""); } } } /** * Set the ending date text field * * @param date * The date */ public void setToDateTextField(Date date) { intervalEndDate = date; if (dateSelectVisible) { if (date != null) { dateTo.setText(dts.formatDate(date, dateFormatInfo.getDisplayFormat().getPattern())); } else { dateTo.setText(""); } } } /** * The top bar height * * @return Height in pixels */ public int getTopBarHeight() { if (topBar.isVisible()) { return topBar.getOffsetHeight(); } else { return 0; } } /** * The caption height * * @return Height in pixels */ public int getCaptionHeight() { if (caption.isVisible()) { return caption.getOffsetHeight(); } else { return 0; } } /** * The legend height * * @return height in pixels */ public int getLegendHeight() { if (modeLegendBar.isVisible()) { return modeLegendBar.getOffsetHeight(); } else { return 0; } } /** * A zoom level was clicked * * @param evt * The click event */ private void zoomLevelClicked(ClickEvent evt) { evt.preventDefault(); // If we have no data do nothing if (noDataAvailable) { return; } // Was a zoom level clicked Long time = zoomLevels.get(evt.getSource()); Long totalTime = getEndDate().getTime() - getStartDate().getTime(); if (totalTime >= time) { // Calculate the center Date center; if (browserIsVisible) { Long selectedTime = browser.getSelectedEndDate().getTime() - browser.getSelectedStartDate().getTime(); center = new Date(browser.getSelectedStartDate().getTime() + selectedTime / 2L); } else { center = new Date(display.getSelectionStartDate().getTime() + time / 2L); } // Calculate start date Date start = new Date(center.getTime() - time / 2L); if (start.before(getStartDate())) { start = getStartDate(); } // Calculate end date Date end = new Date(start.getTime() + time); if (end.after(getEndDate())) { end = getEndDate(); } // Set the browser if (browserIsVisible) { setBrowserRange(start, end); } // Set the display setDisplayRange(start, end); } else { if (browserIsVisible) { setBrowserRange(getStartDate(), getEndDate()); } setDisplayRange(getStartDate(), getEndDate()); } } /** * Sets the legend and graph visibilites * * @param graph * The graph index * @param visibility * The visibility */ private void setLegendCaptionVisibility(int graph, boolean visibility) { // Store the visiblities graphVisibilites.put(graph, visibility); // Remove cached points for hidden graphs if (!visibility) { display.removeGraph(graph); } // Remove legend entries if (legendCaptions.size() > graph) { Label caption = legendCaptions.get(graph); HTML color = legendColors.get(graph); Label value = legendValues.get(graph); caption.setVisible(visibility); color.setVisible(visibility); value.setVisible(visibility); } } /** * Timer to prevent flogging the server with date range changed events */ private Timer dateRangeChangeEventTimer = new Timer() { @Override public void run() { String[] values = new String[] { String.valueOf(selectedStartDate.getTime()), String.valueOf(selectedEndDate.getTime()) }; client.updateVariable(uidlId, TimelineConstants.VARIABLE_DATE_RANGE_CHANGED_EVENT, values, true); } }; /** * Fire a date range change event */ public void fireDateRangeChangedEvent() { if (dateRangeChangeEventsEnabled && display.getSelectionStartDate() != null && display.getSelectionEndDate() != null) { selectedStartDate = display.getSelectionStartDate(); selectedEndDate = display.getSelectionEndDate(); dateRangeChangeEventTimer.cancel(); dateRangeChangeEventTimer.schedule(100); } } /** * Fire a event button click event * * @param indexes */ public void fireEventButtonClickEvent(List<Integer> indexes) { if (eventClickListenersEnabled) { String[] ixs = new String[indexes.size()]; for (int i = 0; i < indexes.size(); i++) { ixs[i] = String.valueOf(indexes.get(i)); } client.updateVariable(uidlId, TimelineConstants.VARIABLE_EVENT_BUTTON_CLICK, ixs, true); } } /** * Returns the height of the widget in pixels * * @return A pixel height */ public int getWidgetHeight() { try { int height = Integer.parseInt(DOM.getAttribute(getElement(), "height").replaceAll("px", "")); return height; } catch (Exception e) { try { int height = Integer.parseInt(DOM.getStyleAttribute(getElement(), "height").replaceAll("px", "")); return height; } catch (Exception f) { return getOffsetHeight(); } } } public int getWidgetWidth() { try { int width = Integer.parseInt(DOM.getAttribute(getElement(), "width").replaceAll("px", "")); return width; } catch (Exception e) { try { int width = Integer.parseInt(DOM.getStyleAttribute(getElement(), "width").replaceAll("px", "")); return width; } catch (Exception f) { return getOffsetWidth(); } } } /** * Get the browser height * * @return The height in pixels */ public int getBrowserHeight() { if (browserIsVisible) { return browser.getOffsetHeight(); } else { return 0; } } /** * Returns true if a graph is visible * * @param graph * The graph index * @return True if graph is visible, false if not */ public boolean graphIsVisible(int graph) { if (graphVisibilites.get(graph) == null) { return true; } return graphVisibilites.get(graph); } /** * The idle state of the widget * * @return If the widget is idle true is returned else false */ public boolean isIdle() { return isIdle; } /** * Sets the legend value * * @param graph * The graph the value is from * @param value * The value */ public void setLegendValue(int graph, float value) { if (legendValues.size() > graph) { Label lbl = legendValues.get(graph); if (lbl != null) { NumberFormat format = display.getVerticalAxisNumberFormat(); lbl.setText(format.format(value) + " " + units.get(graph)); } } } /** * Get the unit of the vertical scale * * @param graph * The graph * @return */ public String getVerticalUnit(int graph) { return units.get(graph); } /** * Has the widget been properly initialized * * @return */ public boolean isInitDone() { return initDone; } /** * Are the graphs stacked * * @return */ public boolean isGraphsStacked() { return graphStacking; } /** * Are the bars in the bar chart plotted uniformly * * @return */ public boolean isBarChartUniform() { return uniformBarThickness; } /** * Get the selections start date * * @return */ public Date getSelectedStartDate() { return selectedStartDate; } /** * Get the selects end date */ public Date getSelectedEndDate() { return selectedEndDate; } /** * Sets the date formats used by the timeline. Recieved from the server. * * @param uidl * The UIDL which contains the date format info */ private void setDateFormatInfo(UIDL uidl) { if (uidl.hasAttribute(TimelineConstants.ATTRIBUTE_DATE_FORMATS)) { dateFormatInfo.setDateFormatInfo(uidl); // Update textfields with the new format setToDateTextField(intervalEndDate); setFromDateTextField(intervalStartDate); // Update scales by redrawing if (isInitDone()) { display.redraw(); } } } /** * * Returns the date formats used by the timeline Get date formats */ public VDateFormatInfo getDateFormats() { return dateFormatInfo; } /* * (non-Javadoc) * * @see * com.google.gwt.event.dom.client.KeyPressHandler#onKeyPress(com.google * .gwt.event.dom.client.KeyPressEvent) */ @Override public void onKeyPress(KeyPressEvent event) { if (!inTextBoxes(event)) { event.preventDefault(); handleKeyboardEvent(event); } } private boolean inTextBoxes(KeyEvent<?> event) { Element eventTarget = event.getNativeEvent().getEventTarget().cast(); if (eventTarget == dateFrom.getElement() || eventTarget == dateTo.getElement()) { return true; } return false; } /* * (non-Javadoc) * * @see * com.google.gwt.event.dom.client.KeyUpHandler#onKeyUp(com.google.gwt.event * .dom.client.KeyUpEvent) */ @Override public void onKeyUp(KeyUpEvent event) { if (!inTextBoxes(event)) { event.preventDefault(); handleKeyboardEvent(event); } } /* * (non-Javadoc) * * @see * com.google.gwt.event.dom.client.KeyDownHandler#onKeyDown(com.google.gwt * .event.dom.client.KeyDownEvent) */ @Override public void onKeyDown(KeyDownEvent event) { if (!inTextBoxes(event)) { event.preventDefault(); handleKeyboardEvent(event); } } /* * (non-Javadoc) * * @see com.vaadin.terminal.gwt.client.Focusable#focus() */ @Override public void focus() { setFocus(true); } /** * Handles keyboard events recieved from the user * * @param event * The event recieved */ protected void handleKeyboardEvent(KeyEvent<? extends EventHandler> event) { int keyCode = event.getNativeEvent().getKeyCode(); if (browser.isVisible()) { /* * Using browser to scroll with */ if (event.getAssociatedType() == KeyUpEvent.getType()) { browser.refreshSelection(); } else if (keyCode == KeyCodes.KEY_LEFT) { browser.scrollLeft(event.isShiftKeyDown()); } else if (keyCode == KeyCodes.KEY_RIGHT) { browser.scrollRight(event.isShiftKeyDown()); } else if (keyCode == KeyCodes.KEY_UP) { browser.zoomIn(5); } else if (keyCode == KeyCodes.KEY_DOWN) { browser.zoomOut(5); } } else { /* * Using display to scroll if browser is not available */ if (keyCode == KeyCodes.KEY_LEFT) { display.scrollLeft(event.isShiftKeyDown()); } else if (keyCode == KeyCodes.KEY_RIGHT) { display.scrollRight(event.isShiftKeyDown()); } else if (keyCode == KeyCodes.KEY_UP) { // TODO VConsole.error("Zooming when no browser bar present not implemented"); } else if (keyCode == KeyCodes.KEY_DOWN) { // TODO VConsole.error("Zooming when no browser bar present not implemented"); } } } /** * Are graph shadows enabled */ public boolean isGraphShadows() { return graphShadows; } /** * Returns the amount of offscreen points which should be rendered * * @return */ int getOffscreenRenderingPoints() { return offscreenPoints; } }