@raruto/leaflet-elevation 2.0.8 → 2.2.0

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/src/control.js CHANGED
@@ -1,7 +1,11 @@
1
- import 'leaflet-i18n';
2
1
  import * as _ from './utils';
3
2
  import { Options } from './options';
4
3
 
4
+ // "leaflet-i18n" fallback
5
+ if (!L._ || !L.i18n) {
6
+ L._ = L.i18n = (string, data) => string;
7
+ }
8
+
5
9
  export const Elevation = L.Control.Elevation = L.Control.extend({
6
10
 
7
11
  includes: L.Evented ? L.Evented.prototype : L.Mixin.Events,
@@ -228,17 +232,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
228
232
 
229
233
  if (!this.eleDiv) this.eleDiv = container;
230
234
 
231
- let modules = [
232
- "Distance",
233
- "Time",
234
- "Altitude",
235
- "Slope",
236
- "Speed",
237
- "Acceleration",
238
- ...this.options.handlers
239
- ].filter(m => false !== this.options[typeof m == "string" && m.toLowerCase()]);
240
-
241
- this._loadModules(modules).then(() => { // Inject here required modules (data handlers)
235
+ this._loadModules(this.options.handlers).then(() => { // Inject here required modules (data handlers)
242
236
  this._initChart(container);
243
237
  this._initButton(container);
244
238
  this._initSummary(container);
@@ -578,14 +572,15 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
578
572
  * Generate "svg" chart (DOM element).
579
573
  */
580
574
  _initChart: function(container) {
581
- let opts = this.options;
575
+ let opts = this.options;
576
+ let map = this._map;
582
577
 
583
578
  if (opts.detached) {
584
579
  let { offsetWidth, offsetHeight} = this.eleDiv;
585
580
  if (offsetWidth > 0) opts.width = offsetWidth;
586
581
  if (offsetHeight > 20) opts.height = offsetHeight - 20; // 20 = horizontal scrollbar size.
587
582
  } else {
588
- let { clientWidth } = this._map.getContainer();
583
+ let { clientWidth } = map.getContainer();
589
584
  opts._maxWidth = opts._maxWidth > opts.width ? opts._maxWidth : opts.width;
590
585
  this._container.style.maxWidth = opts._maxWidth + 'px';
591
586
  if (opts._maxWidth > clientWidth) opts.width = clientWidth - 30;
@@ -725,22 +720,16 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
725
720
  // First map known classnames (eg. "Altitude" --> L.Control.Elevation.Altitude)
726
721
  handlers = handlers.map((h) => typeof h === 'string' && typeof Elevation[h] !== "undefined" ? Elevation[h] : h);
727
722
  // Then load optional classes and custom imports (eg. "Cadence" --> import('../src/handlers/cadence.js'))
728
- return Promise.
729
- all(
730
- handlers
731
- .filter(h => typeof h === 'string' || h instanceof Promise)
732
- .map(file => file instanceof Promise ? file : this.import(this.__modulesFolder + file.toLowerCase() + '.js'))
733
- )
734
- .then((m) => {
735
- _.each(m, (exported) => {
736
- let fn = Object.keys(exported)[0];
737
- if (fn && typeof Elevation[fn] === "undefined" ) {
738
- handlers[fn] = Elevation[fn] = exported[fn];
739
-
740
- }
741
- });
742
- _.each(handlers, h => this._registerHandler(h));
723
+ let modules = handlers.map(file => (typeof file === 'string' && this.import(this.__modulesFolder + file.toLowerCase() + '.js')) || (file instanceof Promise && file) || Promise.resolve());
724
+ return Promise.all(modules).then((m) => {
725
+ _.each(m, (exported, i) => {
726
+ let fn = exported && Object.keys(exported)[0];
727
+ if (fn) {
728
+ handlers[i] = Elevation[fn] = (Elevation[fn] ?? exported[fn]);
729
+ }
743
730
  });
731
+ _.each(handlers, h => ["function", "object"].includes(typeof h) && this._registerHandler(h));
732
+ });
744
733
  },
745
734
 
746
735
  /**
@@ -1030,7 +1019,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
1030
1019
  if (props.stats) {
1031
1020
  for (const key in props.stats) {
1032
1021
  let sname = (props.statsName || attr) + (key != '' ? '_' : '');
1033
- this.track_info[sname + key] = props.stats[key].call(this, curr[attr], this.track_info[sname + key]);
1022
+ this.track_info[sname + key] = props.stats[key].call(this, curr[attr], this.track_info[sname + key], index);
1034
1023
  }
1035
1024
  }
1036
1025
 
@@ -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) + '&nbsp;' + unit,
39
- // order: 30
40
- },
41
- "maxbpm": {
42
- label: "Max BPM: ",
43
- value: (track, unit) => Math.round(track.heart_min || 0) + '&nbsp;' + unit,
44
- // order: 30
45
- },
46
- "avgbpm": {
47
- label: "Avg BPM: ",
48
- value: (track, unit) => Math.round(track.heart_avg || 0) + '&nbsp;' + 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) + '&nbsp;' + unit,
39
+ // order: 30
40
+ },
41
+ "maxbpm": {
42
+ label: "Max BPM: ",
43
+ value: (track, unit) => Math.round(track.heart_max || 0) + '&nbsp;' + unit,
44
+ // order: 30
45
+ },
46
+ "avgbpm": {
47
+ label: "Avg BPM: ",
48
+ value: (track, unit) => Math.round(track.heart_avg || 0) + '&nbsp;' + 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) + '&nbsp;' + unit,
51
+ order: 51
52
+ },
53
+ "maxpace" : {
54
+ label: "Max Pace: ",
55
+ value: (track, unit) => Math.round(track.pace_max || 0) + '&nbsp;' + unit,
56
+ order: 51
57
+ },
58
+ "avgpace": {
59
+ label: "Avg Pace: ",
60
+ value: (track, unit) => Math.round(track.pace_avg || 0) + '&nbsp;' + unit,
61
+ order: 52
62
+ },
63
+ }
64
+ };
65
+ }
package/src/index.js CHANGED
@@ -34,21 +34,9 @@
34
34
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
35
35
  */
36
36
 
37
- import 'leaflet-i18n';
38
37
  import * as _ from './utils';
39
38
  import { Elevation } from './control';
40
39
 
41
40
  Elevation.Utils = _;
42
41
 
43
- /* Temporary fix for empty values evaluated as false (leaflet-i18n v0.3.1) */
44
- (function(){
45
- let proto = L.i18n.bind({});
46
- L.i18n = L._ = (string, data) => {
47
- if (L.locale && L.locales[L.locale] && L.locales[L.locale][string] == "") {
48
- L.locales[L.locale][string] = "\u200B";
49
- }
50
- return proto.call(null, string, data);
51
- };
52
- })();
53
-
54
42
  L.control.elevation = (options) => new Elevation(options);
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: false,
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 || parseInt).call(this, (isMulti ? props[key][isMulti] : props[key]), id);
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 parseInt = (property, id) => window.parseInt((typeof property === 'object' ? property[id] : property));
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) || -Infinity;
135
- export const iMin = (iVal, min) => (iVal < min ? iVal : min) || +Infinity;
136
- export const iAvg = (iVal, avg) => (iVal + (avg || 0)) / 2.0;
137
- export const iSum = (iVal, sum) => iVal + (sum || 0);
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