@raruto/leaflet-elevation 1.9.4 → 1.9.5
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 +4 -4
- package/dist/leaflet-elevation.js +558 -407
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.js +2 -2
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/libs/leaflet-distance-marker.js +17 -18
- package/libs/leaflet-distance-marker.min.js +1 -1
- package/libs/leaflet-ruler.css +42 -0
- package/libs/leaflet-ruler.js +183 -0
- package/libs/leaflet-ruler.min.css +1 -0
- package/libs/leaflet-ruler.min.js +1 -0
- package/package.json +1 -1
- package/src/acceleration.js +56 -51
- package/src/altitude.js +78 -79
- package/src/chart.js +10 -0
- package/src/components.js +18 -11
- package/src/control.js +107 -44
- package/src/distance.js +31 -40
- package/src/index.js +1 -1
- package/src/options.js +5 -5
- package/src/slope.js +87 -71
- package/src/speed.js +57 -49
- package/src/summary.js +12 -1
- package/src/time.js +43 -42
package/src/altitude.js
CHANGED
|
@@ -5,8 +5,11 @@ import { Elevation } from './control';
|
|
|
5
5
|
|
|
6
6
|
Elevation.addInitHook(function() {
|
|
7
7
|
|
|
8
|
-
let opts
|
|
9
|
-
let altitude
|
|
8
|
+
let opts = this.options;
|
|
9
|
+
let altitude = {};
|
|
10
|
+
|
|
11
|
+
let theme = opts.theme.replace('-theme', '');
|
|
12
|
+
let color = D3.Colors[theme] || {};
|
|
10
13
|
|
|
11
14
|
if (opts.imperial) {
|
|
12
15
|
opts.altitudeFactor = this.__footFactor;
|
|
@@ -16,105 +19,101 @@ Elevation.addInitHook(function() {
|
|
|
16
19
|
altitude.label = opts.yLabel;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
this.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
22
|
+
this._registerDataAttribute({
|
|
23
|
+
name: 'z',
|
|
24
|
+
skipNull: this.options.skipNullZCoords,
|
|
25
|
+
init: ({point, }) => {
|
|
26
|
+
// "alt" property is generated inside "leaflet"
|
|
27
|
+
if ("alt" in point) point.meta.ele = point.alt;
|
|
28
|
+
|
|
29
|
+
// this.track_info.elevation_max = -Infinity;
|
|
30
|
+
// this.track_info.elevation_min = +Infinity;
|
|
31
|
+
// this.track_info.elevation_avg = 0;
|
|
32
|
+
},
|
|
33
|
+
fetch: (i) => {
|
|
34
|
+
return this._data[i].z * opts.altitudeFactor;
|
|
35
|
+
},
|
|
36
|
+
update: (z, i) => {
|
|
37
|
+
this.track_info.elevation_max = this.track_info.elevation_max || -Infinity;
|
|
38
|
+
this.track_info.elevation_min = this.track_info.elevation_max || +Infinity;
|
|
39
|
+
this.track_info.elevation_avg = this.track_info.elevation_avg || 0;
|
|
40
|
+
|
|
41
|
+
let data = this._data;
|
|
42
|
+
let track = this.track_info;
|
|
43
|
+
|
|
44
|
+
// Try to smooth "crazy" elevation values.
|
|
45
|
+
if (this.options.altitudeDeltaMax) {
|
|
46
|
+
let delta = z - data[i > 0 ? i - 1 : i].z;
|
|
47
|
+
let deltaMax = this.options.altitudeDeltaMax;
|
|
48
|
+
if (Math.abs(delta) > deltaMax) {
|
|
49
|
+
z = data[i - 1].z + deltaMax * Math.sign(delta);
|
|
40
50
|
}
|
|
41
|
-
if (!isNaN(prevZ)) return data.splice(i - 1, 1);
|
|
42
|
-
data[i - 1].z = prevZ;
|
|
43
51
|
}
|
|
44
|
-
}
|
|
45
|
-
// skip point if it has not elevation
|
|
46
|
-
if (!isNaN(z)) {
|
|
47
|
-
this._lastValidZ = z;
|
|
48
|
-
}
|
|
49
52
|
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
// Range of acceptable elevation values.
|
|
54
|
+
z = _.clamp(z, this.options.altitudeRange);
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
this.on("elechart_axis", function() {
|
|
56
|
+
if (z > track.elevation_max) track.elevation_max = z;
|
|
57
|
+
if (z < track.elevation_min) track.elevation_min = z;
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
axis : "y",
|
|
60
|
-
position : "left",
|
|
61
|
-
scale : this._chart._y,
|
|
62
|
-
});
|
|
59
|
+
track.elevation_avg = (z + track.elevation_avg) / 2.0;
|
|
63
60
|
|
|
61
|
+
return z;
|
|
62
|
+
}
|
|
64
63
|
});
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
labelY : -8,
|
|
77
|
-
name : "altitude",
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
this.on("elechart_init", function() {
|
|
83
|
-
|
|
84
|
-
let theme = this.options.theme.replace('-theme', '');
|
|
85
|
-
let color = D3.Colors[theme] || {};
|
|
86
|
-
|
|
87
|
-
this._chart._registerAreaPath({
|
|
88
|
-
name : 'altitude',
|
|
89
|
-
label : 'Altitude',
|
|
90
|
-
scaleX : 'distance',
|
|
91
|
-
scaleY : 'altitude',
|
|
92
|
-
color : color.area || theme,
|
|
93
|
-
strokeColor : this.options.detached ? color.stroke : '#000',
|
|
94
|
-
strokeOpacity: "1",
|
|
95
|
-
fillOpacity : this.options.detached ? (color.alpha || '0.8') : 1,
|
|
96
|
-
preferCanvas : this.options.preferCanvas,
|
|
97
|
-
});
|
|
65
|
+
this._registerAxisScale({
|
|
66
|
+
axis : "y",
|
|
67
|
+
position: "left",
|
|
68
|
+
scale : "y", // this._chart._y,
|
|
69
|
+
label : altitude.label,
|
|
70
|
+
labelX : -3,
|
|
71
|
+
labelY : -8,
|
|
72
|
+
name : "altitude",
|
|
73
|
+
visbile : this.options.altitude != "summary"
|
|
74
|
+
});
|
|
98
75
|
|
|
99
|
-
|
|
76
|
+
this._registerAxisGrid({
|
|
77
|
+
axis : "y",
|
|
78
|
+
position : "left",
|
|
79
|
+
scale : "y" // this._chart._y,
|
|
80
|
+
});
|
|
100
81
|
|
|
101
|
-
|
|
82
|
+
this._registerAreaPath({
|
|
83
|
+
name : 'altitude',
|
|
84
|
+
label : 'Altitude',
|
|
85
|
+
scaleX : 'distance',
|
|
86
|
+
scaleY : 'altitude',
|
|
87
|
+
color : color.area || theme,
|
|
88
|
+
strokeColor : opts.detached ? color.stroke : '#000',
|
|
89
|
+
strokeOpacity: "1",
|
|
90
|
+
fillOpacity : opts.detached ? (color.alpha || '0.8') : 1,
|
|
91
|
+
preferCanvas : opts.preferCanvas,
|
|
92
|
+
visbile : this.options.altitude != "summary"
|
|
93
|
+
});
|
|
102
94
|
|
|
103
95
|
this._registerTooltip({
|
|
104
96
|
name: 'y',
|
|
105
97
|
chart: (item) => L._("y: ") + d3.format("." + opts.decimalsY + "f")(item[opts.yAttr]) + " " + altitude.label,
|
|
106
98
|
marker: (item) => d3.format("." + opts.decimalsY + "f")(item[opts.yAttr]) + " " + altitude.label,
|
|
99
|
+
order: 10,
|
|
107
100
|
});
|
|
108
101
|
|
|
109
102
|
this._registerSummary({
|
|
110
103
|
"maxele" : {
|
|
111
104
|
label: "Max Elevation: ",
|
|
112
|
-
value: (track) => (track.elevation_max || 0).toFixed(2) + ' ' + altitude.label
|
|
105
|
+
value: (track) => (track.elevation_max || 0).toFixed(2) + ' ' + altitude.label,
|
|
106
|
+
order: 30,
|
|
113
107
|
},
|
|
114
108
|
"minele" : {
|
|
115
109
|
label: "Min Elevation: ",
|
|
116
|
-
value: (track) => (track.elevation_min || 0).toFixed(2) + ' ' + altitude.label
|
|
110
|
+
value: (track) => (track.elevation_min || 0).toFixed(2) + ' ' + altitude.label,
|
|
111
|
+
order: 30,
|
|
112
|
+
},
|
|
113
|
+
"avgele" : {
|
|
114
|
+
label: "Avg Elevation: ",
|
|
115
|
+
value: (track) => (track.elevation_avg || 0).toFixed(2) + ' ' + altitude.label,
|
|
116
|
+
order: 30,
|
|
117
117
|
},
|
|
118
118
|
});
|
|
119
|
-
|
|
120
|
-
});
|
|
119
|
+
});
|
package/src/chart.js
CHANGED
|
@@ -344,6 +344,9 @@ export var Chart = L.Class.extend({
|
|
|
344
344
|
},
|
|
345
345
|
|
|
346
346
|
_registerAreaPath: function(props) {
|
|
347
|
+
if (props.scale == 'y') props.scale = this._y;
|
|
348
|
+
else if (props.scale == 'x') props.scale = this._x;
|
|
349
|
+
|
|
347
350
|
let opts = this.options;
|
|
348
351
|
|
|
349
352
|
if (!props.xAttr) props.xAttr = opts.xAttr;
|
|
@@ -368,10 +371,16 @@ export var Chart = L.Class.extend({
|
|
|
368
371
|
},
|
|
369
372
|
|
|
370
373
|
_registerAxisGrid: function(props) {
|
|
374
|
+
if (props.scale == 'y') props.scale = this._y;
|
|
375
|
+
else if(props.scale == 'x') props.scale = this._x;
|
|
376
|
+
|
|
371
377
|
this._props.grids[props.name || props.axis] = props;
|
|
372
378
|
},
|
|
373
379
|
|
|
374
380
|
_registerAxisScale: function(props) {
|
|
381
|
+
if (props.scale == 'y') props.scale = this._y;
|
|
382
|
+
else if(props.scale == 'x') props.scale = this._x;
|
|
383
|
+
|
|
375
384
|
let opts = this.options;
|
|
376
385
|
let scale = props.scale;
|
|
377
386
|
|
|
@@ -433,6 +442,7 @@ export var Chart = L.Class.extend({
|
|
|
433
442
|
},
|
|
434
443
|
|
|
435
444
|
_registerTooltip: function(props) {
|
|
445
|
+
props.order = props.order ?? 100;
|
|
436
446
|
this._props.tooltipItems[props.name] = props;
|
|
437
447
|
},
|
|
438
448
|
|
package/src/components.js
CHANGED
|
@@ -150,7 +150,10 @@ export const PositionMarker = ({
|
|
|
150
150
|
|
|
151
151
|
let label;
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
Object
|
|
154
|
+
.keys(labels)
|
|
155
|
+
.sort((a, b) => labels[a].order - labels[b].order) // TODO: any performance issues?
|
|
156
|
+
.forEach((i)=> {
|
|
154
157
|
label = text.select(".height-focus-" + labels[i].name);
|
|
155
158
|
|
|
156
159
|
if (!label.size()) {
|
|
@@ -160,7 +163,8 @@ export const PositionMarker = ({
|
|
|
160
163
|
}
|
|
161
164
|
|
|
162
165
|
label.text(typeof labels[i].value !== "function" ? labels[i].value : labels[i].value(item));
|
|
163
|
-
|
|
166
|
+
|
|
167
|
+
});
|
|
164
168
|
|
|
165
169
|
text.select('tspan').attr("dy", text.selectAll('tspan').size() > 1 ? "-1.5em" : "0em" );
|
|
166
170
|
text.selectAll('tspan').attr("x", xCoord + 5);
|
|
@@ -274,17 +278,20 @@ export const Tooltip = ({
|
|
|
274
278
|
|
|
275
279
|
let label;
|
|
276
280
|
|
|
277
|
-
|
|
278
|
-
|
|
281
|
+
Object
|
|
282
|
+
.keys(labels)
|
|
283
|
+
.sort((a, b) => labels[a].order - labels[b].order) // TODO: any performance issues?
|
|
284
|
+
.forEach((i)=> {
|
|
285
|
+
label = text.select(".mouse-focus-label-" + labels[i].name);
|
|
279
286
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
287
|
+
if (!label.size()) {
|
|
288
|
+
label = text.append("svg:tspan", ".mouse-focus-label-x")
|
|
289
|
+
.attr("class", "mouse-focus-label-" + labels[i].name)
|
|
290
|
+
.attr("dy", "1.5em");
|
|
291
|
+
}
|
|
285
292
|
|
|
286
|
-
|
|
287
|
-
|
|
293
|
+
label.text(typeof labels[i].value !== "function" ? labels[i].value : labels[i].value(item));
|
|
294
|
+
});
|
|
288
295
|
|
|
289
296
|
text.select('tspan').attr("dy", "1em");
|
|
290
297
|
text.selectAll('tspan').attr("x", xAlign);
|
package/src/control.js
CHANGED
|
@@ -17,7 +17,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
17
17
|
__TOGEOJSON: 'https://unpkg.com/@tmcw/togeojson@4.5.0/dist/togeojson.umd.js',
|
|
18
18
|
__LGEOMUTIL: 'https://unpkg.com/leaflet-geometryutil@0.9.3/src/leaflet.geometryutil.js',
|
|
19
19
|
__LALMOSTOVER: 'https://unpkg.com/leaflet-almostover@1.0.1/src/leaflet.almostover.js',
|
|
20
|
-
__LDISTANCEM: 'https://unpkg.com/@raruto/leaflet-elevation@1.9.
|
|
20
|
+
__LDISTANCEM: 'https://unpkg.com/@raruto/leaflet-elevation@1.9.5/libs/leaflet-distance-marker.min.js',
|
|
21
21
|
|
|
22
22
|
/*
|
|
23
23
|
* Add data to the diagram either from GPX or GeoJSON and update the axis domain and data
|
|
@@ -89,6 +89,22 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
89
89
|
}
|
|
90
90
|
},
|
|
91
91
|
|
|
92
|
+
/**
|
|
93
|
+
* TODO: Create a base class to handle custom data attributes (heart rate, cadence, temperature, ...)
|
|
94
|
+
*
|
|
95
|
+
* @link https://leafletjs.com/examples/extending/extending-3-controls.html#handlers
|
|
96
|
+
*/
|
|
97
|
+
// addHandler: function (name, HandlerClass) {
|
|
98
|
+
// if (HandlerClass) {
|
|
99
|
+
// let handler = this[name] = new HandlerClass(this);
|
|
100
|
+
// this.handlers.push(handler);
|
|
101
|
+
// if (this.options[name]) {
|
|
102
|
+
// handler.enable();
|
|
103
|
+
// }
|
|
104
|
+
// }
|
|
105
|
+
// return this;
|
|
106
|
+
// },
|
|
107
|
+
|
|
92
108
|
/**
|
|
93
109
|
* Disable chart brushing.
|
|
94
110
|
*/
|
|
@@ -133,7 +149,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
133
149
|
},
|
|
134
150
|
|
|
135
151
|
/**
|
|
136
|
-
* Get default zoom level
|
|
152
|
+
* Get default zoom level (followMarker: true).
|
|
137
153
|
*/
|
|
138
154
|
getZFollow: function() {
|
|
139
155
|
return this.options.zFollow;
|
|
@@ -156,6 +172,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
156
172
|
this._markedSegments = L.polyline([]);
|
|
157
173
|
this._chartEnabled = true,
|
|
158
174
|
this.track_info = {};
|
|
175
|
+
this.handlers = [];
|
|
159
176
|
|
|
160
177
|
L.setOptions(this, options);
|
|
161
178
|
|
|
@@ -208,7 +225,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
208
225
|
},
|
|
209
226
|
|
|
210
227
|
/**
|
|
211
|
-
* Load elevation data (GPX, GeoJSON or
|
|
228
|
+
* Load elevation data (GPX, GeoJSON, KML or TCX).
|
|
212
229
|
*/
|
|
213
230
|
load: function(data) {
|
|
214
231
|
this._parseFromString(data).then( geojson => geojson ? this._loadLayer(geojson) : this._loadFile(data));
|
|
@@ -283,7 +300,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
283
300
|
},
|
|
284
301
|
|
|
285
302
|
/**
|
|
286
|
-
* Set default zoom level
|
|
303
|
+
* Set default zoom level (followMarker: true).
|
|
287
304
|
*/
|
|
288
305
|
setZFollow: function(zoom) {
|
|
289
306
|
this.options.zFollow = zoom;
|
|
@@ -343,20 +360,10 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
343
360
|
// Inspired by L.GPX layer properties
|
|
344
361
|
point.meta = point.meta ?? { time: null, ele: null, hr: null, cad: null, atemp: null };
|
|
345
362
|
|
|
346
|
-
// "alt" property is generated inside "leaflet"
|
|
347
|
-
if ("alt" in point) point.meta.ele = point.alt;
|
|
348
|
-
|
|
349
363
|
// "coordinateProperties" property is generated inside "@tmcw/toGeoJSON"
|
|
350
364
|
let props = (properties && properties.coordinateProperties) || properties;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
else if("times" in props) point.meta.time = new Date(Date.parse(props.times[i]));
|
|
354
|
-
else if("time" in props) point.meta.time = new Date(Date.parse((typeof props.time === 'object' ? props.time[i] : props.time)));
|
|
355
|
-
if ("heartRates" in props) point.meta.hr = parseInt(props.heartRates[i]);
|
|
356
|
-
else if("heartRate" in props) point.meta.hr = parseInt((typeof props.heartRate === 'object' ? props.heartRate[i] : props.heartRate));
|
|
357
|
-
else if("heart" in props) point.meta.hr = parseInt((typeof props.heart === 'object' ? props.heart[i] : props.heart));
|
|
358
|
-
// TODO: ask to "@tmcw/toGeoJSON" for "cadence" and "temperature" implementation
|
|
359
|
-
}
|
|
365
|
+
|
|
366
|
+
this.fire("elepoint_init", { point: point, props: props, id: i });
|
|
360
367
|
|
|
361
368
|
this._addPoint(
|
|
362
369
|
point.lat ?? point[1],
|
|
@@ -364,10 +371,10 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
364
371
|
point.alt ?? point.meta.ele ?? point[2]
|
|
365
372
|
);
|
|
366
373
|
|
|
367
|
-
this.
|
|
374
|
+
this.fire("elepoint_added", { point: point, index: this._data.length - 1 });
|
|
368
375
|
});
|
|
369
376
|
|
|
370
|
-
this.
|
|
377
|
+
this.fire("eletrack_added", { coords: coords, index: this._data.length - 1 });
|
|
371
378
|
},
|
|
372
379
|
|
|
373
380
|
/*
|
|
@@ -385,7 +392,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
385
392
|
latlng: L.latLng(x, y, z)
|
|
386
393
|
});
|
|
387
394
|
|
|
388
|
-
this.
|
|
395
|
+
this.fire("eledata_updated", { index: this._data.length - 1 });
|
|
389
396
|
},
|
|
390
397
|
|
|
391
398
|
_addLayer: function(layer) {
|
|
@@ -572,7 +579,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
572
579
|
},
|
|
573
580
|
|
|
574
581
|
/**
|
|
575
|
-
* Generate "svg" chart DOM element.
|
|
582
|
+
* Generate "svg" chart (DOM element).
|
|
576
583
|
*/
|
|
577
584
|
_initChart: function(container) {
|
|
578
585
|
let opts = this.options;
|
|
@@ -602,7 +609,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
602
609
|
|
|
603
610
|
chart
|
|
604
611
|
.on('reset_drag', this._hideMarker, this)
|
|
605
|
-
.on('mouse_enter', this.
|
|
612
|
+
.on('mouse_enter', this._mouseenterHandler, this)
|
|
606
613
|
.on('dragged', this._dragendHandler, this)
|
|
607
614
|
.on('mouse_move', this._mousemoveHandler, this)
|
|
608
615
|
.on('mouse_out', this._mouseoutHandler, this)
|
|
@@ -612,10 +619,11 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
612
619
|
.on('margins_updated',this._resizeChart, this);
|
|
613
620
|
|
|
614
621
|
|
|
615
|
-
this.
|
|
616
|
-
|
|
622
|
+
this.fire("elechart_axis");
|
|
623
|
+
|
|
624
|
+
if (this.options.legend) this.fire("elechart_legend");
|
|
617
625
|
|
|
618
|
-
this.
|
|
626
|
+
this.fire("elechart_init");
|
|
619
627
|
},
|
|
620
628
|
|
|
621
629
|
_initLayer: function() {
|
|
@@ -641,7 +649,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
641
649
|
this._renderer = L.svg({ pane: "elevationPane" }).addTo(this._map); // default leaflet svg renderer
|
|
642
650
|
this._marker = new Marker(this.options);
|
|
643
651
|
|
|
644
|
-
this.
|
|
652
|
+
this.fire("elechart_marker");
|
|
645
653
|
},
|
|
646
654
|
|
|
647
655
|
/**
|
|
@@ -772,7 +780,14 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
772
780
|
this._hideMarker();
|
|
773
781
|
this.fitBounds(L.latLngBounds([e.dragstart.latlng, e.dragend.latlng]));
|
|
774
782
|
|
|
775
|
-
this.
|
|
783
|
+
this.fire("elechart_dragged");
|
|
784
|
+
},
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* Trigger mouseenter event
|
|
788
|
+
*/
|
|
789
|
+
_mouseenterHandler: function(e) {
|
|
790
|
+
this.fire('elechart_enter');
|
|
776
791
|
},
|
|
777
792
|
|
|
778
793
|
/*
|
|
@@ -796,8 +811,8 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
796
811
|
_.addClass(this._map.getContainer(), 'elechart-hover');
|
|
797
812
|
}
|
|
798
813
|
|
|
799
|
-
this.
|
|
800
|
-
this.
|
|
814
|
+
this.fire("elechart_change", { data: item, xCoord: xCoord });
|
|
815
|
+
this.fire("elechart_hover", { data: item, xCoord: xCoord });
|
|
801
816
|
}
|
|
802
817
|
},
|
|
803
818
|
|
|
@@ -817,7 +832,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
817
832
|
|
|
818
833
|
this._updateMarker(item);
|
|
819
834
|
|
|
820
|
-
this.
|
|
835
|
+
this.fire("elechart_change", { data: item, xCoord: xCoord });
|
|
821
836
|
}
|
|
822
837
|
},
|
|
823
838
|
|
|
@@ -834,7 +849,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
834
849
|
_.removeClass(this._map.getContainer(), 'elechart-hover');
|
|
835
850
|
}
|
|
836
851
|
|
|
837
|
-
this.
|
|
852
|
+
this.fire("elechart_leave");
|
|
838
853
|
},
|
|
839
854
|
|
|
840
855
|
/**
|
|
@@ -919,13 +934,6 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
919
934
|
return geojson.features.filter(feauture => feauture.geometry.type != "MultiLineString");
|
|
920
935
|
},
|
|
921
936
|
|
|
922
|
-
/**
|
|
923
|
-
* Add a point of interest over the diagram
|
|
924
|
-
*/
|
|
925
|
-
_registerCheckPoint: function(props) {
|
|
926
|
-
this.on("elechart_updated", () => this._chart._registerCheckPoint(props));
|
|
927
|
-
},
|
|
928
|
-
|
|
929
937
|
/**
|
|
930
938
|
* Add chart profile to diagram
|
|
931
939
|
*/
|
|
@@ -947,6 +955,60 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
947
955
|
this.on("elechart_axis", () => this._chart._registerAxisScale(props));
|
|
948
956
|
},
|
|
949
957
|
|
|
958
|
+
/**
|
|
959
|
+
* Add a point of interest over the diagram
|
|
960
|
+
*/
|
|
961
|
+
_registerCheckPoint: function(props) {
|
|
962
|
+
this.on("elechart_updated", () => this._chart._registerCheckPoint(props));
|
|
963
|
+
},
|
|
964
|
+
|
|
965
|
+
|
|
966
|
+
/**
|
|
967
|
+
* Base handler for iterative track statistics (dist, time, z, slope, speed, acceleration, ...)
|
|
968
|
+
*/
|
|
969
|
+
_registerDataAttribute: function(props) {
|
|
970
|
+
// save here a reference to last used point
|
|
971
|
+
let lastValid = null;
|
|
972
|
+
|
|
973
|
+
// parse of "coordinateProperties" for later usage
|
|
974
|
+
if (props.init) {
|
|
975
|
+
this.on("elepoint_init", (e) => props.init.call(this, e));
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
// iteration
|
|
979
|
+
this.on("elepoint_added", (e) => {
|
|
980
|
+
|
|
981
|
+
// check and fix missing data on last added point
|
|
982
|
+
if (props.skipNull === false) {
|
|
983
|
+
let curr = this._data[e.index][props.name];
|
|
984
|
+
if(e.index > 0) {
|
|
985
|
+
let prev = this._data[e.index - 1][props.name];
|
|
986
|
+
if (isNaN(prev)) {
|
|
987
|
+
if (!isNaN(lastValid) && !isNaN(curr)) {
|
|
988
|
+
prev = (lastValid + curr) / 2;
|
|
989
|
+
} else if (!isNaN(lastValid)) {
|
|
990
|
+
prev = lastValid;
|
|
991
|
+
} else if (!isNaN(curr)) {
|
|
992
|
+
prev = curr;
|
|
993
|
+
}
|
|
994
|
+
if (!isNaN(prev)) return this._data.splice(e.index - 1, 1);
|
|
995
|
+
this._data[e.index - 1][props.name] = prev;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
// update reference to last used point (ie. if it has data)
|
|
999
|
+
if (!isNaN(curr)) {
|
|
1000
|
+
lastValid = curr;
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
// retrieve point value
|
|
1005
|
+
this._data[e.index][props.name] = props.fetch.call(this, e.index, e.point);
|
|
1006
|
+
|
|
1007
|
+
// update here some mixins (eg. "track_info", value validators, ...)
|
|
1008
|
+
if(props.update) this._data[e.index][props.name] = props.update.call(this, this._data[e.index][props.name], e.index, e.point)
|
|
1009
|
+
});
|
|
1010
|
+
},
|
|
1011
|
+
|
|
950
1012
|
/**
|
|
951
1013
|
* Add chart or marker tooltip info
|
|
952
1014
|
*/
|
|
@@ -1030,7 +1092,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
1030
1092
|
},
|
|
1031
1093
|
|
|
1032
1094
|
/**
|
|
1033
|
-
* Collapse or Expand
|
|
1095
|
+
* Collapse or Expand chart control.
|
|
1034
1096
|
*/
|
|
1035
1097
|
_toggle: function() {
|
|
1036
1098
|
if (_.hasClass(this._container, "elevation-expanded"))
|
|
@@ -1040,7 +1102,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
1040
1102
|
},
|
|
1041
1103
|
|
|
1042
1104
|
/**
|
|
1043
|
-
*
|
|
1105
|
+
* Update map center and zoom (followMarker: true)
|
|
1044
1106
|
*/
|
|
1045
1107
|
_setMapView: function(item) {
|
|
1046
1108
|
if (!this.options.followMarker || !this._map) return;
|
|
@@ -1080,15 +1142,15 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
1080
1142
|
_updateChart: function() {
|
|
1081
1143
|
if (/*!this._data.length ||*/ !this._chart || !this._container) return;
|
|
1082
1144
|
|
|
1083
|
-
this.
|
|
1084
|
-
this.
|
|
1145
|
+
this.fire("elechart_axis");
|
|
1146
|
+
this.fire("elechart_area");
|
|
1085
1147
|
|
|
1086
1148
|
this._chart.update({ data: this._data, options: this.options });
|
|
1087
1149
|
|
|
1088
1150
|
this._x = this._chart._x;
|
|
1089
1151
|
this._y = this._chart._y;
|
|
1090
1152
|
|
|
1091
|
-
this.
|
|
1153
|
+
this.fire('elechart_updated');
|
|
1092
1154
|
},
|
|
1093
1155
|
|
|
1094
1156
|
/*
|
|
@@ -1131,7 +1193,8 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
1131
1193
|
this._summary.reset();
|
|
1132
1194
|
|
|
1133
1195
|
if (this.options.summary) {
|
|
1134
|
-
this.
|
|
1196
|
+
this.fire("elechart_summary");
|
|
1197
|
+
this._summary.update();
|
|
1135
1198
|
}
|
|
1136
1199
|
if (this.options.downloadLink && this._downloadURL) { // TODO: generate dynamically file content instead of using static file urls.
|
|
1137
1200
|
this._summary._container.innerHTML += '<span class="download"><a href="#">' + L._('Download') + '</a></span>'
|
|
@@ -1143,7 +1206,7 @@ export const Elevation = L.Control.Elevation = L.Control.extend({
|
|
|
1143
1206
|
} else if (this.options.downloadLink == 'link' || this.options.downloadLink === true) {
|
|
1144
1207
|
event.confirm();
|
|
1145
1208
|
}
|
|
1146
|
-
this.
|
|
1209
|
+
this.fire('eletrack_download', event);
|
|
1147
1210
|
};
|
|
1148
1211
|
};
|
|
1149
1212
|
},
|