@raruto/leaflet-elevation 1.9.6 → 2.0.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/README.md +6 -5
- package/dist/leaflet-elevation.css +51 -161
- package/dist/leaflet-elevation.js +1587 -3884
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.css +1 -1
- package/dist/leaflet-elevation.min.js +1 -3
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/images/checkered.png +0 -0
- package/libs/leaflet-gpxgroup.js +2 -2
- package/package.json +9 -11
- package/src/chart.js +147 -144
- package/src/components.js +43 -71
- package/src/control.js +421 -326
- package/src/handlers/acceleration.js +64 -0
- package/src/handlers/acceleration.min.js +1 -0
- package/src/handlers/altitude.js +76 -0
- package/src/handlers/altitude.min.js +1 -0
- package/src/handlers/cadence.js +54 -0
- package/src/handlers/distance.js +45 -0
- package/src/handlers/distance.min.js +1 -0
- package/src/handlers/heart.js +53 -0
- package/src/handlers/slope.js +79 -0
- package/src/handlers/slope.min.js +1 -0
- package/src/handlers/speed.js +66 -0
- package/src/handlers/speed.min.js +1 -0
- package/src/{time.js → handlers/time.js} +31 -54
- package/src/handlers/time.min.js +1 -0
- package/src/index.css +51 -161
- package/src/index.js +0 -24
- package/src/marker.js +11 -14
- package/src/options.js +20 -28
- package/src/summary.js +4 -5
- package/src/utils.js +74 -102
- package/src/acceleration.js +0 -113
- package/src/altitude.js +0 -119
- package/src/distance.js +0 -69
- package/src/slope.js +0 -129
- package/src/speed.js +0 -118
package/src/utils.js
CHANGED
|
@@ -1,10 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TODO: exget computed styles of theese values from actual "CSS vars"
|
|
3
|
+
**/
|
|
4
|
+
export const Colors = {
|
|
5
|
+
'lightblue': { area: '#3366CC', alpha: 0.45, stroke: '#3366CC' },
|
|
6
|
+
'magenta' : { area: '#FF005E' },
|
|
7
|
+
'yellow' : { area: '#FF0' },
|
|
8
|
+
'purple' : { area: '#732C7B' },
|
|
9
|
+
'steelblue': { area: '#4682B4' },
|
|
10
|
+
'red' : { area: '#F00' },
|
|
11
|
+
'lime' : { area: '#9CC222', line: '#566B13' }
|
|
12
|
+
};
|
|
13
|
+
|
|
1
14
|
const SEC = 1000;
|
|
2
15
|
const MIN = SEC * 60;
|
|
3
16
|
const HOUR = MIN * 60;
|
|
4
17
|
const DAY = HOUR * 24;
|
|
5
18
|
|
|
6
19
|
/**
|
|
7
|
-
* Convert a
|
|
20
|
+
* Convert a time (millis) to a human readable duration string (%Dd %H:%M'%S")
|
|
8
21
|
*/
|
|
9
22
|
export function formatTime(t) {
|
|
10
23
|
let d = Math.floor(t / DAY);
|
|
@@ -17,6 +30,20 @@ export function formatTime(t) {
|
|
|
17
30
|
return (d ? d + "d " : '') + h.toString().padStart(2, 0) + ':' + m.toString().padStart(2, 0) + "'" + s.toString().padStart(2, 0) + '"';
|
|
18
31
|
}
|
|
19
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Convert a time (millis) to human readable date string (dd-mm-yyyy hh:mm:ss)
|
|
35
|
+
*/
|
|
36
|
+
export function formatDate(format) {
|
|
37
|
+
if (!format) {
|
|
38
|
+
return (time) => (new Date(time)).toLocaleString().replaceAll('/', '-').replaceAll(',', ' ');
|
|
39
|
+
} else if (format == 'time') {
|
|
40
|
+
return (time) => (new Date(time)).toLocaleTimeString();
|
|
41
|
+
} else if (format == 'date') {
|
|
42
|
+
return (time) => (new Date(time)).toLocaleDateString();
|
|
43
|
+
}
|
|
44
|
+
return (time) => format(time);
|
|
45
|
+
}
|
|
46
|
+
|
|
20
47
|
/**
|
|
21
48
|
* Generate download data event.
|
|
22
49
|
*/
|
|
@@ -28,23 +55,6 @@ export function formatTime(t) {
|
|
|
28
55
|
b.removeChild(a);
|
|
29
56
|
}
|
|
30
57
|
|
|
31
|
-
/**
|
|
32
|
-
* Async JS script download.
|
|
33
|
-
*/
|
|
34
|
-
export function lazyLoader(url, skip, loader) {
|
|
35
|
-
if (skip === false) {
|
|
36
|
-
return Promise.resolve();
|
|
37
|
-
}
|
|
38
|
-
if (loader instanceof Promise) {
|
|
39
|
-
return loader;
|
|
40
|
-
}
|
|
41
|
-
return new Promise((resolve, reject) => {
|
|
42
|
-
let tag = document.createElement("script");
|
|
43
|
-
tag.addEventListener('load', resolve, { once: true });
|
|
44
|
-
tag.src = url;
|
|
45
|
-
document.head.appendChild(tag);
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
58
|
|
|
49
59
|
/**
|
|
50
60
|
* Convert SVG Path into Path2D and then update canvas
|
|
@@ -75,113 +85,75 @@ export function lazyLoader(url, skip, loader) {
|
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
/**
|
|
78
|
-
*
|
|
79
|
-
*/
|
|
80
|
-
export function clamp(val, range) {
|
|
81
|
-
if (range) return val < range[0] ? range[0] : val > range[1] ? range[1] : val;
|
|
82
|
-
return val;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* A little bit safier than L.DomUtil.addClass
|
|
88
|
+
* Loop and extract GPX Extensions handled by "@tmcw/toGeoJSON" (eg. "coordinateProperties" > "times")
|
|
87
89
|
*/
|
|
88
|
-
export function
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function toggleClass(targetNode, className, conditional) {
|
|
100
|
-
return (conditional ? addClass : removeClass).call(null, targetNode, className)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function replaceClass(targetNode, removeClassName, addClassName) {
|
|
104
|
-
if (removeClassName) removeClass(targetNode, removeClassName);
|
|
105
|
-
if (addClassName) addClass(targetNode, addClassName);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export function style(targetNode, name, value) {
|
|
109
|
-
if (typeof value === "undefined") return L.DomUtil.getStyle(targetNode, name);
|
|
110
|
-
else return targetNode.style.setProperty(name, value);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function toggleStyle(targetNode, name, value, conditional) {
|
|
114
|
-
return style(targetNode, name, conditional ? value : '');
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function toggleEvent(leafletElement, eventName, handler, conditional) {
|
|
118
|
-
return leafletElement[conditional ? 'on' : 'off'](eventName, handler);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* A little bit shorter than L.DomUtil.create()
|
|
123
|
-
*/
|
|
124
|
-
export function create(tagName, className, attributes, parent) {
|
|
125
|
-
let elem = L.DomUtil.create(tagName, className || "");
|
|
126
|
-
if (attributes) setAttributes(elem, attributes);
|
|
127
|
-
if (parent) append(parent, elem);
|
|
128
|
-
return elem;
|
|
90
|
+
export function coordPropsToMeta(coordProps, name, parser) {
|
|
91
|
+
return coordProps && (({props, point, id}) => {
|
|
92
|
+
if (props) {
|
|
93
|
+
for (const key of coordProps) {
|
|
94
|
+
if (key in props) {
|
|
95
|
+
point.meta[name] = (parser || parseInt).call(this, props[key], id);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
129
101
|
}
|
|
130
102
|
|
|
131
103
|
/**
|
|
132
|
-
*
|
|
104
|
+
* Extract numeric property (id) from GeoJSON object
|
|
133
105
|
*/
|
|
134
|
-
export
|
|
135
|
-
return parent.appendChild(child);
|
|
136
|
-
}
|
|
106
|
+
export const parseInt = (property, id) => window.parseInt((typeof property === 'object' ? property[id] : property));
|
|
137
107
|
|
|
138
108
|
/**
|
|
139
|
-
*
|
|
109
|
+
* Extract datetime property (id) from GeoJSON object
|
|
140
110
|
*/
|
|
141
|
-
export
|
|
142
|
-
return parent.insertAdjacentElement(position, child);
|
|
143
|
-
}
|
|
111
|
+
export const parseDate = (property, id) => new Date(Date.parse((typeof property === 'object' ? property[id] : property)));
|
|
144
112
|
|
|
145
113
|
/**
|
|
146
|
-
*
|
|
114
|
+
* A little bit shorter than L.DomUtil
|
|
147
115
|
*/
|
|
148
|
-
export
|
|
149
|
-
|
|
150
|
-
|
|
116
|
+
export const addClass = (n, str) => n && str.split(" ").every(s => s && L.DomUtil.addClass(n, s));
|
|
117
|
+
export const removeClass = (n, str) => n && str.split(" ").every(s => s && L.DomUtil.removeClass(n, s));
|
|
118
|
+
export const toggleClass = (n, str, cond) => (cond ? addClass : removeClass)(n, str);
|
|
119
|
+
export const replaceClass = (n, rem, add) => (rem && removeClass(n, rem)) || (add && addClass(n, add));
|
|
120
|
+
export const style = (n, k, v) => (typeof v === "undefined" && L.DomUtil.getStyle(n, k)) || n.style.setProperty(k, v);
|
|
121
|
+
export const toggleStyle = (n, k, v, cond) => style(n, k, cond ? v : '');
|
|
122
|
+
export const setAttributes = (n, attrs) => { for (let k in attrs) { n.setAttribute(k, attrs[k]); } };
|
|
123
|
+
export const toggleEvent = (el, e, fn, cond) => el[cond ? 'on' : 'off'](e, fn);
|
|
124
|
+
export const create = (tag, str, attrs, n) => { let elem = L.DomUtil.create(tag, str || ""); if (attrs) setAttributes(elem, attrs); if (n) append(n, elem); return elem; };
|
|
125
|
+
export const append = (n, c) => n.appendChild(c);
|
|
126
|
+
export const insert = (n, c, pos) => n.insertAdjacentElement(pos, c);
|
|
127
|
+
export const select = (str, n) => (n || document).querySelector(str);
|
|
128
|
+
export const each = (obj, fn) => { for (let i in obj) fn(obj[i], i); };
|
|
129
|
+
export const randomId = () => Math.random().toString(36).substr(2, 9);
|
|
151
130
|
|
|
152
131
|
/**
|
|
153
|
-
*
|
|
132
|
+
* TODO: use generators instead? (ie. "yield")
|
|
154
133
|
*/
|
|
155
|
-
export
|
|
156
|
-
|
|
157
|
-
|
|
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);
|
|
158
138
|
|
|
159
139
|
/**
|
|
160
|
-
* Alias for
|
|
140
|
+
* Alias for some leaflet core functions
|
|
161
141
|
*/
|
|
162
|
-
export const on = L.DomEvent
|
|
142
|
+
export const { on, off } = L.DomEvent;
|
|
143
|
+
export const { throttle } = L.Util;
|
|
144
|
+
export const { hasClass } = L.DomUtil;
|
|
163
145
|
|
|
164
146
|
/**
|
|
165
|
-
*
|
|
147
|
+
* Limit floating point precision
|
|
166
148
|
*/
|
|
167
|
-
export const
|
|
149
|
+
export const round = L.Util.formatNum;
|
|
168
150
|
|
|
169
151
|
/**
|
|
170
|
-
*
|
|
171
|
-
*/
|
|
172
|
-
export const hasClass = L.DomUtil.hasClass;
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Generate a random string
|
|
152
|
+
* Limit a number between min / max values
|
|
177
153
|
*/
|
|
178
|
-
export
|
|
179
|
-
return Math.random().toString(36).substr(2, 9);
|
|
180
|
-
}
|
|
154
|
+
export const clamp = (val, range) => range ? (val < range[0] ? range[0] : val > range[1] ? range[1] : val) : val;
|
|
181
155
|
|
|
182
156
|
/**
|
|
183
|
-
*
|
|
157
|
+
* Limit a delta difference between two values
|
|
184
158
|
*/
|
|
185
|
-
export
|
|
186
|
-
for (let i in obj) fn(obj[i], i);
|
|
187
|
-
}
|
|
159
|
+
export const wrapDelta = (curr, prev, deltaMax) => Math.abs(curr - prev) > deltaMax ? prev + deltaMax * Math.sign(curr - prev) : curr;
|
package/src/acceleration.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import 'leaflet-i18n';
|
|
2
|
-
import * as _ from './utils';
|
|
3
|
-
import * as D3 from './components';
|
|
4
|
-
import { Elevation } from './control';
|
|
5
|
-
|
|
6
|
-
Elevation.addInitHook(function() {
|
|
7
|
-
|
|
8
|
-
if (!this.options.acceleration) return;
|
|
9
|
-
|
|
10
|
-
let opts = this.options;
|
|
11
|
-
let acceleration = {};
|
|
12
|
-
|
|
13
|
-
acceleration.label = opts.accelerationLabel || L._(opts.imperial ? 'ft/s²' : 'm/s²');
|
|
14
|
-
opts.accelerationFactor = opts.accelerationFactor || 1;
|
|
15
|
-
|
|
16
|
-
this._registerDataAttribute({
|
|
17
|
-
name: 'acceleration',
|
|
18
|
-
init: () => {
|
|
19
|
-
// this.track_info.acceleration_max = -Infinity; // Acceleration Max
|
|
20
|
-
// this.track_info.acceleration_min = +Infinity; // Acceleration Min
|
|
21
|
-
// this.track_info.acceleration_avg = 0; // Acceleration Avg
|
|
22
|
-
},
|
|
23
|
-
fetch: (i) => {
|
|
24
|
-
let data = this._data;
|
|
25
|
-
let dv = (data[i].speed - data[i > 0 ? i - 1 : i].speed) * (1000 / opts.timeFactor);
|
|
26
|
-
let dt = (data[i].time - data[i > 0 ? i - 1 : i].time) / 1000;
|
|
27
|
-
return dt > 0 ? Math.abs((dv / dt)) * opts.accelerationFactor : 0;
|
|
28
|
-
},
|
|
29
|
-
update: (acceleration, i) => {
|
|
30
|
-
this.track_info.acceleration_max = this.track_info.acceleration_max || -Infinity; // Acceleration Max
|
|
31
|
-
this.track_info.acceleration_min = this.track_info.acceleration_min || +Infinity; // Acceleration Min
|
|
32
|
-
this.track_info.acceleration_avg = this.track_info.acceleration_avg || 0; // Acceleration Avg
|
|
33
|
-
|
|
34
|
-
let data = this._data;
|
|
35
|
-
let track = this.track_info;
|
|
36
|
-
|
|
37
|
-
// Try to smooth "crazy" acceleration values.
|
|
38
|
-
if (this.options.accelerationDeltaMax) {
|
|
39
|
-
let delta = acceleration - data[i > 0 ? i - 1 : i].acceleration;
|
|
40
|
-
let deltaMax = this.options.accelerationDeltaMax;
|
|
41
|
-
if (Math.abs(delta) > deltaMax) {
|
|
42
|
-
acceleration = data[i - 1].acceleration + deltaMax * Math.sign(delta);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Range of acceptable acceleration values.
|
|
47
|
-
acceleration = _.clamp(acceleration, this.options.accelerationRange);
|
|
48
|
-
|
|
49
|
-
if (acceleration > track.acceleration_max) track.acceleration_max = acceleration;
|
|
50
|
-
if (acceleration < track.acceleration_min) track.acceleration_min = acceleration;
|
|
51
|
-
|
|
52
|
-
track.acceleration_avg = (acceleration + track.acceleration_avg) / 2.0;
|
|
53
|
-
|
|
54
|
-
return L.Util.formatNum(acceleration, 2);
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
if (this.options.acceleration != "summary") {
|
|
59
|
-
|
|
60
|
-
this._registerAxisScale({
|
|
61
|
-
axis : "y",
|
|
62
|
-
position : "right",
|
|
63
|
-
scale : {
|
|
64
|
-
min : 0,
|
|
65
|
-
max : +1,
|
|
66
|
-
},
|
|
67
|
-
tickPadding: 16,
|
|
68
|
-
label : acceleration.label,
|
|
69
|
-
labelX : 25,
|
|
70
|
-
labelY : -8,
|
|
71
|
-
name : 'acceleration',
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
this._registerAreaPath({
|
|
75
|
-
name : 'acceleration',
|
|
76
|
-
label : 'Acceleration',
|
|
77
|
-
yAttr : 'acceleration',
|
|
78
|
-
scaleX : 'distance',
|
|
79
|
-
scaleY : 'acceleration',
|
|
80
|
-
color : '#050402',
|
|
81
|
-
strokeColor : '#000',
|
|
82
|
-
strokeOpacity: "0.5",
|
|
83
|
-
fillOpacity : "0.25",
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
this._registerTooltip({
|
|
89
|
-
name : 'acceleration',
|
|
90
|
-
chart: (item) => L._("a: ") + item.acceleration + " " + acceleration.label,
|
|
91
|
-
marker: (item) => Math.round(item.acceleration) + " " + acceleration.label,
|
|
92
|
-
order: 60,
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
this._registerSummary({
|
|
96
|
-
"minacceleration" : {
|
|
97
|
-
label: "Min Acceleration: ",
|
|
98
|
-
value: (track) => Math.round(track.acceleration_min || 0) + ' ' + acceleration.label,
|
|
99
|
-
order: 60
|
|
100
|
-
},
|
|
101
|
-
"maxacceleration" : {
|
|
102
|
-
label: "Max Acceleration: ",
|
|
103
|
-
value: (track) => Math.round(track.acceleration_max || 0) + ' ' + acceleration.label,
|
|
104
|
-
order: 60
|
|
105
|
-
},
|
|
106
|
-
"avgacceleration": {
|
|
107
|
-
label: "Avg Acceleration: ",
|
|
108
|
-
value: (track) => Math.round(track.acceleration_avg || 0) + ' ' + acceleration.label,
|
|
109
|
-
order: 60
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
});
|
package/src/altitude.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import 'leaflet-i18n';
|
|
2
|
-
import * as _ from './utils';
|
|
3
|
-
import * as D3 from './components';
|
|
4
|
-
import { Elevation } from './control';
|
|
5
|
-
|
|
6
|
-
Elevation.addInitHook(function() {
|
|
7
|
-
|
|
8
|
-
let opts = this.options;
|
|
9
|
-
let altitude = {};
|
|
10
|
-
|
|
11
|
-
let theme = opts.theme.replace('-theme', '');
|
|
12
|
-
let color = D3.Colors[theme] || {};
|
|
13
|
-
|
|
14
|
-
if (opts.imperial) {
|
|
15
|
-
opts.altitudeFactor = this.__footFactor;
|
|
16
|
-
altitude.label = "ft";
|
|
17
|
-
} else {
|
|
18
|
-
opts.altitudeFactor = opts.heightFactor || opts.altitudeFactor || 1;
|
|
19
|
-
altitude.label = opts.yLabel;
|
|
20
|
-
}
|
|
21
|
-
|
|
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);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Range of acceptable elevation values.
|
|
54
|
-
z = _.clamp(z, this.options.altitudeRange);
|
|
55
|
-
|
|
56
|
-
if (z > track.elevation_max) track.elevation_max = z;
|
|
57
|
-
if (z < track.elevation_min) track.elevation_min = z;
|
|
58
|
-
|
|
59
|
-
track.elevation_avg = (z + track.elevation_avg) / 2.0;
|
|
60
|
-
|
|
61
|
-
return z;
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
|
|
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
|
-
});
|
|
75
|
-
|
|
76
|
-
this._registerAxisGrid({
|
|
77
|
-
axis : "y",
|
|
78
|
-
position : "left",
|
|
79
|
-
scale : "y" // this._chart._y,
|
|
80
|
-
});
|
|
81
|
-
|
|
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
|
-
});
|
|
94
|
-
|
|
95
|
-
this._registerTooltip({
|
|
96
|
-
name: 'y',
|
|
97
|
-
chart: (item) => L._("y: ") + d3.format("." + opts.decimalsY + "f")(item[opts.yAttr]) + " " + altitude.label,
|
|
98
|
-
marker: (item) => d3.format("." + opts.decimalsY + "f")(item[opts.yAttr]) + " " + altitude.label,
|
|
99
|
-
order: 10,
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
this._registerSummary({
|
|
103
|
-
"maxele" : {
|
|
104
|
-
label: "Max Elevation: ",
|
|
105
|
-
value: (track) => (track.elevation_max || 0).toFixed(2) + ' ' + altitude.label,
|
|
106
|
-
order: 30,
|
|
107
|
-
},
|
|
108
|
-
"minele" : {
|
|
109
|
-
label: "Min Elevation: ",
|
|
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
|
-
},
|
|
118
|
-
});
|
|
119
|
-
});
|
package/src/distance.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import 'leaflet-i18n';
|
|
2
|
-
import * as _ from './utils';
|
|
3
|
-
import * as D3 from './components';
|
|
4
|
-
import { Elevation } from './control';
|
|
5
|
-
|
|
6
|
-
Elevation.addInitHook(function() {
|
|
7
|
-
|
|
8
|
-
let opts = this.options;
|
|
9
|
-
let distance = {};
|
|
10
|
-
|
|
11
|
-
if (opts.imperial) {
|
|
12
|
-
opts.distanceFactor = this.__mileFactor;
|
|
13
|
-
distance.label = "mi";
|
|
14
|
-
} else {
|
|
15
|
-
opts.distanceFactor = opts.distanceFactor || 1;
|
|
16
|
-
distance.label = opts.xLabel;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
this._registerDataAttribute({
|
|
20
|
-
name: 'dist',
|
|
21
|
-
init: () => {
|
|
22
|
-
// this.track_info.distance = 0;
|
|
23
|
-
},
|
|
24
|
-
fetch: (i) => {
|
|
25
|
-
let delta = this._data[i].latlng.distanceTo(this._data[i > 0 ? i - 1 : i].latlng) * opts.distanceFactor;
|
|
26
|
-
return Math.round(delta / 1000 * 100000) / 100000; // handles floating points calc
|
|
27
|
-
},
|
|
28
|
-
update: (distance) => {
|
|
29
|
-
this.track_info.distance = this.track_info.distance || 0;
|
|
30
|
-
this.track_info.distance += distance;
|
|
31
|
-
return this.track_info.distance;
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
if (this.options.distance != "summary") {
|
|
36
|
-
|
|
37
|
-
this._registerAxisScale({
|
|
38
|
-
axis : "x",
|
|
39
|
-
position: "bottom",
|
|
40
|
-
scale : "x", // this._chart._x,
|
|
41
|
-
label : distance.label,
|
|
42
|
-
labelY : 25,
|
|
43
|
-
labelX : () => this._width() + 6,
|
|
44
|
-
name : "distance",
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
this._registerAxisGrid({
|
|
50
|
-
axis : "x",
|
|
51
|
-
position : "bottom",
|
|
52
|
-
scale : "x" // this._chart._x,
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
this._registerTooltip({
|
|
56
|
-
name: 'x',
|
|
57
|
-
chart: (item) => L._("x: ") + d3.format("." + opts.decimalsX + "f")(item[opts.xAttr]) + " " + distance.label,
|
|
58
|
-
order: 20
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
this._registerSummary({
|
|
62
|
-
"totlen" : {
|
|
63
|
-
label: "Total Length: ",
|
|
64
|
-
value: (track) => (track.distance || 0).toFixed(2) + ' ' + distance.label,
|
|
65
|
-
order: 10
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
});
|
package/src/slope.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import 'leaflet-i18n';
|
|
2
|
-
import * as _ from './utils';
|
|
3
|
-
import * as D3 from './components';
|
|
4
|
-
import { Elevation } from './control';
|
|
5
|
-
|
|
6
|
-
Elevation.addInitHook(function() {
|
|
7
|
-
|
|
8
|
-
if (!this.options.slope) return;
|
|
9
|
-
|
|
10
|
-
let opts = this.options;
|
|
11
|
-
let slope = {};
|
|
12
|
-
|
|
13
|
-
slope.label = opts.slopeLabel || '%';
|
|
14
|
-
|
|
15
|
-
this._registerDataAttribute({
|
|
16
|
-
name: 'slope',
|
|
17
|
-
// init: () => {
|
|
18
|
-
// // this.track_info.ascent = 0; // Total Ascent
|
|
19
|
-
// // this.track_info.descent = 0; // Total Descent
|
|
20
|
-
// // this.track_info.slope_max = -Infinity; // Slope Max
|
|
21
|
-
// // this.track_info.slope_min = +Infinity; // Slope Min
|
|
22
|
-
// // this.track_info.slope_avg = 0; // Acceleration Avg
|
|
23
|
-
// },
|
|
24
|
-
fetch: (i) => {
|
|
25
|
-
let data = this._data;
|
|
26
|
-
let dx = (data[i].dist - data[i > 0 ? i - 1 : i].dist) * 1000;
|
|
27
|
-
let dz = data[i].z - data[i > 0 ? i - 1 : i].z;
|
|
28
|
-
return (!isNaN(dz) && dx !== 0) ? (dz / dx) * 100 : 0; // slope in % = ( height / length ) * 100;
|
|
29
|
-
},
|
|
30
|
-
update: (slope, i) => {
|
|
31
|
-
this.track_info.ascent = this.track_info.ascent || 0; // Total Ascent
|
|
32
|
-
this.track_info.descent = this.track_info.descent || 0; // Total Descent
|
|
33
|
-
this.track_info.slope_max = this.track_info.slope_max || -Infinity; // Slope Max
|
|
34
|
-
this.track_info.slope_min = this.track_info.slope_min || +Infinity; // Slope Min
|
|
35
|
-
this.track_info.slope_avg = this.track_info.slope_avg || 0; // Acceleration Avg
|
|
36
|
-
|
|
37
|
-
let track = this.track_info;
|
|
38
|
-
let data = this._data;
|
|
39
|
-
let dz = data[i].z - data[i > 0 ? i - 1 : i].z;
|
|
40
|
-
|
|
41
|
-
// Try to smooth "crazy" acceleration values.
|
|
42
|
-
if (this.options.slopeDeltaMax) {
|
|
43
|
-
let delta = slop - data[i > 0 ? i - 1 : i].slope;
|
|
44
|
-
let deltaMax = this.options.slopeDeltaMax;
|
|
45
|
-
if (Math.abs(delta) > deltaMax) {
|
|
46
|
-
slope = data[i - 1].slope + deltaMax * Math.sign(delta);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Range of acceptable slope values.
|
|
51
|
-
slope = _.clamp(slope, this.options.slopeRange);
|
|
52
|
-
|
|
53
|
-
if (dz > 0) this.track_info.ascent += dz;
|
|
54
|
-
else if (dz < 0) this.track_info.descent -= dz;
|
|
55
|
-
|
|
56
|
-
if (slope > track.slope_max) track.slope_max = slope;
|
|
57
|
-
if (slope < track.slope_min) track.slope_min = slope;
|
|
58
|
-
|
|
59
|
-
track.slope_avg = (slope + track.slope_avg) / 2.0;
|
|
60
|
-
|
|
61
|
-
return L.Util.formatNum(slope, 2);;
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
this._registerAxisScale({
|
|
66
|
-
axis : "y",
|
|
67
|
-
position : "right",
|
|
68
|
-
scale : {
|
|
69
|
-
min : -1,
|
|
70
|
-
max : +1,
|
|
71
|
-
},
|
|
72
|
-
tickPadding: 16,
|
|
73
|
-
label : slope.label,
|
|
74
|
-
labelX : 25,
|
|
75
|
-
labelY : -8,
|
|
76
|
-
name : 'slope',
|
|
77
|
-
visbile : this.options.slope != "summary"
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
this._registerAreaPath({
|
|
81
|
-
name : 'slope',
|
|
82
|
-
label : 'Slope',
|
|
83
|
-
yAttr : 'slope',
|
|
84
|
-
scaleX : 'distance',
|
|
85
|
-
scaleY : 'slope',
|
|
86
|
-
color : '#F00',
|
|
87
|
-
strokeColor : '#000',
|
|
88
|
-
strokeOpacity: "0.5",
|
|
89
|
-
fillOpacity : "0.25",
|
|
90
|
-
visbile : this.options.slope != "summary"
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
this._registerTooltip({
|
|
94
|
-
name: 'slope',
|
|
95
|
-
chart: (item) => L._("m: ") + item.slope + slope.label,
|
|
96
|
-
marker: (item) => Math.round(item.slope) + slope.label,
|
|
97
|
-
order: 40,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
this._registerSummary({
|
|
101
|
-
"ascent" : {
|
|
102
|
-
label: "Total Ascent: ",
|
|
103
|
-
value: (track) => Math.round(track.ascent || 0) + ' ' + (this.options.imperial ? 'ft' : 'm'),
|
|
104
|
-
order: 40
|
|
105
|
-
},
|
|
106
|
-
"descent" : {
|
|
107
|
-
label: "Total Descent: ",
|
|
108
|
-
value: (track) => Math.round(track.descent || 0) + ' ' + (this.options.imperial ? 'ft' : 'm'),
|
|
109
|
-
order: 40
|
|
110
|
-
},
|
|
111
|
-
"minslope": {
|
|
112
|
-
label: "Min Slope: ",
|
|
113
|
-
value: (track) => Math.round(track.slope_min || 0) + ' ' + slope.label,
|
|
114
|
-
order: 40
|
|
115
|
-
},
|
|
116
|
-
"maxslope": {
|
|
117
|
-
label: "Max Slope: ",
|
|
118
|
-
value: (track) => Math.round(track.slope_max || 0) + ' ' + slope.label,
|
|
119
|
-
order: 40
|
|
120
|
-
},
|
|
121
|
-
"avgslope": {
|
|
122
|
-
label: "Avg Slope: ",
|
|
123
|
-
value: (track) => Math.round(track.slope_avg || 0) + ' ' + slope.label,
|
|
124
|
-
order: 40
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
});
|