@raruto/leaflet-elevation 1.7.2 → 1.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/dist/leaflet-elevation.js +273 -233
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.js +3 -1
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/libs/leaflet-gpxgroup.js +48 -39
- package/libs/leaflet-gpxgroup.min.js +14 -13
- package/package.json +1 -1
- package/src/acceleration.js +1 -1
- package/src/altitude.js +6 -0
- package/src/chart.js +3 -24
- package/src/components.js +36 -24
- package/src/control.js +10 -6
- package/src/distance.js +5 -0
- package/src/index.js +12 -1
- package/src/marker.js +3 -20
- package/src/options.js +2 -0
- package/src/slope.js +1 -1
- package/src/speed.js +2 -2
- package/src/time.js +9 -4
- package/src/utils.js +37 -25
package/libs/leaflet-gpxgroup.js
CHANGED
|
@@ -100,11 +100,10 @@ L.control.layersLegend = function(baseLayers, overlays, options) {
|
|
|
100
100
|
return new L.Control.LayersLegend(baseLayers, overlays, options);
|
|
101
101
|
};
|
|
102
102
|
|
|
103
|
-
L.
|
|
103
|
+
L.GeoJSON.include(L.Mixin.Selectable);
|
|
104
104
|
|
|
105
105
|
L.GpxGroup = L.Class.extend({
|
|
106
106
|
options: {
|
|
107
|
-
async: true,
|
|
108
107
|
highlight: {
|
|
109
108
|
color: '#ff0',
|
|
110
109
|
opacity: 1,
|
|
@@ -125,7 +124,6 @@ L.GpxGroup = L.Class.extend({
|
|
|
125
124
|
elevation: true,
|
|
126
125
|
elevation_options: {
|
|
127
126
|
theme: 'yellow-theme',
|
|
128
|
-
// width: 500,
|
|
129
127
|
detachedView: true,
|
|
130
128
|
elevationDiv: '#elevation-div',
|
|
131
129
|
},
|
|
@@ -133,14 +131,6 @@ L.GpxGroup = L.Class.extend({
|
|
|
133
131
|
distanceMarkers_options: {
|
|
134
132
|
lazy: true
|
|
135
133
|
},
|
|
136
|
-
marker_options: {
|
|
137
|
-
startIconUrl: null,
|
|
138
|
-
endIconUrl: null,
|
|
139
|
-
shadowUrl: null,
|
|
140
|
-
},
|
|
141
|
-
gpx_options: {
|
|
142
|
-
parseElements: ["track", "route"],
|
|
143
|
-
}
|
|
144
134
|
},
|
|
145
135
|
|
|
146
136
|
initialize: function(tracks, options) {
|
|
@@ -190,10 +180,40 @@ L.GpxGroup = L.Class.extend({
|
|
|
190
180
|
},
|
|
191
181
|
|
|
192
182
|
addTrack: function(track) {
|
|
193
|
-
|
|
183
|
+
fetch(track).then(response => {
|
|
184
|
+
if (response.ok) {
|
|
185
|
+
response.text().then(doc => {
|
|
186
|
+
let geojson;
|
|
187
|
+
doc = doc.trim();
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
let xml = (new DOMParser()).parseFromString(doc, "text/xml");
|
|
191
|
+
let type = xml.documentElement.tagName.toLowerCase(); // "kml" or "gpx"
|
|
192
|
+
let name = xml.getElementsByTagName('name');
|
|
193
|
+
if (!(type in toGeoJSON)) {
|
|
194
|
+
type = xml.documentElement.tagName == "TrainingCenterDatabase" ? 'tcx' : 'gpx';
|
|
195
|
+
}
|
|
196
|
+
geojson = toGeoJSON[type](xml);
|
|
197
|
+
geojson.name = name.length > 0 ? Array.from(name).find(tag => tag.parentElement.tagName == "trk").textContent : '';
|
|
198
|
+
} catch (e) {
|
|
199
|
+
try {
|
|
200
|
+
geojson = JSON.parse(doc.toString());
|
|
201
|
+
} catch (e) {
|
|
202
|
+
console.warn("Error parsing track: " + track);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (!geojson.name) {
|
|
206
|
+
geojson.name = track.split('/').pop().split('#')[0].split('?')[0];
|
|
207
|
+
}
|
|
208
|
+
this._loadRoute(geojson);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
});
|
|
194
212
|
},
|
|
195
213
|
|
|
196
214
|
_loadRoute: function(data) {
|
|
215
|
+
if (!data) return;
|
|
216
|
+
|
|
197
217
|
var colors = this._uniqueColors(this._tracks.length);
|
|
198
218
|
var color = colors[this._count++];
|
|
199
219
|
|
|
@@ -204,24 +224,24 @@ L.GpxGroup = L.Class.extend({
|
|
|
204
224
|
distanceMarkers: this.options.distanceMarkers_options,
|
|
205
225
|
};
|
|
206
226
|
|
|
207
|
-
var route =
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
227
|
+
var route = L.geoJson(data, {
|
|
228
|
+
name: data.name || '',
|
|
229
|
+
style: (feature) => line_style,
|
|
230
|
+
distanceMarkers: line_style.distanceMarkers,
|
|
231
|
+
originalStyle: line_style,
|
|
232
|
+
filter: feature => feature.geometry.type != "Point",
|
|
212
233
|
});
|
|
213
234
|
|
|
214
|
-
route.originalStyle = line_style;
|
|
215
|
-
|
|
216
|
-
route.on('addline', L.bind(this._onRouteAddLine, this, route));
|
|
217
|
-
route.on('loaded', L.bind(this._onRouteLoaded, this, route));
|
|
218
|
-
|
|
219
235
|
route.addTo(this._layers);
|
|
220
236
|
this._routes[route._leaflet_id] = route;
|
|
237
|
+
|
|
238
|
+
route.eachLayer((layer) => this._onRouteLayer(route, layer));
|
|
239
|
+
this._onRouteLoaded(route);
|
|
240
|
+
|
|
221
241
|
},
|
|
222
242
|
|
|
223
|
-
|
|
224
|
-
var polyline =
|
|
243
|
+
_onRouteLayer: function(route, layer) {
|
|
244
|
+
var polyline = layer;
|
|
225
245
|
|
|
226
246
|
route.on('selected', L.bind(this._onRouteSelected, this, route, polyline));
|
|
227
247
|
|
|
@@ -229,7 +249,7 @@ L.GpxGroup = L.Class.extend({
|
|
|
229
249
|
polyline.on('mouseout', L.bind(this._onRouteMouseOut, this, route, polyline));
|
|
230
250
|
polyline.on('click', L.bind(this._onRouteClick, this, route, polyline));
|
|
231
251
|
|
|
232
|
-
polyline.bindTooltip(route.
|
|
252
|
+
polyline.bindTooltip(route.options.name, {
|
|
233
253
|
direction: 'auto',
|
|
234
254
|
sticky: true,
|
|
235
255
|
});
|
|
@@ -243,7 +263,7 @@ L.GpxGroup = L.Class.extend({
|
|
|
243
263
|
},
|
|
244
264
|
|
|
245
265
|
unhighlight: function(route, polyline) {
|
|
246
|
-
polyline.setStyle(route.originalStyle);
|
|
266
|
+
polyline.setStyle(route.options.originalStyle);
|
|
247
267
|
if (this.options.distanceMarkers) {
|
|
248
268
|
polyline.removeDistanceMarkers();
|
|
249
269
|
}
|
|
@@ -285,7 +305,7 @@ L.GpxGroup = L.Class.extend({
|
|
|
285
305
|
|
|
286
306
|
_onRouteLoaded: function(route) {
|
|
287
307
|
if (this.options.legend) {
|
|
288
|
-
this._legend.addBaseLayer(route, '<svg id="legend_' + route._leaflet_id + '" width="25" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">' + '<line x1="0" x2="50" y1="5" y2="5" stroke="' + route.options.
|
|
308
|
+
this._legend.addBaseLayer(route, '<svg id="legend_' + route._leaflet_id + '" width="25" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">' + '<line x1="0" x2="50" y1="5" y2="5" stroke="' + route.options.originalStyle.color + '" fill="transparent" stroke-width="5" /></svg>' + ' ' + route.options.name);
|
|
289
309
|
}
|
|
290
310
|
this.fire('route_loaded', {
|
|
291
311
|
route: route,
|
|
@@ -318,7 +338,7 @@ L.GpxGroup = L.Class.extend({
|
|
|
318
338
|
}
|
|
319
339
|
route.getLayers().forEach(function(layer) {
|
|
320
340
|
if (layer instanceof L.Polyline) {
|
|
321
|
-
elevation.addData(layer);
|
|
341
|
+
elevation.addData(layer, false);
|
|
322
342
|
layer.bringToFront();
|
|
323
343
|
}
|
|
324
344
|
});
|
|
@@ -357,17 +377,6 @@ L.GpxGroup = L.Class.extend({
|
|
|
357
377
|
}
|
|
358
378
|
},
|
|
359
379
|
|
|
360
|
-
_get: function(url, callback) {
|
|
361
|
-
var xhr = new XMLHttpRequest();
|
|
362
|
-
xhr.open("GET", url);
|
|
363
|
-
xhr.onreadystatechange = function() {
|
|
364
|
-
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
|
|
365
|
-
callback(xhr.response);
|
|
366
|
-
}
|
|
367
|
-
};
|
|
368
|
-
xhr.send();
|
|
369
|
-
},
|
|
370
|
-
|
|
371
380
|
_uniqueColors: function(count) {
|
|
372
381
|
if (count === 0) return [];
|
|
373
382
|
if (count === 1) return ['#0000ff'];
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
'use strict';L.Mixin.Selectable={includes:L.Mixin.Events,setSelected:function(s){var selected=!!s;if(this._selected!==selected){this._selected=selected;this.fire("selected")}},isSelected:function(){return!!this._selected}};
|
|
2
2
|
L.Mixin.Selection={includes:L.Mixin.Events,getSelection:function(){return this._selected},setSelection:function(item){if(this._selected===item){if(item!==null){item.setSelected(!item.isSelected());if(!item.isSelected())this._selected=null}}else{if(this._selected)this._selected.setSelected(false);this._selected=item;if(this._selected)this._selected.setSelected(true)}this.fire("selection_changed")}};
|
|
3
3
|
L.Control.LayersLegend=L.Control.Layers.extend({_onInputClick:function(){var inputs=this._layerControlInputs,input,layer;var addedLayers=[],removedLayers=[];this._handlingClick=true;for(var i=inputs.length-1;i>=0;i--){input=inputs[i];layer=this._getLayer(input.layerId).layer;if(input.checked)this._map.fireEvent("legend_selected",{layer:layer,input:input},true)}this._handlingClick=false;this._refocusOnMap()}});
|
|
4
|
-
L.control.layersLegend=function(baseLayers,overlays,options){return new L.Control.LayersLegend(baseLayers,overlays,options)};L.
|
|
5
|
-
L.GpxGroup=L.Class.extend({options:{
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
polyline);this.
|
|
12
|
-
|
|
13
|
-
route.
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
p;g=v;b=t;break;case 3:r=p;g=q;b=v;break;case 4:r=t;g=p;b=v;break;case 5:r=v;g=p;b=q;
|
|
4
|
+
L.control.layersLegend=function(baseLayers,overlays,options){return new L.Control.LayersLegend(baseLayers,overlays,options)};L.GeoJSON.include(L.Mixin.Selectable);
|
|
5
|
+
L.GpxGroup=L.Class.extend({options:{highlight:{color:"#ff0",opacity:1},points:[],points_options:{icon:{iconUrl:"../images/elevation-poi.png",iconSize:[12,12]}},flyToBounds:true,legend:false,legend_options:{position:"topright",collapsed:false},elevation:true,elevation_options:{theme:"yellow-theme",detachedView:true,elevationDiv:"#elevation-div"},distanceMarkers:true,distanceMarkers_options:{lazy:true}},initialize:function(tracks,options){L.Util.setOptions(this,options);this._count=0;this._loadedCount=
|
|
6
|
+
0;this._tracks=tracks;this._routes={};this._layers=L.featureGroup();this._markers=L.featureGroup();this._elevation=L.control.elevation(this.options.elevation_options);this._legend=L.control.layersLegend(null,null,this.options.legend_options);var icon=L.icon(this.options.points_options.icon);this.options.points.forEach(function(poi){var marker=L.marker(poi.latlng,{icon:icon});marker.bindTooltip(poi.name,{direction:"auto"});marker.addTo(this._markers)},this);if(typeof L.DistanceMarkers==="undefined")this.options.distanceMarkers=
|
|
7
|
+
false},getBounds:function(){return this._layers.getBounds()},addTo:function(map){this._layers.addTo(map);this._markers.addTo(map);this._map=map;this.on("selection_changed",this._onSelectionChanged,this);this._map.on("legend_selected",this._onLegendSelected,this);this._tracks.forEach(this.addTrack,this)},addTrack:function(track){fetch(track).then((response)=>{if(response.ok)response.text().then((doc)=>{let geojson;doc=doc.trim();try{let xml=(new DOMParser).parseFromString(doc,"text/xml");let type=
|
|
8
|
+
xml.documentElement.tagName.toLowerCase();let name=xml.getElementsByTagName("name");if(!(type in toGeoJSON))type=xml.documentElement.tagName=="TrainingCenterDatabase"?"tcx":"gpx";geojson=toGeoJSON[type](xml);geojson.name=name.length>0?Array.from(name).find((tag)=>tag.parentElement.tagName=="trk").textContent:""}catch(e){try{geojson=JSON.parse(doc.toString())}catch(e){console.warn("Error parsing track: "+track)}}if(!geojson.name)geojson.name=track.split("/").pop().split("#")[0].split("?")[0];this._loadRoute(geojson)})})},
|
|
9
|
+
_loadRoute:function(data){if(!data)return;var colors=this._uniqueColors(this._tracks.length);var color=colors[this._count++];var line_style={color:color,opacity:.75,weight:5,distanceMarkers:this.options.distanceMarkers_options};var route=L.geoJson(data,{name:data.name||"",style:(feature)=>line_style,distanceMarkers:line_style.distanceMarkers,originalStyle:line_style,filter:(feature)=>feature.geometry.type!="Point"});route.addTo(this._layers);this._routes[route._leaflet_id]=route;route.eachLayer((layer)=>
|
|
10
|
+
this._onRouteLayer(route,layer));this._onRouteLoaded(route)},_onRouteLayer:function(route,layer){var polyline=layer;route.on("selected",L.bind(this._onRouteSelected,this,route,polyline));polyline.on("mouseover",L.bind(this._onRouteMouseOver,this,route,polyline));polyline.on("mouseout",L.bind(this._onRouteMouseOut,this,route,polyline));polyline.on("click",L.bind(this._onRouteClick,this,route,polyline));polyline.bindTooltip(route.options.name,{direction:"auto",sticky:true})},highlight:function(route,
|
|
11
|
+
polyline){polyline.setStyle(this.options.highlight);if(this.options.distanceMarkers)polyline.addDistanceMarkers()},unhighlight:function(route,polyline){polyline.setStyle(route.options.originalStyle);if(this.options.distanceMarkers)polyline.removeDistanceMarkers()},_onRouteMouseOver:function(route,polyline){if(!route.isSelected()){this.highlight(route,polyline);if(this.options.legend){this.setSelection(route);L.DomUtil.get("legend_"+route._leaflet_id).parentNode.previousSibling.click()}}this.fire("route_mouseover",
|
|
12
|
+
{route:route,polyline:polyline})},_onRouteMouseOut:function(route,polyline){if(!route.isSelected())this.unhighlight(route,polyline);this.fire("route_mouseout",{route:route,polyline:polyline})},_onRouteClick:function(route,polyline){this.setSelection(route)},_onRouteSelected:function(route,polyline){if(!route.isSelected())this.unhighlight(route,polyline)},_onRouteLoaded:function(route){if(this.options.legend)this._legend.addBaseLayer(route,'<svg id="legend_'+route._leaflet_id+'" width="25" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">'+
|
|
13
|
+
'<line x1="0" x2="50" y1="5" y2="5" stroke="'+route.options.originalStyle.color+'" fill="transparent" stroke-width="5" /></svg>'+" "+route.options.name);this.fire("route_loaded",{route:route});if(++this._loadedCount===this._tracks.length){this.fire("loaded");if(this.options.flyToBounds)this._map.flyToBounds(this.getBounds(),{duration:.25,easeLinearity:.25,noMoveStart:true});if(this.options.legend)this._legend.addTo(this._map)}},_onSelectionChanged:function(e){var elevation=this._elevation;var eleDiv=
|
|
14
|
+
elevation.getContainer();var route=this.getSelection();elevation.clear();if(route&&route.isSelected()){if(!eleDiv)elevation.loadChart(this._map);route.getLayers().forEach(function(layer){if(layer instanceof L.Polyline){elevation.addData(layer,false);layer.bringToFront()}})}else if(eleDiv)elevation.remove()},_onLegendSelected:function(e){var layers=this._layers._layers;var route=e.layer;if(!route.isSelected()){this.setSelection(route);for(var i in route._layers)this.highlight(route,route._layers[i]);
|
|
15
|
+
this._map.flyToBounds(e.layer.getBounds())}var parent=e.input.closest(".leaflet-control-layers-list");var offset=e.input.offsetTop-parent.offsetTop;parent.scroll({top:offset||0,behavior:"smooth"});for(var j in layers){var selected=layers[j].isSelected();var legend=L.DomUtil.get("legend_"+layers[j]._leaflet_id);legend.querySelector("line").style.stroke=selected?this.options.highlight.color:"";legend.parentNode.style.fontWeight=selected?"700":""}},_uniqueColors:function(count){if(count===0)return[];
|
|
16
|
+
if(count===1)return["#0000ff"];var increment=1/count;var colors=[];for(var i=0;i<count;++i){var hue=i*increment;var rgb=this._hsvToRgb(hue,1,.7);var hex="#"+this._rgbToHex(rgb[0],rgb[1],rgb[2]);colors.push(hex)}return colors},_hsvToRgb:function(h,s,v){var r,g,b;var i=Math.floor(h*6);var f=h*6-i;var p=v*(1-s);var q=v*(1-f*s);var t=v*(1-(1-f)*s);switch(i%6){case 0:r=v;g=t;b=p;break;case 1:r=q;g=v;b=p;break;case 2:r=p;g=v;b=t;break;case 3:r=p;g=q;b=v;break;case 4:r=t;g=p;b=v;break;case 5:r=v;g=p;b=q;
|
|
17
|
+
break}return[r*255,g*255,b*255]},_rgbToHex:function(r,g,b){return this._byteToHex(r)+this._byteToHex(g)+this._byteToHex(b)},_byteToHex:function(n){return(n>>4&15).toString(16)+(n&15).toString(16)},removeFrom:function(map){this._layers.removeFrom(map)}});L.GpxGroup.include(L.Mixin.Events);L.GpxGroup.include(L.Mixin.Selection);L.gpxGroup=function(tracks,options){return new L.GpxGroup(tracks,options)};
|
package/package.json
CHANGED
package/src/acceleration.js
CHANGED
|
@@ -96,7 +96,7 @@ Elevation.addInitHook(function() {
|
|
|
96
96
|
|
|
97
97
|
this._registerFocusLabel({
|
|
98
98
|
name : 'acceleration',
|
|
99
|
-
chart
|
|
99
|
+
chart: (item) => L._("a: ") + item.acceleration + " " + acceleration.label,
|
|
100
100
|
marker: (item) => Math.round(item.acceleration) + " " + acceleration.label,
|
|
101
101
|
});
|
|
102
102
|
|
package/src/altitude.js
CHANGED
|
@@ -107,6 +107,12 @@ Elevation.addInitHook(function() {
|
|
|
107
107
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
this._registerFocusLabel({
|
|
111
|
+
name: 'y',
|
|
112
|
+
chart: (item) => L._("y: ") + d3.format("." + opts.decimalsY + "f")(item[opts.yAttr]) + " " + this._yLabel,
|
|
113
|
+
marker: (item) => d3.format("." + opts.decimalsY + "f")(item[opts.yAttr]) + " " + this._yLabel,
|
|
114
|
+
});
|
|
115
|
+
|
|
110
116
|
this._registerSummary({
|
|
111
117
|
"maxele" : {
|
|
112
118
|
label: "Max Elevation: ",
|
package/src/chart.js
CHANGED
|
@@ -783,38 +783,17 @@ export var Chart = L.Class.extend({
|
|
|
783
783
|
height: this._height()
|
|
784
784
|
})
|
|
785
785
|
);
|
|
786
|
+
|
|
786
787
|
this._focuslabel.call(
|
|
787
788
|
D3.MouseFocusLabel({
|
|
788
789
|
xCoord: xCoordinate,
|
|
789
790
|
yCoord: yCoordinate,
|
|
790
791
|
height: this._height(),
|
|
791
792
|
width : this._width(),
|
|
792
|
-
|
|
793
|
-
|
|
793
|
+
labels: this._props.focusLabels,
|
|
794
|
+
item: item
|
|
794
795
|
})
|
|
795
796
|
);
|
|
796
|
-
|
|
797
|
-
// this._focuslabel.selectAll('tspan').data(Object.values(this._focuslabels));
|
|
798
|
-
|
|
799
|
-
let labels = this._props.focusLabels;
|
|
800
|
-
let tooltip = this._focuslabel.select('text');
|
|
801
|
-
let label;
|
|
802
|
-
|
|
803
|
-
for (var i in labels) {
|
|
804
|
-
label = tooltip.select(".mouse-focus-label-" + labels[i].name);
|
|
805
|
-
|
|
806
|
-
if (!label.size()) {
|
|
807
|
-
label = tooltip.append("svg:tspan", ".mouse-focus-label-x")
|
|
808
|
-
.attr("class", "mouse-focus-label-" + labels[i].name)
|
|
809
|
-
.attr("dy", "1.5em");
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
label.text(typeof labels[i].value !== "function" ? labels[i].value : labels[i].value(item) );
|
|
813
|
-
|
|
814
|
-
this._focuslabel.select('.mouse-focus-label-x')
|
|
815
|
-
.attr("dy", "1.5em");
|
|
816
|
-
}
|
|
817
|
-
|
|
818
797
|
},
|
|
819
798
|
|
|
820
799
|
_hideDiagramIndicator: function() {
|
package/src/components.js
CHANGED
|
@@ -124,7 +124,8 @@ export const HeightFocusLabel = ({
|
|
|
124
124
|
theme,
|
|
125
125
|
xCoord = 0,
|
|
126
126
|
yCoord = 0,
|
|
127
|
-
|
|
127
|
+
labels = {},
|
|
128
|
+
item = {}
|
|
128
129
|
}) => {
|
|
129
130
|
return text => {
|
|
130
131
|
text
|
|
@@ -133,13 +134,21 @@ export const HeightFocusLabel = ({
|
|
|
133
134
|
.attr("x", xCoord + 5)
|
|
134
135
|
.attr("y", yCoord);
|
|
135
136
|
|
|
136
|
-
let
|
|
137
|
-
|
|
137
|
+
let label;
|
|
138
|
+
|
|
139
|
+
for (var i in labels) {
|
|
140
|
+
label = text.select(".height-focus-" + labels[i].name);
|
|
138
141
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
+
if (!label.size()) {
|
|
143
|
+
label = text.append("svg:tspan")
|
|
144
|
+
.attr("class", "height-focus-" + labels[i].name)
|
|
145
|
+
.attr("dy", "1.5em");
|
|
146
|
+
}
|
|
142
147
|
|
|
148
|
+
label.text(typeof labels[i].value !== "function" ? labels[i].value : labels[i].value(item));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
text.select('tspan').attr("dy", text.selectAll('tspan').size() > 1 ? "-1.5em" : "0em" );
|
|
143
152
|
text.selectAll('tspan').attr("x", xCoord + 5);
|
|
144
153
|
|
|
145
154
|
return text;
|
|
@@ -161,7 +170,7 @@ export const HeightFocusMarker = ({
|
|
|
161
170
|
|
|
162
171
|
export const LegendItem = ({
|
|
163
172
|
name,
|
|
164
|
-
|
|
173
|
+
label,
|
|
165
174
|
width,
|
|
166
175
|
height,
|
|
167
176
|
margins = {},
|
|
@@ -222,9 +231,9 @@ export const MouseFocusLine = ({
|
|
|
222
231
|
export const MouseFocusLabel = ({
|
|
223
232
|
xCoord,
|
|
224
233
|
yCoord,
|
|
225
|
-
labelX = "",
|
|
226
|
-
labelY = "",
|
|
227
234
|
width,
|
|
235
|
+
labels = {},
|
|
236
|
+
item = {},
|
|
228
237
|
}) => {
|
|
229
238
|
return g => {
|
|
230
239
|
|
|
@@ -232,16 +241,9 @@ export const MouseFocusLabel = ({
|
|
|
232
241
|
|
|
233
242
|
let rect = g.select(".mouse-focus-label-rect");
|
|
234
243
|
let text = g.select(".mouse-focus-label-text");
|
|
235
|
-
let y = text.select(".mouse-focus-label-y");
|
|
236
|
-
let x = text.select(".mouse-focus-label-x");
|
|
237
244
|
|
|
238
245
|
if (!rect.node()) rect = g.append("svg:rect");
|
|
239
246
|
if (!text.node()) text = g.append("svg:text");
|
|
240
|
-
if (!y.node()) y = text.append("svg:tspan");
|
|
241
|
-
if (!x.node()) x = text.append("svg:tspan");
|
|
242
|
-
|
|
243
|
-
y.text(labelY);
|
|
244
|
-
x.text(labelX);
|
|
245
247
|
|
|
246
248
|
// Sets focus-label-text position to the left / right of the mouse-focus-line
|
|
247
249
|
let xAlign = 0;
|
|
@@ -264,13 +266,22 @@ export const MouseFocusLabel = ({
|
|
|
264
266
|
.attr("class", "mouse-focus-label-text")
|
|
265
267
|
.style("font-weight", "700")
|
|
266
268
|
.attr("y", yAlign);
|
|
267
|
-
y
|
|
268
|
-
.attr("class", "mouse-focus-label-y")
|
|
269
|
-
.attr("dy", "1em");
|
|
270
|
-
x
|
|
271
|
-
.attr("class", "mouse-focus-label-x")
|
|
272
|
-
.attr("dy", "2em");
|
|
273
269
|
|
|
270
|
+
let label;
|
|
271
|
+
|
|
272
|
+
for (var i in labels) {
|
|
273
|
+
label = text.select(".mouse-focus-label-" + labels[i].name);
|
|
274
|
+
|
|
275
|
+
if (!label.size()) {
|
|
276
|
+
label = text.append("svg:tspan", ".mouse-focus-label-x")
|
|
277
|
+
.attr("class", "mouse-focus-label-" + labels[i].name)
|
|
278
|
+
.attr("dy", "1.5em");
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
label.text(typeof labels[i].value !== "function" ? labels[i].value : labels[i].value(item));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
text.select('tspan').attr("dy", "1em");
|
|
274
285
|
text.selectAll('tspan').attr("x", xAlign);
|
|
275
286
|
|
|
276
287
|
return g;
|
|
@@ -460,8 +471,9 @@ export const Chart = ({
|
|
|
460
471
|
yCoord: 0,
|
|
461
472
|
height: _height,
|
|
462
473
|
width : _width,
|
|
463
|
-
|
|
464
|
-
|
|
474
|
+
labels: {}
|
|
475
|
+
// labelX: "",
|
|
476
|
+
// labelY: "",
|
|
465
477
|
})
|
|
466
478
|
);
|
|
467
479
|
|
package/src/control.js
CHANGED
|
@@ -17,13 +17,13 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
17
17
|
__TOGEOJSON: 'https://unpkg.com/@tmcw/togeojson@4.3.0/dist/togeojson.umd.js',
|
|
18
18
|
__LGEOMUTIL: 'https://unpkg.com/leaflet-geometryutil@0.9.3/src/leaflet.geometryutil.js',
|
|
19
19
|
__LALMOSTOVER: 'https://unpkg.com/leaflet-almostover@1.0.1/src/leaflet.almostover.js',
|
|
20
|
-
__LDISTANCEM: 'https://unpkg.com/@raruto/leaflet-elevation@1.7.
|
|
20
|
+
__LDISTANCEM: 'https://unpkg.com/@raruto/leaflet-elevation@1.7.6/libs/leaflet-distance-marker.min.js',
|
|
21
21
|
|
|
22
22
|
/*
|
|
23
23
|
* Add data to the diagram either from GPX or GeoJSON and update the axis domain and data
|
|
24
24
|
*/
|
|
25
25
|
addData: function(d, layer) {
|
|
26
|
-
if (
|
|
26
|
+
if (typeof layer === "undefined" && d.on) {
|
|
27
27
|
layer = d;
|
|
28
28
|
}
|
|
29
29
|
Elevation._d3LazyLoader = _.lazyLoader(
|
|
@@ -70,7 +70,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
70
70
|
|
|
71
71
|
_clearChart: function() {
|
|
72
72
|
if (this._events && this._events.elechart_updated) {
|
|
73
|
-
this._events.elechart_updated.forEach(e =>
|
|
73
|
+
this._events.elechart_updated.forEach(e => this.off('elechart_updated', e.fn, e.ctx));
|
|
74
74
|
}
|
|
75
75
|
if (this._chart && this._chart._container) {
|
|
76
76
|
this._chart._container.selectAll('g.point .point').remove();
|
|
@@ -196,6 +196,8 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
196
196
|
// this._updateSummary = _.debounce(this._updateSummary, 300, this);
|
|
197
197
|
// }
|
|
198
198
|
|
|
199
|
+
if (this.options.wptIcons === true) this.options.wptIcons = Options.wptIcons;
|
|
200
|
+
|
|
199
201
|
// Leaflet canvas renderer colors
|
|
200
202
|
L.extend(D3.Colors, this.options.colors || {});
|
|
201
203
|
},
|
|
@@ -448,7 +450,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
448
450
|
*/
|
|
449
451
|
_addGPXData: function(coords) {
|
|
450
452
|
_.each(coords, point => {
|
|
451
|
-
this._addPoint(point.lat, point.lng, point.meta.ele);
|
|
453
|
+
this._addPoint(point.lat, point.lng, typeof point.alt !== "undefined" ? point.alt : point.meta.ele);
|
|
452
454
|
this._fireEvt("elepoint_added", { point: point, index: this._data.length - 1 });
|
|
453
455
|
});
|
|
454
456
|
this._fireEvt("eletrack_added", { coords: coords, index: this._data.length - 1 });
|
|
@@ -830,6 +832,8 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
830
832
|
* Hacky way for handling chart resize. Deletes it and redraw chart.
|
|
831
833
|
*/
|
|
832
834
|
_resizeChart: function() {
|
|
835
|
+
if(!this._container) return;
|
|
836
|
+
|
|
833
837
|
// prevent displaying chart on resize if hidden
|
|
834
838
|
if (_.style(this._container, "display") == "none") return;
|
|
835
839
|
|
|
@@ -918,7 +922,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
918
922
|
* Calculates [x, y] domain and then update chart.
|
|
919
923
|
*/
|
|
920
924
|
_updateChart: function() {
|
|
921
|
-
if (/*!this._data.length ||*/ !this._container) return;
|
|
925
|
+
if (/*!this._data.length ||*/ !this._chart || !this._container) return;
|
|
922
926
|
|
|
923
927
|
this._fireEvt("elechart_axis");
|
|
924
928
|
this._fireEvt("elechart_area");
|
|
@@ -1110,7 +1114,7 @@ Elevation.addInitHook(function() {
|
|
|
1110
1114
|
if (options.stroke && options.weight !== 0) {
|
|
1111
1115
|
let oldVal = ctx.globalCompositeOperation || 'source-over';
|
|
1112
1116
|
ctx.globalCompositeOperation = 'destination-over'
|
|
1113
|
-
ctx.strokeStyle = '#FFF';
|
|
1117
|
+
ctx.strokeStyle = color.outline || '#FFF';
|
|
1114
1118
|
ctx.lineWidth = options.weight * 1.75;
|
|
1115
1119
|
ctx.stroke();
|
|
1116
1120
|
ctx.globalCompositeOperation = oldVal;
|
package/src/distance.js
CHANGED
|
@@ -66,6 +66,11 @@ Elevation.addInitHook(function() {
|
|
|
66
66
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
this._registerFocusLabel({
|
|
70
|
+
name: 'x',
|
|
71
|
+
chart: (item) => L._("x: ") + d3.format("." + opts.decimalsX + "f")(item[opts.xAttr]) + " " + this._xLabel,
|
|
72
|
+
});
|
|
73
|
+
|
|
69
74
|
this._registerSummary({
|
|
70
75
|
"totlen" : {
|
|
71
76
|
label: "Total Length: ",
|
package/src/index.js
CHANGED
|
@@ -39,8 +39,8 @@ import * as _ from './utils';
|
|
|
39
39
|
import * as D3 from './components';
|
|
40
40
|
import { Chart } from './chart';
|
|
41
41
|
import { Elevation } from './control';
|
|
42
|
-
import './distance';
|
|
43
42
|
import './altitude';
|
|
43
|
+
import './distance';
|
|
44
44
|
import './time';
|
|
45
45
|
import './slope';
|
|
46
46
|
import './speed';
|
|
@@ -50,4 +50,15 @@ Elevation.Utils = _;
|
|
|
50
50
|
Elevation.Components = D3;
|
|
51
51
|
Elevation.Chart = Chart;
|
|
52
52
|
|
|
53
|
+
/* Temporary fix for empty values evaluated as false (leaflet-i18n v0.3.1) */
|
|
54
|
+
(function(){
|
|
55
|
+
let proto = L.i18n.bind({});
|
|
56
|
+
L.i18n = L._ = (string, data) => {
|
|
57
|
+
if (L.locale && L.locales[L.locale] && L.locales[L.locale][string] == "") {
|
|
58
|
+
L.locales[L.locale][string] = "\u200B";
|
|
59
|
+
}
|
|
60
|
+
return proto.call(null, string, data);
|
|
61
|
+
};
|
|
62
|
+
})();
|
|
63
|
+
|
|
53
64
|
L.control.elevation = (options) => new Elevation(options);
|
package/src/marker.js
CHANGED
|
@@ -93,35 +93,18 @@ export var Marker = L.Class.extend({
|
|
|
93
93
|
length: normalizedY
|
|
94
94
|
})
|
|
95
95
|
);
|
|
96
|
+
|
|
96
97
|
this._focuslabel
|
|
97
98
|
.call(
|
|
98
99
|
D3.HeightFocusLabel({
|
|
99
100
|
theme : opts.theme,
|
|
100
101
|
xCoord: point.x,
|
|
101
102
|
yCoord: normalizedY,
|
|
102
|
-
|
|
103
|
+
labels: this._focuslabels,
|
|
104
|
+
item: point
|
|
103
105
|
})
|
|
104
106
|
);
|
|
105
107
|
|
|
106
|
-
let labels = this._focuslabels;
|
|
107
|
-
let tooltip = this._focuslabel;
|
|
108
|
-
let label;
|
|
109
|
-
|
|
110
|
-
for (var i in labels) {
|
|
111
|
-
label = tooltip.select(".height-focus-" + labels[i].name);
|
|
112
|
-
|
|
113
|
-
if (!label.size()) {
|
|
114
|
-
label = tooltip.append("svg:tspan")
|
|
115
|
-
.attr("class", "height-focus-" + labels[i].name)
|
|
116
|
-
.attr("dy", "1.5em");
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
label.text(typeof labels[i].value !== "function" ? labels[i].value : labels[i].value(props.item) );
|
|
120
|
-
|
|
121
|
-
this._focuslabel.select('.height-focus-y')
|
|
122
|
-
.attr("dy", "-1.5em");
|
|
123
|
-
}
|
|
124
|
-
|
|
125
108
|
} else if (this.options.marker == 'position-marker') {
|
|
126
109
|
_.removeClass(this._marker.getElement(), 'leaflet-hidden');
|
|
127
110
|
this._marker.setLatLng(this._latlng);
|
package/src/options.js
CHANGED
|
@@ -68,6 +68,7 @@ export var Options = {
|
|
|
68
68
|
time: false,
|
|
69
69
|
timeFactor: 3600,
|
|
70
70
|
timeFormat: false,
|
|
71
|
+
timestamps: false,
|
|
71
72
|
sDeltaMax: undefined,
|
|
72
73
|
sInterpolation: "curveStepAfter",
|
|
73
74
|
sRange: undefined,
|
|
@@ -81,6 +82,7 @@ export var Options = {
|
|
|
81
82
|
iconAnchor: [8, 30],
|
|
82
83
|
}),
|
|
83
84
|
},
|
|
85
|
+
wptLabels: true,
|
|
84
86
|
xAttr: "dist",
|
|
85
87
|
xLabel: "km",
|
|
86
88
|
xTicks: undefined,
|
package/src/slope.js
CHANGED
|
@@ -95,7 +95,7 @@ Elevation.addInitHook(function() {
|
|
|
95
95
|
|
|
96
96
|
this._registerFocusLabel({
|
|
97
97
|
name: 'slope',
|
|
98
|
-
chart: (item) => item.slope + slope.label,
|
|
98
|
+
chart: (item) => L._("m: ") + item.slope + slope.label,
|
|
99
99
|
marker: (item) => Math.round(item.slope) + slope.label
|
|
100
100
|
});
|
|
101
101
|
|
package/src/speed.js
CHANGED
|
@@ -96,8 +96,8 @@ Elevation.addInitHook(function() {
|
|
|
96
96
|
|
|
97
97
|
this._registerFocusLabel({
|
|
98
98
|
name: 'speed',
|
|
99
|
-
chart: (item) => item.speed + " " + speed.label,
|
|
100
|
-
marker: (item) => Math.round(item.speed) + " " + speed.label
|
|
99
|
+
chart: (item) => L._('v: ') + item.speed + " " + speed.label,
|
|
100
|
+
marker: (item) => Math.round(item.speed) + " " + speed.label,
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
this._registerSummary({
|
package/src/time.js
CHANGED
|
@@ -100,20 +100,25 @@ Elevation.addInitHook(function() {
|
|
|
100
100
|
this.track_info.time = duration;
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
-
if (this.options.time) {
|
|
104
103
|
|
|
104
|
+
if (this.options.timestamps) {
|
|
105
105
|
this._registerFocusLabel({
|
|
106
|
-
name: '
|
|
107
|
-
chart: (item) => this.options.timeFormat(item.time)
|
|
106
|
+
name: 'date',
|
|
107
|
+
chart: (item) => L._("t: ") + this.options.timeFormat(item.time)
|
|
108
108
|
});
|
|
109
|
+
}
|
|
109
110
|
|
|
111
|
+
if (this.options.time) {
|
|
112
|
+
this._registerFocusLabel({
|
|
113
|
+
name: 'time',
|
|
114
|
+
chart: (item) => L._("T: ") + _.formatTime(item.duration || 0)
|
|
115
|
+
});
|
|
110
116
|
this._registerSummary({
|
|
111
117
|
"tottime" : {
|
|
112
118
|
label: "Total Time: ",
|
|
113
119
|
value: (track) => _.formatTime(track.time || 0)
|
|
114
120
|
}
|
|
115
121
|
});
|
|
116
|
-
|
|
117
122
|
}
|
|
118
123
|
|
|
119
124
|
});
|