@raruto/leaflet-elevation 2.1.1 → 2.2.2
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 +8 -8
- package/dist/leaflet-elevation.js +19 -25
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.js +1 -1
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/libs/leaflet-gpxgroup.js +340 -340
- package/package.json +4 -2
- package/src/components/chart.js +1 -1
- package/src/control.js +17 -23
- package/src/handlers/pace.js +65 -0
- package/src/options.js +2 -2
- package/spec/index.js +0 -2
- package/spec/index.min.js +0 -1
- package/spec/mock.js +0 -26
- package/spec/mock.min.js +0 -1
- package/spec/utils.test.js +0 -41
- package/spec/utils.test.min.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raruto/leaflet-elevation",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "A Leaflet plugin that allows to add elevation profiles using d3js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/leaflet-elevation.min.js",
|
|
@@ -23,9 +23,11 @@
|
|
|
23
23
|
"javascript",
|
|
24
24
|
"elevation",
|
|
25
25
|
"highchart",
|
|
26
|
+
"kml",
|
|
26
27
|
"altitude",
|
|
27
28
|
"gpx",
|
|
28
|
-
"gps-visualizer"
|
|
29
|
+
"gps-visualizer",
|
|
30
|
+
"tcx"
|
|
29
31
|
],
|
|
30
32
|
"author": {
|
|
31
33
|
"name": "Felix “MrMufflon” Bache",
|
package/src/components/chart.js
CHANGED
|
@@ -83,11 +83,11 @@ export var Chart = L.Control.Elevation.Chart = L.Class.extend({
|
|
|
83
83
|
this.options.yTicks = this._yTicks();
|
|
84
84
|
|
|
85
85
|
this._updateScale();
|
|
86
|
-
this._updateArea();
|
|
87
86
|
this._updateAxis();
|
|
88
87
|
this._updateMargins();
|
|
89
88
|
this._updateLegend();
|
|
90
89
|
this._updateClipper();
|
|
90
|
+
this._updateArea();
|
|
91
91
|
|
|
92
92
|
return this;
|
|
93
93
|
},
|
package/src/control.js
CHANGED
|
@@ -30,10 +30,14 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
30
30
|
addData: function(d, layer) {
|
|
31
31
|
this.import(this.__D3)
|
|
32
32
|
.then(() => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
if (this._modulesLoaded) {
|
|
34
|
+
layer = layer ?? (d.on && d);
|
|
35
|
+
this._addData(d);
|
|
36
|
+
this._addLayer(layer);
|
|
37
|
+
this._fireEvt("eledata_added", { data: d, layer: layer, track_info: this.track_info });
|
|
38
|
+
} else {
|
|
39
|
+
this.once('modules_loaded', () => this.addData(d,layer));
|
|
40
|
+
}
|
|
37
41
|
});
|
|
38
42
|
},
|
|
39
43
|
|
|
@@ -232,22 +236,14 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
232
236
|
|
|
233
237
|
if (!this.eleDiv) this.eleDiv = container;
|
|
234
238
|
|
|
235
|
-
|
|
236
|
-
"Distance",
|
|
237
|
-
"Time",
|
|
238
|
-
"Altitude",
|
|
239
|
-
"Slope",
|
|
240
|
-
"Speed",
|
|
241
|
-
"Acceleration",
|
|
242
|
-
...this.options.handlers
|
|
243
|
-
].filter(m => false !== this.options[typeof m == "string" && m.toLowerCase()]);
|
|
244
|
-
|
|
245
|
-
this._loadModules(modules).then(() => { // Inject here required modules (data handlers)
|
|
239
|
+
this._loadModules(this.options.handlers).then(() => { // Inject here required modules (data handlers)
|
|
246
240
|
this._initChart(container);
|
|
247
241
|
this._initButton(container);
|
|
248
242
|
this._initSummary(container);
|
|
249
243
|
this._initMarker(map);
|
|
250
244
|
this._initLayer(map);
|
|
245
|
+
this._modulesLoaded = true;
|
|
246
|
+
this.fire('modules_loaded');
|
|
251
247
|
});
|
|
252
248
|
|
|
253
249
|
this.fire('add');
|
|
@@ -316,7 +312,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
316
312
|
if (geom) {
|
|
317
313
|
switch (geom.type) {
|
|
318
314
|
case 'LineString': return this._addGeoJSONData(geom.coordinates, d.properties);
|
|
319
|
-
case 'MultiLineString':
|
|
315
|
+
case 'MultiLineString': return _.each(geom.coordinates, (coords, i) => this._addGeoJSONData(coords, d.properties, i));
|
|
320
316
|
case 'Point':
|
|
321
317
|
default: return console.warn('Unsopperted GeoJSON feature geometry type:' + geom.type);
|
|
322
318
|
}
|
|
@@ -730,14 +726,12 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
730
726
|
// First map known classnames (eg. "Altitude" --> L.Control.Elevation.Altitude)
|
|
731
727
|
handlers = handlers.map((h) => typeof h === 'string' && typeof Elevation[h] !== "undefined" ? Elevation[h] : h);
|
|
732
728
|
// Then load optional classes and custom imports (eg. "Cadence" --> import('../src/handlers/cadence.js'))
|
|
733
|
-
let modules = handlers
|
|
734
|
-
.filter(h => typeof h === 'string' || h instanceof Promise)
|
|
735
|
-
.map(file => file instanceof Promise ? file : this.import(this.__modulesFolder + file.toLowerCase() + '.js'));
|
|
729
|
+
let modules = handlers.map(file => (typeof file === 'string' && this.import(this.__modulesFolder + file.toLowerCase() + '.js')) || (file instanceof Promise && file) || Promise.resolve());
|
|
736
730
|
return Promise.all(modules).then((m) => {
|
|
737
|
-
_.each(m, (exported) => {
|
|
738
|
-
let fn = Object.keys(exported)[0];
|
|
731
|
+
_.each(m, (exported, i) => {
|
|
732
|
+
let fn = exported && Object.keys(exported)[0];
|
|
739
733
|
if (fn) {
|
|
740
|
-
handlers[
|
|
734
|
+
handlers[i] = Elevation[fn] = (Elevation[fn] ?? exported[fn]);
|
|
741
735
|
}
|
|
742
736
|
});
|
|
743
737
|
_.each(handlers, h => ["function", "object"].includes(typeof h) && this._registerHandler(h));
|
|
@@ -1031,7 +1025,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
1031
1025
|
if (props.stats) {
|
|
1032
1026
|
for (const key in props.stats) {
|
|
1033
1027
|
let sname = (props.statsName || attr) + (key != '' ? '_' : '');
|
|
1034
|
-
this.track_info[sname + key] = props.stats[key].call(this, curr[attr], this.track_info[sname + key],
|
|
1028
|
+
this.track_info[sname + key] = props.stats[key].call(this, curr[attr], this.track_info[sname + key], this._data.length);
|
|
1035
1029
|
}
|
|
1036
1030
|
}
|
|
1037
1031
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export function Pace() {
|
|
2
|
+
|
|
3
|
+
const _ = L.Control.Elevation.Utils;
|
|
4
|
+
|
|
5
|
+
let opts = this.options;
|
|
6
|
+
let pace = {};
|
|
7
|
+
|
|
8
|
+
pace.label = opts.paceLabel || L._(opts.imperial ? 'min/mi' : 'min/km');
|
|
9
|
+
opts.paceFactor = opts.paceFactor || 60; // 1 min = 60 sec
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
name: 'pace',
|
|
13
|
+
unit: pace.label,
|
|
14
|
+
deltaMax: this.options.paceDeltaMax,
|
|
15
|
+
clampRange: this.options.paceRange,
|
|
16
|
+
decimals: 2,
|
|
17
|
+
pointToAttr: (_, i) => {
|
|
18
|
+
let dx = (this._data[i].dist - this._data[i > 0 ? i - 1 : i].dist) * 1000;
|
|
19
|
+
let dt = this._data[i].time - this._data[ i > 0 ? i - 1 : i].time;
|
|
20
|
+
return dx > 0 ? Math.abs((dt / dx) / opts.paceFactor) : 0;
|
|
21
|
+
},
|
|
22
|
+
stats: { max: _.iMax, min: _.iMin, avg: _.iAvg },
|
|
23
|
+
scale : (this.options.pace && this.options.pace != "summary") && {
|
|
24
|
+
axis : "y",
|
|
25
|
+
position : "right",
|
|
26
|
+
scale : { min : 0, max : +1 },
|
|
27
|
+
tickPadding: 16,
|
|
28
|
+
labelX : 25,
|
|
29
|
+
labelY : -8,
|
|
30
|
+
},
|
|
31
|
+
path: (this.options.pace && this.options.pace != "summary") && {
|
|
32
|
+
// name : 'pace',
|
|
33
|
+
label : 'Pace',
|
|
34
|
+
yAttr : "pace",
|
|
35
|
+
scaleX : 'distance',
|
|
36
|
+
scaleY : 'pace',
|
|
37
|
+
color : '#03ffff',
|
|
38
|
+
strokeColor : '#000',
|
|
39
|
+
strokeOpacity: "0.5",
|
|
40
|
+
fillOpacity : "0.25",
|
|
41
|
+
},
|
|
42
|
+
tooltip: (this.options.pace) && {
|
|
43
|
+
chart: (item) => L._('pace: ') + item.pace + " " + pace.label,
|
|
44
|
+
marker: (item) => Math.round(item.pace) + " " + pace.label,
|
|
45
|
+
order: 50,
|
|
46
|
+
},
|
|
47
|
+
summary: (this.options.pace) && {
|
|
48
|
+
"minpace" : {
|
|
49
|
+
label: "Min Pace: ",
|
|
50
|
+
value: (track, unit) => Math.round(track.pace_min || 0) + ' ' + unit,
|
|
51
|
+
order: 51
|
|
52
|
+
},
|
|
53
|
+
"maxpace" : {
|
|
54
|
+
label: "Max Pace: ",
|
|
55
|
+
value: (track, unit) => Math.round(track.pace_max || 0) + ' ' + unit,
|
|
56
|
+
order: 51
|
|
57
|
+
},
|
|
58
|
+
"avgpace": {
|
|
59
|
+
label: "Avg Pace: ",
|
|
60
|
+
value: (track, unit) => Math.round(track.pace_avg || 0) + ' ' + unit,
|
|
61
|
+
order: 52
|
|
62
|
+
},
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
package/src/options.js
CHANGED
|
@@ -17,7 +17,7 @@ export var Options = {
|
|
|
17
17
|
followMarker: true,
|
|
18
18
|
imperial: false,
|
|
19
19
|
legend: true,
|
|
20
|
-
handlers: [],
|
|
20
|
+
handlers: ["Distance", "Time", "Altitude", "Slope", "Speed", "Acceleration"],
|
|
21
21
|
hotline: 'elevation',
|
|
22
22
|
marker: 'elevation-line',
|
|
23
23
|
markerIcon: L.divIcon({
|
|
@@ -46,7 +46,7 @@ export var Options = {
|
|
|
46
46
|
summary: 'inline',
|
|
47
47
|
slope: false,
|
|
48
48
|
speed: false,
|
|
49
|
-
time:
|
|
49
|
+
time: true,
|
|
50
50
|
timeFactor: 3600,
|
|
51
51
|
timestamps: false,
|
|
52
52
|
trkStart: L.circleMarker([0,0], { className: 'start-marker', radius: 6, weight: 2, color: '#fff', fillColor: '#00d800', fillOpacity: 1, interactive: false }),
|
package/spec/index.js
DELETED
package/spec/index.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./mock.js";import"./utils.test.js";
|
package/spec/mock.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { JSDOM } from 'jsdom';
|
|
2
|
-
|
|
3
|
-
const { window } = new JSDOM('<main></main>');
|
|
4
|
-
|
|
5
|
-
global.window = window;
|
|
6
|
-
global.document = window.document;
|
|
7
|
-
global.navigator = window.navigator;
|
|
8
|
-
global.getComputedStyle = window.getComputedStyle;
|
|
9
|
-
global.requestAnimationFrame = null;
|
|
10
|
-
|
|
11
|
-
global.L = {
|
|
12
|
-
DomEvent: {
|
|
13
|
-
on: () => {},
|
|
14
|
-
off: () => {}
|
|
15
|
-
},
|
|
16
|
-
Util: {
|
|
17
|
-
throttle: () => {},
|
|
18
|
-
wrapNum: () => {},
|
|
19
|
-
formatNum: () => {}
|
|
20
|
-
},
|
|
21
|
-
DomUtil: {
|
|
22
|
-
hasClass: () => {}
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
|
package/spec/mock.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{JSDOM}from"jsdom";const{window:window}=new JSDOM("<main></main>");global.window=window,global.document=window.document,global.navigator=window.navigator,global.getComputedStyle=window.getComputedStyle,global.requestAnimationFrame=null,global.L={DomEvent:{on:()=>{},off:()=>{}},Util:{throttle:()=>{},wrapNum:()=>{},formatNum:()=>{}},DomUtil:{hasClass:()=>{}}};
|
package/spec/utils.test.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { suite } from 'uvu';
|
|
2
|
-
import * as assert from 'uvu/assert';
|
|
3
|
-
import { iAvg, iMin, iMax, iSum } from "../src/utils.js";
|
|
4
|
-
|
|
5
|
-
const toFixed = (n) => +n.toFixed(2);
|
|
6
|
-
|
|
7
|
-
const test = suite('stats');
|
|
8
|
-
|
|
9
|
-
test('iAvg()', () => {
|
|
10
|
-
let avg;
|
|
11
|
-
avg = iAvg(100, undefined, 1); assert.is(toFixed(avg), 100); // average for [100] is 100
|
|
12
|
-
avg = iAvg(100, avg, 2); assert.is(toFixed(avg), 100); // average for [100, 100] is 100
|
|
13
|
-
avg = iAvg(200, avg, 3); assert.is(toFixed(avg), 133.33); // average for [100, 100, 200] is 133.33
|
|
14
|
-
avg = iAvg(200, avg, 4); assert.is(toFixed(avg), 150); // average for [100, 100, 200, 200] is 150
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
test('iMin()', () => {
|
|
18
|
-
let min;
|
|
19
|
-
min = iMin(100, undefined); assert.is(toFixed(min), 100); // min for [100] is 100
|
|
20
|
-
min = iMin(0, min); assert.is(toFixed(min), 0); // min for [100, 0] is 100
|
|
21
|
-
min = iMin(-200, min); assert.is(toFixed(min), -200); // min for [100, 0, -200] is -200
|
|
22
|
-
min = iMin(200, min); assert.is(toFixed(min), -200); // min for [100, -100, -200, 200] is -200
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test('iMax()', () => {
|
|
26
|
-
let max;
|
|
27
|
-
max = iMax(100, undefined); assert.is(toFixed(max), 100); // max for [100] is 100
|
|
28
|
-
max = iMax(0, max); assert.is(toFixed(max), 100); // max for [100, 0] is 100
|
|
29
|
-
max = iMax(-200, max); assert.is(toFixed(max), 100); // max for [100, 0, -200] is 100
|
|
30
|
-
max = iMax(200, max); assert.is(toFixed(max), 200); // max for [100, -100, -200, 200] is 200
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test('iSum()', () => {
|
|
34
|
-
let sum;
|
|
35
|
-
sum = iSum(10.25, undefined); assert.is(toFixed(sum), 10.25); // sum for [10.25] is 10.25
|
|
36
|
-
sum = iSum(0, sum); assert.is(toFixed(sum), 10.25); // sum for [10.25, 0] is 10.25
|
|
37
|
-
sum = iSum(-0.25, sum); assert.is(toFixed(sum), 10); // sum for [100, 0, -0.25] is 10
|
|
38
|
-
sum = iSum(-10, sum); assert.is(toFixed(sum), 0); // sum for [100, 0, -0.25, -10] is 0
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test.run();
|
package/spec/utils.test.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{suite}from"uvu";import*as assert from"uvu/assert";import{iAvg,iMin,iMax,iSum}from"../src/utils.js";const toFixed=n=>+n.toFixed(2),test=suite("stats");test("iAvg()",()=>{let avg;avg=iAvg(100,void 0,1),assert.is(toFixed(avg),100),avg=iAvg(100,avg,2),assert.is(toFixed(avg),100),avg=iAvg(200,avg,3),assert.is(toFixed(avg),133.33),avg=iAvg(200,avg,4),assert.is(toFixed(avg),150)}),test("iMin()",()=>{let min;min=iMin(100,void 0),assert.is(toFixed(min),100),min=iMin(0,min),assert.is(toFixed(min),0),min=iMin(-200,min),assert.is(toFixed(min),-200),min=iMin(200,min),assert.is(toFixed(min),-200)}),test("iMax()",()=>{let max;max=iMax(100,void 0),assert.is(toFixed(max),100),max=iMax(0,max),assert.is(toFixed(max),100),max=iMax(-200,max),assert.is(toFixed(max),100),max=iMax(200,max),assert.is(toFixed(max),200)}),test("iSum()",()=>{let sum;sum=iSum(10.25,void 0),assert.is(toFixed(sum),10.25),sum=iSum(0,sum),assert.is(toFixed(sum),10.25),sum=iSum(-.25,sum),assert.is(toFixed(sum),10),sum=iSum(-10,sum),assert.is(toFixed(sum),0)}),test.run();
|