@raruto/leaflet-elevation 2.1.0 → 2.2.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 +29 -8
- package/dist/leaflet-elevation.js +23 -38
- 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 +11 -4
- package/src/components/chart.js +1 -1
- package/src/components/d3.js +1 -1
- package/src/control.js +14 -29
- package/src/handlers/heart.js +52 -52
- package/src/handlers/pace.js +65 -0
- package/src/options.js +2 -2
- package/src/utils.js +6 -6
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
|
};
|
|
@@ -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/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
|