client.ui.components.VectorMap.java Source code

Java tutorial

Introduction

Here is the source code for client.ui.components.VectorMap.java

Source

/*
 * 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.ui.components;

import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
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.Widget;

import client.ClientConf;
import client.ui.components.utils.Script;

/**
 * Widget displaying a map.
 * http://jvectormap.com
 */
public class VectorMap extends Composite {
    /**
     * Map displayed by a {@link VectorMap}.
     */
    public static enum Visual {
        /**
         * Map of Europe.
         */
        EUROPE("europe_mill_en", ClientConf.asset("js/jvectormap/jvectormap-europe-mill-en.js")),

        /**
         * Map of the World.
         */
        WORLD("world_mill_en", ClientConf.asset("js/jvectormap/jvectormap-world-mill-en.js"));

        /**
         * Map identifier.
         */
        private String name;

        /**
         * Map script.
         */
        private String script;

        /**
         * Initialize {@code Visual}.
         *
         * @param name Map identifier.
         * @param script Map script.
         */
        private Visual(String name, String script) {
            this.name = name;
            this.script = script;
        }

        /**
         * Get map identifier.
         *
         * @return Map identifier.
         */
        public String getName() {
            return name;
        }

        /**
         * Get map script.
         *
         * @return Map script.
         */
        public String getScript() {
            return script;
        }
    }

    public interface VectorMapUiBinder extends UiBinder<Widget, VectorMap> {
    }

    private static VectorMapUiBinder uiBinder = GWT.create(VectorMapUiBinder.class);

    /**
     * Element containing the map.
     */
    @UiField
    public DivElement div;

    /**
     * Library base script.
     */
    public static final String BASE_SCRIPT = ClientConf.asset("js/jvectormap/jvectormap-2.0.1.min.js");

    /**
     * {@link Script.Loader} for {@link VectorMap#BASE_SCRIPT}.
     */
    public static final Script.Loader BASE_SCRIPT_LOADER = new Script.Loader(BASE_SCRIPT, Script.JQUERY);

    /**
     * Map displayed.
     */
    private Visual visual;

    /**
     * {@link Script.Loader} for the current {@link Visual}.
     */
    private Script.Loader visualScriptLoader;

    /**
     * Whether the current {@code Visual} is loaded.
     */
    private boolean visualLoaded = false;

    /**
     * Initialize {@code VectorMap}.
     */
    public VectorMap() {
        initWidget(uiBinder.createAndBindUi(this));
    }

    /**
     * Initialize {@code VectorMap}.
     *
     * @param visual {@link Visual} that specifies the map to display.
     */
    public VectorMap(Visual visual) {
        this();
        setVisual(visual);
    }

    /**
     * Set the {@link Visual} that specifies the map to display.
     *
     * @param visual Map to display.
     */
    public void setVisual(Visual visual) {
        this.visual = visual;
        visualScriptLoader = new Script.Loader(visual.getScript(), BASE_SCRIPT_LOADER);
    }

    /**
     * Load the required scripts.
     *
     * @param callback {@code Runnable} called when ready.
     */
    private void loadVisual(final Runnable callback) {
        visualScriptLoader.load(new Runnable() {
            @Override
            public void run() {
                if (!visualLoaded) {
                    loadVisual(visual.getName());
                    visualLoaded = true;
                }

                callback.run();
            }
        });
    }

    /**
     * Initialize map graphics.
     *
     * @param visualName Map identifier from a loaded {@link Visual}.
     */
    private native void loadVisual(String visualName) /*-{
                                                      (function (that, $, jvm) {
                                                      var div = $(that.@client.ui.components.VectorMap::div);
                                                          
                                                      that.map = new jvm.Map({
                                                      container: div,
                                                      map: visualName,
                                                      backgroundColor: 'transparent',
                                                      zoomOnScroll: false,
                                                      regionStyle: {
                                                      initial: {
                                                      fill: '#DDDDDD'
                                                      },
                                                      hover: {
                                                      cursor: 'pointer'
                                                      }
                                                      },
                                                      series: {
                                                      regions: [{
                                                      values: {},
                                                      scale: ['#DDDDDD', '#666666'],
                                                      normalizeFunction: 'linear'
                                                      }],
                                                      },
                                                      onRegionTipShow: function(event, label, code) {
                                                      var data = that.series.values;
                                                          
                                                      if (data[code] != undefined) {
                                                      label.html(
                                                      label.text() + ' (' +
                                                      Math.floor(data[code] * 10) / 10 + ')');
                                                      }
                                                      }
                                                      });
                                                          
                                                      that.series = that.map.series.regions[0];
                                                      })(this, $wnd.jQuery, $wnd.jvm);
                                                      }-*/;

    /**
     * Get a {@code JavaScriptObject} containing map information as
     * required by the library.
     *
     * @param data {@code Map} of ISO codes and values.
     * @return {@code JavaScriptObject} as required by the library.
     */
    private JavaScriptObject dataToJSObject(Map<String, Double> data) {
        if (data == null) {
            return null;
        }

        JSONObject dataObject = new JSONObject();

        for (Map.Entry<String, Double> entry : data.entrySet()) {
            dataObject.put(entry.getKey(), new JSONNumber(entry.getValue()));
        }

        return dataObject.getJavaScriptObject();
    }

    /**
     * Set data displayed by the map.
     *
     * @param data {@code Map} of ISO codes and values.
     */
    public void setData(final Map<String, Double> data) {
        loadVisual(new Runnable() {
            @Override
            public void run() {
                setData(dataToJSObject(data));
            }
        });
    }

    /**
     * Display the specified data.
     *
     * @param data Map information as required by the library.
     * @see VectorMap#dataToJSObject
     */
    private native void setData(JavaScriptObject data) /*-{
                                                       (function (that, $, jvm) {
                                                       var div = $(that.@client.ui.components.VectorMap::div);
                                                           
                                                       that.map.reset();
                                                           
                                                       that.series.params.min = undefined;
                                                       that.series.params.max = undefined;
                                                       that.series.setValues(data);
                                                           
                                                       setTimeout(function () {
                                                       that.map.updateSize();
                                                       });
                                                       })(this, $wnd.jQuery, $wnd.jvm);
                                                       }-*/;
}