Daniel@0
|
1 "use strict";
|
Daniel@0
|
2
|
Daniel@0
|
3 App.module("GraphicsRenderingModule", function(GraphicsRenderingModule, App, Backbone, Marionette, $, _, Logger) {
|
Daniel@0
|
4
|
Daniel@0
|
5 GraphicsRenderingModule.addInitializer(function(options){
|
Daniel@0
|
6
|
Daniel@0
|
7 // Map data source: http://data.okfn.org/data/datasets/geo-boundaries-world-110m#resource-countries
|
Daniel@0
|
8 GraphicsRenderingModule.registerRenderer({
|
Daniel@0
|
9 id: "geography",
|
Daniel@0
|
10 inherit: "_",
|
Daniel@0
|
11
|
Daniel@0
|
12 defaultVegaConfig: {
|
Daniel@0
|
13 comparisonMode: null,
|
Daniel@0
|
14
|
Daniel@0
|
15 transformPropertiesByRegion: {
|
Daniel@0
|
16 "planet": {
|
Daniel@0
|
17 defaultScale: 500,
|
Daniel@0
|
18 translateProportionX: 1/2,
|
Daniel@0
|
19 translateProportionY: 1/2,
|
Daniel@0
|
20 circleSizeMult: 20
|
Daniel@0
|
21 },
|
Daniel@0
|
22 "africa": {
|
Daniel@0
|
23 defaultScale: 100,
|
Daniel@0
|
24 translateProportionX: 0.20,
|
Daniel@0
|
25 translateProportionY: .5,
|
Daniel@0
|
26 circleSizeMult: 50
|
Daniel@0
|
27 },
|
Daniel@0
|
28 "europe": {
|
Daniel@0
|
29 defaultScale: 70,
|
Daniel@0
|
30 translateProportionX: 0.20,
|
Daniel@0
|
31 translateProportionY: 1.90,
|
Daniel@0
|
32 circleSizeMult: 50
|
Daniel@0
|
33 }
|
Daniel@0
|
34 },
|
Daniel@0
|
35
|
Daniel@0
|
36 symbolSize: 20,
|
Daniel@0
|
37 internalSpaceOffset: 6,
|
Daniel@0
|
38 colorForData: "#3182bd",
|
Daniel@0
|
39
|
Daniel@0
|
40 padding: {"top": 10, "left": 10, "bottom": 10, "right": 10},
|
Daniel@0
|
41 },
|
Daniel@0
|
42
|
Daniel@0
|
43
|
Daniel@0
|
44 _formVC: function(vc, data) {
|
Daniel@0
|
45 vc.width = vc.totalWidth - vc.padding.left - vc.padding.right;
|
Daniel@0
|
46 vc.height = vc.totalHeight - vc.padding.top - vc.padding.bottom;
|
Daniel@0
|
47
|
Daniel@0
|
48
|
Daniel@0
|
49 // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
Daniel@0
|
50 // Data
|
Daniel@0
|
51
|
Daniel@0
|
52 var countryStatsByCountryNumericCode = {};
|
Daniel@0
|
53 var hist = data.self.stats ? data.self.stats.hist : null;
|
Daniel@0
|
54 if (!hist) {
|
Daniel@0
|
55 hist = {
|
Daniel@0
|
56 counts: [],
|
Daniel@0
|
57 places: []
|
Daniel@0
|
58 }
|
Daniel@0
|
59 }
|
Daniel@0
|
60
|
Daniel@0
|
61 var countTotal = data.self.coverage.errors_count + data.self.coverage.failed_count;
|
Daniel@0
|
62 var countFailures = countTotal;
|
Daniel@0
|
63
|
Daniel@0
|
64 for (var i = hist.counts.length - 1; i >= 0; --i) {
|
Daniel@0
|
65 var countryNumericCode = vc.placeCountryNumericCodes[hist.places[i]];
|
Daniel@0
|
66 countTotal += hist.counts[i];
|
Daniel@0
|
67 if (!countryNumericCode) {
|
Daniel@0
|
68 countFailures += hist.counts[i];
|
Daniel@0
|
69 continue;
|
Daniel@0
|
70 }
|
Daniel@0
|
71 var country = vc.countriesByCountryNumericCode[countryNumericCode];
|
Daniel@0
|
72
|
Daniel@0
|
73 var countryStats = countryStatsByCountryNumericCode[countryNumericCode];
|
Daniel@0
|
74 if (!countryStats) {
|
Daniel@0
|
75 countryStats = {
|
Daniel@0
|
76 numericCode: country[1],
|
Daniel@0
|
77 name: country[2],
|
Daniel@0
|
78 count: 0
|
Daniel@0
|
79 };
|
Daniel@0
|
80 countryStatsByCountryNumericCode[countryNumericCode] = countryStats;
|
Daniel@0
|
81 }
|
Daniel@0
|
82 countryStats.count += hist.counts[i];
|
Daniel@0
|
83 }
|
Daniel@0
|
84
|
Daniel@0
|
85 var countryStats = _.values(countryStatsByCountryNumericCode);
|
Daniel@0
|
86
|
Daniel@0
|
87 for (var i = countryStats.length - 1; i >= 0; --i) {
|
Daniel@0
|
88 var count = countryStats[i].count;
|
Daniel@0
|
89 var percentage = 100 * count / countTotal;
|
Daniel@0
|
90 countryStats[i].percentage = percentage;
|
Daniel@0
|
91 }
|
Daniel@0
|
92
|
Daniel@0
|
93 // .............................................................
|
Daniel@0
|
94 // Data - points
|
Daniel@0
|
95 vc.data.push({
|
Daniel@0
|
96 "name": "countries",
|
Daniel@0
|
97 "values": vc.countries
|
Daniel@0
|
98 });
|
Daniel@0
|
99
|
Daniel@0
|
100 // .............................................................
|
Daniel@0
|
101 // Data - country outlines
|
Daniel@0
|
102 vc.data.push({
|
Daniel@0
|
103 "name": "countryOutlines",
|
Daniel@0
|
104 "values": vc.countryOutlines,
|
Daniel@0
|
105 "format": {
|
Daniel@0
|
106 "type": "topojson",
|
Daniel@0
|
107 "feature": "countries"
|
Daniel@0
|
108 }
|
Daniel@0
|
109 });
|
Daniel@0
|
110
|
Daniel@0
|
111 // .............................................................
|
Daniel@0
|
112 // Data - country stats
|
Daniel@0
|
113 vc.data.push({
|
Daniel@0
|
114 "name": "countryStats",
|
Daniel@0
|
115 "values": countryStats
|
Daniel@0
|
116 });
|
Daniel@0
|
117
|
Daniel@0
|
118 // .............................................................
|
Daniel@0
|
119 // Data - country summary
|
Daniel@0
|
120 var transformProperties = vc.transformPropertiesByRegion[vc.region];
|
Daniel@0
|
121 vc.data.push({
|
Daniel@0
|
122 "name": "countrySummary",
|
Daniel@0
|
123 "source": "countryOutlines",
|
Daniel@0
|
124 "transform": [
|
Daniel@0
|
125 {
|
Daniel@0
|
126 "type": "geopath",
|
Daniel@0
|
127 "value": "data",
|
Daniel@0
|
128 "projection": "eckert3",
|
Daniel@0
|
129 "scale": 100 / transformProperties.defaultScale * vc.width,
|
Daniel@0
|
130 "translate": [
|
Daniel@0
|
131 vc.width * transformProperties.translateProportionX,
|
Daniel@0
|
132 vc.height * transformProperties.translateProportionY
|
Daniel@0
|
133 ]
|
Daniel@0
|
134 },
|
Daniel@0
|
135 { "type": "lookup", "on": "countryStats", "onKey": "numericCode",
|
Daniel@0
|
136 "keys": ["id"], "as": ["cs"], "default": {"count": 0, "percentage": 0}},
|
Daniel@0
|
137
|
Daniel@0
|
138 { "type": "lookup", "on": "countries", "onKey": "1",
|
Daniel@0
|
139 "keys": ["id"], "as": ["tooltip"], "default": null}
|
Daniel@0
|
140 ]
|
Daniel@0
|
141 });
|
Daniel@0
|
142
|
Daniel@0
|
143
|
Daniel@0
|
144 // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
Daniel@0
|
145 // Scales
|
Daniel@0
|
146
|
Daniel@0
|
147 // .............................................................
|
Daniel@0
|
148 // Scale - color
|
Daniel@0
|
149 vc.scales.push({
|
Daniel@0
|
150 "name": "color",
|
Daniel@0
|
151 "type": "linear",
|
Daniel@0
|
152 "domain": [0, 0.01, 50],
|
Daniel@0
|
153 "clamp": true,
|
Daniel@0
|
154 "range": ["#ccc", "#c6dbef", "#055893"]
|
Daniel@0
|
155 });
|
Daniel@0
|
156
|
Daniel@0
|
157
|
Daniel@0
|
158 // :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
Daniel@0
|
159 // Marks
|
Daniel@0
|
160
|
Daniel@0
|
161 // .............................................................
|
Daniel@0
|
162 // Mark - background (to catch mouse events and remove tooltips)
|
Daniel@0
|
163 vc.marks.push({
|
Daniel@0
|
164 "type": "rect",
|
Daniel@0
|
165 "properties": {
|
Daniel@0
|
166 "enter": {
|
Daniel@0
|
167 "x": {"value": -vc.padding.left},
|
Daniel@0
|
168 "y": {"value": -vc.padding.top},
|
Daniel@0
|
169 "fill": {"value": "#fff"},
|
Daniel@0
|
170 "y2": {"field": {"group": "height"}, "offset": vc.padding.left + vc.padding.right},
|
Daniel@0
|
171 "x2": {"field": {"group": "width"}, "offset": vc.padding.top + vc.padding.bottom},
|
Daniel@0
|
172 }
|
Daniel@0
|
173 }
|
Daniel@0
|
174 });
|
Daniel@0
|
175
|
Daniel@0
|
176
|
Daniel@0
|
177 // .............................................................
|
Daniel@0
|
178 // Mark - countries as polygons
|
Daniel@0
|
179 if (!vc.showCountriesAsCircles) {
|
Daniel@0
|
180 vc.marks.push({
|
Daniel@0
|
181 "type": "path",
|
Daniel@0
|
182 "from": {
|
Daniel@0
|
183 "data": "countrySummary",
|
Daniel@0
|
184 },
|
Daniel@0
|
185 "properties": {
|
Daniel@0
|
186 "enter": {
|
Daniel@0
|
187 "stroke": {"value": "#fff"},
|
Daniel@0
|
188 "path": {"field": "layout_path"}
|
Daniel@0
|
189 },
|
Daniel@0
|
190 "update": {
|
Daniel@0
|
191 "fill": {"scale": "color", "field": "cs.percentage"}
|
Daniel@0
|
192 },
|
Daniel@0
|
193 "hover": {
|
Daniel@0
|
194 "fill": {"value": "#000"},
|
Daniel@0
|
195 }
|
Daniel@0
|
196 }
|
Daniel@0
|
197 });
|
Daniel@0
|
198
|
Daniel@0
|
199 // .............................................................
|
Daniel@0
|
200 // Mark - countries as circles
|
Daniel@0
|
201 } else {
|
Daniel@0
|
202 vc.marks.push({
|
Daniel@0
|
203 "type": "path",
|
Daniel@0
|
204 "from": {
|
Daniel@0
|
205 "data": "countrySummary",
|
Daniel@0
|
206 },
|
Daniel@0
|
207 "properties": {
|
Daniel@0
|
208 "enter": {
|
Daniel@0
|
209 "stroke": {"value": "#fff"},
|
Daniel@0
|
210 "path": {"field": "layout_path"}
|
Daniel@0
|
211 },
|
Daniel@0
|
212 "update": {
|
Daniel@0
|
213 "fill": {"value": "#f0f0f0"}
|
Daniel@0
|
214 }
|
Daniel@0
|
215 }
|
Daniel@0
|
216 });
|
Daniel@0
|
217 vc.marks.push({
|
Daniel@0
|
218 "type": "symbol",
|
Daniel@0
|
219 "from": {
|
Daniel@0
|
220 "data": "countrySummary",
|
Daniel@0
|
221 "transform": [{"type":"centroid", "field": "layout_path"}],
|
Daniel@0
|
222 },
|
Daniel@0
|
223 "properties": {
|
Daniel@0
|
224 "enter": {
|
Daniel@0
|
225 //"size": {/*"scale": "color",*/ "value": 100},
|
Daniel@0
|
226 "size": {/*"scale": "color",*/ "field": "cs.percentage", "mult": transformProperties.circleSizeMult},
|
Daniel@0
|
227 "opacity": {"value": 0.5},
|
Daniel@0
|
228 "x": {"field": "centroid_x"},
|
Daniel@0
|
229 "y": {"field": "centroid_y"}
|
Daniel@0
|
230 },
|
Daniel@0
|
231 "update": {
|
Daniel@0
|
232 "fill": {"value": vc.colorForData}
|
Daniel@0
|
233 },
|
Daniel@0
|
234 "hover": {
|
Daniel@0
|
235 "fill": {"value": "#000"},
|
Daniel@0
|
236 }
|
Daniel@0
|
237 }
|
Daniel@0
|
238 });
|
Daniel@0
|
239 }
|
Daniel@0
|
240 },
|
Daniel@0
|
241 });
|
Daniel@0
|
242 });
|
Daniel@0
|
243 }, Logger);
|