forked from calvinmetcalf/leaflet.d3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
leaflet.d3.js
128 lines (116 loc) · 3.66 KB
/
leaflet.d3.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//very much based off of http://bost.ocks.org/mike/leaflet/
L.D3 = L.Class.extend({
includes: L.Mixin.Events,
options:{
type:"json",
topojson:false,
pathClass:"path"
},
initialize: function (data,options) {
var _this = this;
L.setOptions(_this, options);
_this._loaded=false;
if(typeof data === "string"){
d3[_this.options.type](data,function(err,json){
if(err){
return;
}else{
if(_this.options.topojson){
_this.data = topojson.object(json, json.objects[_this.options.topojson]);
}else if(L.Util.isArray(json)){
_this.data = {type:"FeatureCollection",features:json};
}else{
_this.data = json;
}
_this._loaded = true;
_this.fire("dataLoaded");
}
});
}else{
if(_this.options.topojson){
_this.data = topojson.object(data, data.objects[_this.options.topojson]);
}else if(L.Util.isArray(data)){
_this.data={type:"FeatureCollection",features:data};
}else{
_this.data = data;
}
_this._loaded = true;
_this.fire("dataLoaded");
}
},
onAdd: function (map) {
this._map = map;
this._project = function (x) {
var point = map.latLngToLayerPoint(new L.LatLng(x[1], x[0]));
return [point.x, point.y];
};
this._el = d3.select(this._map.getPanes().overlayPane).append("svg");
this._g = this._el.append("g").attr("class",this.options.svgClass?this.options.svgClass+" leaflet-zoom-hide":"leaflet-zoom-hide");
if(this._loaded){
this.onLoaded();
}else{
this.on("dataLoaded",this.onLoaded,this);
}
this._popup=L.popup();
this.fire("added");
},
addTo: function (map) {
map.addLayer(this);
return this;
},
onLoaded: function(){
this.bounds = d3.geo.bounds(this.data);
this.path = d3.geo.path().projection(this._project);
if(this.options.before){
this.options.before.call(this, this.data);
}
this._feature = this._g.selectAll("path").data(this.options.topojson?this.data.geometries:this.data.features).enter().append("path").attr("class", this.options.pathClass);
this._map.on('viewreset', this._reset, this);
this._reset();
},
onRemove: function (map) {
// remove layer's DOM elements and listeners
this._el.remove();
map.off('viewreset', this._reset, this);
},
_reset: function () {
var bottomLeft = this._project(this.bounds[0]),
topRight = this._project(this.bounds[1]);
this._el .attr("width", topRight[0] - bottomLeft[0])
.attr("height", bottomLeft[1] - topRight[1])
.style("margin-left", bottomLeft[0] + "px")
.style("margin-top", topRight[1] + "px");
this._g .attr("transform", "translate(" + -bottomLeft[0] + "," + -topRight[1] + ")");
this._feature.attr("d", this.path);
},
bindPopup:function(content){
this._popup=L.popup();
this._popupContent = content;
if(this._map){
this._bindPopup();
}
this.on("added",function(){this._bindPopup()},this);
},
_bindPopup:function(){
var _this=this;
_this._g.on("click",function(){
var props=d3.select(d3.event.target).datum().properties;
if(typeof _this._popupContent==="string"){
_this.fire("pathClicked",{cont:_this._popupContent});
}else if(typeof _this._popupContent==="function"){
_this.fire("pathClicked",{cont:_this._popupContent(props)});
}
},true);
_this.on("pathClicked",function(e){_this._popup.setContent(e.cont);
_this._openable=true;;});
_this._map.on("click",function(e){
if(_this._openable){
_this._openable=false;
_this._popup.setLatLng(e.latlng).openOn(_this._map);
}
});
}
});
L.d3=function(data,options){
return new L.D3(data,options);
};