/* * WBI Indicator Explorer * * Copyright 2015 Sebastian Nogara <snogaraleal@gmail.com> * * This file is part of WBI. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package client.dashboard; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.TabLayoutPanel; import com.google.gwt.user.client.ui.Widget; import rpc.client.ClientRequest; import client.history.CountryHistory; import client.history.IndicatorHistory; import client.history.IntervalHistory; import client.history.SeriesPanelHistory; import client.managers.models.CountryManager; import client.managers.models.IndicatorManager; import client.managers.models.IntervalManager; import client.managers.models.SeriesManager; import client.serializers.CSVSeriesSerializer; import client.serializers.JSONSeriesSerializer; import client.serializers.XMLSeriesSerializer; import client.ui.GlobalLoadingIndicator; import client.ui.SeriesSerializerDialogBox; import client.ui.components.MaterialButton; import client.ui.components.VectorMap; import client.ui.coordinators.SimpleCoordinator; import client.ui.coordinators.TabCoordinator; import client.ui.views.country.CountrySelector; import client.ui.views.indicator.IndicatorSelector; import client.ui.views.interval.IntervalSwitch; import client.ui.views.series.ChartSeriesView; import client.ui.views.series.MapSeriesView; import client.ui.views.series.SeriesView; import client.ui.views.series.TableSeriesView; /** * Main viewport widget. */ public class Dashboard extends Composite { public interface DashboardUiBinder extends UiBinder<Widget, Dashboard> {} private static DashboardUiBinder uiBinder = GWT.create(DashboardUiBinder.class); /** * Root widget containing all other widgets. */ @UiField public FlowPanel viewport; /** * Tab panel for indicators (left panel). */ @UiField public TabLayoutPanel indicatorPanel; /** * Tab panel for countries (right panel). */ @UiField public TabLayoutPanel countryPanel; /** * Tab panel for series (center panel). */ @UiField public TabLayoutPanel seriesPanel; /** * Floating panel. */ @UiField public FlowPanel overlay; /** * Interval selector (part of {@code overlay}). */ @UiField public IntervalSwitch seriesInterval; /** * Serializers buttons (part of {@code overlay}). */ @UiField public FlowPanel seriesAnchors; /* * Model managers */ private IntervalManager intervalManager = new IntervalManager(); private IndicatorManager indicatorManager = new IndicatorManager(); private CountryManager countryManager = new CountryManager(); private SeriesManager seriesManager = new SeriesManager(); /** * Initialize viewport. */ public Dashboard() { initWidget(uiBinder.createAndBindUi(this)); setupLoadingIndicator(); initIntervalComponents(); initIndicatorComponents(); initCountryComponents(); initSeriesComponents(); } /** * Add {@code GlobalLoadingIndicator} to the viewport. */ private void setupLoadingIndicator() { viewport.add(GlobalLoadingIndicator.get()); /* * Change the visibility of the loading indicator when RPC requests * are sent and received. */ ClientRequest.addGlobalListener(new ClientRequest.GlobalListener() { @Override public void onSend(ClientRequest<?> clientRequest) { GlobalLoadingIndicator.start(); } @Override public void onFinish(ClientRequest<?> clientRequest) { GlobalLoadingIndicator.finish(); } }); } /** * Connect views and history to the main {@code IntervalManager}. */ private void initIntervalComponents() { SimpleCoordinator<IntervalManager> intervalCoordinator = new SimpleCoordinator<IntervalManager>(intervalManager); intervalCoordinator.setView(seriesInterval); new IntervalHistory().connect(intervalManager); // Select the last interval option by default if (intervalManager.getSelectedOption() == null) { intervalManager.select( IntervalManager.OPTIONS[IntervalManager.OPTIONS.length - 1]); } } /** * Connect views and history to the main {@code IndicatorManager}. */ private void initIndicatorComponents() { TabCoordinator<IndicatorManager> indicatorTabCoordinator = new TabCoordinator<IndicatorManager>( indicatorManager, indicatorPanel); indicatorTabCoordinator.addTab( "search", "Indicators", new IndicatorSelector()); new IndicatorHistory().connect(indicatorManager); } /** * Connect views and history to the main {@code CountryManager}. */ private void initCountryComponents() { TabCoordinator<CountryManager> countryTabCoordinator = new TabCoordinator<CountryManager>(countryManager, countryPanel); countryTabCoordinator.addTab( "search", "Countries", new CountrySelector()); new CountryHistory().connect(countryManager); } /** * Connect views and history to the main {@code IntervalManager}. */ private void initSeriesComponents() { seriesManager.connect(intervalManager); seriesManager.connect(indicatorManager); seriesManager.connect(countryManager); final TabCoordinator<SeriesManager> seriesTabCoordinator = new TabCoordinator<SeriesManager>(seriesManager, seriesPanel); seriesTabCoordinator.addTab( "table", "Table", new TableSeriesView()); seriesTabCoordinator.addTab( "chart", "Chart", new ChartSeriesView()); seriesTabCoordinator.addTab( "map:world", "Map: World", new MapSeriesView(VectorMap.Visual.WORLD)); seriesTabCoordinator.addTab( "map:europe", "Map: Europe", new MapSeriesView(VectorMap.Visual.EUROPE)); /* * Serializers */ addSeriesSerializer("CSV", new CSVSeriesSerializer()); addSeriesSerializer("XML", new XMLSeriesSerializer()); addSeriesSerializer("JSON", new JSONSeriesSerializer()); /* * Tabs */ new SeriesPanelHistory().connect(seriesTabCoordinator); autoEnableScroll(seriesTabCoordinator, seriesPanel.getSelectedIndex()); seriesPanel.addSelectionHandler(new SelectionHandler<Integer>() { @Override public void onSelection(SelectionEvent<Integer> event) { autoEnableScroll(seriesTabCoordinator, event.getSelectedItem()); } }); SelectionEvent.fire(seriesPanel, seriesPanel.getSelectedIndex()); } /** * Add a {@code SeriesManager.Serializer} to the serializers menu. * * @param title Display name of the serializer. * @param serializer Serializer instance. */ private void addSeriesSerializer( String title, SeriesManager.Serializer serializer) { MaterialButton button = new MaterialButton(title); button.setAnimationEnabled(true); button.addClickHandler( new SeriesSerializerDialogBox.OpenClickHandler( seriesManager, serializer)); seriesAnchors.add(button); } /** * Class name added to {@code overlay} when scrollbars are enabled in * the series tab panel. */ private static final String CLASS_NAME_OVERLAY_SCROLL = "overlay-scroll"; /** * Enable or disable scrollbars depending on the current tab. * * @param seriesTabCoordinator {@code TabCoordinator} managing series tabs. * @param tabIndex Index of the current tab. */ private void autoEnableScroll( TabCoordinator<SeriesManager> seriesTabCoordinator, int tabIndex) { Element overlayElement = overlay.getElement(); if (tabIndex == 0) { overlayElement.addClassName(CLASS_NAME_OVERLAY_SCROLL); } else { overlayElement.removeClassName(CLASS_NAME_OVERLAY_SCROLL); } SeriesView view = (SeriesView) seriesTabCoordinator.getView(0); if (view != null) { if (tabIndex == 0) { view.setScrollEnabled(true); } else { view.setScrollEnabled(false); } } } }