@raruto/leaflet-elevation 2.1.0 → 2.1.1
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 +22 -1
- package/dist/leaflet-elevation.js +22 -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/package.json +8 -3
- package/spec/index.js +2 -0
- package/spec/index.min.js +1 -0
- package/spec/mock.js +26 -0
- package/spec/mock.min.js +1 -0
- package/spec/utils.test.js +41 -0
- package/spec/utils.test.min.js +1 -0
- package/src/components/d3.js +1 -1
- package/src/control.js +15 -18
- package/src/handlers/heart.js +52 -52
- package/src/utils.js +6 -6
package/src/control.js
CHANGED
|
@@ -582,14 +582,15 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
582
582
|
* Generate "svg" chart (DOM element).
|
|
583
583
|
*/
|
|
584
584
|
_initChart: function(container) {
|
|
585
|
-
let opts
|
|
585
|
+
let opts = this.options;
|
|
586
|
+
let map = this._map;
|
|
586
587
|
|
|
587
588
|
if (opts.detached) {
|
|
588
589
|
let { offsetWidth, offsetHeight} = this.eleDiv;
|
|
589
590
|
if (offsetWidth > 0) opts.width = offsetWidth;
|
|
590
591
|
if (offsetHeight > 20) opts.height = offsetHeight - 20; // 20 = horizontal scrollbar size.
|
|
591
592
|
} else {
|
|
592
|
-
let { clientWidth } =
|
|
593
|
+
let { clientWidth } = map.getContainer();
|
|
593
594
|
opts._maxWidth = opts._maxWidth > opts.width ? opts._maxWidth : opts.width;
|
|
594
595
|
this._container.style.maxWidth = opts._maxWidth + 'px';
|
|
595
596
|
if (opts._maxWidth > clientWidth) opts.width = clientWidth - 30;
|
|
@@ -729,22 +730,18 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
729
730
|
// First map known classnames (eg. "Altitude" --> L.Control.Elevation.Altitude)
|
|
730
731
|
handlers = handlers.map((h) => typeof h === 'string' && typeof Elevation[h] !== "undefined" ? Elevation[h] : h);
|
|
731
732
|
// Then load optional classes and custom imports (eg. "Cadence" --> import('../src/handlers/cadence.js'))
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
if (fn && typeof Elevation[fn] === "undefined" ) {
|
|
742
|
-
handlers[fn] = Elevation[fn] = exported[fn];
|
|
743
|
-
|
|
744
|
-
}
|
|
745
|
-
});
|
|
746
|
-
_.each(handlers, h => this._registerHandler(h));
|
|
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'));
|
|
736
|
+
return Promise.all(modules).then((m) => {
|
|
737
|
+
_.each(m, (exported) => {
|
|
738
|
+
let fn = Object.keys(exported)[0];
|
|
739
|
+
if (fn) {
|
|
740
|
+
handlers[fn] = Elevation[fn] = (Elevation[fn] ?? exported[fn]);
|
|
741
|
+
}
|
|
747
742
|
});
|
|
743
|
+
_.each(handlers, h => ["function", "object"].includes(typeof h) && this._registerHandler(h));
|
|
744
|
+
});
|
|
748
745
|
},
|
|
749
746
|
|
|
750
747
|
/**
|
|
@@ -1034,7 +1031,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
1034
1031
|
if (props.stats) {
|
|
1035
1032
|
for (const key in props.stats) {
|
|
1036
1033
|
let sname = (props.statsName || attr) + (key != '' ? '_' : '');
|
|
1037
|
-
this.track_info[sname + key] = props.stats[key].call(this, curr[attr], this.track_info[sname + key]);
|
|
1034
|
+
this.track_info[sname + key] = props.stats[key].call(this, curr[attr], this.track_info[sname + key], index);
|
|
1038
1035
|
}
|
|
1039
1036
|
}
|
|
1040
1037
|
|
package/src/handlers/heart.js
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
export function Heart() {
|
|
2
|
-
|
|
3
|
-
const _ = L.Control.Elevation.Utils;
|
|
4
|
-
|
|
5
|
-
return {
|
|
6
|
-
name: 'heart', // <-- Your custom option name (eg. "heart: true")
|
|
7
|
-
unit: 'bpm',
|
|
8
|
-
meta: 'hr', // <-- point.meta.hr
|
|
9
|
-
coordinateProperties: ["heart", "heartRates", "heartRate"], // List of GPX Extensions ("coordinateProperties") to be handled by "@tmcw/toGeoJSON"
|
|
10
|
-
pointToAttr: (point, i) => (point.hr ?? point.meta.hr ?? point.prev('heart')) || 0,
|
|
11
|
-
stats: { max: _.iMax, min: _.iMin, avg: _.iAvg },
|
|
12
|
-
scale: {
|
|
13
|
-
axis : "y",
|
|
14
|
-
position : "left",
|
|
15
|
-
scale : { min: -1, max: +1 },
|
|
16
|
-
tickPadding: 25,
|
|
17
|
-
labelX : -30,
|
|
18
|
-
labelY : -8,
|
|
19
|
-
},
|
|
20
|
-
path: {
|
|
21
|
-
label : 'ECG',
|
|
22
|
-
yAttr : 'heart',
|
|
23
|
-
scaleX : 'distance',
|
|
24
|
-
scaleY : 'heart',
|
|
25
|
-
color : 'white',
|
|
26
|
-
strokeColor : 'red',
|
|
27
|
-
strokeOpacity: "0.85",
|
|
28
|
-
fillOpacity : "0.1",
|
|
29
|
-
},
|
|
30
|
-
tooltip: {
|
|
31
|
-
chart: (item) => L._("hr: ") + item.heart + " " + 'bpm',
|
|
32
|
-
marker: (item) => Math.round(item.heart) + " " + 'bpm',
|
|
33
|
-
order: 1
|
|
34
|
-
},
|
|
35
|
-
summary: {
|
|
36
|
-
"minbpm": {
|
|
37
|
-
label: "Min BPM: ",
|
|
38
|
-
value: (track, unit) => Math.round(track.heart_min || 0) + ' ' + unit,
|
|
39
|
-
// order: 30
|
|
40
|
-
},
|
|
41
|
-
"maxbpm": {
|
|
42
|
-
label: "Max BPM: ",
|
|
43
|
-
value: (track, unit) => Math.round(track.
|
|
44
|
-
// order: 30
|
|
45
|
-
},
|
|
46
|
-
"avgbpm": {
|
|
47
|
-
label: "Avg BPM: ",
|
|
48
|
-
value: (track, unit) => Math.round(track.heart_avg || 0) + ' ' + unit,
|
|
49
|
-
// order: 20
|
|
50
|
-
},
|
|
51
|
-
}
|
|
52
|
-
};
|
|
1
|
+
export function Heart() {
|
|
2
|
+
|
|
3
|
+
const _ = L.Control.Elevation.Utils;
|
|
4
|
+
|
|
5
|
+
return {
|
|
6
|
+
name: 'heart', // <-- Your custom option name (eg. "heart: true")
|
|
7
|
+
unit: 'bpm',
|
|
8
|
+
meta: 'hr', // <-- point.meta.hr
|
|
9
|
+
coordinateProperties: ["heart", "heartRates", "heartRate"], // List of GPX Extensions ("coordinateProperties") to be handled by "@tmcw/toGeoJSON"
|
|
10
|
+
pointToAttr: (point, i) => (point.hr ?? point.meta.hr ?? point.prev('heart')) || 0,
|
|
11
|
+
stats: { max: _.iMax, min: _.iMin, avg: _.iAvg },
|
|
12
|
+
scale: {
|
|
13
|
+
axis : "y",
|
|
14
|
+
position : "left",
|
|
15
|
+
scale : { min: -1, max: +1 },
|
|
16
|
+
tickPadding: 25,
|
|
17
|
+
labelX : -30,
|
|
18
|
+
labelY : -8,
|
|
19
|
+
},
|
|
20
|
+
path: {
|
|
21
|
+
label : 'ECG',
|
|
22
|
+
yAttr : 'heart',
|
|
23
|
+
scaleX : 'distance',
|
|
24
|
+
scaleY : 'heart',
|
|
25
|
+
color : 'white',
|
|
26
|
+
strokeColor : 'red',
|
|
27
|
+
strokeOpacity: "0.85",
|
|
28
|
+
fillOpacity : "0.1",
|
|
29
|
+
},
|
|
30
|
+
tooltip: {
|
|
31
|
+
chart: (item) => L._("hr: ") + item.heart + " " + 'bpm',
|
|
32
|
+
marker: (item) => Math.round(item.heart) + " " + 'bpm',
|
|
33
|
+
order: 1
|
|
34
|
+
},
|
|
35
|
+
summary: {
|
|
36
|
+
"minbpm": {
|
|
37
|
+
label: "Min BPM: ",
|
|
38
|
+
value: (track, unit) => Math.round(track.heart_min || 0) + ' ' + unit,
|
|
39
|
+
// order: 30
|
|
40
|
+
},
|
|
41
|
+
"maxbpm": {
|
|
42
|
+
label: "Max BPM: ",
|
|
43
|
+
value: (track, unit) => Math.round(track.heart_max || 0) + ' ' + unit,
|
|
44
|
+
// order: 30
|
|
45
|
+
},
|
|
46
|
+
"avgbpm": {
|
|
47
|
+
label: "Avg BPM: ",
|
|
48
|
+
value: (track, unit) => Math.round(track.heart_avg || 0) + ' ' + unit,
|
|
49
|
+
// order: 20
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
53
|
};
|
package/src/utils.js
CHANGED
|
@@ -92,7 +92,7 @@ export function coordPropsToMeta(coordProps, name, parser) {
|
|
|
92
92
|
if (props) {
|
|
93
93
|
for (const key of coordProps) {
|
|
94
94
|
if (key in props) {
|
|
95
|
-
point.meta[name] = (parser ||
|
|
95
|
+
point.meta[name] = (parser || parseNumeric).call(this, (isMulti ? props[key][isMulti] : props[key]), id);
|
|
96
96
|
break;
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -103,7 +103,7 @@ export function coordPropsToMeta(coordProps, name, parser) {
|
|
|
103
103
|
/**
|
|
104
104
|
* Extract numeric property (id) from GeoJSON object
|
|
105
105
|
*/
|
|
106
|
-
export const
|
|
106
|
+
export const parseNumeric = (property, id) => parseInt((typeof property === 'object' ? property[id] : property));
|
|
107
107
|
|
|
108
108
|
/**
|
|
109
109
|
* Extract datetime property (id) from GeoJSON object
|
|
@@ -131,10 +131,10 @@ export const randomId = () => Math.random().toString(36).
|
|
|
131
131
|
/**
|
|
132
132
|
* TODO: use generators instead? (ie. "yield")
|
|
133
133
|
*/
|
|
134
|
-
export const iMax = (iVal, max) => (iVal > max ? iVal : max)
|
|
135
|
-
export const iMin = (iVal, min) => (iVal < min ? iVal : min)
|
|
136
|
-
export const iAvg = (iVal, avg) => (iVal +
|
|
137
|
-
export const iSum = (iVal, sum) => iVal +
|
|
134
|
+
export const iMax = (iVal, max = -Infinity) => (iVal > max ? iVal : max);
|
|
135
|
+
export const iMin = (iVal, min = +Infinity) => (iVal < min ? iVal : min);
|
|
136
|
+
export const iAvg = (iVal, avg = 0, idx = 1) => (iVal + avg * (idx - 1)) / idx;
|
|
137
|
+
export const iSum = (iVal, sum = 0) => iVal + sum;
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
140
|
* Alias for some leaflet core functions
|