mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Add choropleth map
This commit is contained in:
parent
0f77646ead
commit
f18b90a94e
@ -184,6 +184,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row-fluid tabDetails" ng-show="isActive('choropleth')">
|
||||||
|
<div class="span8 offset1">
|
||||||
|
<table>
|
||||||
|
<tbody >
|
||||||
|
<tr>
|
||||||
|
<td>Choropleth</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn" bs-button
|
||||||
|
ng-change="$emit('render')"
|
||||||
|
ng-class="{'btn-success': panel.display.choropleth.enabled}"
|
||||||
|
ng-model="panel.display.choropleth.enabled">{{panel.display.choropleth.enabled|enabledText}}</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row-fluid tabDetails" ng-show="isActive('data')">
|
<div class="row-fluid tabDetails" ng-show="isActive('data')">
|
||||||
<div class="span8 offset1">
|
<div class="span8 offset1">
|
||||||
<table>
|
<table>
|
||||||
|
1
panels/map2/lib/queue.v1.min.js
vendored
Normal file
1
panels/map2/lib/queue.v1.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
(function(){function n(n){function t(){for(;f=a<c.length&&n>p;){var u=a++,t=c[u],r=l.call(t,1);r.push(e(u)),++p,t[0].apply(null,r)}}function e(n){return function(u,l){--p,null==d&&(null!=u?(d=u,a=s=0/0,r()):(c[n]=l,--s?f||t():r()))}}function r(){null!=d?v(d):i?v(d,c):v.apply(null,[d].concat(c))}var o,f,i,c=[],a=0,p=0,s=0,d=null,v=u;return n||(n=1/0),o={defer:function(){return d||(c.push(arguments),++s,t()),o},await:function(n){return v=n,i=!1,s||r(),o},awaitAll:function(n){return v=n,i=!0,s||r(),o}}}function u(){}"undefined"==typeof module?self.queue=n:module.exports=n,n.version="1.0.4";var l=[].slice})();
|
1
panels/map2/lib/topojson.v0.min.js
vendored
1
panels/map2/lib/topojson.v0.min.js
vendored
@ -1 +0,0 @@
|
|||||||
topojson=function(){function t(t,e){function n(e){var n=t.arcs[e],r=n[0],o=[0,0];return n.forEach(function(t){o[0]+=t[0],o[1]+=t[1]}),[r,o]}var r={},o={},a={};e.forEach(function(t){var e=n(t);(r[e[0]]||(r[e[0]]=[])).push(t),(r[e[1]]||(r[e[1]]=[])).push(~t)}),e.forEach(function(t){var e,r,i=n(t),c=i[0],s=i[1];if(e=a[c])if(delete a[e.end],e.push(t),e.end=s,r=o[s]){delete o[r.start];var u=r===e?e:e.concat(r);o[u.start=e.start]=a[u.end=r.end]=u}else if(r=a[s]){delete o[r.start],delete a[r.end];var u=e.concat(r.map(function(t){return~t}).reverse());o[u.start=e.start]=a[u.end=r.start]=u}else o[e.start]=a[e.end]=e;else if(e=o[s])if(delete o[e.start],e.unshift(t),e.start=c,r=a[c]){delete a[r.end];var f=r===e?e:r.concat(e);o[f.start=r.start]=a[f.end=e.end]=f}else if(r=o[c]){delete o[r.start],delete a[r.end];var f=r.map(function(t){return~t}).reverse().concat(e);o[f.start=r.end]=a[f.end=e.end]=f}else o[e.start]=a[e.end]=e;else if(e=o[c])if(delete o[e.start],e.unshift(~t),e.start=s,r=a[s]){delete a[r.end];var f=r===e?e:r.concat(e);o[f.start=r.start]=a[f.end=e.end]=f}else if(r=o[s]){delete o[r.start],delete a[r.end];var f=r.map(function(t){return~t}).reverse().concat(e);o[f.start=r.end]=a[f.end=e.end]=f}else o[e.start]=a[e.end]=e;else if(e=a[s])if(delete a[e.end],e.push(~t),e.end=c,r=a[c]){delete o[r.start];var u=r===e?e:e.concat(r);o[u.start=e.start]=a[u.end=r.end]=u}else if(r=o[c]){delete o[r.start],delete a[r.end];var u=e.concat(r.map(function(t){return~t}).reverse());o[u.start=e.start]=a[u.end=r.start]=u}else o[e.start]=a[e.end]=e;else e=[t],o[e.start=c]=a[e.end=s]=e});var i=[];for(var c in a)i.push(a[c]);return i}function e(e,r,o){function a(t){0>t&&(t=~t),(l[t]||(l[t]=[])).push(f)}function i(t){t.forEach(a)}function c(t){t.forEach(i)}function s(t){"GeometryCollection"===t.type?t.geometries.forEach(s):t.type in d&&(f=t,d[t.type](t.arcs))}var u=[];if(arguments.length>1){var f,l=[],d={LineString:i,MultiLineString:c,Polygon:c,MultiPolygon:function(t){t.forEach(c)}};s(r),l.forEach(3>arguments.length?function(t,e){u.push([e])}:function(t,e){o(t[0],t[t.length-1])&&u.push([e])})}else for(var p=0,h=e.arcs.length;h>p;++p)u.push([p]);return n(e,{type:"MultiLineString",arcs:t(e,u)})}function n(t,e){function n(t,e){e.length&&e.pop();for(var n,o=h[0>t?~t:t],a=0,i=o.length,c=0,s=0;i>a;++a)e.push([(c+=(n=o[a])[0])*f+d,(s+=n[1])*l+p]);0>t&&r(e,i)}function o(t){return[t[0]*f+d,t[1]*l+p]}function a(t){for(var e=[],r=0,o=t.length;o>r;++r)n(t[r],e);return 2>e.length&&e.push(e[0]),e}function i(t){for(var e=a(t);4>e.length;)e.push(e[0]);return e}function c(t){return t.map(i)}function s(t){var e=t.type,n="GeometryCollection"===e?{type:e,geometries:t.geometries.map(s)}:e in v?{type:e,coordinates:v[e](t)}:{type:null};return"id"in t&&(n.id=t.id),"properties"in t&&(n.properties=t.properties),n}var u=t.transform,f=u.scale[0],l=u.scale[1],d=u.translate[0],p=u.translate[1],h=t.arcs,v={Point:function(t){return o(t.coordinates)},MultiPoint:function(t){return t.coordinates.map(o)},LineString:function(t){return a(t.arcs)},MultiLineString:function(t){return t.arcs.map(a)},Polygon:function(t){return c(t.arcs)},MultiPolygon:function(t){return t.arcs.map(c)}};return s(e)}function r(t,e){for(var n,r=t.length,o=r-e;--r>o;)n=t[o],t[o++]=t[r],t[r]=n}function o(t,e){for(var n=0,r=t.length;r>n;){var o=n+r>>>1;e>t[o]?n=o+1:r=o}return n}function a(t){function e(t,e){t.forEach(function(t){0>t&&(t=~t);var n=a[t]||(a[t]=[]);n[e]||(n.forEach(function(t){var n,r;r=o(n=i[e],t),n[r]!==t&&n.splice(r,0,t),r=o(n=i[t],e),n[r]!==e&&n.splice(r,0,e)}),n[e]=e)})}function n(t,n){t.forEach(function(t){e(t,n)})}function r(t,e){"GeometryCollection"===t.type?t.geometries.forEach(function(t){r(t,e)}):t.type in c&&c[t.type](t.arcs,e)}var a=[],i=t.map(function(){return[]}),c={LineString:e,MultiLineString:n,Polygon:n,MultiPolygon:function(t,e){t.forEach(function(t){n(t,e)})}};return t.forEach(r),i}return{version:"0.0.32",mesh:e,object:n,neighbors:a}}();
|
|
1
panels/map2/lib/topojson.v1.min.js
vendored
Normal file
1
panels/map2/lib/topojson.v1.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
topojson=function(){function t(t,e){function n(e){var n=t.arcs[e],r=n[0],o=[0,0];return n.forEach(function(t){o[0]+=t[0],o[1]+=t[1]}),[r,o]}var r={},o={},a={};e.forEach(function(t){var e=n(t);(r[e[0]]||(r[e[0]]=[])).push(t),(r[e[1]]||(r[e[1]]=[])).push(~t)}),e.forEach(function(t){var e,r,i=n(t),u=i[0],c=i[1];if(e=a[u])if(delete a[e.end],e.push(t),e.end=c,r=o[c]){delete o[r.start];var s=r===e?e:e.concat(r);o[s.start=e.start]=a[s.end=r.end]=s}else if(r=a[c]){delete o[r.start],delete a[r.end];var s=e.concat(r.map(function(t){return~t}).reverse());o[s.start=e.start]=a[s.end=r.start]=s}else o[e.start]=a[e.end]=e;else if(e=o[c])if(delete o[e.start],e.unshift(t),e.start=u,r=a[u]){delete a[r.end];var f=r===e?e:r.concat(e);o[f.start=r.start]=a[f.end=e.end]=f}else if(r=o[u]){delete o[r.start],delete a[r.end];var f=r.map(function(t){return~t}).reverse().concat(e);o[f.start=r.end]=a[f.end=e.end]=f}else o[e.start]=a[e.end]=e;else if(e=o[u])if(delete o[e.start],e.unshift(~t),e.start=c,r=a[c]){delete a[r.end];var f=r===e?e:r.concat(e);o[f.start=r.start]=a[f.end=e.end]=f}else if(r=o[c]){delete o[r.start],delete a[r.end];var f=r.map(function(t){return~t}).reverse().concat(e);o[f.start=r.end]=a[f.end=e.end]=f}else o[e.start]=a[e.end]=e;else if(e=a[c])if(delete a[e.end],e.push(~t),e.end=u,r=a[u]){delete o[r.start];var s=r===e?e:e.concat(r);o[s.start=e.start]=a[s.end=r.end]=s}else if(r=o[u]){delete o[r.start],delete a[r.end];var s=e.concat(r.map(function(t){return~t}).reverse());o[s.start=e.start]=a[s.end=r.start]=s}else o[e.start]=a[e.end]=e;else e=[t],o[e.start=u]=a[e.end=c]=e});var i=[];for(var u in a)i.push(a[u]);return i}function e(e,n,r){function a(t){0>t&&(t=~t),(l[t]||(l[t]=[])).push(f)}function i(t){t.forEach(a)}function u(t){t.forEach(i)}function c(t){t.type==="GeometryCollection"?t.geometries.forEach(c):t.type in d&&(f=t,d[t.type](t.arcs))}var s=[];if(arguments.length>1){var f,l=[],d={LineString:i,MultiLineString:u,Polygon:u,MultiPolygon:function(t){t.forEach(u)}};c(n),l.forEach(arguments.length<3?function(t,e){s.push([e])}:function(t,e){r(t[0],t[t.length-1])&&s.push([e])})}else for(var p=0,h=e.arcs.length;h>p;++p)s.push([p]);return o(e,{type:"MultiLineString",arcs:t(e,s)})}function n(t,e){return e.type==="GeometryCollection"?{type:"FeatureCollection",features:e.geometries.map(function(e){return r(t,e)})}:r(t,e)}function r(t,e){var n={type:"Feature",id:e.id,properties:e.properties||{},geometry:o(t,e)};return e.id==null&&delete n.id,n}function o(t,e){function n(t,e){e.length&&e.pop();for(var n,r=h[0>t?~t:t],o=0,i=r.length,u=0,c=0;i>o;++o)e.push([(u+=(n=r[o])[0])*f+d,(c+=n[1])*l+p]);0>t&&a(e,i)}function r(t){return[t[0]*f+d,t[1]*l+p]}function o(t){for(var e=[],r=0,o=t.length;o>r;++r)n(t[r],e);return e.length<2&&e.push(e[0]),e}function i(t){for(var e=o(t);e.length<4;)e.push(e[0]);return e}function u(t){return t.map(i)}function c(t){var e=t.type;return"GeometryCollection"===e?{type:e,geometries:t.geometries.map(c)}:e in v?{type:e,coordinates:v[e](t)}:null}var s=t.transform,f=s.scale[0],l=s.scale[1],d=s.translate[0],p=s.translate[1],h=t.arcs,v={Point:function(t){return r(t.coordinates)},MultiPoint:function(t){return t.coordinates.map(r)},LineString:function(t){return o(t.arcs)},MultiLineString:function(t){return t.arcs.map(o)},Polygon:function(t){return u(t.arcs)},MultiPolygon:function(t){return t.arcs.map(u)}};return c(e)}function a(t,e){for(var n,r=t.length,o=r-e;o<--r;)n=t[o],t[o++]=t[r],t[r]=n}function i(t,e){for(var n=0,r=t.length;r>n;){var o=n+r>>>1;t[o]<e?n=o+1:r=o}return n}function u(t){function e(t,e){t.forEach(function(t){0>t&&(t=~t);var n=o[t]||(o[t]=[]);n[e]||(n.forEach(function(t){var n,r;r=i(n=a[e],t),n[r]!==t&&n.splice(r,0,t),r=i(n=a[t],e),n[r]!==e&&n.splice(r,0,e)}),n[e]=e)})}function n(t,n){t.forEach(function(t){e(t,n)})}function r(t,e){t.type==="GeometryCollection"?t.geometries.forEach(function(t){r(t,e)}):t.type in u&&u[t.type](t.arcs,e)}var o=[],a=t.map(function(){return[]}),u={LineString:e,MultiLineString:n,Polygon:n,MultiPolygon:function(t,e){t.forEach(function(t){n(t,e)})}};return t.forEach(r),a}return{version:"1.0.0pre",mesh:e,feature:n,neighbors:u}}();
|
1
panels/map2/lib/world-110m.json
Normal file
1
panels/map2/lib/world-110m.json
Normal file
File diff suppressed because one or more lines are too long
251
panels/map2/lib/world-country-names.tsv
Normal file
251
panels/map2/lib/world-country-names.tsv
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
id short name
|
||||||
|
4 AF Afghanistan
|
||||||
|
8 AL Albania
|
||||||
|
10 AQ Antarctica
|
||||||
|
12 DZ Algeria
|
||||||
|
16 AS American Samoa
|
||||||
|
20 AD Andorra
|
||||||
|
24 AO Angola
|
||||||
|
28 AG Antigua and Barbuda
|
||||||
|
31 AZ Azerbaijan
|
||||||
|
32 AR Argentina
|
||||||
|
36 AU Australia
|
||||||
|
40 AT Austria
|
||||||
|
44 BS Bahamas
|
||||||
|
48 BH Bahrain
|
||||||
|
50 BD Bangladesh
|
||||||
|
51 AM Armenia
|
||||||
|
52 BB Barbados
|
||||||
|
56 BE Belgium
|
||||||
|
60 BM Bermuda
|
||||||
|
64 BT Bhutan
|
||||||
|
68 BO Bolivia, Plurinational State of
|
||||||
|
70 BA Bosnia and Herzegovina
|
||||||
|
72 BW Botswana
|
||||||
|
74 BV Bouvet Island
|
||||||
|
76 BR Brazil
|
||||||
|
84 BZ Belize
|
||||||
|
86 IO British Indian Ocean Territory
|
||||||
|
90 SB Solomon Islands
|
||||||
|
92 VG Virgin Islands, British
|
||||||
|
96 BN Brunei Darussalam
|
||||||
|
100 BG Bulgaria
|
||||||
|
104 MM Myanmar
|
||||||
|
108 BI Burundi
|
||||||
|
112 BY Belarus
|
||||||
|
116 KH Cambodia
|
||||||
|
120 CM Cameroon
|
||||||
|
124 CA Canada
|
||||||
|
132 CV Cape Verde
|
||||||
|
136 KY Cayman Islands
|
||||||
|
140 CF Central African Republic
|
||||||
|
144 LK Sri Lanka
|
||||||
|
148 TD Chad
|
||||||
|
152 CL Chile
|
||||||
|
156 CN China
|
||||||
|
158 TW Taiwan, Province of China
|
||||||
|
162 CX Christmas Island
|
||||||
|
166 CC Cocos (Keeling) Islands
|
||||||
|
170 CO Colombia
|
||||||
|
174 KM Comoros
|
||||||
|
175 YT Mayotte
|
||||||
|
178 CG Congo
|
||||||
|
180 CD Congo, the Democratic Republic of the
|
||||||
|
184 CK Cook Islands
|
||||||
|
188 CR Costa Rica
|
||||||
|
191 HR Croatia
|
||||||
|
192 CU Cuba
|
||||||
|
196 CY Cyprus
|
||||||
|
203 CZ Czech Republic
|
||||||
|
204 BJ Benin
|
||||||
|
208 DK Denmark
|
||||||
|
212 DM Dominica
|
||||||
|
214 DO Dominican Republic
|
||||||
|
218 EC Ecuador
|
||||||
|
222 SV El Salvador
|
||||||
|
226 GQ Equatorial Guinea
|
||||||
|
231 ET Ethiopia
|
||||||
|
232 ER Eritrea
|
||||||
|
233 EE Estonia
|
||||||
|
234 FO Faroe Islands
|
||||||
|
238 FK Falkland Islands (Malvinas)
|
||||||
|
239 GS South Georgia and the South Sandwich Islands
|
||||||
|
242 FJ Fiji
|
||||||
|
246 FI Finland
|
||||||
|
248 AX Åland Islands
|
||||||
|
250 FR France
|
||||||
|
254 GF French Guiana
|
||||||
|
258 PF French Polynesia
|
||||||
|
260 TF French Southern Territories
|
||||||
|
262 DJ Djibouti
|
||||||
|
266 GA Gabon
|
||||||
|
268 GE Georgia
|
||||||
|
270 GM Gambia
|
||||||
|
275 Palestinian Territory, Occupied
|
||||||
|
276 DE Germany
|
||||||
|
288 GH Ghana
|
||||||
|
292 GI Gibraltar
|
||||||
|
296 KI Kiribati
|
||||||
|
300 GR Greece
|
||||||
|
304 GL Greenland
|
||||||
|
308 GD Grenada
|
||||||
|
312 GP Guadeloupe
|
||||||
|
316 GU Guam
|
||||||
|
320 GT Guatemala
|
||||||
|
324 GN Guinea
|
||||||
|
328 GY Guyana
|
||||||
|
332 HT Haiti
|
||||||
|
334 HM Heard Island and McDonald Islands
|
||||||
|
336 VA Holy See (Vatican City State)
|
||||||
|
340 HN Honduras
|
||||||
|
344 HK Hong Kong
|
||||||
|
348 HU Hungary
|
||||||
|
352 IS Iceland
|
||||||
|
356 IN India
|
||||||
|
360 ID Indonesia
|
||||||
|
364 IR Iran, Islamic Republic of
|
||||||
|
368 IQ Iraq
|
||||||
|
372 IE Ireland
|
||||||
|
376 IL Israel
|
||||||
|
380 IT Italy
|
||||||
|
384 Côte d'Ivoire
|
||||||
|
388 JM Jamaica
|
||||||
|
392 JP Japan
|
||||||
|
398 KZ Kazakhstan
|
||||||
|
400 JO Jordan
|
||||||
|
404 KE Kenya
|
||||||
|
408 KP Korea, Democratic People's Republic of
|
||||||
|
410 KR Korea, Republic of
|
||||||
|
414 KW Kuwait
|
||||||
|
417 KG Kyrgyzstan
|
||||||
|
418 LA Lao People's Democratic Republic
|
||||||
|
422 LB Lebanon
|
||||||
|
426 LS Lesotho
|
||||||
|
428 LV Latvia
|
||||||
|
430 LR Liberia
|
||||||
|
434 LY Libya
|
||||||
|
438 LI Liechtenstein
|
||||||
|
440 LT Lithuania
|
||||||
|
442 LU Luxembourg
|
||||||
|
446 MO Macao
|
||||||
|
450 MG Madagascar
|
||||||
|
454 MW Malawi
|
||||||
|
458 MY Malaysia
|
||||||
|
462 MV Maldives
|
||||||
|
466 ML Mali
|
||||||
|
470 MT Malta
|
||||||
|
474 MQ Martinique
|
||||||
|
478 MR Mauritania
|
||||||
|
480 MU Mauritius
|
||||||
|
484 MX Mexico
|
||||||
|
492 MC Monaco
|
||||||
|
496 MN Mongolia
|
||||||
|
498 MD Moldova, Republic of
|
||||||
|
499 ME Montenegro
|
||||||
|
500 MS Montserrat
|
||||||
|
504 MA Morocco
|
||||||
|
508 MZ Mozambique
|
||||||
|
512 OM Oman
|
||||||
|
516 NA Namibia
|
||||||
|
520 NR Nauru
|
||||||
|
524 NP Nepal
|
||||||
|
528 NL Netherlands
|
||||||
|
531 Curaçao
|
||||||
|
533 AW Aruba
|
||||||
|
534 SX Sint Maarten (Dutch part)
|
||||||
|
535 BQ Bonaire, Sint Eustatius and Saba
|
||||||
|
540 NC New Caledonia
|
||||||
|
548 VU Vanuatu
|
||||||
|
554 NZ New Zealand
|
||||||
|
558 NI Nicaragua
|
||||||
|
562 NE Niger
|
||||||
|
566 NG Nigeria
|
||||||
|
570 NU Niue
|
||||||
|
574 NF Norfolk Island
|
||||||
|
578 NO Norway
|
||||||
|
580 MP Northern Mariana Islands
|
||||||
|
581 UM United States Minor Outlying Islands
|
||||||
|
583 FM Micronesia, Federated States of
|
||||||
|
584 MH Marshall Islands
|
||||||
|
585 PW Palau
|
||||||
|
586 PK Pakistan
|
||||||
|
591 PA Panama
|
||||||
|
598 PG Papua New Guinea
|
||||||
|
600 PY Paraguay
|
||||||
|
604 PE Peru
|
||||||
|
608 PH Philippines
|
||||||
|
612 PN Pitcairn
|
||||||
|
616 PL Poland
|
||||||
|
620 PT Portugal
|
||||||
|
624 GW Guinea-Bissau
|
||||||
|
626 TL Timor-Leste
|
||||||
|
630 PR Puerto Rico
|
||||||
|
634 QA Qatar
|
||||||
|
638 Réunion
|
||||||
|
642 RO Romania
|
||||||
|
643 RU Russian Federation
|
||||||
|
646 RW Rwanda
|
||||||
|
652 Saint Barthélemy
|
||||||
|
654 SH Saint Helena, Ascension and Tristan da Cunha
|
||||||
|
659 KN Saint Kitts and Nevis
|
||||||
|
660 AI Anguilla
|
||||||
|
662 LC Saint Lucia
|
||||||
|
663 MF Saint Martin (French part)
|
||||||
|
666 PM Saint Pierre and Miquelon
|
||||||
|
670 VC Saint Vincent and the Grenadines
|
||||||
|
674 SM San Marino
|
||||||
|
678 ST Sao Tome and Principe
|
||||||
|
682 SA Saudi Arabia
|
||||||
|
686 SN Senegal
|
||||||
|
688 RS Serbia
|
||||||
|
690 SC Seychelles
|
||||||
|
694 SL Sierra Leone
|
||||||
|
702 SG Singapore
|
||||||
|
703 SK Slovakia
|
||||||
|
704 VN Viet Nam
|
||||||
|
705 SI Slovenia
|
||||||
|
706 SO Somalia
|
||||||
|
710 ZA South Africa
|
||||||
|
716 ZW Zimbabwe
|
||||||
|
724 ES Spain
|
||||||
|
728 SS South Sudan
|
||||||
|
729 SD Sudan
|
||||||
|
732 EH Western Sahara
|
||||||
|
740 SR Suriname
|
||||||
|
744 SJ Svalbard and Jan Mayen
|
||||||
|
748 SZ Swaziland
|
||||||
|
752 SE Sweden
|
||||||
|
756 CH Switzerland
|
||||||
|
760 SY Syrian Arab Republic
|
||||||
|
762 TJ Tajikistan
|
||||||
|
764 TH Thailand
|
||||||
|
768 TG Togo
|
||||||
|
772 TK Tokelau
|
||||||
|
776 TO Tonga
|
||||||
|
780 TT Trinidad and Tobago
|
||||||
|
784 AE United Arab Emirates
|
||||||
|
788 TN Tunisia
|
||||||
|
792 TR Turkey
|
||||||
|
795 TM Turkmenistan
|
||||||
|
796 TC Turks and Caicos Islands
|
||||||
|
798 TV Tuvalu
|
||||||
|
800 UG Uganda
|
||||||
|
804 UA Ukraine
|
||||||
|
807 MK Macedonia, the former Yugoslav Republic of
|
||||||
|
818 EG Egypt
|
||||||
|
826 GB United Kingdom
|
||||||
|
831 GG Guernsey
|
||||||
|
832 JE Jersey
|
||||||
|
833 IM Isle of Man
|
||||||
|
834 TZ Tanzania, United Republic of
|
||||||
|
840 US United States
|
||||||
|
850 VI Virgin Islands, U.S.
|
||||||
|
854 BF Burkina Faso
|
||||||
|
858 UY Uruguay
|
||||||
|
860 UZ Uzbekistan
|
||||||
|
862 VE Venezuela, Bolivarian Republic of
|
||||||
|
876 WF Wallis and Futuna
|
||||||
|
882 WS Samoa
|
||||||
|
887 YE Yemen
|
||||||
|
894 ZM Zambia
|
||||||
|
|
|
@ -22,6 +22,16 @@
|
|||||||
stroke-width: .1px;
|
stroke-width: .1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.q1 { fill:rgb(247,251,255); }
|
||||||
|
.q2 { fill:rgb(222,235,247); }
|
||||||
|
.q3 { fill:rgb(198,219,239); }
|
||||||
|
.q4 { fill:rgb(158,202,225); }
|
||||||
|
.q5 { fill:rgb(107,174,214); }
|
||||||
|
.q6 { fill:rgb(66,146,198); }
|
||||||
|
.q7 { fill:rgb(33,113,181); }
|
||||||
|
.q8 { fill:rgb(8,81,156); }
|
||||||
|
.q9 { fill:rgb(8,48,107); }
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<span ng-show="panel.spyable" style="position:absolute;right:0px;top:0px" class='panelextra pointer'>
|
<span ng-show="panel.spyable" style="position:absolute;right:0px;top:0px" class='panelextra pointer'>
|
||||||
<i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>
|
<i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>
|
||||||
|
@ -31,9 +31,12 @@ angular.module('kibana.map2', [])
|
|||||||
areaEncodingField: "primary",
|
areaEncodingField: "primary",
|
||||||
colorEncoding: true,
|
colorEncoding: true,
|
||||||
colorEncodingField: "primary"
|
colorEncodingField: "primary"
|
||||||
|
},
|
||||||
|
choropleth: {
|
||||||
|
enabled: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
displayTabs: ["Geopoints", "Binning", "Data"],
|
displayTabs: ["Geopoints", "Binning", "Choropleth", "Data"],
|
||||||
activeDisplayTab:"Geopoints"
|
activeDisplayTab:"Geopoints"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -187,6 +190,9 @@ angular.module('kibana.map2', [])
|
|||||||
|
|
||||||
elem.html('<center><img src="common/img/load_big.gif"></center>')
|
elem.html('<center><img src="common/img/load_big.gif"></center>')
|
||||||
|
|
||||||
|
var worldData = null,
|
||||||
|
worldNames = null;
|
||||||
|
|
||||||
// Receive render events
|
// Receive render events
|
||||||
scope.$on('render', function () {
|
scope.$on('render', function () {
|
||||||
console.log("render");
|
console.log("render");
|
||||||
@ -200,192 +206,255 @@ angular.module('kibana.map2', [])
|
|||||||
});
|
});
|
||||||
|
|
||||||
function render_panel() {
|
function render_panel() {
|
||||||
//console.log("render_panel");
|
|
||||||
//console.log(scope.panel);
|
|
||||||
//console.log(elem);
|
|
||||||
|
|
||||||
// Using LABjs, wait until all scripts are loaded before rendering panel
|
// Using LABjs, wait until all scripts are loaded before rendering panel
|
||||||
var scripts = $LAB.script("panels/map2/lib/d3.v3.min.js")
|
var scripts = $LAB.script("panels/map2/lib/d3.v3.min.js")
|
||||||
.script("panels/map2/lib/topojson.v0.min.js")
|
.script("panels/map2/lib/topojson.v1.min.js")
|
||||||
.script("panels/map2/lib/node-geohash.js")
|
.script("panels/map2/lib/node-geohash.js")
|
||||||
.script("panels/map2/lib/d3.hexbin.v0.min.js");
|
.script("panels/map2/lib/d3.hexbin.v0.min.js")
|
||||||
|
.script("panels/map2/lib/queue.v1.min.js");
|
||||||
|
|
||||||
// Populate element. Note that jvectormap appends, does not replace.
|
// Populate element. Note that jvectormap appends, does not replace.
|
||||||
scripts.wait(function () {
|
scripts.wait(function () {
|
||||||
elem.text('');
|
elem.text('');
|
||||||
|
|
||||||
//Better way to get these values? Seems kludgy to use jQuery on the div...
|
if (worldData === null || worldNames === null) {
|
||||||
var width = $(elem[0]).width(),
|
queue()
|
||||||
height = $(elem[0]).height();
|
.defer(d3.json, "panels/map2/lib/world-110m.json")
|
||||||
|
.defer(d3.tsv, "panels/map2/lib/world-country-names.tsv")
|
||||||
console.log("draw map", width, height);
|
.await(function(error, world, names) {
|
||||||
|
worldData = world;
|
||||||
|
worldNames = names;
|
||||||
var scale = (width > height) ? (height / 2 / Math.PI) : (width / 2 / Math.PI);
|
ready();
|
||||||
|
});
|
||||||
var projection = d3.geo.mercator()
|
} else {
|
||||||
.translate([0,0])
|
ready();
|
||||||
.scale(scale);
|
|
||||||
|
|
||||||
var zoom = d3.behavior.zoom()
|
|
||||||
.scaleExtent([1, 8])
|
|
||||||
.on("zoom", move);
|
|
||||||
|
|
||||||
var path = d3.geo.path()
|
|
||||||
.projection(projection);
|
|
||||||
|
|
||||||
var svg = d3.select(elem[0]).append("svg")
|
|
||||||
.attr("width", width)
|
|
||||||
.attr("height", height)
|
|
||||||
.append("g")
|
|
||||||
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
|
|
||||||
.call(zoom);
|
|
||||||
|
|
||||||
var g = svg.append("g");
|
|
||||||
|
|
||||||
svg.append("rect")
|
|
||||||
.attr("class", "overlay")
|
|
||||||
.attr("x", -width / 2)
|
|
||||||
.attr("y", -height / 2)
|
|
||||||
.attr("width", width)
|
|
||||||
.attr("height", height);
|
|
||||||
|
|
||||||
d3.json("panels/map2/lib/world-50m.json", function (error, world) {
|
|
||||||
g.append("path")
|
|
||||||
.datum(topojson.object(world, world.objects.countries))
|
|
||||||
.attr("class", "land")
|
|
||||||
.attr("d", path);
|
|
||||||
|
|
||||||
g.append("path")
|
|
||||||
.datum(topojson.mesh(world, world.objects.countries, function (a, b) {
|
|
||||||
return a !== b;
|
|
||||||
}))
|
|
||||||
.attr("class", "boundary")
|
|
||||||
.attr("d", path);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Geocoded points are decoded into lat/lon, then projected onto x/y
|
|
||||||
points = _.map(scope.data, function (k, v) {
|
|
||||||
var decoded = geohash.decode(v);
|
|
||||||
return projection([decoded.longitude, decoded.latitude]);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//hexagonal binning
|
|
||||||
if (scope.panel.display.binning.enabled) {
|
|
||||||
|
|
||||||
var binPoints = [];
|
|
||||||
|
|
||||||
//primary field is just binning raw counts
|
|
||||||
//secondary field is binning some metric like mean/median/total. Hexbins doesn't support that,
|
|
||||||
//so we cheat a little and just add more points to compensate.
|
|
||||||
//However, we don't want to add a million points, so normalize against the largest value
|
|
||||||
if (scope.panel.display.binning.areaEncodingField === 'secondary') {
|
|
||||||
var max = Math.max.apply(Math, _.map(scope.data, function(k,v){return k;})),
|
|
||||||
scale = 10/max;
|
|
||||||
|
|
||||||
_.map(scope.data, function (k, v) {
|
|
||||||
var decoded = geohash.decode(v);
|
|
||||||
return _.map(_.range(0, k*scale), function(a,b) {
|
|
||||||
binPoints.push(projection([decoded.longitude, decoded.latitude]));
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
binPoints = points;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var hexbin = d3.hexbin()
|
|
||||||
.size([width, height])
|
|
||||||
.radius(scope.panel.display.binning.hexagonSize);
|
|
||||||
|
|
||||||
//bin and sort the points, so we can set the various ranges appropriately
|
|
||||||
var binnedPoints = hexbin(binPoints).sort(function(a, b) { return b.length - a.length; });;
|
|
||||||
console.log("binnedpoints",binnedPoints);
|
|
||||||
//clean up some memory
|
|
||||||
binPoints = [];
|
|
||||||
|
|
||||||
|
|
||||||
var radius = d3.scale.sqrt()
|
|
||||||
.domain([0, binnedPoints[0].length])
|
|
||||||
.range([0, scope.panel.display.binning.hexagonSize]);
|
|
||||||
|
|
||||||
|
|
||||||
var color = d3.scale.linear()
|
|
||||||
.domain([0,binnedPoints[0].length])
|
|
||||||
.range(["white", "steelblue"])
|
|
||||||
.interpolate(d3.interpolateLab);
|
|
||||||
|
|
||||||
g.selectAll(".hexagon")
|
|
||||||
.data(binnedPoints)
|
|
||||||
.enter().append("path")
|
|
||||||
.attr("d", function (d) {
|
|
||||||
if (scope.panel.display.binning.areaEncoding === false) {
|
|
||||||
return hexbin.hexagon();
|
|
||||||
} else {
|
|
||||||
return hexbin.hexagon(radius(d.length));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.attr("class", "hexagon")
|
|
||||||
.attr("transform", function (d) {
|
|
||||||
return "translate(" + d.x + "," + d.y + ")";
|
|
||||||
})
|
|
||||||
.style("fill", function (d) {
|
|
||||||
if (scope.panel.display.binning.colorEncoding === false) {
|
|
||||||
return color(binnedPoints[0].length / 2);
|
|
||||||
} else {
|
|
||||||
return color(d.length);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.attr("opacity", scope.panel.display.binning.hexagonAlpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Raw geopoints
|
|
||||||
if (scope.panel.display.geopoints.enabled) {
|
|
||||||
g.selectAll("circles.points")
|
|
||||||
.data(points)
|
|
||||||
.enter()
|
|
||||||
.append("circle")
|
|
||||||
.attr("r", scope.panel.display.geopoints.pointSize)
|
|
||||||
.attr("opacity", scope.panel.display.geopoints.pointAlpha)
|
|
||||||
.attr("transform", function (d) {
|
|
||||||
return "translate(" + d[0] + "," + d[1] + ")";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
console.log("initial", scope.panel.display.scale, scope.panel.display.translate);
|
|
||||||
|
|
||||||
if (scope.panel.display.scale != -1) {
|
|
||||||
zoom.scale(scope.panel.display.scale).translate(scope.panel.display.translate);
|
|
||||||
g.style("stroke-width", 1 / scope.panel.display.scale).attr("transform", "translate(" + scope.panel.display.translate + ") scale(" + scope.panel.display.scale + ")");
|
|
||||||
//svg.redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
function move() {
|
|
||||||
var t = d3.event.translate,
|
|
||||||
s = d3.event.scale;
|
|
||||||
t[0] = Math.min(width / 2 * (s - 1), Math.max(width / 2 * (1 - s), t[0]));
|
|
||||||
t[1] = Math.min(height / 2 * (s - 1) + 230 * s, Math.max(height / 2 * (1 - s) - 230 * s, t[1]));
|
|
||||||
zoom.translate(t);
|
|
||||||
|
|
||||||
scope.panel.display.translate = t;
|
|
||||||
scope.panel.display.scale = s;
|
|
||||||
g.style("stroke-width", 1 / s).attr("transform", "translate(" + t + ")scale(" + s + ")");
|
|
||||||
|
|
||||||
console.log("move", scope.panel.display.scale, scope.panel.display.translate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ready() {
|
||||||
|
|
||||||
|
var world = worldData,
|
||||||
|
names = worldNames;
|
||||||
|
|
||||||
|
//Better way to get these values? Seems kludgy to use jQuery on the div...
|
||||||
|
var width = $(elem[0]).width(),
|
||||||
|
height = $(elem[0]).height();
|
||||||
|
|
||||||
|
console.log("draw map", width, height);
|
||||||
|
|
||||||
|
|
||||||
|
var scale = (width > height) ? (height / 2 / Math.PI) : (width / 2 / Math.PI);
|
||||||
|
|
||||||
|
var projection = d3.geo.mercator()
|
||||||
|
.translate([0,0])
|
||||||
|
.scale(scale);
|
||||||
|
|
||||||
|
var zoom = d3.behavior.zoom()
|
||||||
|
.scaleExtent([1, 8])
|
||||||
|
.on("zoom", move);
|
||||||
|
|
||||||
|
var path = d3.geo.path()
|
||||||
|
.projection(projection);
|
||||||
|
|
||||||
|
var svg = d3.select(elem[0]).append("svg")
|
||||||
|
.attr("width", width)
|
||||||
|
.attr("height", height)
|
||||||
|
.append("g")
|
||||||
|
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
|
||||||
|
.call(zoom);
|
||||||
|
|
||||||
|
var g = svg.append("g");
|
||||||
|
|
||||||
|
svg.append("rect")
|
||||||
|
.attr("class", "overlay")
|
||||||
|
.attr("x", -width / 2)
|
||||||
|
.attr("y", -height / 2)
|
||||||
|
.attr("width", width)
|
||||||
|
.attr("height", height);
|
||||||
|
|
||||||
|
/*
|
||||||
|
d3.json("panels/map2/lib/world-50m.json", function (error, world) {
|
||||||
|
g.append("path")
|
||||||
|
.datum(topojson.object(world, world.objects.countries))
|
||||||
|
.attr("class", "land")
|
||||||
|
.attr("d", path);
|
||||||
|
|
||||||
|
g.append("path")
|
||||||
|
.datum(topojson.mesh(world, world.objects.countries, function (a, b) {
|
||||||
|
return a !== b;
|
||||||
|
}))
|
||||||
|
.attr("class", "boundary")
|
||||||
|
.attr("d", path);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
console.log(world);
|
||||||
|
console.log("feature", topojson.feature(world, world.objects.countries));
|
||||||
|
|
||||||
|
var countries = topojson.feature(world, world.objects.countries).features;
|
||||||
|
|
||||||
|
countries = countries.filter(function(d) {
|
||||||
|
return names.some(function(n) {
|
||||||
|
if (d.id == n.id) {
|
||||||
|
d.name = n.name;
|
||||||
|
return d.short = n.short;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).sort(function(a, b) {
|
||||||
|
return a.name.localeCompare(b.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var quantize = d3.scale.quantize()
|
||||||
|
.domain([0, 1000])
|
||||||
|
.range(d3.range(9).map(function(i) { return "q" + (i+1); }));
|
||||||
|
|
||||||
|
|
||||||
|
g.selectAll("path")
|
||||||
|
.data(countries)
|
||||||
|
.enter().append("path")
|
||||||
|
.attr("class", function(d) {
|
||||||
|
if (scope.panel.display.choropleth.enabled) {
|
||||||
|
return 'land ' + quantize(scope.data[d.short]);
|
||||||
|
} else {
|
||||||
|
return 'land';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.attr("d", path);
|
||||||
|
|
||||||
|
g.append("path")
|
||||||
|
.datum(topojson.mesh(world, world.objects.land, function(a, b) { return a !== b; }))
|
||||||
|
.attr("class", "land boundary")
|
||||||
|
.attr("d", path);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Geocoded points are decoded into lat/lon, then projected onto x/y
|
||||||
|
points = _.map(scope.data, function (k, v) {
|
||||||
|
var decoded = geohash.decode(v);
|
||||||
|
return projection([decoded.longitude, decoded.latitude]);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//hexagonal binning
|
||||||
|
if (scope.panel.display.binning.enabled) {
|
||||||
|
|
||||||
|
var binPoints = [];
|
||||||
|
|
||||||
|
//primary field is just binning raw counts
|
||||||
|
//secondary field is binning some metric like mean/median/total. Hexbins doesn't support that,
|
||||||
|
//so we cheat a little and just add more points to compensate.
|
||||||
|
//However, we don't want to add a million points, so normalize against the largest value
|
||||||
|
if (scope.panel.display.binning.areaEncodingField === 'secondary') {
|
||||||
|
var max = Math.max.apply(Math, _.map(scope.data, function(k,v){return k;})),
|
||||||
|
scale = 10/max;
|
||||||
|
|
||||||
|
_.map(scope.data, function (k, v) {
|
||||||
|
var decoded = geohash.decode(v);
|
||||||
|
return _.map(_.range(0, k*scale), function(a,b) {
|
||||||
|
binPoints.push(projection([decoded.longitude, decoded.latitude]));
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
binPoints = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var hexbin = d3.hexbin()
|
||||||
|
.size([width, height])
|
||||||
|
.radius(scope.panel.display.binning.hexagonSize);
|
||||||
|
|
||||||
|
//bin and sort the points, so we can set the various ranges appropriately
|
||||||
|
var binnedPoints = hexbin(binPoints).sort(function(a, b) { return b.length - a.length; });;
|
||||||
|
console.log("binnedpoints",binnedPoints);
|
||||||
|
//clean up some memory
|
||||||
|
binPoints = [];
|
||||||
|
|
||||||
|
|
||||||
|
var radius = d3.scale.sqrt()
|
||||||
|
.domain([0, binnedPoints[0].length])
|
||||||
|
.range([0, scope.panel.display.binning.hexagonSize]);
|
||||||
|
|
||||||
|
|
||||||
|
var color = d3.scale.linear()
|
||||||
|
.domain([0,binnedPoints[0].length])
|
||||||
|
.range(["white", "steelblue"])
|
||||||
|
.interpolate(d3.interpolateLab);
|
||||||
|
|
||||||
|
g.selectAll(".hexagon")
|
||||||
|
.data(binnedPoints)
|
||||||
|
.enter().append("path")
|
||||||
|
.attr("d", function (d) {
|
||||||
|
if (scope.panel.display.binning.areaEncoding === false) {
|
||||||
|
return hexbin.hexagon();
|
||||||
|
} else {
|
||||||
|
return hexbin.hexagon(radius(d.length));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.attr("class", "hexagon")
|
||||||
|
.attr("transform", function (d) {
|
||||||
|
return "translate(" + d.x + "," + d.y + ")";
|
||||||
|
})
|
||||||
|
.style("fill", function (d) {
|
||||||
|
if (scope.panel.display.binning.colorEncoding === false) {
|
||||||
|
return color(binnedPoints[0].length / 2);
|
||||||
|
} else {
|
||||||
|
return color(d.length);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.attr("opacity", scope.panel.display.binning.hexagonAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Raw geopoints
|
||||||
|
if (scope.panel.display.geopoints.enabled) {
|
||||||
|
g.selectAll("circles.points")
|
||||||
|
.data(points)
|
||||||
|
.enter()
|
||||||
|
.append("circle")
|
||||||
|
.attr("r", scope.panel.display.geopoints.pointSize)
|
||||||
|
.attr("opacity", scope.panel.display.geopoints.pointAlpha)
|
||||||
|
.attr("transform", function (d) {
|
||||||
|
return "translate(" + d[0] + "," + d[1] + ")";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.log("initial", scope.panel.display.scale, scope.panel.display.translate);
|
||||||
|
|
||||||
|
if (scope.panel.display.scale != -1) {
|
||||||
|
zoom.scale(scope.panel.display.scale).translate(scope.panel.display.translate);
|
||||||
|
g.style("stroke-width", 1 / scope.panel.display.scale).attr("transform", "translate(" + scope.panel.display.translate + ") scale(" + scope.panel.display.scale + ")");
|
||||||
|
//svg.redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function move() {
|
||||||
|
var t = d3.event.translate,
|
||||||
|
s = d3.event.scale;
|
||||||
|
t[0] = Math.min(width / 2 * (s - 1), Math.max(width / 2 * (1 - s), t[0]));
|
||||||
|
t[1] = Math.min(height / 2 * (s - 1) + 230 * s, Math.max(height / 2 * (1 - s) - 230 * s, t[1]));
|
||||||
|
zoom.translate(t);
|
||||||
|
|
||||||
|
scope.panel.display.translate = t;
|
||||||
|
scope.panel.display.scale = s;
|
||||||
|
g.style("stroke-width", 1 / s).attr("transform", "translate(" + t + ")scale(" + s + ")");
|
||||||
|
|
||||||
|
//console.log("move", scope.panel.display.scale, scope.panel.display.translate);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user