@raruto/leaflet-elevation 2.0.2 → 2.0.5
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 +5 -3
- package/dist/leaflet-elevation.css +114 -137
- package/dist/leaflet-elevation.js +54 -74
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.css +1 -1
- package/dist/leaflet-elevation.min.js +1 -1
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/images/elevation-steelblue.svg +1 -1
- package/libs/fullpage.css +13 -0
- package/libs/leaflet-gpxgroup.js +1 -1
- package/libs/leaflet-gpxgroup.min.js +1 -1
- package/package.json +1 -1
- package/src/components/chart.js +82 -54
- package/src/components/d3.js +74 -17
- package/src/control.js +40 -62
- package/src/handlers/altitude.js +1 -1
- package/src/handlers/heart.js +2 -2
- package/src/index.css +114 -137
- package/src/options.js +9 -9
- package/src/utils.js +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><defs/><path fill="#4682b4" fill-opacity=".8" d="M23.1 20.8l-4.2-8-3.9-.2-2.7 1.8-2.4-5.5-5.2 6.2v5.7" opacity=".9"/><path fill="none" stroke="#174a75" stroke-width="1.5" d="M4.7 14.8h1.1l4.3-6.2 2.5 5.6 2.5-2.3 3.7.2 4 8.3v.4"/><path fill="none" stroke="#737373" stroke-linecap="square" d="M3.4 5v19.8M24.7 22.4H.9"/></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26"><defs/><path fill="#4682b4" fill-opacity=".8" d="M23.1 20.8l-4.2-8-3.9-.2-2.7 1.8-2.4-5.5-5.2 6.2v5.7" opacity=".9"/><path fill="none" stroke="#174a75" stroke-width="1.5" d="M4.7 14.8h1.1l4.3-6.2 2.5 5.6 2.5-2.3 3.7.2 4 8.3v.4"/><path fill="none" stroke="#737373" stroke-linecap="square" d="M3.4 5v19.8M24.7 22.4H.9"/></svg>
|
package/libs/leaflet-gpxgroup.js
CHANGED
|
@@ -164,7 +164,7 @@ L.GpxGroup = L.Class.extend({
|
|
|
164
164
|
.then(text => this._elevation._parseFromString(text))
|
|
165
165
|
.then(geojson => {
|
|
166
166
|
if(geojson) {
|
|
167
|
-
geojson.name = geojson.name
|
|
167
|
+
geojson.name = geojson.name || (geojson[0] && geojson[0].properties.name) || track.split('/').pop().split('#')[0].split('?')[0];
|
|
168
168
|
this._loadRoute(geojson);
|
|
169
169
|
}
|
|
170
170
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
L.Mixin.Selectable={includes:L.Mixin.Events,setSelected:function(s){var selected=!!s;this._selected!==selected&&(this._selected=selected,this.fire("selected"))},isSelected:function(){return!!this._selected}},L.Mixin.Selection={includes:L.Mixin.Events,getSelection:function(){return this._selected},setSelection:function(item){this._selected===item?null!==item&&(item.setSelected(!item.isSelected()),item.isSelected()||(this._selected=null)):(this._selected&&this._selected.setSelected(!1),this._selected=item,this._selected&&this._selected.setSelected(!0)),this.fire("selection_changed")}},L.Control.LayersLegend=L.Control.Layers.extend({_onInputClick:function(){
|
|
1
|
+
L.Mixin.Selectable={includes:L.Mixin.Events,setSelected:function(s){var selected=!!s;this._selected!==selected&&(this._selected=selected,this.fire("selected"))},isSelected:function(){return!!this._selected}},L.Mixin.Selection={includes:L.Mixin.Events,getSelection:function(){return this._selected},setSelection:function(item){this._selected===item?null!==item&&(item.setSelected(!item.isSelected()),item.isSelected()||(this._selected=null)):(this._selected&&this._selected.setSelected(!1),this._selected=item,this._selected&&this._selected.setSelected(!0)),this.fire("selection_changed")}},L.Control.LayersLegend=L.Control.Layers.extend({_onInputClick:function(){this._handlingClick=!0,this._layerControlInputs.reduceRight((_,input)=>{if(input.checked)return this._map.fireEvent("legend_selected",{layer:this._getLayer(input.layerId).layer,input:input},!0),input},0),this._handlingClick=!1,this._refocusOnMap()}}),L.control.layersLegend=(baseLayers,overlays,options)=>new L.Control.LayersLegend(baseLayers,overlays,options),L.GeoJSON.include(L.Mixin.Selectable),L.GpxGroup=L.Class.extend({options:{highlight:{color:"#ff0",opacity:1},points:[],points_options:{icon:{iconUrl:"../images/elevation-poi.png",iconSize:[12,12]}},flyToBounds:!0,legend:!1,legend_options:{position:"topright",collapsed:!1},elevation:!0,elevation_options:{theme:"yellow-theme",detached:!0,elevationDiv:"#elevation-div"},distanceMarkers:!0,distanceMarkers_options:{lazy:!0}},initialize:function(tracks,options){L.Util.setOptions(this,options),this._count=0,this._loadedCount=0,this._tracks=tracks,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),this.options.points.forEach(poi=>L.marker(poi.latlng,{icon:L.icon(this.options.points_options.icon)}).bindTooltip(poi.name,{direction:"auto"}).addTo(this._markers))},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=>response.ok&&response.text()).then(text=>this._elevation._parseFromString(text)).then(geojson=>{geojson&&(geojson.name=geojson.name||geojson[0]&&geojson[0].properties.name||track.split("/").pop().split("#")[0].split("?")[0],this._loadRoute(geojson))})},_loadRoute:function(data){if(data){var line_style={color:this._uniqueColors(this._tracks.length)[this._count++],opacity:.75,weight:5,distanceMarkers:this.options.distanceMarkers_options},route=L.geoJson(data,{name:data.name||"",style:feature=>line_style,distanceMarkers:line_style.distanceMarkers,originalStyle:line_style,filter:feature=>"Point"!=feature.geometry.type});this._elevation.import(this._elevation.__LGEOMUTIL).then(()=>{route.addTo(this._layers),route.eachLayer(layer=>this._onEachRouteLayer(route,layer)),this._onEachRouteLoaded(route)})}},_onEachRouteLayer: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:!0})},_onEachRouteLoaded:function(route){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.originalStyle.color+'" fill="transparent" stroke-width="5" /></svg> '+route.options.name),this.fire("route_loaded",{route:route}),++this._loadedCount===this._tracks.length&&(this.fire("loaded"),this.options.flyToBounds&&this._map.flyToBounds(this.getBounds(),{duration:.25,easeLinearity:.25,noMoveStart:!0}),this.options.legend&&this._legend.addTo(this._map))},highlight:function(route,polyline){polyline.setStyle(this.options.highlight),this.options.distanceMarkers&&polyline.addDistanceMarkers()},unhighlight:function(route,polyline){polyline.setStyle(route.options.originalStyle),this.options.distanceMarkers&&polyline.removeDistanceMarkers()},_onRouteMouseOver:function(route,polyline){route.isSelected()||(this.highlight(route,polyline),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){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){route.isSelected()||this.unhighlight(route,polyline)},_onSelectionChanged:function(e){var elevation=this._elevation,eleDiv=elevation.getContainer(),route=this.getSelection();elevation.clear(),route&&route.isSelected()?(eleDiv||elevation.addTo(this._map),route.getLayers().forEach((function(layer){layer instanceof L.Polyline&&(elevation.addData(layer,!1),layer.bringToFront())}))):eleDiv&&elevation.remove()},_onLegendSelected:function(e){var parent=e.input.closest(".leaflet-control-layers-list"),route=e.layer;if(!route.isSelected()){for(var i in this.setSelection(route),route._layers)this.highlight(route,route._layers[i]);this._map.flyToBounds(e.layer.getBounds())}parent.scroll({top:e.input.offsetTop-parent.offsetTop||0,behavior:"smooth"}),this._layers.eachLayer(layer=>{var legend=L.DomUtil.get("legend_"+layer._leaflet_id);legend.querySelector("line").style.stroke=layer.isSelected()?this.options.highlight.color:"",legend.parentNode.style.fontWeight=layer.isSelected()?"700":""})},_uniqueColors:function(count){return 1===count?["#0000ff"]:new Array(count).fill(null).map((_,i)=>this._hsvToHex(i*(1/count),1,.7))},_hsvToHex:function(h,s,v){var i=Math.floor(6*h),f=6*h-i,p=v*(1-s),q=v*(1-f*s),t=v*(1-(1-f)*s),rgb;return{0:[v,t,p],1:[q,v,p],2:[p,v,t],3:[p,q,v],4:[t,p,v],5:[v,p,q]}[i%6].map(d=>255*d).reduce((hex,byte)=>hex+(byte>>4&15).toString(16)+(15&byte).toString(16),"#")},removeFrom:function(map){this._layers.removeFrom(map)}}),L.GpxGroup.include(L.Mixin.Events),L.GpxGroup.include(L.Mixin.Selection),L.gpxGroup=(tracks,options)=>new L.GpxGroup(tracks,options);
|
package/package.json
CHANGED
package/src/components/chart.js
CHANGED
|
@@ -85,6 +85,7 @@ export var Chart = L.Control.Elevation.Chart = L.Class.extend({
|
|
|
85
85
|
this._updateScale();
|
|
86
86
|
this._updateArea();
|
|
87
87
|
this._updateAxis();
|
|
88
|
+
this._updateMargins();
|
|
88
89
|
this._updateLegend();
|
|
89
90
|
this._updateClipper();
|
|
90
91
|
|
|
@@ -350,7 +351,7 @@ export var Chart = L.Control.Elevation.Chart = L.Class.extend({
|
|
|
350
351
|
if (typeof props.preferCanvas === "undefined") props.preferCanvas = opts.preferCanvas;
|
|
351
352
|
|
|
352
353
|
// Save paths in memory for latter usage
|
|
353
|
-
this._paths[props.name] = D3.Path(props)
|
|
354
|
+
this._paths[props.name] = D3.Path(props);
|
|
354
355
|
this._props.areas[props.name] = props;
|
|
355
356
|
|
|
356
357
|
if (opts.legend) {
|
|
@@ -536,80 +537,92 @@ export var Chart = L.Control.Elevation.Chart = L.Class.extend({
|
|
|
536
537
|
},
|
|
537
538
|
|
|
538
539
|
_updateLegend: function () {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const legendOpts = {
|
|
543
|
-
width : this._width(),
|
|
544
|
-
height : this._height(),
|
|
545
|
-
margins: this.options.margins,
|
|
546
|
-
};
|
|
547
|
-
|
|
548
|
-
// Reset legend items
|
|
549
|
-
this._legend.selectAll('g').remove();
|
|
550
|
-
_.each(this._props.legendItems, (legend) => {
|
|
551
|
-
this._legend.append("g").call(D3.LegendItem(L.extend(legendOpts, legend)));
|
|
552
|
-
});
|
|
553
|
-
|
|
540
|
+
let xAxesB = this._axis.selectAll('.x.axis.bottom').nodes().length;
|
|
541
|
+
|
|
554
542
|
// Get legend items
|
|
555
|
-
let items
|
|
543
|
+
let items = Object.keys(this._paths);
|
|
556
544
|
|
|
557
545
|
// Calculate legend item positions
|
|
558
|
-
let n = items.
|
|
546
|
+
let n = items.length;
|
|
559
547
|
let v = Array(Math.floor(n / 2)).fill(null).map((d, i) => (i + 1) * 2 - (1 - Math.sign(n % 2)));
|
|
560
548
|
let rev = v.slice().reverse().map((d) => -(d));
|
|
561
549
|
|
|
550
|
+
// push a fake element to handle center alignment (odd numbers)
|
|
562
551
|
if (n % 2 !== 0) {
|
|
563
552
|
rev.push(0);
|
|
564
553
|
}
|
|
565
554
|
v = rev.concat(v);
|
|
566
555
|
|
|
567
|
-
//
|
|
568
|
-
|
|
569
|
-
let marginB = 30 + (xAxesB * 2);
|
|
570
|
-
let marginR = n * 30;
|
|
556
|
+
// Reset legend items
|
|
557
|
+
this._legend.selectAll('g').remove();
|
|
571
558
|
|
|
572
|
-
//
|
|
573
|
-
|
|
574
|
-
this.
|
|
575
|
-
|
|
576
|
-
|
|
559
|
+
// Render legend items
|
|
560
|
+
_.each(this._props.legendItems, (legend) => {
|
|
561
|
+
this._legend.append("g").call(
|
|
562
|
+
D3.LegendItem(L.extend({
|
|
563
|
+
width : this._width(),
|
|
564
|
+
height : this._height(),
|
|
565
|
+
margins: this.options.margins,
|
|
566
|
+
}, legend))
|
|
567
|
+
);
|
|
568
|
+
});
|
|
577
569
|
|
|
578
|
-
//
|
|
579
|
-
if(
|
|
580
|
-
this.
|
|
581
|
-
|
|
570
|
+
// Render legend item switcher
|
|
571
|
+
if (n > 1) {
|
|
572
|
+
this._legend.append("g").call(
|
|
573
|
+
D3.LegendSmall({
|
|
574
|
+
width : this._width(),
|
|
575
|
+
height : this._height(),
|
|
576
|
+
items : items,
|
|
577
|
+
onClick: (selected) => {
|
|
578
|
+
_.each(items, name => this._togglePath(name, selected == name, true));
|
|
579
|
+
this._updateArea();
|
|
580
|
+
}
|
|
581
|
+
})
|
|
582
|
+
);
|
|
582
583
|
}
|
|
584
|
+
|
|
585
|
+
_.each(items, (name, i) => {
|
|
586
|
+
// Adjust legend item positions
|
|
587
|
+
this._legend.select('[data-name=' + name + ']').attr("transform", "translate(" + (v[i] * 55) + ", " + (xAxesB * 2) + ")");
|
|
588
|
+
// Set initial state (disabled controls)
|
|
589
|
+
this._togglePath(name, !(name in this.options && this.options[name] == 'disabled'), true);
|
|
590
|
+
});
|
|
583
591
|
|
|
584
|
-
|
|
585
|
-
.each((d, i, n) => {
|
|
586
|
-
|
|
587
|
-
let legend = d3.select(n[i]);
|
|
588
|
-
let rect = legend.select('rect');
|
|
589
|
-
let name = legend.attr('data-name');
|
|
590
|
-
let path = this._paths[name];
|
|
592
|
+
},
|
|
591
593
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
+
_updateMargins: function() {
|
|
595
|
+
// Get chart margins
|
|
596
|
+
let xAxesB = this._axis.selectAll('.x.axis.bottom').nodes().length;
|
|
597
|
+
let xAxesL = this._axis.selectAll('.y.axis.left').nodes().length;
|
|
598
|
+
let xAxesR = this._axis.selectAll('.y.axis.right').nodes().length;
|
|
599
|
+
let marginB = 60 + (xAxesB * 2);
|
|
600
|
+
let marginL = 10 + (xAxesL * 30);
|
|
601
|
+
let marginR = 40 + (xAxesR * 30);
|
|
594
602
|
|
|
595
|
-
|
|
603
|
+
let marginsUpdated = false
|
|
596
604
|
|
|
597
|
-
|
|
598
|
-
|
|
605
|
+
// Adjust right margin
|
|
606
|
+
if (xAxesR && this.options.margins.right < marginR) {
|
|
607
|
+
this.options.margins.right = marginR;
|
|
608
|
+
marginsUpdated = true;
|
|
609
|
+
}
|
|
599
610
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
}
|
|
611
|
+
// Adjust left margin
|
|
612
|
+
if(xAxesL && this.options.margins.left < marginL) {
|
|
613
|
+
this.options.margins.left = marginL;
|
|
614
|
+
marginsUpdated = true;
|
|
615
|
+
}
|
|
606
616
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
617
|
+
// Adjust bottom margin
|
|
618
|
+
if(xAxesB && this.options.margins.bottom < marginB) {
|
|
619
|
+
this.options.margins.bottom = marginB;
|
|
620
|
+
marginsUpdated = true;
|
|
621
|
+
}
|
|
611
622
|
|
|
612
|
-
|
|
623
|
+
if (marginsUpdated) {
|
|
624
|
+
this.fire('margins_updated');
|
|
625
|
+
}
|
|
613
626
|
},
|
|
614
627
|
|
|
615
628
|
_updateScale: function() {
|
|
@@ -733,6 +746,21 @@ export var Chart = L.Control.Elevation.Chart = L.Class.extend({
|
|
|
733
746
|
}));
|
|
734
747
|
},
|
|
735
748
|
|
|
749
|
+
_togglePath(name, enabled = true, lazy = false) {
|
|
750
|
+
let path = this._paths[name];
|
|
751
|
+
let legend = this._container.select('.legend [data-name=' + name + ']');
|
|
752
|
+
path.classed('leaflet-hidden', !enabled);
|
|
753
|
+
legend.select('text').style('text-decoration-line', enabled ? '' : 'line-through');
|
|
754
|
+
legend.select('rect').style('fill-opacity', enabled ? '': '0');
|
|
755
|
+
// Apply d3-zoom (bind <clipPath> mask)
|
|
756
|
+
if (this._mask) {
|
|
757
|
+
path.attr('mask', 'url(#' + this._mask.attr('id') + ')');
|
|
758
|
+
}
|
|
759
|
+
if (!lazy) {
|
|
760
|
+
this._updateArea();
|
|
761
|
+
}
|
|
762
|
+
},
|
|
763
|
+
|
|
736
764
|
_hideDiagramIndicator: function() {
|
|
737
765
|
this._tooltip.attr("display", 'none');
|
|
738
766
|
},
|
package/src/components/d3.js
CHANGED
|
@@ -205,7 +205,6 @@ export const LegendItem = ({
|
|
|
205
205
|
.text(L._(label || name))
|
|
206
206
|
.attr("x", (width / 2) + 5)
|
|
207
207
|
.attr("font-size", 10)
|
|
208
|
-
.style("text-decoration-thickness", "2px")
|
|
209
208
|
.style("font-weight", "700")
|
|
210
209
|
.attr('y', height + margins.bottom / 2)
|
|
211
210
|
.attr('dy', "0.75em");
|
|
@@ -214,6 +213,70 @@ export const LegendItem = ({
|
|
|
214
213
|
}
|
|
215
214
|
};
|
|
216
215
|
|
|
216
|
+
export const LegendSmall = ({
|
|
217
|
+
width,
|
|
218
|
+
height,
|
|
219
|
+
items,
|
|
220
|
+
onClick
|
|
221
|
+
}) => {
|
|
222
|
+
return g => {
|
|
223
|
+
let idx = 0;
|
|
224
|
+
|
|
225
|
+
g.data([{
|
|
226
|
+
x: width,
|
|
227
|
+
y: height + 40
|
|
228
|
+
}]).attr("transform", d => "translate(" + d.x + "," + d.y + ")").classed('legend-switcher');
|
|
229
|
+
|
|
230
|
+
// let label = g.selectAll(".legend-switcher-label") .data([{ idx: 0 }]);
|
|
231
|
+
let label = g.append('svg:text')
|
|
232
|
+
.attr("class", "legend-switcher-label")
|
|
233
|
+
.attr("text-anchor", "end")
|
|
234
|
+
.attr("x", -25)
|
|
235
|
+
.attr("y", 5)
|
|
236
|
+
.on("mousedown", (e, d) => setIdx(L.Util.wrapNum((idx + 1), [0, items.length])));
|
|
237
|
+
|
|
238
|
+
let symbol = g.selectAll(".legend-switcher-symbol").data([
|
|
239
|
+
{ type: d3.symbolTriangle, x: 0, y: 3, angle: 0, size: 50, id: "down" },
|
|
240
|
+
{ type: d3.symbolTriangle, x: -13, y: 0, angle: 180, size: 50, id: "up" }
|
|
241
|
+
]);
|
|
242
|
+
|
|
243
|
+
symbol.exit().remove();
|
|
244
|
+
label.exit().remove();
|
|
245
|
+
|
|
246
|
+
symbol.enter()
|
|
247
|
+
.append("svg:path")
|
|
248
|
+
.attr("class", "legend-switcher-symbol")
|
|
249
|
+
.attr("cursor", 'pointer')
|
|
250
|
+
.attr("fill", "#000")
|
|
251
|
+
.merge(symbol)
|
|
252
|
+
.attr("d",
|
|
253
|
+
d3.symbol()
|
|
254
|
+
.type(d => d.type)
|
|
255
|
+
.size(d => d.size)
|
|
256
|
+
)
|
|
257
|
+
.attr("transform", d => "translate(" + d.x + "," + d.y + ") rotate(" + d.angle + ")")
|
|
258
|
+
.on("mousedown", (e, d) => setIdx(L.Util.wrapNum((d.id === "up" ? idx + 1 : idx - 1), [0, items.length])));
|
|
259
|
+
|
|
260
|
+
const setIdx = (id) => {
|
|
261
|
+
idx = id;
|
|
262
|
+
// label.enter()
|
|
263
|
+
// .append('text')
|
|
264
|
+
// .attr("class", "legend-switcher-label")
|
|
265
|
+
// .attr("text-anchor", "end")
|
|
266
|
+
// .attr("x", -25)
|
|
267
|
+
// .attr("y", 5)
|
|
268
|
+
// .merge(label.data([{ idx: id }]))
|
|
269
|
+
// .text(d => items.length ? (items[idx][0].toUpperCase() + items[idx].slice(1)) : '')
|
|
270
|
+
// .on("mousedown", (e, d) => setIdx(L.Util.wrapNum((idx + 1), [0, items.length])));
|
|
271
|
+
label.text(items.length ? (items[idx][0].toUpperCase() + items[idx].slice(1)) : '');
|
|
272
|
+
onClick(items[idx]);
|
|
273
|
+
};
|
|
274
|
+
setIdx(0);
|
|
275
|
+
|
|
276
|
+
return g;
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
|
|
217
280
|
export const Tooltip = ({
|
|
218
281
|
xCoord,
|
|
219
282
|
yCoord,
|
|
@@ -300,27 +363,21 @@ export const Ruler = ({
|
|
|
300
363
|
return g => {
|
|
301
364
|
|
|
302
365
|
g.data([{
|
|
303
|
-
|
|
304
|
-
|
|
366
|
+
x: 0,
|
|
367
|
+
y: height,
|
|
305
368
|
}])
|
|
306
369
|
.attr("transform", d => "translate(" + d.x + "," + d.y + ")");
|
|
307
370
|
|
|
308
|
-
let rect = g.selectAll('.horizontal-drag-rect')
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
let line = g.selectAll('.horizontal-drag-line')
|
|
312
|
-
.data([{ w: width }]);
|
|
313
|
-
|
|
314
|
-
let label = g.selectAll('.horizontal-drag-label')
|
|
315
|
-
.data([{ w: width - 8 }]);
|
|
316
|
-
|
|
371
|
+
let rect = g.selectAll('.horizontal-drag-rect').data([{ w: width }]);
|
|
372
|
+
let line = g.selectAll('.horizontal-drag-line').data([{ w: width }]);
|
|
373
|
+
let label = g.selectAll('.horizontal-drag-label').data([{ w: width - 8 }]);
|
|
317
374
|
let symbol = g.selectAll('.horizontal-drag-symbol')
|
|
318
375
|
.data([{
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
376
|
+
type: d3.symbolTriangle,
|
|
377
|
+
x: width + 7,
|
|
378
|
+
y: 0,
|
|
379
|
+
angle: -90,
|
|
380
|
+
size: 50
|
|
324
381
|
}]);
|
|
325
382
|
|
|
326
383
|
rect.exit().remove();
|
package/src/control.js
CHANGED
|
@@ -7,8 +7,8 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
7
7
|
includes: L.Evented ? L.Evented.prototype : L.Mixin.Events,
|
|
8
8
|
|
|
9
9
|
options: Options,
|
|
10
|
-
__mileFactor:
|
|
11
|
-
__footFactor:
|
|
10
|
+
__mileFactor: 0.621371, // 1 km = (0.621371 mi)
|
|
11
|
+
__footFactor: 3.28084, // 1 m = (3.28084 ft)
|
|
12
12
|
__D3: 'https://unpkg.com/d3@6.5.0/dist/d3.min.js',
|
|
13
13
|
__TOGEOJSON: 'https://unpkg.com/@tmcw/togeojson@4.6.0/dist/togeojson.umd.js',
|
|
14
14
|
__LGEOMUTIL: 'https://unpkg.com/leaflet-geometryutil@0.9.3/src/leaflet.geometryutil.js',
|
|
@@ -37,9 +37,9 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
37
37
|
*/
|
|
38
38
|
addTo: function(map) {
|
|
39
39
|
if (this.options.detached) {
|
|
40
|
-
let
|
|
41
|
-
|
|
42
|
-
_.append(
|
|
40
|
+
let parent = _.select(this.options.elevationDiv);
|
|
41
|
+
let eleDiv = this.onAdd(map);
|
|
42
|
+
parent ? _.append(parent, eleDiv) : _.insert(map.getContainer(), eleDiv, 'afterend');
|
|
43
43
|
} else {
|
|
44
44
|
L.Control.prototype.addTo.call(this, map);
|
|
45
45
|
}
|
|
@@ -221,7 +221,9 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
221
221
|
onAdd: function(map) {
|
|
222
222
|
this._map = map;
|
|
223
223
|
|
|
224
|
-
let container = this._container = _.create("div", "elevation-control
|
|
224
|
+
let container = this._container = _.create("div", "elevation-control " + this.options.theme + " " + (this.options.detached ? 'elevation-detached' : 'leaflet-control'), this.options.detached ? { id: 'elevation-' + _.randomId() } : {});
|
|
225
|
+
|
|
226
|
+
if (!this.eleDiv) this.eleDiv = container;
|
|
225
227
|
|
|
226
228
|
let modules = [
|
|
227
229
|
"Distance",
|
|
@@ -413,21 +415,6 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
413
415
|
}
|
|
414
416
|
},
|
|
415
417
|
|
|
416
|
-
/**
|
|
417
|
-
* Adds the control to the given "detached" div.
|
|
418
|
-
*/
|
|
419
|
-
_initElevationDiv: function() {
|
|
420
|
-
let eleDiv = _.select(this.options.elevationDiv);
|
|
421
|
-
if (!eleDiv) {
|
|
422
|
-
this.options.elevationDiv = '#elevation-div_' + _.randomId();
|
|
423
|
-
eleDiv = _.create('div', 'leaflet-control elevation elevation-div', { id: this.options.elevationDiv.substr(1) });
|
|
424
|
-
}
|
|
425
|
-
if (this.options.detached) {
|
|
426
|
-
_.replaceClass(eleDiv, 'leaflet-control', 'elevation-detached');
|
|
427
|
-
}
|
|
428
|
-
return this.eleDiv = eleDiv;
|
|
429
|
-
},
|
|
430
|
-
|
|
431
418
|
/**
|
|
432
419
|
* Initialize "L.AlmostOver" and "L.DistanceMarkers"
|
|
433
420
|
*/
|
|
@@ -446,6 +433,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
446
433
|
} else if (control.options.polyline) {
|
|
447
434
|
layer.addTo(map);
|
|
448
435
|
}
|
|
436
|
+
map.invalidateSize();
|
|
449
437
|
} else {
|
|
450
438
|
console.warn("Undefined elevation map object");;
|
|
451
439
|
}
|
|
@@ -472,7 +460,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
472
460
|
let oldProto = L.Canvas.prototype._fillStroke;
|
|
473
461
|
let control = this;
|
|
474
462
|
|
|
475
|
-
let theme = this.options.theme.replace('-theme', '');
|
|
463
|
+
let theme = this.options.theme.split(' ')[0].replace('-theme', '');
|
|
476
464
|
let color = _.Colors[theme] || {};
|
|
477
465
|
|
|
478
466
|
L.Canvas.include({
|
|
@@ -593,10 +581,6 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
593
581
|
.on('margins_updated', this._resizeChart, this);
|
|
594
582
|
|
|
595
583
|
|
|
596
|
-
this.fire("elechart_axis");
|
|
597
|
-
|
|
598
|
-
if (this.options.legend) this.fire("elechart_legend");
|
|
599
|
-
|
|
600
584
|
this.fire("elechart_init");
|
|
601
585
|
|
|
602
586
|
map
|
|
@@ -661,23 +645,19 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
661
645
|
.disableScrollPropagation(container);
|
|
662
646
|
}
|
|
663
647
|
|
|
664
|
-
|
|
665
|
-
let link = this._button = _.create('a', "elevation-toggle elevation-toggle-icon" + (this.options.autohide ? "" : " close-button"), { href: '#', title: L._('Elevation') }, container);
|
|
666
|
-
|
|
667
|
-
if (this.options.collapsed) {
|
|
668
|
-
this._collapse();
|
|
669
|
-
if (this.options.autohide) {
|
|
670
|
-
_.on(container, 'mouseover', this._expand, this);
|
|
671
|
-
_.on(container, 'mouseout', this._collapse, this);
|
|
672
|
-
} else {
|
|
673
|
-
_.on(link, 'click', L.DomEvent.stop);
|
|
674
|
-
_.on(link, 'click', this._toggle, this);
|
|
675
|
-
}
|
|
648
|
+
this.options.collapsed ? this._collapse() : this._expand();
|
|
676
649
|
|
|
677
|
-
|
|
650
|
+
if (this.options.autohide) {
|
|
651
|
+
_.on(container, 'mouseover', this._expand, this);
|
|
652
|
+
_.on(container, 'mouseout', this._collapse, this);
|
|
653
|
+
this._map.on('click', this._collapse, this);
|
|
654
|
+
}
|
|
678
655
|
|
|
679
|
-
|
|
680
|
-
}
|
|
656
|
+
if (this.options.closeBtn) {
|
|
657
|
+
let link = this._button = _.create('a', "elevation-toggle-icon", { href: '#', title: L._('Elevation'), }, container);
|
|
658
|
+
_.on(link, 'click', L.DomEvent.stop);
|
|
659
|
+
_.on(link, 'click', this._toggle, this);
|
|
660
|
+
_.on(link, 'focus', this._toggle, this);
|
|
681
661
|
}
|
|
682
662
|
},
|
|
683
663
|
|
|
@@ -1205,7 +1185,6 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
1205
1185
|
_updateChart: function() {
|
|
1206
1186
|
if (this._chart && this._container) {
|
|
1207
1187
|
this.fire("elechart_axis");
|
|
1208
|
-
this.fire("elechart_area");
|
|
1209
1188
|
|
|
1210
1189
|
this._chart.update({ data: this._data, options: this.options });
|
|
1211
1190
|
|
|
@@ -1253,27 +1232,26 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
1253
1232
|
* Update chart summary.
|
|
1254
1233
|
*/
|
|
1255
1234
|
_updateSummary: function() {
|
|
1256
|
-
if (
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
this.
|
|
1235
|
+
if (this._summary) {
|
|
1236
|
+
this._summary.reset();
|
|
1237
|
+
if (this.options.summary) {
|
|
1238
|
+
this.fire("elechart_summary");
|
|
1239
|
+
this._summary.update();
|
|
1240
|
+
}
|
|
1241
|
+
if (this.options.downloadLink && this._downloadURL) { // TODO: generate dynamically file content instead of using static file urls.
|
|
1242
|
+
this._summary._container.innerHTML += '<span class="download"><a href="#">' + L._('Download') + '</a></span>'
|
|
1243
|
+
_.select('.download a', this._summary._container).onclick = (e) => {
|
|
1244
|
+
e.preventDefault();
|
|
1245
|
+
let event = { downloadLink: this.options.downloadLink, confirm: _.saveFile.bind(this, this._downloadURL) };
|
|
1246
|
+
if (this.options.downloadLink == 'modal' && typeof CustomEvent === "function") {
|
|
1247
|
+
document.dispatchEvent(new CustomEvent("eletrack_download", { detail: event }));
|
|
1248
|
+
} else if (this.options.downloadLink == 'link' || this.options.downloadLink === true) {
|
|
1249
|
+
event.confirm();
|
|
1250
|
+
}
|
|
1251
|
+
this.fire('eletrack_download', event);
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1263
1254
|
}
|
|
1264
|
-
if (this.options.downloadLink && this._downloadURL) { // TODO: generate dynamically file content instead of using static file urls.
|
|
1265
|
-
this._summary._container.innerHTML += '<span class="download"><a href="#">' + L._('Download') + '</a></span>'
|
|
1266
|
-
_.select('.download a', this._summary._container).onclick = ({preventDefault}) => {
|
|
1267
|
-
preventDefault();
|
|
1268
|
-
let event = { downloadLink: this.options.downloadLink, confirm: _.saveFile.bind(this, this._downloadURL) };
|
|
1269
|
-
if (this.options.downloadLink == 'modal' && typeof CustomEvent === "function") {
|
|
1270
|
-
document.dispatchEvent(new CustomEvent("eletrack_download", { detail: event }));
|
|
1271
|
-
} else if (this.options.downloadLink == 'link' || this.options.downloadLink === true) {
|
|
1272
|
-
event.confirm();
|
|
1273
|
-
}
|
|
1274
|
-
this.fire('eletrack_download', event);
|
|
1275
|
-
};
|
|
1276
|
-
};
|
|
1277
1255
|
},
|
|
1278
1256
|
|
|
1279
1257
|
|
package/src/handlers/altitude.js
CHANGED
|
@@ -5,7 +5,7 @@ export function Altitude() {
|
|
|
5
5
|
let opts = this.options;
|
|
6
6
|
let altitude = {};
|
|
7
7
|
|
|
8
|
-
let theme = opts.theme.replace('-theme', '');
|
|
8
|
+
let theme = opts.theme.split(' ')[0].replace('-theme', '');
|
|
9
9
|
let color = _.Colors[theme] || {};
|
|
10
10
|
|
|
11
11
|
opts.altitudeFactor = opts.imperial ? this.__footFactor : (opts.altitudeFactor || 1); // 1 m = (1 m)
|