@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.
@@ -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.GPX.include(L.Mixin.Selectable);
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
- this._get(track, this._loadRoute.bind(this));
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 = new L.GPX(data, {
208
- async: this.options.async,
209
- marker_options: this.options.marker_options,
210
- polyline_options: line_style,
211
- gpx_options: this.options.gpx_options,
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
- _onRouteAddLine: function(route, e) {
224
- var polyline = e.line;
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.get_name(), {
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.polyline_options.color + '" fill="transparent" stroke-width="5" /></svg>' + ' ' + route.get_name());
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.GPX.include(L.Mixin.Selectable);
5
- L.GpxGroup=L.Class.extend({options:{async:true,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},marker_options:{startIconUrl:null,endIconUrl:null,shadowUrl:null}},initialize:function(tracks,
6
- options){L.Util.setOptions(this,options);this._count=0;this._loadedCount=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)},
7
- this);if(typeof L.DistanceMarkers==="undefined")this.options.distanceMarkers=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){this._get(track,this._loadRoute.bind(this))},_loadRoute:function(data){var colors=this._uniqueColors(this._tracks.length);
8
- var color=colors[this._count++];var line_style={color:color,opacity:.75,weight:5,distanceMarkers:this.options.distanceMarkers_options};var route=new L.GPX(data,{async:this.options.async,marker_options:this.options.marker_options,polyline_options:line_style});route.originalStyle=line_style;route.on("addline",L.bind(this._onRouteAddLine,this,route));route.on("loaded",L.bind(this._onRouteLoaded,this,route));route.addTo(this._layers);this._routes[route._leaflet_id]=route},_onRouteAddLine:function(route,
9
- e){var polyline=e.line;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.get_name(),{direction:"auto",sticky:true})},highlight:function(route,polyline){polyline.setStyle(this.options.highlight);if(this.options.distanceMarkers)polyline.addDistanceMarkers()},
10
- unhighlight:function(route,polyline){polyline.setStyle(route.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",{route:route,polyline:polyline})},_onRouteMouseOut:function(route,polyline){if(!route.isSelected())this.unhighlight(route,
11
- 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">'+'<line x1="0" x2="50" y1="5" y2="5" stroke="'+route.options.polyline_options.color+
12
- '" fill="transparent" stroke-width="5" /></svg>'+" "+route.get_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=elevation.getContainer();var route=this.getSelection();elevation.clear();if(route&&
13
- route.isSelected()){if(!eleDiv)elevation.loadChart(this._map);route.getLayers().forEach(function(layer){if(layer instanceof L.Polyline){elevation.addData(layer);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]);this._map.flyToBounds(e.layer.getBounds())}var parent=e.input.closest(".leaflet-control-layers-list");
14
- 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":""}},_get:function(url,callback){var xhr=new XMLHttpRequest;xhr.open("GET",url);xhr.onreadystatechange=function(){if(xhr.readyState===XMLHttpRequest.DONE&&xhr.status===
15
- 200)callback(xhr.response)};xhr.send()},_uniqueColors:function(count){if(count===0)return[];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=
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;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)};
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raruto/leaflet-elevation",
3
- "version": "1.7.2",
3
+ "version": "1.7.6",
4
4
  "description": "A Leaflet plugin that allows to add elevation profiles using d3js",
5
5
  "main": "dist/leaflet-elevation.min.js",
6
6
  "module": "src/index.js",
@@ -96,7 +96,7 @@ Elevation.addInitHook(function() {
96
96
 
97
97
  this._registerFocusLabel({
98
98
  name : 'acceleration',
99
- chart : (item) => item.acceleration + " " + acceleration.label,
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
- labelX: d3.format("."+ opts.decimalsX +"f")(item[opts.xAttr]) + " " + this._xLabel,
793
- labelY: d3.format("."+ opts.decimalsY +"f")(item[opts.yAttr]) + " " + this._yLabel
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
- label,
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 y = text.select(".height-focus-y");
137
- if (!y.node()) y = text.append("svg:tspan");
137
+ let label;
138
+
139
+ for (var i in labels) {
140
+ label = text.select(".height-focus-" + labels[i].name);
138
141
 
139
- y
140
- .attr("class", "height-focus-y")
141
- .text(label);
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
- label,
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
- labelX: "",
464
- labelY: "",
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.2/libs/leaflet-distance-marker.min.js',
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 ((typeof layer === "undefined" || layer === null) && d.on) {
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 => controlElevation.off('elechart_updated', e.fn, e.ctx));
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
- label : d3.format("." + opts.decimalsY + "f")(point[opts.yAttr]) + " " + this._yLabel
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: 'time',
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
  });