view src/DML/MainVisBundle/Resources/assets/marionette/modules/GraphicsRenderingModule/GraphicsRenderingModule.20-Renderer.geography.js @ 1:f38015048f48 tip

Added GPL
author Daniel Wolff
date Sat, 13 Feb 2016 20:43:38 +0100
parents 493bcb69166c
children
line wrap: on
line source
"use strict";

App.module("GraphicsRenderingModule", function(GraphicsRenderingModule, App, Backbone, Marionette, $, _, Logger) {

    GraphicsRenderingModule.addInitializer(function(options){

        // Map data source: http://data.okfn.org/data/datasets/geo-boundaries-world-110m#resource-countries
        GraphicsRenderingModule.registerRenderer({
            id: "geography",
            inherit: "_",

            defaultVegaConfig: {
                comparisonMode: null,

                transformPropertiesByRegion: {
                    "planet": {
                        defaultScale: 500,
                        translateProportionX: 1/2,
                        translateProportionY: 1/2,
                        circleSizeMult: 20
                    },
                    "africa": {
                        defaultScale: 100,
                        translateProportionX: 0.20,
                        translateProportionY: .5,
                        circleSizeMult: 50
                    },
                    "europe": {
                        defaultScale: 70,
                        translateProportionX: 0.20,
                        translateProportionY: 1.90,
                        circleSizeMult: 50
                    }
                },

                symbolSize: 20,
                internalSpaceOffset: 6,
                colorForData: "#3182bd",

                padding: {"top": 10, "left": 10, "bottom": 10, "right": 10},
            },


            _formVC: function(vc, data) {
                vc.width  = vc.totalWidth  - vc.padding.left - vc.padding.right;
                vc.height = vc.totalHeight - vc.padding.top  - vc.padding.bottom;


                // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
                // Data

                var countryStatsByCountryNumericCode = {};
                var hist = data.self.stats ? data.self.stats.hist : null;
                if (!hist) {
                    hist = {
                            counts: [],
                            places: []
                    }
                }

                var countTotal = data.self.coverage.errors_count + data.self.coverage.failed_count;
                var countFailures = countTotal;

                for (var i = hist.counts.length - 1; i >= 0; --i) {
                    var countryNumericCode = vc.placeCountryNumericCodes[hist.places[i]];
                    countTotal += hist.counts[i];
                    if (!countryNumericCode) {
                        countFailures += hist.counts[i];
                        continue;
                    }
                    var country = vc.countriesByCountryNumericCode[countryNumericCode];

                    var countryStats = countryStatsByCountryNumericCode[countryNumericCode];
                    if (!countryStats) {
                        countryStats = {
                                numericCode: country[1],
                                name: country[2],
                                count: 0
                            };
                        countryStatsByCountryNumericCode[countryNumericCode] = countryStats;
                    }
                    countryStats.count += hist.counts[i];
                }

                var countryStats = _.values(countryStatsByCountryNumericCode);

                for (var i = countryStats.length - 1; i >= 0; --i) {
                    var count = countryStats[i].count;
                    var percentage = 100 * count / countTotal;
                    countryStats[i].percentage = percentage;
                }

                // .............................................................
                // Data - points
                vc.data.push({
                    "name": "countries",
                    "values": vc.countries
                });

                // .............................................................
                // Data - country outlines
                vc.data.push({
                    "name": "countryOutlines",
                    "values": vc.countryOutlines,
                    "format": {
                        "type": "topojson",
                        "feature": "countries"
                    }
                });

                // .............................................................
                // Data - country stats
                vc.data.push({
                    "name": "countryStats",
                    "values": countryStats
                });

                // .............................................................
                // Data - country summary
                var transformProperties = vc.transformPropertiesByRegion[vc.region];
                vc.data.push({
                    "name": "countrySummary",
                    "source": "countryOutlines",
                    "transform": [
                      {
                        "type": "geopath",
                        "value": "data",
                        "projection": "eckert3",
                        "scale": 100 / transformProperties.defaultScale * vc.width,
                        "translate": [
                          vc.width * transformProperties.translateProportionX,
                          vc.height * transformProperties.translateProportionY
                        ]
                      },
                      { "type": "lookup", "on": "countryStats", "onKey": "numericCode",
                        "keys": ["id"], "as": ["cs"], "default": {"count": 0, "percentage": 0}},

                      { "type": "lookup", "on": "countries", "onKey": "1",
                          "keys": ["id"], "as": ["tooltip"], "default": null}
                    ]
                });


                // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
                // Scales

                // .............................................................
                // Scale - color
                vc.scales.push({
                    "name": "color",
                    "type": "linear",
                    "domain": [0, 0.01, 50],
                    "clamp": true,
                    "range": ["#ccc", "#c6dbef", "#055893"]
                  });


                // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
                // Marks

                // .............................................................
                // Mark - background (to catch mouse events and remove tooltips)
                vc.marks.push({
                   "type": "rect",
                   "properties": {
                       "enter": {
                           "x": {"value": -vc.padding.left},
                           "y": {"value": -vc.padding.top},
                           "fill": {"value": "#fff"},
                           "y2": {"field": {"group": "height"}, "offset": vc.padding.left + vc.padding.right},
                           "x2": {"field": {"group": "width"},  "offset": vc.padding.top + vc.padding.bottom},
                       }
                   }
                });


                // .............................................................
                // Mark - countries as polygons
                if (!vc.showCountriesAsCircles) {
                    vc.marks.push({
                        "type": "path",
                        "from": {
                            "data": "countrySummary",
                        },
                        "properties": {
                            "enter": {
                                "stroke": {"value": "#fff"},
                                "path": {"field": "layout_path"}
                            },
                            "update": {
                                "fill": {"scale": "color", "field": "cs.percentage"}
                            },
                            "hover": {
                                "fill": {"value": "#000"},
                            }
                        }
                    });

                // .............................................................
                // Mark - countries as circles
                } else {
                    vc.marks.push({
                        "type": "path",
                        "from": {
                            "data": "countrySummary",
                        },
                        "properties": {
                            "enter": {
                                "stroke": {"value": "#fff"},
                                "path": {"field": "layout_path"}
                            },
                            "update": {
                                "fill": {"value": "#f0f0f0"}
                            }
                        }
                    });
                    vc.marks.push({
                        "type": "symbol",
                        "from": {
                            "data": "countrySummary",
                            "transform": [{"type":"centroid", "field": "layout_path"}],
                        },
                        "properties": {
                            "enter": {
                                //"size": {/*"scale": "color",*/ "value": 100},
                                "size": {/*"scale": "color",*/ "field": "cs.percentage", "mult": transformProperties.circleSizeMult},
                                "opacity": {"value": 0.5},
                                "x": {"field": "centroid_x"},
                                "y": {"field": "centroid_y"}
                            },
                            "update": {
                                "fill": {"value": vc.colorForData}
                            },
                            "hover": {
                                "fill": {"value": "#000"},
                            }
                        }
                    });
                }
            },
        });
    });
}, Logger);