Package com.vaadin.addon.timeline.gwt.client

Source Code of com.vaadin.addon.timeline.gwt.client.VTimelineWidget

package com.vaadin.addon.timeline.gwt.client;

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.dom.client.Element;
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.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
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.google.gwt.user.client.ui.VerticalPanel;
import com.vaadin.addon.timeline.gwt.client.VTimelineDisplay.PlotMode;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.ValueMap;

/**
* VTimelineWidget
*
* @author Peter Lehto / IT Mill Oy Ltd
* @author John Ahlroos / IT Mill Oy Ltd
*/

public class VTimelineWidget extends Composite implements Paintable,
VMouseOutListener {

    // 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+"-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";

    // Time constants
    private static final Long MONTH = 2629743830L;
    private static final Long DAY = 86400000L;

    // Handlers
    private final FocusHandler dateSelectFocusHandler = new FocusHandler() {
        @Override
        public void onFocus(FocusEvent event) {
            dateSelectEnter(event);
        }
    };
    private final BlurHandler dateSelectBlurHandler = new BlurHandler() {
        @Override
        public void onBlur(BlurEvent event) {
            dateSelectLeave(event);
        }
    };
    private final KeyDownHandler dateSelectEnterHandler = new KeyDownHandler() {
        @Override
        public void onKeyDown(KeyDownEvent event) {
            if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                ((TextBox) event.getSource()).setFocus(false);
            }
        }
    };
    private final ClickHandler modeClickHandler = new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
            if (event.getSource() == lineModeBtn) {
                setChartMode(PlotMode.LINE);
            } else if (event.getSource() == barModeBtn) {
                setChartMode(PlotMode.BAR);
            } else if (event.getSource() == scatterModeBtn) {
                setChartMode(PlotMode.SCATTER);
            }
        }
    };
    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 initDone = false;
    private boolean noDataAvailable = false;

    // Components
    private VTimelineDisplay display;
    private VTimelineBrowser browser;
    private final Map<Integer, VClientCache> multiLevelCache = new HashMap<Integer, VClientCache>();

    // Base
    private final VerticalPanel root = new VerticalPanel();
    private final Label caption;
    private Integer pixelWidth = null;
    private String currentWidth;
    private String currentHeight;
    private boolean isIdle = true;
    private boolean doPreloading = false;
    private boolean clientCacheEnabled = true;
    private PlotMode initPlotMode = PlotMode.LINE;
    private String initGridColor = "rgb(200,200,200)";

    // 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>();

    // Mouse events
    private List<VMouseClickListener> mouseClickListeners;
    private List<VMouseMoveListener> mouseMoveListeners;
    private List<VMouseOutListener> mouseOutListeners;
    private List<VMouseOverListener> mouseOverListeners;
    private List<VMouseScrollListener> mouseScrollListeners;

    // Graph specific properties
    private Date startDate = null;
    private Date endDate = null;
    private int numGraphs = 0;

    // Graph colors
    private final Map<Integer, List<Integer>> colors = new HashMap<Integer, List<Integer>>();
    private final Map<Integer, List<Integer>> fillcolors = new HashMap<Integer, List<Integer>>();

    // Browser colors
    private final Map<Integer, List<Integer>> browserColors = new HashMap<Integer, List<Integer>>();
    private final Map<Integer, List<Integer>> browserFillColors = new HashMap<Integer, List<Integer>>();

    // 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<Anchor, Long> zoomLevels = new HashMap<Anchor, Long>();

    // Event handling
    private boolean changeEventsActive = false;

    // 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;

    public VTimelineWidget() {

        root.setStyleName(CLASSNAME);
        initWidget(root);

        caption = new Label("");
        caption.setStyleName(CAPTION_CLASSNAME);
        caption.setVisible(false);
        root.add(caption);

        endDate = new Date();
        startDate  = new Date(endDate.getTime()-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.addStyleName(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.addKeyDownHandler(dateSelectEnterHandler);
        dateFrom.addFocusHandler(dateSelectFocusHandler);
        dateFrom.addBlurHandler(dateSelectBlurHandler);
        dateFrom.setReadOnly(!dateSelectEnabled);
        dateFrom.setStyleName(CLASSNAME_DATEFIELD);
        dateRangeBar.add(dateFrom);

        Label dash = new Label();
        dash.setText("-");
        dateRangeBar.add(dash);

        dateTo = new TextBox();
        dateTo.addKeyDownHandler(dateSelectEnterHandler);
        dateTo.addFocusHandler(dateSelectFocusHandler);
        dateTo.addBlurHandler(dateSelectBlurHandler);
        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.setVisible(lineChartModeVisible);
        lineModeBtn.setStyleName(CLASSNAME_CHARTMODELINE);
        lineModeBtn.setTitle("Line Graph");
        chartModeBar.add(lineModeBtn);

        barModeBtn = new Button("", modeClickHandler);
        barModeBtn.setVisible(barChartModeVisible);
        barModeBtn.setStyleName(CLASSNAME_CHARTMODEBAR);
        barModeBtn.setTitle("Bar Graph");
        chartModeBar.add(barModeBtn);

        scatterModeBtn = new Button("", modeClickHandler);
        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);
    }

    /**
     * Updates the chart mode and sends the new chart mode to the server
     *
     * @param mode
     *            The chart mode
     */
    private void setChartMode(PlotMode mode) {
        if (mode != null) {
            display.setChartMode(mode, true);
            client.updateVariable(uidlId, "chartMode", mode.toString(), true);
        }
    }

    /**
     * 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) {
        Anchor level = new Anchor(caption);
        level.addClickHandler(zoomClickHandler);
        zoomLevels.put(level, time);
        zoomBar.add(level);
    }

    /**
     * Add mouse listener
     * @param mouseMoveListener
     *     The listener
     */
    private void addMouseMoveListener(VMouseMoveListener mouseMoveListener) {
        mouseMoveListeners.add(mouseMoveListener);
    }

    /**
     * Add mouse listener
     * @param mouseClickListener
     *     The listener
     */
    private void addMouseClickListener(VMouseClickListener mouseClickListener) {
        mouseClickListeners.add(mouseClickListener);
    }

    /**
     * Add mouse listener
     * @param mouseScrollListener
     *     The listener
     */
    private void addMouseScrollListener(VMouseScrollListener mouseScrollListener) {
        mouseScrollListeners.add(mouseScrollListener);
    }

    /**
     * Initializes the widget
     */
    private void init() {

        // Add the mouse listeners
        mouseClickListeners = new LinkedList<VMouseClickListener>();
        mouseMoveListeners = new LinkedList<VMouseMoveListener>();
        mouseOutListeners = new LinkedList<VMouseOutListener>();
        mouseOverListeners = new LinkedList<VMouseOverListener>();
        mouseScrollListeners = new LinkedList<VMouseScrollListener>();

        // Sink the mouse events
        Event.addNativePreviewHandler(new Event.NativePreviewHandler() {
            @Override
            public void onPreviewNativeEvent(NativePreviewEvent nativeEvent) {
                if (initDone) {
                    Event event = (Event) nativeEvent.getNativeEvent();
                    Element e = Element.as(event.getEventTarget());

                    if (display.hasElement(e) || browser.hasElement(e)
                            || DOM.eventGetType(event) == Event.ONMOUSEUP
                            || DOM.eventGetType(event) == Event.ONMOUSEMOVE) {

                        // Prevent default browser behaviour
                        event.preventDefault();

                        // Notify listeners of event
                        onBrowserEvent(event);
                    }
                }
            }
        });

        //Add the display
        display = new VTimelineDisplay(this);
        display.setWidth("100%");
        display.setHeight("100%");
        root.add(display);

        // Add the browser
        browser = new VTimelineBrowser(this);
        browser.setWidth("100%");
        browser.setVisible(browserIsVisible);
        root.add(browser);

        addMouseMoveListener(display);
        addMouseClickListener(display);
        addMouseScrollListener(display);

        addMouseMoveListener(browser);
        addMouseClickListener(browser);
        addMouseScrollListener(browser);

        // Add density 1 cache with background loading
        multiLevelCache.put(1, new VClientCache(this, true));

        int h = getWidgetHeight() - getLegendHeight() - getCaptionHeight()
        - getTopBarHeight() - getBrowserHeight() - 2;
        display.setCanvasHeight(h);

        client.updateVariable(uidlId, "init", true, false);
        client.updateVariable(uidlId, "canvasWidth", getWidgetWidth(), true);
    }

    /*
     * (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) {

        boolean refresh = false;
        Date refreshStartDate = null;
        Date refreshEndDate = null;

        // Set the pixel width
        if (uidl.hasAttribute("width")) {
            String width = uidl.getStringAttribute("width");
            if(width.contains("px")){
                pixelWidth = Integer.parseInt(width.replace("px", ""));
            } else {
                pixelWidth = null;
            }
        }

        // Set the caption
        if (uidl.hasAttribute("caption")) {
            String captionText = uidl.getStringAttribute("caption");
            if (captionText.equals("")) {
                caption.setText("");
                caption.setVisible(false);
            } else {
                caption.setText(captionText);
                caption.setVisible(true);
            }

        }

        // Check parent components
        if (client.updateComponent(this, uidl, true)) {
            return;
        }

        // Store reference variables for later usage
        this.client = client;
        uidlId = uidl.getId();

        // Get the container sizes
        if (uidl.hasVariable("ContainerSizes")) {
            int[] sizes = uidl.getIntArrayVariable("ContainerSizes");
            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
            multiLevelCache.clear();
            multiLevelCache.put(1, new VClientCache(this, true));
        }

        // Activate change events
        if(uidl.hasAttribute("e1")) {
            changeEventsActive = uidl.getBooleanAttribute("e1");
        }

        // Should preloading be used
        if(uidl.hasAttribute("load")){
            doPreloading = uidl.getBooleanAttribute("load");
            if(doPreloading){
                for(VClientCache cache : multiLevelCache.values()){
                    cache.stopPreloading();
                }
            }
        }

        // Should client cache be used
        if(uidl.hasAttribute("cache")){
            clientCacheEnabled = uidl.getBooleanAttribute("cache");

            // Clear current cache
            multiLevelCache.clear();
            multiLevelCache.put(1, new VClientCache(this, true));
        }

        // Set the start date
        if(uidl.hasAttribute("startDate")) {
            startDate = new Date(uidl.getLongAttribute("startDate"));
        }

        // Set the end date
        if(uidl.hasAttribute("endDate")) {
            endDate = new Date(uidl.getLongAttribute("endDate"));
        }

        /*
         * Check if we have a container with only one point?
         */
        if (startDate.equals(endDate)) {
            long halfDay = DAY / 2L;
            startDate = new Date(startDate.getTime() - halfDay);
            endDate = new Date(endDate.getTime() + halfDay);

        }

        // Set the number of graphs
        if(uidl.hasAttribute("numGraphs")){
            numGraphs = uidl.getIntAttribute("numGraphs");
        }

        // Set the graph colors
        if(uidl.hasAttribute("colors")){
            colors.clear();
            String[] colorStrings = uidl.getStringArrayAttribute("colors");
            for(int s=0; s<colorStrings.length; s++){
                List<Integer> colorComponents = new ArrayList<Integer>();
                String[] comp = colorStrings[s].split(";");
                colorComponents.add(Integer.parseInt(comp[0]));
                colorComponents.add(Integer.parseInt(comp[1]));
                colorComponents.add(Integer.parseInt(comp[2]));
                colors.put(s, colorComponents);
            }
        }

        // Set the browser colors
        if(uidl.hasAttribute("bcolors")){
            browserColors.clear();
            String[] colorStrings = uidl.getStringArrayAttribute("bcolors");
            for(int s=0; s<colorStrings.length; s++){
                List<Integer> colorComponents = new ArrayList<Integer>();
                String[] comp = colorStrings[s].split(";");
                colorComponents.add(Integer.parseInt(comp[0]));
                colorComponents.add(Integer.parseInt(comp[1]));
                colorComponents.add(Integer.parseInt(comp[2]));
                browserColors.put(s, colorComponents);
            }
        }

        // Set the fill colors of the graphs
        if(uidl.hasAttribute("fillcolors")){
            fillcolors.clear();
            String[] colorStrings = uidl.getStringArrayAttribute("fillcolors");
            for(int s=0; s<colorStrings.length; s++){
                List<Integer> colorComponents = new ArrayList<Integer>();
                String[] comp = colorStrings[s].split(";");
                colorComponents.add(Integer.parseInt(comp[0]));
                colorComponents.add(Integer.parseInt(comp[1]));
                colorComponents.add(Integer.parseInt(comp[2]));
                colorComponents.add(Integer.parseInt(comp[3]));
                fillcolors.put(s, colorComponents);
            }
        }

        // Set the browser fill colors
        if(uidl.hasAttribute("bfillcolors")){
            browserFillColors.clear();
            String[] colorStrings = uidl.getStringArrayAttribute("bfillcolors");
            for(int s=0; s<colorStrings.length; s++){
                List<Integer> colorComponents = new ArrayList<Integer>();
                String[] comp = colorStrings[s].split(";");
                colorComponents.add(Integer.parseInt(comp[0]));
                colorComponents.add(Integer.parseInt(comp[1]));
                colorComponents.add(Integer.parseInt(comp[2]));
                colorComponents.add(Integer.parseInt(comp[3]));
                browserFillColors.put(s, colorComponents);
            }
        }

        // Set the graph legend captions
        if(uidl.hasVariable("captions")){
            String[] caps = uidl.getStringArrayVariable("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");
                        List<Integer> cc = colors.get(graph);
                        DOM.setStyleAttribute(color.getElement(), "color", "rgb("+cc.get(0)+","+cc.get(1)+","+cc.get(2)+")");
                        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);
                }
            }
        }

        // Set the graph visibilities
        if(uidl.hasVariable("gvis")){
            String[] v = uidl.getStringArrayVariable("gvis");
            for (int i = 0; i < v.length; i++) {
                setLegendCaptionVisibility(i, Boolean.parseBoolean(v[i]));
            }

            if (initDone) {
                refresh = true;
            }
        }

        // Set the selected time range
        Date initStartDate = null;
        Date initEndDate = null;
        if (uidl.hasVariable("selectStart") && uidl.hasVariable("selectEnd")) {
            final Date start = new Date(uidl.getLongVariable("selectStart"));
            final Date end = new Date(uidl.getLongVariable("selectEnd"));

            if (!initDone) {
                initStartDate = start;
                initEndDate = end;

                /*
                 * If init dates are exactly the same then we are dealing with a
                 * container with only one point. So, we set the dates to
                 * display a day.
                 */
                if (initStartDate.equals(initEndDate)) {
                    long halfDay = DAY / 2L;
                    initStartDate = new Date(start.getTime() - halfDay);
                    initEndDate = new Date(start.getTime() + halfDay);

                }

            } else {
                refresh = true;
                refreshStartDate = start;
                refreshEndDate = end;
            }
        }

        // Set vertical fitting
        if(uidl.hasVariable("vfit")){
            boolean auto = uidl.getBooleanVariable("vfit");
            float min = 0f;
            float max = 0f;

            if(uidl.hasVariable("vmin") && uidl.hasVariable("vmax")){
                min = uidl.getFloatVariable("vmin");
                max = uidl.getFloatVariable("vmax");
            }

            display.setVerticalFitting(auto, min, max);
        }

        // Set vertical unit in the graph legend
        if(uidl.hasVariable("vunit")){
            String[] gUnits = uidl.getStringArrayVariable("vunit");
            for (int g = 0; g < gUnits.length; g++) {
                units.put(g, gUnits[g]);
            }
        }

        // Enable line caps
        if (uidl.hasAttribute("lineCaps") && display != null) {
            display.setLineCaps(uidl.getBooleanAttribute("lineCaps"), initDone);
        }

        // Set line thickness
        if (uidl.hasAttribute("lineGraphThickness") && display != null) {
            display.setLineThickness(uidl
                    .getDoubleAttribute("lineGraphThickness"), initDone);
        }

        // Set browser visibility
        if (uidl.hasAttribute("browserVisibility")) {
            browserIsVisible = uidl.getBooleanAttribute("browserVisibility");

            if (browser != null) {
                browser.setVisible(browserIsVisible);
            }
        }

        // Set zoom visibility
        if (uidl.hasAttribute("zoomVisibility")) {
            zoomIsVisible = uidl.getBooleanAttribute("zoomVisibility");

            if (zoomBar != null) {
                zoomBar.setVisible(zoomIsVisible);
                topBar.setVisible(zoomIsVisible || dateSelectVisible);
            }
        }

        // Set date select visibility
        if (uidl.hasAttribute("dateSelectVisibility")) {
            dateSelectVisible = uidl
            .getBooleanAttribute("dateSelectVisibility");

            if (dateRangeBar != null) {
                dateRangeBar.setVisible(dateSelectVisible);
                topBar.setVisible(zoomIsVisible || dateSelectVisible);
            }
        }

        // Set date select enabled
        if (uidl.hasAttribute("dateSelectEnabled")) {
            dateSelectEnabled = uidl.getBooleanAttribute("dateSelectEnabled");

            dateFrom.setReadOnly(!dateSelectEnabled);
            dateTo.setReadOnly(!dateSelectEnabled);
        }

        // Set chart mode visibility
        if (uidl.hasAttribute("chartModeVisibility")) {
            chartModeVisible = uidl.getBooleanAttribute("chartModeVisibility");
            if (chartModeBar != null) {
                chartModeBar.setVisible(chartModeVisible);
            }
        }

        // Set line chart mode visible
        if (uidl.hasAttribute("lineChartModeVisible")) {
            lineChartModeVisible = uidl
            .getBooleanAttribute("lineChartModeVisible");
            if (lineModeBtn != null) {
                lineModeBtn.setVisible(lineChartModeVisible);
                chartModeBar
                .setVisible(chartModeVisible
                        && (lineChartModeVisible || barChartModeVisible || scatterChartModeVisible));
            }
        }

        // Set bar chart mode visible
        if (uidl.hasAttribute("barChartModeVisible")) {
            barChartModeVisible = uidl
            .getBooleanAttribute("barChartModeVisible");
            if (barModeBtn != null) {
                barModeBtn.setVisible(barChartModeVisible);
                chartModeBar
                .setVisible(chartModeVisible
                        && (lineChartModeVisible || barChartModeVisible || scatterChartModeVisible));
            }
        }

        // Set scatter chart mode visible
        if (uidl.hasAttribute("scatterChartModeVisible")) {
            scatterChartModeVisible = uidl
            .getBooleanAttribute("scatterChartModeVisible");
            if (scatterModeBtn != null) {
                scatterModeBtn.setVisible(scatterChartModeVisible);
                chartModeBar
                .setVisible(chartModeVisible
                        && (lineChartModeVisible || barChartModeVisible || scatterChartModeVisible));
            }
        }

        // Set legend visible
        if (uidl.hasAttribute("legendVisibility")) {
            legendVisible = uidl.getBooleanAttribute("legendVisibility");
            if (legend != null) {
                legend.setVisible(legendVisible);
                modeLegendBar.setVisible(legendVisible
                        || chartModeBar.isVisible());
            }
        }

        // Set zoom levels visible
        if (uidl.hasAttribute("zoomLevels")) {
            ValueMap levelMap = uidl.getMapAttribute("zoomLevels");

            if (zoomBar != null) {
                for (Anchor lvl : zoomLevels.keySet()) {
                    zoomBar.remove(lvl);
                }
            }
            zoomLevels.clear();

            for (String caption : levelMap.getKeySet()) {
                Long time = Long.parseLong(levelMap.getString(caption));
                addZoomLevel(caption, time);
            }
        }

        // Set the chart mode
        if (uidl.hasAttribute("chartMode")) {
            initPlotMode = PlotMode.valueOf(uidl
                    .getStringAttribute("chartMode"));
            if (initStage1Done && initPlotMode != null) {
                display.setChartMode(initPlotMode, initDone);
            }
        }

        // Set the graph grid color
        if(uidl.hasAttribute("gridColor")) {
            String color = uidl.getStringAttribute("gridColor");
            if (color == null || color.equals("")) {
                initGridColor = null;
            } else {
                String[] rgba = color.split(";");
                initGridColor = "rgba(" + rgba[0] + "," + rgba[1] + ","
                + rgba[2] + "," + rgba[3] + ")";
            }

            if (initStage1Done) {
                display.setGridColor(initGridColor);
            }
        }

        // Initialization stage 1
        if(!initStage1Done){
            init();
            initStage1Done = true;

            // Initialization done
        } else if(!initDone){
            initDone = true;

            if (initStartDate != null && initEndDate != null) {

                // Request given init date
                display.setRange(initStartDate, initEndDate, true, true, false);
                browser.setRange(initStartDate, initEndDate);
            } else {
                // Request the default range
                display.setRange(getStartDate(), getEndDate(), true, true, false);
                browser.setRange(getStartDate(), getEndDate());
            }

            fireDateRangeChangedEvent();
        }

        // Data received
        if (uidl.hasAttribute("data")) {
            ValueMap map = uidl.getMapAttribute("data");
            ValueMap changedDensitiesMap = uidl.getMapAttribute("cdensities");

            List<Long> removableRequests = new LinkedList<Long>();

            //Check waiting data list
            for (Long req : waitingForData.keySet()) {
                for (String req2 : map.getKeySet()) {
                    if (req2.equals(req.toString())) {
                        VDataListener comp = waitingForData.get(req);

                        // Get the values.
                        List<String> values = new ArrayList<String>();
                        String valuesString = map.getString(req2);
                        if (valuesString != null && !valuesString.equals("")) {
                            for (String val : map.getString(req2).split(";")) {
                                values.add(val);
                            }
                        }

                        List<Float> fvalues = new ArrayList<Float>();
                        List<Date> dvalues = new ArrayList<Date>();
                        Integer density = densityMap.get(req);

                        if (changedDensitiesMap != null) {
                            /*
                             * Note: This might throw an exception when using
                             * hosted mode for an unknown reason. If that
                             * happens then continue to use the last known
                             * density which will work as expected.
                             */
                            try {
                                Integer newDensity = changedDensitiesMap
                                .getInt(req2);
                                if (newDensity != null) {
                                    density = newDensity;
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }

                        Long lastTime = null;
                        Long prePointTime = null;
                        Float prePointValue = 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 time is less than zero then it means it is before the first selected
                            //time and that again means we have a prepoint.
                            if(time < 0){
                                prePointTime = time;
                                prePointValue = value;
                                continue;
                            }

                            // 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);
                        }

                        // We got a point outside the selected range. This is used so we can
                        // render the graf browsing smoothly.
                        if(prePointTime != null){
                            dvalues.add(0, new Date(dvalues.get(0).getTime()+prePointTime));
                            fvalues.add(0, prePointValue);
                        }

                        //Get markers
                        Set<String> markers = null;
                        if(uidl.hasVariable("markers")) {
                            markers = uidl.getStringArrayVariableAsSet("markers");
                        }

                        //Get events
                        Set<String> events = null;
                        if(uidl.hasVariable("events")) {
                            events = uidl.getStringArrayVariableAsSet("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, false);
                                    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);

                        //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();
        }

        if(uidl.hasAttribute("refresh")){
            refresh = true;
        }

        // Refresh the component if requested by any command
        if (refresh) {
            redraw(refreshStartDate, refreshEndDate);
        }

        // Disable component since no data source has been defined on the server
        if(uidl.hasAttribute("nodata")){
            setWidgetNoData(true);
        }

    }

    private void redraw(Date start, Date end) {
        if (browserIsVisible) {
            if (start == null) {
                start = browser.getSelectedStartDate();
            }
            if (end == null) {
                end = browser.getSelectedEndDate();
            }

            display.setForcedPlotting(true);
            display.setRange(start, end, true, true, false);

            browser.setRange(start, end);
            browser.redraw();
        } else {
            if (start == null) {
                start = display.getSelectionStartDate();
            }
            if (end == null) {
                end = display.getSelectionEndDate();
            }

            display.setForcedPlotting(true);
            display.setRange(start, end, true, true, false);
        }
    }

    /**
     * Set the not data state
     * @param enabled
     */
    private void setWidgetNoData(boolean enabled){
        noDataAvailable = enabled;

        display.displayNoDataMessage(enabled);

        display.setEnabled(!enabled);
        browser.setEnabled(!enabled);

        barModeBtn.setEnabled(!enabled);
        lineModeBtn.setEnabled(!enabled);
        scatterModeBtn.setEnabled(!enabled);

        dateFrom.setEnabled(!enabled);
        dateTo.setEnabled(!enabled);

        for (Anchor lvl : zoomLevels.keySet()) {
            lvl.setEnabled(!enabled);
        }
    }

    /**
     * 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){

        isIdle = false;
        requestCounter++;
        component.setCurrentRequestId(Long.valueOf(requestCounter), graphIndex);

        waitingForData.put(requestCounter, component);
        requestGraphMap.put(requestCounter, graphIndex);
        densityMap.put(requestCounter, density);

        client.updateVariable(uidlId, "ddata-"+requestCounter, new Object[] {
                Long.valueOf(requestCounter), Integer.valueOf(graphIndex),
                Long.valueOf(startDate.getTime()),
                Long.valueOf(endDate.getTime()), Integer.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 = 999999F;
            Float totalMaximum = -999999F;

            for (int g = 0; g < getNumGraphs(); 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];

                    /*
                     * 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);
                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;
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * com.google.gwt.user.client.ui.Composite#onBrowserEvent(com.google.gwt
     * .user.client.Event)
     */
    @Override
    public void onBrowserEvent(Event event) {
        if (uidlId == null || client == null) {
            return;
        }

        switch (DOM.eventGetType(event)) {
        case Event.ONMOUSEMOVE: {
            fireMouseMoveEvent(event);
            break;
        }
        case Event.ONMOUSEDOWN: {
            fireMouseDownEvent(event);
            break;
        }
        case Event.ONMOUSEUP: {
            fireMouseUpEvent(event);
            break;
        }
        case Event.ONMOUSEOUT: {
            fireMouseOutEvent(event);
            break;
        }
        case Event.ONMOUSEOVER: {
            fireMouseOverEvent(event);
            break;
        }
        case Event.ONMOUSEWHEEL: {
            fireMouseScrollEvent(event);
        }
        }
    }

    /**
     * @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, boolean useCurtain, boolean loadAllPoints){
        display.setRange(start, end, useCurtain, loadAllPoints, false);
    }

    /**
     * Set the displayed date range
     * @param start
     *     The start date
     * @param end
     *     The end date
     * @param useCurtain'
     *     Should the loading curtain be displayed
     */
    public void setDisplayRange(Date start, Date end, boolean useCurtain){
        setDisplayRange(start, end, useCurtain,true);
    }

    /**
     * Set the selected date range
     * @param start
     *     The start date
     * @param end
     *     The end date
     */
    public void setBrowserRange(Date start, Date end) {
        browser.setRange(start, end);
    }

    /**
     * Fire a mouse event
     * @param mouseEvent
     *     The event
     */
    private void fireMouseMoveEvent(Event mouseEvent) {
        for (VMouseMoveListener mouseMoveListener : mouseMoveListeners) {
            mouseMoveListener.mouseMoved(mouseEvent);
        }
    }

    /**
     * Fire a mouse event
     * @param mouseEvent
     *     The event
     */
    private void fireMouseDownEvent(Event mouseEvent) {
        for (VMouseClickListener mouseClickListener : mouseClickListeners) {
            mouseClickListener.mouseDown(mouseEvent);
        }
    }

    /**
     * Fire a mouse event
     * @param mouseEvent
     *     The event
     */
    private void fireMouseUpEvent(Event mouseEvent) {
        for (VMouseClickListener mouseClickListener : mouseClickListeners) {
            mouseClickListener.mouseUp(mouseEvent);
        }
    }

    /**
     * Fire a mouse event
     * @param mouseEvent
     *     The event
     */
    private void fireMouseOutEvent(Event mouseEvent) {
        for(VMouseOutListener mouseOutListener : mouseOutListeners){
            mouseOutListener.mouseOut(mouseEvent);
        }
    }

    /**
     * Fire a mouse event
     * @param mouseEvent
     *     The event
     */
    private void fireMouseOverEvent(Event mouseEvent) {
        for(VMouseOverListener mouseOverListener : mouseOverListeners){
            mouseOverListener.mouseOver(mouseEvent);
        }
    }

    /**
     * Fire a mouse event
     * @param up
     *     Is the mouse scrolled up or down
     */
    private void fireMouseScrollEvent(Event mouseEvent) {
        for(VMouseScrollListener mouseScrollListener : mouseScrollListeners){
            mouseScrollListener.scroll(mouseEvent);
        }
    }

    /**
     * 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
     */
    @SuppressWarnings("deprecation")
    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
     */
    @SuppressWarnings("deprecation")
    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, "send", true, true);
    }

    /**
     * Returns the colormap where the graph colors are stored
     * @return
     *     A map of colors
     */
    public Map<Integer, List<Integer>> getColorMap(){
        return colors;
    }

    /**
     * Get the colormap used in the browser
     * @return
     */
    public Map<Integer, List<Integer>> getBrowserColorMap(){
        return browserColors;
    }

    /**
     * Returns the colormap where the graph fill colors are stored
     * @return
     *     A map of colors
     */
    public Map<Integer, List<Integer>> getFillColorMap(){
        return fillcolors;
    }

    public Map<Integer, List<Integer>> getBrowserFillColorMap(){
        return browserFillColors;
    }

    /**
     * Set the starting date text field
     * @param date
     *     The date
     */
    public void setFromDateTextField(Date date){
        intervalStartDate = date;

        DateTimeFormat formatter = DateTimeFormat.getFormat("MMM d, y");
        dateFrom.setText(formatter.format(date));
    }

    /**
     * Set the ending date text field
     * @param date
     *     The date
     */
    public void setToDateTextField(Date date){
        intervalEndDate = date;

        DateTimeFormat formatter = DateTimeFormat.getFormat("MMM d, y");
        dateTo.setText(formatter.format(date));
    }

    /**
     * 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, true);

        } else {
            if (browserIsVisible) {
                setBrowserRange(getStartDate(), getEndDate());
            }

            setDisplayRange(getStartDate(), getEndDate(), true);
        }
    }

    /**
     * The date select is focused
     *
     * @param event
     *            The focus event
     */
    public void dateSelectEnter(FocusEvent event) {
        if (!dateSelectEnabled) {
            return;
        }

        if (event.getRelativeElement() == dateTo.getElement()) {

            dateTo.setStyleName(CLASSNAME_DATEFIELDEDIT);

            DateTimeFormat formatter = DateTimeFormat.getFormat("dd/MM/yyyy");

            dateTo.setText(formatter.format(intervalEndDate));
            dateTo.selectAll();

        } else if (event.getRelativeElement() == dateFrom.getElement()) {
            dateFrom.setStyleName(CLASSNAME_DATEFIELDEDIT);

            DateTimeFormat formatter = DateTimeFormat.getFormat("dd/MM/yyyy");

            dateFrom.setText(formatter.format(intervalStartDate));
            dateFrom.selectAll();
        }
    }

    /**
     * The date select is blurred
     *
     * @param event
     *            The blur event
     */
    public void dateSelectLeave(BlurEvent event) {
        if (!dateSelectEnabled) {
            return;
        }

        // Start date text field selected
        if (event.getRelativeElement() == dateTo.getElement()) {

            dateTo.setStyleName(CLASSNAME_DATEFIELD);

            DateTimeFormat format = DateTimeFormat.getFormat("dd/MM/yyyy");

            Date end = format.parse(dateTo.getText());

            DateTimeFormat formatter = DateTimeFormat.getFormat("MMM d, y");

            if (end.compareTo(getEndDate()) <= 0
                    && end.compareTo(intervalStartDate) > 0) {
                dateTo.setText(formatter.format(end));
                intervalEndDate = end;

                setBrowserRange(intervalStartDate, intervalEndDate);
                setDisplayRange(intervalStartDate, intervalEndDate, true);
            } else {
                dateTo.setText(formatter.format(intervalEndDate));
            }

            // End date textfield selected
        } else if (event.getRelativeElement() == dateFrom.getElement()) {

            dateFrom.setStyleName(CLASSNAME_DATEFIELD);

            DateTimeFormat format = DateTimeFormat.getFormat("dd/MM/yyyy");
            Date start = format.parse(dateFrom.getText());

            DateTimeFormat formatter = DateTimeFormat.getFormat("MMM d, y");

            if (start.compareTo(getStartDate()) >= 0
                    && start.compareTo(intervalEndDate) < 0) {
                dateFrom.setText(formatter.format(start));

                intervalStartDate = start;

                setBrowserRange(intervalStartDate, intervalEndDate);
                setDisplayRange(intervalStartDate, intervalEndDate, true);
            } else {
                dateFrom.setText(formatter.format(intervalStartDate));
            }
        }
    }

    /**
     * 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);
        }
    }

    /**
     * Fire a date range change event
     */
    public void fireDateRangeChangedEvent(){
        if(display.getSelectionStartDate() != null &&
                display.getSelectionEndDate() != null && changeEventsActive){
            Object[] values = new Object[]{
                    display.getSelectionStartDate().getTime(),
                    display.getSelectionEndDate().getTime(),
            };

            client.updateVariable(uidlId, "drce", values, true);
        }
    }

    /**
     * Fire a event button click event
     * @param indexes
     */
    public void fireEventButtonClickEvent(List<Integer> indexes){
        client.updateVariable(uidlId, "ebce", indexes.toArray(), true);
    }

    /**
     * Returns the width of the display
     * @return
     *     Width in pixels
     */
    @SuppressWarnings("deprecation")
    public int getWidgetWidth(){
        if(pixelWidth != null) {
            return pixelWidth;
        } else{
            try{
                int width = Integer.parseInt(DOM.getAttribute(root.getElement(), "width").replaceAll("px", ""));
                return width;
            } catch(Exception e){
                try{
                    int width = Integer.parseInt(DOM.getStyleAttribute(root.getElement(), "width").replaceAll("px", ""));
                    return width;
                } catch(Exception f){
                    return root.getOffsetWidth();
                }
            }
        }
    }

    /**
     * Returns the height of the widget in pixels
     *
     * @return A pixel height
     */
    @SuppressWarnings("deprecation")
    public int getWidgetHeight() {
        try {
            int height = Integer.parseInt(DOM.getAttribute(root.getElement(),
            "height").replaceAll("px", ""));
            return height;
        } catch (Exception e) {
            try {
                int height = Integer.parseInt(DOM.getStyleAttribute(
                        root.getElement(), "height").replaceAll("px", ""));
                return height;
            } catch (Exception f) {
                return root.getOffsetHeight();
            }
        }
    }

    /**
     * Get the browser height
     * @return
     *     The height in pixels
     */
    public int getBrowserHeight(){
        if (browserIsVisible) {
            return browser.getOffsetHeight();
        } else {
            return 0;
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see com.google.gwt.user.client.ui.UIObject#setWidth(java.lang.String)
     */
    @Override
    public void setWidth(String width) {
        if (initDone && !width.equals(currentWidth)) {
            currentWidth = width;

            // Store dates before resizing
            Date start, end;
            if (browserIsVisible) {
                start = browser.getSelectedStartDate();
                end = browser.getSelectedEndDate();
            } else {
                start = display.getSelectionStartDate();
                end = display.getSelectionEndDate();
            }

            super.setWidth(width);

            int w = getWidgetWidth();
            display.setCanvasWidth(w);
            browser.setCanvasWidth(w);

            redraw(start, end);

        } else {
            super.setWidth(width);
        }
    }

    @Override
    public void setHeight(String height) {
        if (initDone && !height.equals(currentHeight)) {
            currentHeight = height;

            // Store dates before resizing
            Date start, end;
            if (browserIsVisible) {
                start = browser.getSelectedStartDate();
                end = browser.getSelectedEndDate();
            } else {
                start = display.getSelectionStartDate();
                end = display.getSelectionEndDate();
            }

            super.setHeight(height);

            int h = getWidgetHeight() - getLegendHeight() - getCaptionHeight()
            - getTopBarHeight() - getBrowserHeight() - 2;
            display.setCanvasHeight(h);

            redraw(start, end);

        } else {
            super.setHeight(height);
        }
    }

    /**
     * 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);
    }

    /*
     * (non-Javadoc)
     * @see com.vaadin.trends.ws.client.VMouseOutListener#mouseOut(com.google.gwt.user.client.Event)
     */
    @Override
    public void mouseOut(Event mouseEvent) {
        Element mouseMovedFrom = Element.as(mouseEvent.getEventTarget());

        if(browser.hasElement(mouseMovedFrom)){
            browser.mouseOut(mouseEvent);
        }
    }

    /**
     * The idle state of the widget
     * @return
     *     If the widget is idle true is returned else false
     */
    public boolean isIdle(){
        return isIdle;
    }

    /**
     * Turns preloading on/off
     * @return
     */
    public boolean usePreloading(){
        return doPreloading;
    }

    /**
     * Sets the preloading percent
     * @param percent
     *     The percent of the preloading completion
     */
    public void setPreloadingPercent(int percent){
        display.setCacheLoadingPercentage(percent);
    }

    /**
     * Sets the legend value
     * @param graph
     *     The graph the value is from
     * @param value
     *     The value
     */
    public void setLegendValue(int graph, String value){
        Label lbl = legendValues.get(graph);
        if(lbl != null) {
            lbl.setText(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);
    }
}
TOP

Related Classes of com.vaadin.addon.timeline.gwt.client.VTimelineWidget

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.