@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raruto/leaflet-elevation",
3
- "version": "2.1.1",
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",
@@ -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
- layer = layer ?? (d.on && d);
34
- this._addData(d);
35
- this._addLayer(layer);
36
- this._fireEvt("eledata_added", { data: d, layer: layer, track_info: this.track_info });
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
- let modules = [
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': return _.each(geom.coordinates, (coords, i) => this._addGeoJSONData(coords, d.properties, i));
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[fn] = Elevation[fn] = (Elevation[fn] ?? exported[fn]);
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], index);
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: 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/spec/index.js DELETED
@@ -1,2 +0,0 @@
1
- import './mock.js';
2
- import './utils.test.js';
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:()=>{}}};
@@ -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();
@@ -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();