@raruto/leaflet-elevation 1.9.3 → 1.9.6

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.
@@ -406,8 +406,10 @@
406
406
  line.attr("class", theme + " height-focus line").attr("x1", xCoord).attr("x2", xCoord).attr("y1", yCoord).attr("y2", length);
407
407
  text.attr("class", theme + " height-focus-label").style("pointer-events", "none").attr("x", xCoord + 5).attr("y", length);
408
408
  var label;
409
-
410
- for (var i in labels) {
409
+ Object.keys(labels).sort(function (a, b) {
410
+ return labels[a].order - labels[b].order;
411
+ }) // TODO: any performance issues?
412
+ .forEach(function (i) {
411
413
  label = text.select(".height-focus-" + labels[i].name);
412
414
 
413
415
  if (!label.size()) {
@@ -415,8 +417,7 @@
415
417
  }
416
418
 
417
419
  label.text(typeof labels[i].value !== "function" ? labels[i].value : labels[i].value(item));
418
- }
419
-
420
+ });
420
421
  text.select('tspan').attr("dy", text.selectAll('tspan').size() > 1 ? "-1.5em" : "0em");
421
422
  text.selectAll('tspan').attr("x", xCoord + 5);
422
423
  return g;
@@ -487,8 +488,10 @@
487
488
  rect.attr("class", "mouse-focus-label-rect").attr("x", xAlign - 5).attr("y", yAlign - 5).attr("width", bbox.width + 10).attr("height", bbox.height + 10).attr("rx", 3).attr("ry", 3);
488
489
  text.attr("class", "mouse-focus-label-text").style("font-weight", "700").attr("y", yAlign);
489
490
  var label;
490
-
491
- for (var i in labels) {
491
+ Object.keys(labels).sort(function (a, b) {
492
+ return labels[a].order - labels[b].order;
493
+ }) // TODO: any performance issues?
494
+ .forEach(function (i) {
492
495
  label = text.select(".mouse-focus-label-" + labels[i].name);
493
496
 
494
497
  if (!label.size()) {
@@ -496,8 +499,7 @@
496
499
  }
497
500
 
498
501
  label.text(typeof labels[i].value !== "function" ? labels[i].value : labels[i].value(item));
499
- }
500
-
502
+ });
501
503
  text.select('tspan').attr("dy", "1em");
502
504
  text.selectAll('tspan').attr("x", xAlign);
503
505
  return g;
@@ -1173,6 +1175,7 @@
1173
1175
  this._y = this._scales.altitude;
1174
1176
  },
1175
1177
  _registerAreaPath: function _registerAreaPath(props) {
1178
+ if (props.scale == 'y') props.scale = this._y;else if (props.scale == 'x') props.scale = this._x;
1176
1179
  var opts = this.options;
1177
1180
  if (!props.xAttr) props.xAttr = opts.xAttr;
1178
1181
  if (!props.yAttr) props.yAttr = opts.yAttr;
@@ -1192,9 +1195,11 @@
1192
1195
  }
1193
1196
  },
1194
1197
  _registerAxisGrid: function _registerAxisGrid(props) {
1198
+ if (props.scale == 'y') props.scale = this._y;else if (props.scale == 'x') props.scale = this._x;
1195
1199
  this._props.grids[props.name || props.axis] = props;
1196
1200
  },
1197
1201
  _registerAxisScale: function _registerAxisScale(props) {
1202
+ if (props.scale == 'y') props.scale = this._y;else if (props.scale == 'x') props.scale = this._x;
1198
1203
  var opts = this.options;
1199
1204
  var scale = props.scale;
1200
1205
 
@@ -1248,6 +1253,9 @@
1248
1253
  }));
1249
1254
  },
1250
1255
  _registerTooltip: function _registerTooltip(props) {
1256
+ var _props$order;
1257
+
1258
+ props.order = (_props$order = props.order) !== null && _props$order !== void 0 ? _props$order : 100;
1251
1259
  this._props.tooltipItems[props.name] = props;
1252
1260
  },
1253
1261
  _updateArea: function _updateArea() {
@@ -1670,6 +1678,7 @@
1670
1678
  initialize: function initialize(opts, control) {
1671
1679
  this.options = opts;
1672
1680
  this.control = control;
1681
+ this.labels = {};
1673
1682
 
1674
1683
  var summary = this._container = create("div", "elevation-summary " + (opts.summary ? opts.summary + "-summary" : ''));
1675
1684
 
@@ -1691,9 +1700,22 @@
1691
1700
  this._container.innerHTML += "<span class=\"".concat(className, "\"><span class=\"summarylabel\">").concat(label, "</span><span class=\"summaryvalue\">").concat(value, "</span></span>");
1692
1701
  return this;
1693
1702
  },
1703
+ update: function update() {
1704
+ var _this2 = this;
1705
+
1706
+ Object.keys(this.labels).sort(function (a, b) {
1707
+ return _this2.labels[a].order - _this2.labels[b].order;
1708
+ }) // TODO: any performance issues?
1709
+ .forEach(function (i) {
1710
+ _this2.append(i, L._(_this2.labels[i].label), typeof _this2.labels[i].value !== "function" ? _this2.labels[i].value : _this2.labels[i].value(_this2.control.track_info));
1711
+ });
1712
+ },
1694
1713
  _registerSummary: function _registerSummary(data) {
1695
1714
  for (var i in data) {
1696
- this.append(i, L._(data[i].label), typeof data[i].value !== "function" ? data[i].value : data[i].value(this.control.track_info));
1715
+ var _data$i$order;
1716
+
1717
+ data[i].order = (_data$i$order = data[i].order) !== null && _data$i$order !== void 0 ? _data$i$order : 100;
1718
+ this.labels[i] = data[i];
1697
1719
  }
1698
1720
  }
1699
1721
  });
@@ -1707,7 +1729,11 @@
1707
1729
  collapsed: false,
1708
1730
  detached: true,
1709
1731
  distance: true,
1710
- distanceMarkers: false,
1732
+ distanceMarkers: {
1733
+ lazy: true,
1734
+ distance: true,
1735
+ direction: true
1736
+ },
1711
1737
  decimalsX: 2,
1712
1738
  decimalsY: 0,
1713
1739
  dragging: !L.Browser.mobile,
@@ -1753,15 +1779,15 @@
1753
1779
  theme: "lightblue-theme",
1754
1780
  summary: 'inline',
1755
1781
  slope: false,
1782
+ slopeDeltaMax: undefined,
1783
+ slopeRange: undefined,
1756
1784
  speed: false,
1757
- sLimit: undefined,
1785
+ speedDeltaMax: undefined,
1786
+ speedRange: undefined,
1758
1787
  time: false,
1759
1788
  timeFactor: 3600,
1760
1789
  timeFormat: false,
1761
1790
  timestamps: false,
1762
- sDeltaMax: undefined,
1763
- sInterpolation: "curveStepAfter",
1764
- sRange: undefined,
1765
1791
  width: 600,
1766
1792
  waypoints: true,
1767
1793
  wptIcons: {
@@ -1794,7 +1820,7 @@
1794
1820
  __TOGEOJSON: 'https://unpkg.com/@tmcw/togeojson@4.5.0/dist/togeojson.umd.js',
1795
1821
  __LGEOMUTIL: 'https://unpkg.com/leaflet-geometryutil@0.9.3/src/leaflet.geometryutil.js',
1796
1822
  __LALMOSTOVER: 'https://unpkg.com/leaflet-almostover@1.0.1/src/leaflet.almostover.js',
1797
- __LDISTANCEM: 'https://unpkg.com/@raruto/leaflet-elevation@1.9.3/libs/leaflet-distance-marker.min.js',
1823
+ __LDISTANCEM: 'https://unpkg.com/@raruto/leaflet-elevation@1.9.6/libs/leaflet-distance-marker.min.js',
1798
1824
 
1799
1825
  /*
1800
1826
  * Add data to the diagram either from GPX or GeoJSON and update the axis domain and data
@@ -1885,6 +1911,22 @@
1885
1911
  }
1886
1912
  },
1887
1913
 
1914
+ /**
1915
+ * TODO: Create a base class to handle custom data attributes (heart rate, cadence, temperature, ...)
1916
+ *
1917
+ * @link https://leafletjs.com/examples/extending/extending-3-controls.html#handlers
1918
+ */
1919
+ // addHandler: function (name, HandlerClass) {
1920
+ // if (HandlerClass) {
1921
+ // let handler = this[name] = new HandlerClass(this);
1922
+ // this.handlers.push(handler);
1923
+ // if (this.options[name]) {
1924
+ // handler.enable();
1925
+ // }
1926
+ // }
1927
+ // return this;
1928
+ // },
1929
+
1888
1930
  /**
1889
1931
  * Disable chart brushing.
1890
1932
  */
@@ -1932,7 +1974,7 @@
1932
1974
  },
1933
1975
 
1934
1976
  /**
1935
- * Get default zoom level when "followMarker" is true.
1977
+ * Get default zoom level (followMarker: true).
1936
1978
  */
1937
1979
  getZFollow: function getZFollow() {
1938
1980
  return this.options.zFollow;
@@ -1954,14 +1996,13 @@
1954
1996
  this._markers = L.featureGroup();
1955
1997
  this._markedSegments = L.polyline([]);
1956
1998
  this._chartEnabled = true, this.track_info = {};
1999
+ this.handlers = [];
1957
2000
  L.setOptions(this, options);
1958
2001
  if (this.options.followMarker) this._setMapView = L.Util.throttle(this._setMapView, 300, this);
1959
2002
  if (this.options.legend) this.options.margins.bottom += 30;
1960
2003
  if (this.options.theme) this.options.polylineSegments.className += ' ' + this.options.theme;
1961
2004
  if (this.options.wptIcons === true) this.options.wptIcons = Options.wptIcons;
1962
- if (this.options.distanceMarkers === true) this.options.distanceMarkers = {
1963
- lazy: true
1964
- };
2005
+ if (this.options.distanceMarkers === true) this.options.distanceMarkers = Options.distanceMarkers;
1965
2006
 
1966
2007
  this._markedSegments.setStyle(this.options.polylineSegments); // Leaflet canvas renderer colors
1967
2008
 
@@ -2015,7 +2056,7 @@
2015
2056
  },
2016
2057
 
2017
2058
  /**
2018
- * Load elevation data (GPX, GeoJSON or KML).
2059
+ * Load elevation data (GPX, GeoJSON, KML or TCX).
2019
2060
  */
2020
2061
  load: function load(data) {
2021
2062
  var _this3 = this;
@@ -2089,7 +2130,7 @@
2089
2130
  },
2090
2131
 
2091
2132
  /**
2092
- * Set default zoom level when "followMarker" is true.
2133
+ * Set default zoom level (followMarker: true).
2093
2134
  */
2094
2135
  setZFollow: function setZFollow(zoom) {
2095
2136
  this.options.zFollow = zoom;
@@ -2168,26 +2209,24 @@
2168
2209
  hr: null,
2169
2210
  cad: null,
2170
2211
  atemp: null
2171
- }; // "alt" property is generated inside "leaflet"
2172
-
2173
- if ("alt" in point) point.meta.ele = point.alt; // "coordinateProperties" property is generated inside "@tmcw/toGeoJSON"
2212
+ }; // "coordinateProperties" property is generated inside "@tmcw/toGeoJSON"
2174
2213
 
2175
2214
  var props = properties && properties.coordinateProperties || properties;
2176
2215
 
2177
- if (props) {
2178
- if ("coordTimes" in props) point.meta.time = new Date(Date.parse(props.coordTimes[i]));else if ("times" in props) point.meta.time = new Date(Date.parse(props.times[i]));else if ("time" in props) point.meta.time = new Date(Date.parse(_typeof(props.time) === 'object' ? props.time[i] : props.time));
2179
- if ("heartRates" in props) point.meta.hr = parseInt(props.heartRates[i]);else if ("heartRate" in props) point.meta.hr = parseInt(_typeof(props.heartRate) === 'object' ? props.heartRate[i] : props.heartRate);else if ("heart" in props) point.meta.hr = parseInt(_typeof(props.heart) === 'object' ? props.heart[i] : props.heart); // TODO: ask to "@tmcw/toGeoJSON" for "cadence" and "temperature" implementation
2180
- }
2216
+ _this6.fire("elepoint_init", {
2217
+ point: point,
2218
+ props: props,
2219
+ id: i
2220
+ });
2181
2221
 
2182
2222
  _this6._addPoint((_point$lat = point.lat) !== null && _point$lat !== void 0 ? _point$lat : point[1], (_point$lng = point.lng) !== null && _point$lng !== void 0 ? _point$lng : point[0], (_ref = (_point$alt = point.alt) !== null && _point$alt !== void 0 ? _point$alt : point.meta.ele) !== null && _ref !== void 0 ? _ref : point[2]);
2183
2223
 
2184
- _this6._fireEvt("elepoint_added", {
2224
+ _this6.fire("elepoint_added", {
2185
2225
  point: point,
2186
2226
  index: _this6._data.length - 1
2187
2227
  });
2188
2228
  });
2189
-
2190
- this._fireEvt("eletrack_added", {
2229
+ this.fire("eletrack_added", {
2191
2230
  coords: coords,
2192
2231
  index: this._data.length - 1
2193
2232
  });
@@ -2210,7 +2249,7 @@
2210
2249
  latlng: L.latLng(x, y, z)
2211
2250
  });
2212
2251
 
2213
- this._fireEvt("eledata_updated", {
2252
+ this.fire("eledata_updated", {
2214
2253
  index: this._data.length - 1
2215
2254
  });
2216
2255
  },
@@ -2419,7 +2458,7 @@
2419
2458
  },
2420
2459
 
2421
2460
  /**
2422
- * Generate "svg" chart DOM element.
2461
+ * Generate "svg" chart (DOM element).
2423
2462
  */
2424
2463
  _initChart: function _initChart(container) {
2425
2464
  var opts = this.options;
@@ -2445,13 +2484,10 @@
2445
2484
  this._x = this._chart._x;
2446
2485
  this._y = this._chart._y;
2447
2486
  d3.select(container).call(chart.render());
2448
- chart.on('reset_drag', this._hideMarker, this).on('mouse_enter', this._fireEvt.bind('elechart_enter'), this).on('dragged', this._dragendHandler, this).on('mouse_move', this._mousemoveHandler, this).on('mouse_out', this._mouseoutHandler, this).on('ruler_filter', this._rulerFilterHandler, this).on('zoom', this._updateChart, this).on('elepath_toggle', this._toggleChartHandler, this).on('margins_updated', this._resizeChart, this);
2449
-
2450
- this._fireEvt("elechart_axis");
2451
-
2452
- if (this.options.legend) this._fireEvt("elechart_legend");
2453
-
2454
- this._fireEvt("elechart_init");
2487
+ chart.on('reset_drag', this._hideMarker, this).on('mouse_enter', this._mouseenterHandler, this).on('dragged', this._dragendHandler, this).on('mouse_move', this._mousemoveHandler, this).on('mouse_out', this._mouseoutHandler, this).on('ruler_filter', this._rulerFilterHandler, this).on('zoom', this._updateChart, this).on('elepath_toggle', this._toggleChartHandler, this).on('margins_updated', this._resizeChart, this);
2488
+ this.fire("elechart_axis");
2489
+ if (this.options.legend) this.fire("elechart_legend");
2490
+ this.fire("elechart_init");
2455
2491
  },
2456
2492
  _initLayer: function _initLayer() {
2457
2493
  var _this10 = this;
@@ -2483,8 +2519,7 @@
2483
2519
  }).addTo(this._map); // default leaflet svg renderer
2484
2520
 
2485
2521
  this._marker = new Marker(this.options);
2486
-
2487
- this._fireEvt("elechart_marker");
2522
+ this.fire("elechart_marker");
2488
2523
  },
2489
2524
 
2490
2525
  /**
@@ -2648,8 +2683,14 @@
2648
2683
  this._hideMarker();
2649
2684
 
2650
2685
  this.fitBounds(L.latLngBounds([e.dragstart.latlng, e.dragend.latlng]));
2686
+ this.fire("elechart_dragged");
2687
+ },
2651
2688
 
2652
- this._fireEvt("elechart_dragged");
2689
+ /**
2690
+ * Trigger mouseenter event
2691
+ */
2692
+ _mouseenterHandler: function _mouseenterHandler(e) {
2693
+ this.fire('elechart_enter');
2653
2694
  },
2654
2695
 
2655
2696
  /*
@@ -2674,12 +2715,11 @@
2674
2715
  addClass(this._map.getContainer(), 'elechart-hover');
2675
2716
  }
2676
2717
 
2677
- this._fireEvt("elechart_change", {
2718
+ this.fire("elechart_change", {
2678
2719
  data: item,
2679
2720
  xCoord: xCoord
2680
2721
  });
2681
-
2682
- this._fireEvt("elechart_hover", {
2722
+ this.fire("elechart_hover", {
2683
2723
  data: item,
2684
2724
  xCoord: xCoord
2685
2725
  });
@@ -2702,7 +2742,7 @@
2702
2742
 
2703
2743
  this._updateMarker(item);
2704
2744
 
2705
- this._fireEvt("elechart_change", {
2745
+ this.fire("elechart_change", {
2706
2746
  data: item,
2707
2747
  xCoord: xCoord
2708
2748
  });
@@ -2723,7 +2763,7 @@
2723
2763
  removeClass(this._map.getContainer(), 'elechart-hover');
2724
2764
  }
2725
2765
 
2726
- this._fireEvt("elechart_leave");
2766
+ this.fire("elechart_leave");
2727
2767
  },
2728
2768
 
2729
2769
  /**
@@ -2829,46 +2869,97 @@
2829
2869
  },
2830
2870
 
2831
2871
  /**
2832
- * Add a point of interest over the diagram
2872
+ * Add chart profile to diagram
2833
2873
  */
2834
- _registerCheckPoint: function _registerCheckPoint(props) {
2874
+ _registerAreaPath: function _registerAreaPath(props) {
2835
2875
  var _this13 = this;
2836
2876
 
2837
- this.on("elechart_updated", function () {
2838
- return _this13._chart._registerCheckPoint(props);
2877
+ this.on("elechart_init", function () {
2878
+ return _this13._chart._registerAreaPath(props);
2839
2879
  });
2840
2880
  },
2841
2881
 
2842
2882
  /**
2843
- * Add chart profile to diagram
2883
+ * Add chart grid to diagram
2844
2884
  */
2845
- _registerAreaPath: function _registerAreaPath(props) {
2885
+ _registerAxisGrid: function _registerAxisGrid(props) {
2846
2886
  var _this14 = this;
2847
2887
 
2848
- this.on("elechart_init", function () {
2849
- return _this14._chart._registerAreaPath(props);
2888
+ this.on("elechart_axis", function () {
2889
+ return _this14._chart._registerAxisGrid(props);
2850
2890
  });
2851
2891
  },
2852
2892
 
2853
2893
  /**
2854
- * Add chart grid to diagram
2894
+ * Add chart axis to diagram
2855
2895
  */
2856
- _registerAxisGrid: function _registerAxisGrid(props) {
2896
+ _registerAxisScale: function _registerAxisScale(props) {
2857
2897
  var _this15 = this;
2858
2898
 
2859
2899
  this.on("elechart_axis", function () {
2860
- return _this15._chart._registerAxisGrid(props);
2900
+ return _this15._chart._registerAxisScale(props);
2861
2901
  });
2862
2902
  },
2863
2903
 
2864
2904
  /**
2865
- * Add chart axis to diagram
2905
+ * Add a point of interest over the diagram
2866
2906
  */
2867
- _registerAxisScale: function _registerAxisScale(props) {
2907
+ _registerCheckPoint: function _registerCheckPoint(props) {
2868
2908
  var _this16 = this;
2869
2909
 
2870
- this.on("elechart_axis", function () {
2871
- return _this16._chart._registerAxisScale(props);
2910
+ this.on("elechart_updated", function () {
2911
+ return _this16._chart._registerCheckPoint(props);
2912
+ });
2913
+ },
2914
+
2915
+ /**
2916
+ * Base handler for iterative track statistics (dist, time, z, slope, speed, acceleration, ...)
2917
+ */
2918
+ _registerDataAttribute: function _registerDataAttribute(props) {
2919
+ var _this17 = this;
2920
+
2921
+ // save here a reference to last used point
2922
+ var lastValid = null; // parse of "coordinateProperties" for later usage
2923
+
2924
+ if (props.init) {
2925
+ this.on("elepoint_init", function (e) {
2926
+ return props.init.call(_this17, e);
2927
+ });
2928
+ } // iteration
2929
+
2930
+
2931
+ this.on("elepoint_added", function (e) {
2932
+ // check and fix missing data on last added point
2933
+ if (props.skipNull === false) {
2934
+ var curr = _this17._data[e.index][props.name];
2935
+
2936
+ if (e.index > 0) {
2937
+ var prev = _this17._data[e.index - 1][props.name];
2938
+
2939
+ if (isNaN(prev)) {
2940
+ if (!isNaN(lastValid) && !isNaN(curr)) {
2941
+ prev = (lastValid + curr) / 2;
2942
+ } else if (!isNaN(lastValid)) {
2943
+ prev = lastValid;
2944
+ } else if (!isNaN(curr)) {
2945
+ prev = curr;
2946
+ }
2947
+
2948
+ if (!isNaN(prev)) return _this17._data.splice(e.index - 1, 1);
2949
+ _this17._data[e.index - 1][props.name] = prev;
2950
+ }
2951
+ } // update reference to last used point (ie. if it has data)
2952
+
2953
+
2954
+ if (!isNaN(curr)) {
2955
+ lastValid = curr;
2956
+ }
2957
+ } // retrieve point value
2958
+
2959
+
2960
+ _this17._data[e.index][props.name] = props.fetch.call(_this17, e.index, e.point); // update here some mixins (eg. "track_info", value validators, ...)
2961
+
2962
+ if (props.update) _this17._data[e.index][props.name] = props.update.call(_this17, _this17._data[e.index][props.name], e.index, e.point);
2872
2963
  });
2873
2964
  },
2874
2965
 
@@ -2876,14 +2967,14 @@
2876
2967
  * Add chart or marker tooltip info
2877
2968
  */
2878
2969
  _registerTooltip: function _registerTooltip(props) {
2879
- var _this17 = this;
2970
+ var _this18 = this;
2880
2971
 
2881
2972
  if (props.chart) {
2882
2973
  var label = L.extend({}, props, {
2883
2974
  value: props.chart
2884
2975
  });
2885
2976
  this.on("elechart_init", function () {
2886
- return _this17._chart._registerTooltip(label);
2977
+ return _this18._chart._registerTooltip(label);
2887
2978
  });
2888
2979
  }
2889
2980
 
@@ -2893,7 +2984,7 @@
2893
2984
  });
2894
2985
 
2895
2986
  this.on("elechart_marker", function () {
2896
- return _this17._marker._registerTooltip(_label);
2987
+ return _this18._marker._registerTooltip(_label);
2897
2988
  });
2898
2989
  }
2899
2990
  },
@@ -2902,10 +2993,10 @@
2902
2993
  * Add summary info to diagram
2903
2994
  */
2904
2995
  _registerSummary: function _registerSummary(props) {
2905
- var _this18 = this;
2996
+ var _this19 = this;
2906
2997
 
2907
2998
  this.on('elechart_summary', function () {
2908
- return _this18._summary._registerSummary(props);
2999
+ return _this19._summary._registerSummary(props);
2909
3000
  });
2910
3001
  },
2911
3002
 
@@ -2977,14 +3068,14 @@
2977
3068
  },
2978
3069
 
2979
3070
  /**
2980
- * Collapse or Expand current chart control.
3071
+ * Collapse or Expand chart control.
2981
3072
  */
2982
3073
  _toggle: function _toggle() {
2983
3074
  if (hasClass(this._container, "elevation-expanded")) this._collapse();else this._expand();
2984
3075
  },
2985
3076
 
2986
3077
  /**
2987
- * Sets the view of the map (center and zoom). Useful when "followMarker" is true.
3078
+ * Update map center and zoom (followMarker: true)
2988
3079
  */
2989
3080
  _setMapView: function _setMapView(item) {
2990
3081
  if (!this.options.followMarker || !this._map) return;
@@ -3010,14 +3101,14 @@
3010
3101
  * Toggle chart data on legend click
3011
3102
  */
3012
3103
  _toggleChartHandler: function _toggleChartHandler(e) {
3013
- var _this19 = this;
3104
+ var _this20 = this;
3014
3105
 
3015
3106
  var name = e.name,
3016
3107
  enabled = e.enabled;
3017
3108
  this._chartEnabled = this._chart._hasActiveLayers(); // toggle layer visibility on empty chart
3018
3109
 
3019
3110
  this._layers.eachLayer(function (layer) {
3020
- return toggleClass(layer.getElement && layer.getElement(), _this19.options.polyline.className + ' ' + _this19.options.theme, _this19._chartEnabled);
3111
+ return toggleClass(layer.getElement && layer.getElement(), _this20.options.polyline.className + ' ' + _this20.options.theme, _this20._chartEnabled);
3021
3112
  }); // toggle option value (eg. altitude = { 'disabled' || 'disabled' })
3022
3113
 
3023
3114
 
@@ -3037,10 +3128,8 @@
3037
3128
  if (
3038
3129
  /*!this._data.length ||*/
3039
3130
  !this._chart || !this._container) return;
3040
-
3041
- this._fireEvt("elechart_axis");
3042
-
3043
- this._fireEvt("elechart_area");
3131
+ this.fire("elechart_axis");
3132
+ this.fire("elechart_area");
3044
3133
 
3045
3134
  this._chart.update({
3046
3135
  data: this._data,
@@ -3049,8 +3138,7 @@
3049
3138
 
3050
3139
  this._x = this._chart._x;
3051
3140
  this._y = this._chart._y;
3052
-
3053
- this._fireEvt('elechart_updated');
3141
+ this.fire('elechart_updated');
3054
3142
  },
3055
3143
 
3056
3144
  /*
@@ -3091,12 +3179,14 @@
3091
3179
  * Update chart summary.
3092
3180
  */
3093
3181
  _updateSummary: function _updateSummary() {
3094
- var _this20 = this;
3182
+ var _this21 = this;
3095
3183
 
3096
3184
  this._summary.reset();
3097
3185
 
3098
3186
  if (this.options.summary) {
3099
- this._fireEvt("elechart_summary");
3187
+ this.fire("elechart_summary");
3188
+
3189
+ this._summary.update();
3100
3190
  }
3101
3191
 
3102
3192
  if (this.options.downloadLink && this._downloadURL) {
@@ -3106,19 +3196,19 @@
3106
3196
  select('.download a', this._summary._container).onclick = function (e) {
3107
3197
  e.preventDefault();
3108
3198
  var event = {
3109
- downloadLink: _this20.options.downloadLink,
3110
- confirm: saveFile.bind(_this20, _this20._downloadURL)
3199
+ downloadLink: _this21.options.downloadLink,
3200
+ confirm: saveFile.bind(_this21, _this21._downloadURL)
3111
3201
  };
3112
3202
 
3113
- if (_this20.options.downloadLink == 'modal' && typeof CustomEvent === "function") {
3203
+ if (_this21.options.downloadLink == 'modal' && typeof CustomEvent === "function") {
3114
3204
  document.dispatchEvent(new CustomEvent("eletrack_download", {
3115
3205
  detail: event
3116
3206
  }));
3117
- } else if (_this20.options.downloadLink == 'link' || _this20.options.downloadLink === true) {
3207
+ } else if (_this21.options.downloadLink == 'link' || _this21.options.downloadLink === true) {
3118
3208
  event.confirm();
3119
3209
  }
3120
3210
 
3121
- _this20._fireEvt('eletrack_download', event);
3211
+ _this21.fire('eletrack_download', event);
3122
3212
  };
3123
3213
  }
3124
3214
  },
@@ -3150,119 +3240,8 @@
3150
3240
  });
3151
3241
 
3152
3242
  Elevation.addInitHook(function () {
3153
- var opts = this.options;
3154
- var altitude = {};
3155
-
3156
- if (opts.imperial) {
3157
- opts.altitudeFactor = this.__footFactor;
3158
- altitude.label = "ft";
3159
- } else {
3160
- opts.altitudeFactor = opts.heightFactor || opts.altitudeFactor || 1;
3161
- altitude.label = opts.yLabel;
3162
- }
3163
-
3164
- this.on("eledata_updated", function (e) {
3165
- var data = this._data;
3166
- var i = e.index;
3167
- var z = data[i].z * opts.altitudeFactor;
3168
- var track = this.track_info;
3169
- var zMax = track.elevation_max || -Infinity;
3170
- var zMin = track.elevation_min || +Infinity; // check and fix missing elevation data on last added point
3171
-
3172
- if (!this.options.skipNullZCoords && i > 0) {
3173
- var prevZ = data[i - 1].z;
3174
-
3175
- if (isNaN(prevZ)) {
3176
- var lastZ = this._lastValidZ;
3177
- var currZ = z;
3178
-
3179
- if (!isNaN(lastZ) && !isNaN(currZ)) {
3180
- prevZ = (lastZ + currZ) / 2;
3181
- } else if (!isNaN(lastZ)) {
3182
- prevZ = lastZ;
3183
- } else if (!isNaN(currZ)) {
3184
- prevZ = currZ;
3185
- }
3186
-
3187
- if (!isNaN(prevZ)) return data.splice(i - 1, 1);
3188
- data[i - 1].z = prevZ;
3189
- }
3190
- } // skip point if it has not elevation
3191
-
3192
-
3193
- if (!isNaN(z)) {
3194
- this._lastValidZ = z;
3195
- }
3196
-
3197
- track.elevation_max = z > zMax ? z : zMax;
3198
- track.elevation_min = z < zMin ? z : zMin;
3199
- data[i].z = z;
3200
- });
3201
- this.on("elechart_axis", function () {
3202
- this._chart._registerAxisGrid({
3203
- axis: "y",
3204
- position: "left",
3205
- scale: this._chart._y
3206
- });
3207
- });
3208
-
3209
- if (this.options.altitude != "summary") {
3210
- this.on("elechart_axis", function () {
3211
- this._chart._registerAxisScale({
3212
- axis: "y",
3213
- position: "left",
3214
- scale: this._chart._y,
3215
- label: altitude.label,
3216
- labelX: -3,
3217
- labelY: -8,
3218
- name: "altitude"
3219
- });
3220
- });
3221
- this.on("elechart_init", function () {
3222
- var theme = this.options.theme.replace('-theme', '');
3223
- var color = Colors[theme] || {};
3224
-
3225
- this._chart._registerAreaPath({
3226
- name: 'altitude',
3227
- label: 'Altitude',
3228
- scaleX: 'distance',
3229
- scaleY: 'altitude',
3230
- color: color.area || theme,
3231
- strokeColor: this.options.detached ? color.stroke : '#000',
3232
- strokeOpacity: "1",
3233
- fillOpacity: this.options.detached ? color.alpha || '0.8' : 1,
3234
- preferCanvas: this.options.preferCanvas
3235
- });
3236
- });
3237
- }
3238
-
3239
- this._registerTooltip({
3240
- name: 'y',
3241
- chart: function chart(item) {
3242
- return L._("y: ") + d3.format("." + opts.decimalsY + "f")(item[opts.yAttr]) + " " + altitude.label;
3243
- },
3244
- marker: function marker(item) {
3245
- return d3.format("." + opts.decimalsY + "f")(item[opts.yAttr]) + " " + altitude.label;
3246
- }
3247
- });
3248
-
3249
- this._registerSummary({
3250
- "maxele": {
3251
- label: "Max Elevation: ",
3252
- value: function value(track) {
3253
- return (track.elevation_max || 0).toFixed(2) + '&nbsp;' + altitude.label;
3254
- }
3255
- },
3256
- "minele": {
3257
- label: "Min Elevation: ",
3258
- value: function value(track) {
3259
- return (track.elevation_min || 0).toFixed(2) + '&nbsp;' + altitude.label;
3260
- }
3261
- }
3262
- });
3263
- });
3243
+ var _this = this;
3264
3244
 
3265
- Elevation.addInitHook(function () {
3266
3245
  var opts = this.options;
3267
3246
  var distance = {};
3268
3247
 
@@ -3274,50 +3253,49 @@
3274
3253
  distance.label = opts.xLabel;
3275
3254
  }
3276
3255
 
3277
- this.on("eledata_updated", function (e) {
3278
- var data = this._data;
3279
- var i = e.index;
3280
- var track = this.track_info;
3281
- var dist = track.distance || 0;
3282
- var curr = data[i].latlng;
3283
- var prev = i > 0 ? data[i - 1].latlng : curr;
3284
- var delta = curr.distanceTo(prev) * opts.distanceFactor;
3285
- dist += Math.round(delta / 1000 * 100000) / 100000; // handles floating points calc
3286
-
3287
- track.distance = dist;
3288
- data[i].dist = dist;
3289
- });
3290
- this.on("elechart_axis", function () {
3291
- this._chart._registerAxisGrid({
3292
- axis: "x",
3293
- position: "bottom",
3294
- scale: this._chart._x
3295
- });
3256
+ this._registerDataAttribute({
3257
+ name: 'dist',
3258
+ init: function init() {// this.track_info.distance = 0;
3259
+ },
3260
+ fetch: function fetch(i) {
3261
+ var delta = _this._data[i].latlng.distanceTo(_this._data[i > 0 ? i - 1 : i].latlng) * opts.distanceFactor;
3262
+ return Math.round(delta / 1000 * 100000) / 100000; // handles floating points calc
3263
+ },
3264
+ update: function update(distance) {
3265
+ _this.track_info.distance = _this.track_info.distance || 0;
3266
+ _this.track_info.distance += distance;
3267
+ return _this.track_info.distance;
3268
+ }
3296
3269
  });
3297
3270
 
3298
3271
  if (this.options.distance != "summary") {
3299
- this.on("elechart_axis", function () {
3300
- var _this = this;
3301
-
3302
- this._chart._registerAxisScale({
3303
- axis: "x",
3304
- position: "bottom",
3305
- scale: this._chart._x,
3306
- label: distance.label,
3307
- labelY: 25,
3308
- labelX: function labelX() {
3309
- return _this._width() + 6;
3310
- },
3311
- name: "distance"
3312
- });
3272
+ this._registerAxisScale({
3273
+ axis: "x",
3274
+ position: "bottom",
3275
+ scale: "x",
3276
+ // this._chart._x,
3277
+ label: distance.label,
3278
+ labelY: 25,
3279
+ labelX: function labelX() {
3280
+ return _this._width() + 6;
3281
+ },
3282
+ name: "distance"
3313
3283
  });
3314
3284
  }
3315
3285
 
3286
+ this._registerAxisGrid({
3287
+ axis: "x",
3288
+ position: "bottom",
3289
+ scale: "x" // this._chart._x,
3290
+
3291
+ });
3292
+
3316
3293
  this._registerTooltip({
3317
3294
  name: 'x',
3318
3295
  chart: function chart(item) {
3319
3296
  return L._("x: ") + d3.format("." + opts.decimalsX + "f")(item[opts.xAttr]) + " " + distance.label;
3320
- }
3297
+ },
3298
+ order: 20
3321
3299
  });
3322
3300
 
3323
3301
  this._registerSummary({
@@ -3325,7 +3303,8 @@
3325
3303
  label: "Total Length: ",
3326
3304
  value: function value(track) {
3327
3305
  return (track.distance || 0).toFixed(2) + '&nbsp;' + distance.label;
3328
- }
3306
+ },
3307
+ order: 10
3329
3308
  }
3330
3309
  });
3331
3310
  });
@@ -3341,7 +3320,7 @@
3341
3320
  * Common AVG speeds:
3342
3321
  * ----------------------
3343
3322
  * slow walk = 1.8 km/h
3344
- * walking = 3.6 km/h
3323
+ * walking = 3.6 km/h <-- default: 3.6
3345
3324
  * running = 10.8 km/h
3346
3325
  * cycling = 18 km/h
3347
3326
  * driving = 72 km/h
@@ -3368,6 +3347,50 @@
3368
3347
  return formatTime(t).split("'")[0];
3369
3348
  };
3370
3349
 
3350
+ this._registerDataAttribute({
3351
+ name: 'time',
3352
+ init: function init(_ref) {
3353
+ var point = _ref.point,
3354
+ props = _ref.props,
3355
+ id = _ref.id;
3356
+
3357
+ // "coordinateProperties" property is generated inside "@tmcw/toGeoJSON"
3358
+ if (props) {
3359
+ if ("coordTimes" in props) point.meta.time = new Date(Date.parse(props.coordTimes[id]));else if ("times" in props) point.meta.time = new Date(Date.parse(props.times[id]));else if ("time" in props) point.meta.time = new Date(Date.parse(_typeof(props.time) === 'object' ? props.time[id] : props.time));
3360
+ }
3361
+ },
3362
+ fetch: function fetch(i, point) {
3363
+ // Add missing timestamps (see: options.timeAVGSpeed)
3364
+ if (!point.meta || !point.meta.time) {
3365
+ point.meta = point.meta || {};
3366
+
3367
+ if (i > 0) {
3368
+ var dx = this._data[i].dist - this._data[i - 1].dist;
3369
+
3370
+ var t0 = this._data[i - 1].time.getTime();
3371
+
3372
+ var dt = dx / this._timeAVGSpeed * this.options.timeFactor * 1000;
3373
+ point.meta.time = new Date(t0 + dt);
3374
+ } else {
3375
+ point.meta.time = new Date(Date.now());
3376
+ }
3377
+ }
3378
+
3379
+ var time = point.meta.time; // Handle timezone offset
3380
+
3381
+ if (time.getTime() - time.getTimezoneOffset() * 60 * 1000 === 0) {
3382
+ time = 0;
3383
+ }
3384
+
3385
+ return time;
3386
+ },
3387
+ update: function update(time, i) {
3388
+ this.track_info.time = (this.track_info.time || 0) + Math.abs(this._data[i].time - this._data[i > 0 ? i - 1 : i].time);
3389
+ this._data[i].duration = this.track_info.time;
3390
+ return time;
3391
+ }
3392
+ });
3393
+
3371
3394
  if (opts.time && opts.time != "summary" && !L.Browser.mobile) {
3372
3395
  this._registerAxisScale({
3373
3396
  axis: "x",
@@ -3393,38 +3416,13 @@
3393
3416
  });
3394
3417
  }
3395
3418
 
3396
- this.on('elepoint_added', function (e) {
3397
- var data = this._data;
3398
- var i = e.index; // Add missing timestamps (see: options.timeAVGSpeed)
3399
-
3400
- if (!e.point.meta || !e.point.meta.time) {
3401
- e.point.meta = e.point.meta || {};
3402
- var delta = data[i].dist - data[i > 0 ? i - 1 : i].dist;
3403
- var speed = this._timeAVGSpeed;
3404
- e.point.meta.time = new Date(i > 0 ? data[i - 1].time.getTime() + delta / speed * opts.timeFactor * 1000 : Date.now());
3405
- }
3406
-
3407
- var time = e.point.meta.time; // Handle timezone offset
3408
-
3409
- if (time.getTime() - time.getTimezoneOffset() * 60 * 1000 === 0) {
3410
- time = 0;
3411
- }
3412
-
3413
- var currT = time;
3414
- var prevT = i > 0 ? data[i - 1].time : currT;
3415
- var deltaT = Math.abs(currT - prevT);
3416
- var duration = (this.track_info.time || 0) + deltaT;
3417
- this.track_info.time = duration;
3418
- data[i].time = time;
3419
- data[i].duration = duration;
3420
- });
3421
-
3422
3419
  if (this.options.timestamps) {
3423
3420
  this._registerTooltip({
3424
3421
  name: 'date',
3425
3422
  chart: function chart(item) {
3426
3423
  return L._("t: ") + _this.options.timeFormat(item.time);
3427
- }
3424
+ },
3425
+ order: 20
3428
3426
  });
3429
3427
  }
3430
3428
 
@@ -3433,7 +3431,8 @@
3433
3431
  name: 'time',
3434
3432
  chart: function chart(item) {
3435
3433
  return L._("T: ") + formatTime(item.duration || 0);
3436
- }
3434
+ },
3435
+ order: 20
3437
3436
  });
3438
3437
 
3439
3438
  this._registerSummary({
@@ -3441,7 +3440,8 @@
3441
3440
  label: "Total Time: ",
3442
3441
  value: function value(track) {
3443
3442
  return formatTime(track.time || 0);
3444
- }
3443
+ },
3444
+ order: 20
3445
3445
  }
3446
3446
  });
3447
3447
  }
@@ -3450,80 +3450,208 @@
3450
3450
  Elevation.addInitHook(function () {
3451
3451
  var _this = this;
3452
3452
 
3453
- if (!this.options.slope) return;
3454
3453
  var opts = this.options;
3455
- var slope = {};
3456
- slope.label = opts.slopeLabel || '%';
3454
+ var altitude = {};
3455
+ var theme = opts.theme.replace('-theme', '');
3456
+ var color = Colors[theme] || {};
3457
3457
 
3458
- if (this.options.slope != "summary") {
3459
- this._registerAxisScale({
3460
- axis: "y",
3461
- position: "right",
3462
- scale: {
3463
- min: -1,
3464
- max: +1
3458
+ if (opts.imperial) {
3459
+ opts.altitudeFactor = this.__footFactor;
3460
+ altitude.label = "ft";
3461
+ } else {
3462
+ opts.altitudeFactor = opts.heightFactor || opts.altitudeFactor || 1;
3463
+ altitude.label = opts.yLabel;
3464
+ }
3465
+
3466
+ this._registerDataAttribute({
3467
+ name: 'z',
3468
+ skipNull: this.options.skipNullZCoords,
3469
+ init: function init(_ref) {
3470
+ var point = _ref.point;
3471
+ // "alt" property is generated inside "leaflet"
3472
+ if ("alt" in point) point.meta.ele = point.alt; // this.track_info.elevation_max = -Infinity;
3473
+ // this.track_info.elevation_min = +Infinity;
3474
+ // this.track_info.elevation_avg = 0;
3475
+ },
3476
+ fetch: function fetch(i) {
3477
+ return _this._data[i].z * opts.altitudeFactor;
3478
+ },
3479
+ update: function update(z, i) {
3480
+ _this.track_info.elevation_max = _this.track_info.elevation_max || -Infinity;
3481
+ _this.track_info.elevation_min = _this.track_info.elevation_max || +Infinity;
3482
+ _this.track_info.elevation_avg = _this.track_info.elevation_avg || 0;
3483
+ var data = _this._data;
3484
+ var track = _this.track_info; // Try to smooth "crazy" elevation values.
3485
+
3486
+ if (_this.options.altitudeDeltaMax) {
3487
+ var delta = z - data[i > 0 ? i - 1 : i].z;
3488
+ var deltaMax = _this.options.altitudeDeltaMax;
3489
+
3490
+ if (Math.abs(delta) > deltaMax) {
3491
+ z = data[i - 1].z + deltaMax * Math.sign(delta);
3492
+ }
3493
+ } // Range of acceptable elevation values.
3494
+
3495
+
3496
+ z = clamp(z, _this.options.altitudeRange);
3497
+ if (z > track.elevation_max) track.elevation_max = z;
3498
+ if (z < track.elevation_min) track.elevation_min = z;
3499
+ track.elevation_avg = (z + track.elevation_avg) / 2.0;
3500
+ return z;
3501
+ }
3502
+ });
3503
+
3504
+ this._registerAxisScale({
3505
+ axis: "y",
3506
+ position: "left",
3507
+ scale: "y",
3508
+ // this._chart._y,
3509
+ label: altitude.label,
3510
+ labelX: -3,
3511
+ labelY: -8,
3512
+ name: "altitude",
3513
+ visbile: this.options.altitude != "summary"
3514
+ });
3515
+
3516
+ this._registerAxisGrid({
3517
+ axis: "y",
3518
+ position: "left",
3519
+ scale: "y" // this._chart._y,
3520
+
3521
+ });
3522
+
3523
+ this._registerAreaPath({
3524
+ name: 'altitude',
3525
+ label: 'Altitude',
3526
+ scaleX: 'distance',
3527
+ scaleY: 'altitude',
3528
+ color: color.area || theme,
3529
+ strokeColor: opts.detached ? color.stroke : '#000',
3530
+ strokeOpacity: "1",
3531
+ fillOpacity: opts.detached ? color.alpha || '0.8' : 1,
3532
+ preferCanvas: opts.preferCanvas,
3533
+ visbile: this.options.altitude != "summary"
3534
+ });
3535
+
3536
+ this._registerTooltip({
3537
+ name: 'y',
3538
+ chart: function chart(item) {
3539
+ return L._("y: ") + d3.format("." + opts.decimalsY + "f")(item[opts.yAttr]) + " " + altitude.label;
3540
+ },
3541
+ marker: function marker(item) {
3542
+ return d3.format("." + opts.decimalsY + "f")(item[opts.yAttr]) + " " + altitude.label;
3543
+ },
3544
+ order: 10
3545
+ });
3546
+
3547
+ this._registerSummary({
3548
+ "maxele": {
3549
+ label: "Max Elevation: ",
3550
+ value: function value(track) {
3551
+ return (track.elevation_max || 0).toFixed(2) + '&nbsp;' + altitude.label;
3465
3552
  },
3466
- tickPadding: 16,
3467
- label: slope.label,
3468
- labelX: 25,
3469
- labelY: -8,
3470
- name: 'slope'
3471
- });
3553
+ order: 30
3554
+ },
3555
+ "minele": {
3556
+ label: "Min Elevation: ",
3557
+ value: function value(track) {
3558
+ return (track.elevation_min || 0).toFixed(2) + '&nbsp;' + altitude.label;
3559
+ },
3560
+ order: 30
3561
+ },
3562
+ "avgele": {
3563
+ label: "Avg Elevation: ",
3564
+ value: function value(track) {
3565
+ return (track.elevation_avg || 0).toFixed(2) + '&nbsp;' + altitude.label;
3566
+ },
3567
+ order: 30
3568
+ }
3569
+ });
3570
+ });
3472
3571
 
3473
- this._registerAreaPath({
3474
- name: 'slope',
3475
- label: 'Slope',
3476
- yAttr: 'slope',
3477
- scaleX: 'distance',
3478
- scaleY: 'slope',
3479
- color: '#F00',
3480
- strokeColor: '#000',
3481
- strokeOpacity: "0.5",
3482
- fillOpacity: "0.25"
3483
- });
3484
- }
3572
+ Elevation.addInitHook(function () {
3573
+ var _this = this;
3485
3574
 
3486
- this.on("eledata_updated", function (e) {
3487
- var data = this._data;
3488
- var i = e.index;
3489
- var z = data[i].z;
3490
- var delta = (data[i].dist - data[i > 0 ? i - 1 : i].dist) * 1000; // Slope / Gain
3575
+ if (!this.options.slope) return;
3576
+ var opts = this.options;
3577
+ var slope = {};
3578
+ slope.label = opts.slopeLabel || '%';
3491
3579
 
3492
- var track = this.track_info;
3493
- var tAsc = track.ascent || 0; // Total Ascent
3580
+ this._registerDataAttribute({
3581
+ name: 'slope',
3582
+ // init: () => {
3583
+ // // this.track_info.ascent = 0; // Total Ascent
3584
+ // // this.track_info.descent = 0; // Total Descent
3585
+ // // this.track_info.slope_max = -Infinity; // Slope Max
3586
+ // // this.track_info.slope_min = +Infinity; // Slope Min
3587
+ // // this.track_info.slope_avg = 0; // Acceleration Avg
3588
+ // },
3589
+ fetch: function fetch(i) {
3590
+ var data = _this._data;
3591
+ var dx = (data[i].dist - data[i > 0 ? i - 1 : i].dist) * 1000;
3592
+ var dz = data[i].z - data[i > 0 ? i - 1 : i].z;
3593
+ return !isNaN(dz) && dx !== 0 ? dz / dx * 100 : 0; // slope in % = ( height / length ) * 100;
3594
+ },
3595
+ update: function update(slope, i) {
3596
+ _this.track_info.ascent = _this.track_info.ascent || 0; // Total Ascent
3494
3597
 
3495
- var tDes = track.descent || 0; // Total Descent
3598
+ _this.track_info.descent = _this.track_info.descent || 0; // Total Descent
3496
3599
 
3497
- var sMax = track.slope_max || 0; // Slope Max
3600
+ _this.track_info.slope_max = _this.track_info.slope_max || -Infinity; // Slope Max
3498
3601
 
3499
- var sMin = track.slope_min || 0; // Slope Min
3602
+ _this.track_info.slope_min = _this.track_info.slope_min || +Infinity; // Slope Min
3500
3603
 
3501
- var slope = 0;
3604
+ _this.track_info.slope_avg = _this.track_info.slope_avg || 0; // Acceleration Avg
3502
3605
 
3503
- if (!isNaN(z)) {
3504
- var deltaZ = i > 0 ? z - data[i - 1].z : 0;
3505
- if (deltaZ > 0) tAsc += deltaZ;else if (deltaZ < 0) tDes -= deltaZ; // slope in % = ( height / length ) * 100
3606
+ var track = _this.track_info;
3607
+ var data = _this._data;
3608
+ var dz = data[i].z - data[i > 0 ? i - 1 : i].z; // Try to smooth "crazy" acceleration values.
3506
3609
 
3507
- if (delta !== 0) slope = deltaZ / delta * 100;
3508
- } // Try to smooth "crazy" slope values.
3610
+ if (_this.options.slopeDeltaMax) {
3611
+ var delta = slop - data[i > 0 ? i - 1 : i].slope;
3612
+ var deltaMax = _this.options.slopeDeltaMax;
3509
3613
 
3614
+ if (Math.abs(delta) > deltaMax) {
3615
+ slope = data[i - 1].slope + deltaMax * Math.sign(delta);
3616
+ }
3617
+ } // Range of acceptable slope values.
3510
3618
 
3511
- if (this.options.sDeltaMax) {
3512
- var deltaS = i > 0 ? slope - data[i - 1].slope : 0;
3513
- var maxDeltaS = this.options.sDeltaMax;
3514
3619
 
3515
- if (Math.abs(deltaS) > maxDeltaS) {
3516
- slope = data[i - 1].slope + maxDeltaS * Math.sign(deltaS);
3517
- }
3518
- } // Range of acceptable slope values.
3620
+ slope = clamp(slope, _this.options.slopeRange);
3621
+ if (dz > 0) _this.track_info.ascent += dz;else if (dz < 0) _this.track_info.descent -= dz;
3622
+ if (slope > track.slope_max) track.slope_max = slope;
3623
+ if (slope < track.slope_min) track.slope_min = slope;
3624
+ track.slope_avg = (slope + track.slope_avg) / 2.0;
3625
+ return L.Util.formatNum(slope, 2);
3626
+ }
3627
+ });
3519
3628
 
3629
+ this._registerAxisScale({
3630
+ axis: "y",
3631
+ position: "right",
3632
+ scale: {
3633
+ min: -1,
3634
+ max: +1
3635
+ },
3636
+ tickPadding: 16,
3637
+ label: slope.label,
3638
+ labelX: 25,
3639
+ labelY: -8,
3640
+ name: 'slope',
3641
+ visbile: this.options.slope != "summary"
3642
+ });
3520
3643
 
3521
- slope = clamp(slope, this.options.sRange);
3522
- track.ascent = tAsc;
3523
- track.descent = tDes;
3524
- track.slope_max = slope > sMax ? slope : sMax;
3525
- track.slope_min = slope < sMin ? slope : sMin;
3526
- data[i].slope = L.Util.formatNum(slope, 2);
3644
+ this._registerAreaPath({
3645
+ name: 'slope',
3646
+ label: 'Slope',
3647
+ yAttr: 'slope',
3648
+ scaleX: 'distance',
3649
+ scaleY: 'slope',
3650
+ color: '#F00',
3651
+ strokeColor: '#000',
3652
+ strokeOpacity: "0.5",
3653
+ fillOpacity: "0.25",
3654
+ visbile: this.options.slope != "summary"
3527
3655
  });
3528
3656
 
3529
3657
  this._registerTooltip({
@@ -3533,7 +3661,8 @@
3533
3661
  },
3534
3662
  marker: function marker(item) {
3535
3663
  return Math.round(item.slope) + slope.label;
3536
- }
3664
+ },
3665
+ order: 40
3537
3666
  });
3538
3667
 
3539
3668
  this._registerSummary({
@@ -3541,36 +3670,89 @@
3541
3670
  label: "Total Ascent: ",
3542
3671
  value: function value(track) {
3543
3672
  return Math.round(track.ascent || 0) + '&nbsp;' + (_this.options.imperial ? 'ft' : 'm');
3544
- }
3673
+ },
3674
+ order: 40
3545
3675
  },
3546
3676
  "descent": {
3547
3677
  label: "Total Descent: ",
3548
3678
  value: function value(track) {
3549
3679
  return Math.round(track.descent || 0) + '&nbsp;' + (_this.options.imperial ? 'ft' : 'm');
3550
- }
3680
+ },
3681
+ order: 40
3551
3682
  },
3552
3683
  "minslope": {
3553
3684
  label: "Min Slope: ",
3554
3685
  value: function value(track) {
3555
3686
  return Math.round(track.slope_min || 0) + '&nbsp;' + slope.label;
3556
- }
3687
+ },
3688
+ order: 40
3557
3689
  },
3558
3690
  "maxslope": {
3559
3691
  label: "Max Slope: ",
3560
3692
  value: function value(track) {
3561
3693
  return Math.round(track.slope_max || 0) + '&nbsp;' + slope.label;
3562
- }
3694
+ },
3695
+ order: 40
3696
+ },
3697
+ "avgslope": {
3698
+ label: "Avg Slope: ",
3699
+ value: function value(track) {
3700
+ return Math.round(track.slope_avg || 0) + '&nbsp;' + slope.label;
3701
+ },
3702
+ order: 40
3563
3703
  }
3564
3704
  });
3565
3705
  });
3566
3706
 
3567
3707
  Elevation.addInitHook(function () {
3708
+ var _this = this;
3709
+
3568
3710
  if (!this.options.speed && !this.options.acceleration) return;
3569
3711
  var opts = this.options;
3570
3712
  var speed = {};
3571
3713
  speed.label = opts.speedLabel || L._(opts.imperial ? 'mph' : 'km/h');
3572
3714
  opts.speedFactor = opts.speedFactor || 1;
3573
3715
 
3716
+ this._registerDataAttribute({
3717
+ name: 'speed',
3718
+ init: function init() {// this.track_info.speed_max = -Infinity; // Speed Max
3719
+ // this.track_info.speed_min = +Infinity; // Speed Min
3720
+ // this.track_info.speed_avg = 0; // Speed Avg
3721
+ },
3722
+ fetch: function fetch(i) {
3723
+ var data = _this._data;
3724
+ var dx = (data[i].dist - data[i > 0 ? i - 1 : i].dist) * 1000;
3725
+ var dt = data[i].time - data[i > 0 ? i - 1 : i].time;
3726
+ return dt > 0 ? Math.abs(dx / dt * opts.timeFactor) * opts.speedFactor : 0;
3727
+ },
3728
+ update: function update(speed, i) {
3729
+ _this.track_info.speed_max = _this.track_info.speed_max || -Infinity; // Speed Max
3730
+
3731
+ _this.track_info.speed_min = _this.track_info.speed_min || +Infinity; // Speed Min
3732
+
3733
+ _this.track_info.speed_avg = _this.track_info.speed_avg || 0; // Speed Avg
3734
+
3735
+ var data = _this._data;
3736
+ var track = _this.track_info; // Try to smooth "crazy" speed values.
3737
+
3738
+ if (_this.options.speedDeltaMax) {
3739
+ var delta = speed - data[i > 0 ? i - 1 : i].speed;
3740
+ var deltaMax = _this.options.speedDeltaMax;
3741
+
3742
+ if (Math.abs(delta) > deltaMax) {
3743
+ speed = data[i - 1].speed + deltaMax * Math.sign(delta);
3744
+ }
3745
+ } // Range of acceptable speed values.
3746
+
3747
+
3748
+ speed = clamp(speed, _this.options.speedRange);
3749
+ if (speed > track.speed_max) track.speed_max = speed;
3750
+ if (speed < track.speed_min) track.speed_min = speed;
3751
+ track.speed_avg = (speed + track.speed_avg) / 2.0;
3752
+ return L.Util.formatNum(speed, 2);
3753
+ }
3754
+ });
3755
+
3574
3756
  if (this.options.speed && this.options.speed != "summary") {
3575
3757
  this._registerAxisScale({
3576
3758
  axis: "y",
@@ -3599,44 +3781,6 @@
3599
3781
  });
3600
3782
  }
3601
3783
 
3602
- this.on('elepoint_added', function (e) {
3603
- var data = this._data;
3604
- var i = e.index;
3605
- var currT = data[i].time;
3606
- var prevT = i > 0 ? data[i - 1].time : currT;
3607
- var deltaT = currT - prevT;
3608
- var track = this.track_info;
3609
- var sMax = track.speed_max || -Infinity; // Speed Max
3610
-
3611
- var sMin = track.speed_min || +Infinity; // Speed Min
3612
-
3613
- var sAvg = track.speed_avg || 0; // Speed Avg
3614
-
3615
- var speed = 0;
3616
-
3617
- if (deltaT > 0) {
3618
- var delta = (data[i].dist - data[i > 0 ? i - 1 : i].dist) * 1000;
3619
- speed = Math.abs(delta / deltaT * opts.timeFactor) * opts.speedFactor;
3620
- } // Try to smooth "crazy" speed values.
3621
-
3622
-
3623
- if (this.options.speedDeltaMax) {
3624
- var deltaS = i > 0 ? speed - data[i - 1].speed : 0;
3625
- var maxDeltaS = this.options.speedDeltaMax;
3626
-
3627
- if (Math.abs(deltaS) > maxDeltaS) {
3628
- speed = data[i - 1].speed + maxDeltaS * Math.sign(deltaS);
3629
- }
3630
- } // Range of acceptable speed values.
3631
-
3632
-
3633
- speed = clamp(speed, this.options.speedRange);
3634
- track.speed_max = speed > sMax ? speed : sMax;
3635
- track.speed_min = speed < sMin ? speed : sMin;
3636
- track.speed_avg = (speed + sAvg) / 2.0;
3637
- data[i].speed = L.Util.formatNum(speed, 2);
3638
- });
3639
-
3640
3784
  if (this.options.speed) {
3641
3785
  this._registerTooltip({
3642
3786
  name: 'speed',
@@ -3645,7 +3789,8 @@
3645
3789
  },
3646
3790
  marker: function marker(item) {
3647
3791
  return Math.round(item.speed) + " " + speed.label;
3648
- }
3792
+ },
3793
+ order: 50
3649
3794
  });
3650
3795
 
3651
3796
  this._registerSummary({
@@ -3653,31 +3798,76 @@
3653
3798
  label: "Min Speed: ",
3654
3799
  value: function value(track) {
3655
3800
  return Math.round(track.speed_min || 0) + '&nbsp;' + speed.label;
3656
- }
3801
+ },
3802
+ order: 50
3657
3803
  },
3658
3804
  "maxspeed": {
3659
3805
  label: "Max Speed: ",
3660
3806
  value: function value(track) {
3661
3807
  return Math.round(track.speed_max || 0) + '&nbsp;' + speed.label;
3662
- }
3808
+ },
3809
+ order: 50
3663
3810
  },
3664
3811
  "avgspeed": {
3665
3812
  label: "Avg Speed: ",
3666
3813
  value: function value(track) {
3667
3814
  return Math.round(track.speed_avg || 0) + '&nbsp;' + speed.label;
3668
- }
3815
+ },
3816
+ order: 50
3669
3817
  }
3670
3818
  });
3671
3819
  }
3672
3820
  });
3673
3821
 
3674
3822
  Elevation.addInitHook(function () {
3823
+ var _this = this;
3824
+
3675
3825
  if (!this.options.acceleration) return;
3676
3826
  var opts = this.options;
3677
3827
  var acceleration = {};
3678
3828
  acceleration.label = opts.accelerationLabel || L._(opts.imperial ? 'ft/s²' : 'm/s²');
3679
3829
  opts.accelerationFactor = opts.accelerationFactor || 1;
3680
3830
 
3831
+ this._registerDataAttribute({
3832
+ name: 'acceleration',
3833
+ init: function init() {// this.track_info.acceleration_max = -Infinity; // Acceleration Max
3834
+ // this.track_info.acceleration_min = +Infinity; // Acceleration Min
3835
+ // this.track_info.acceleration_avg = 0; // Acceleration Avg
3836
+ },
3837
+ fetch: function fetch(i) {
3838
+ var data = _this._data;
3839
+ var dv = (data[i].speed - data[i > 0 ? i - 1 : i].speed) * (1000 / opts.timeFactor);
3840
+ var dt = (data[i].time - data[i > 0 ? i - 1 : i].time) / 1000;
3841
+ return dt > 0 ? Math.abs(dv / dt) * opts.accelerationFactor : 0;
3842
+ },
3843
+ update: function update(acceleration, i) {
3844
+ _this.track_info.acceleration_max = _this.track_info.acceleration_max || -Infinity; // Acceleration Max
3845
+
3846
+ _this.track_info.acceleration_min = _this.track_info.acceleration_min || +Infinity; // Acceleration Min
3847
+
3848
+ _this.track_info.acceleration_avg = _this.track_info.acceleration_avg || 0; // Acceleration Avg
3849
+
3850
+ var data = _this._data;
3851
+ var track = _this.track_info; // Try to smooth "crazy" acceleration values.
3852
+
3853
+ if (_this.options.accelerationDeltaMax) {
3854
+ var delta = acceleration - data[i > 0 ? i - 1 : i].acceleration;
3855
+ var deltaMax = _this.options.accelerationDeltaMax;
3856
+
3857
+ if (Math.abs(delta) > deltaMax) {
3858
+ acceleration = data[i - 1].acceleration + deltaMax * Math.sign(delta);
3859
+ }
3860
+ } // Range of acceptable acceleration values.
3861
+
3862
+
3863
+ acceleration = clamp(acceleration, _this.options.accelerationRange);
3864
+ if (acceleration > track.acceleration_max) track.acceleration_max = acceleration;
3865
+ if (acceleration < track.acceleration_min) track.acceleration_min = acceleration;
3866
+ track.acceleration_avg = (acceleration + track.acceleration_avg) / 2.0;
3867
+ return L.Util.formatNum(acceleration, 2);
3868
+ }
3869
+ });
3870
+
3681
3871
  if (this.options.acceleration != "summary") {
3682
3872
  this._registerAxisScale({
3683
3873
  axis: "y",
@@ -3706,46 +3896,6 @@
3706
3896
  });
3707
3897
  }
3708
3898
 
3709
- this.on('elepoint_added', function (e) {
3710
- var data = this._data;
3711
- var i = e.index;
3712
- var currT = data[i].time;
3713
- var prevT = i > 0 ? data[i - 1].time : currT;
3714
- var deltaT = (currT - prevT) / 1000;
3715
- var track = this.track_info;
3716
- var sMax = track.acceleration_max || -Infinity; // Acceleration Max
3717
-
3718
- var sMin = track.acceleration_min || +Infinity; // Acceleration Min
3719
-
3720
- var sAvg = track.acceleration_avg || 0; // Acceleration Avg
3721
-
3722
- var acceleration = 0;
3723
-
3724
- if (deltaT > 0) {
3725
- var curr = data[i].speed;
3726
- var prev = i > 0 ? data[i - 1].speed : curr;
3727
- var delta = (curr - prev) * (1000 / opts.timeFactor);
3728
- acceleration = Math.abs(delta / deltaT) * opts.accelerationFactor;
3729
- } // Try to smooth "crazy" acceleration values.
3730
-
3731
-
3732
- if (this.options.accelerationDeltaMax) {
3733
- var deltaA = i > 0 ? acceleration - data[i - 1].acceleration : 0;
3734
- var maxDeltaS = this.options.accelerationDeltaMax;
3735
-
3736
- if (Math.abs(deltaA) > maxDeltaS) {
3737
- acceleration = data[i - 1].acceleration + maxDeltaS * Math.sign(deltaA);
3738
- }
3739
- } // Range of acceptable acceleration values.
3740
-
3741
-
3742
- acceleration = clamp(acceleration, this.options.accelerationRange);
3743
- track.acceleration_max = acceleration > sMax ? acceleration : sMax;
3744
- track.acceleration_min = acceleration < sMin ? acceleration : sMin;
3745
- track.acceleration_avg = (acceleration + sAvg) / 2.0;
3746
- data[i].acceleration = L.Util.formatNum(acceleration, 2);
3747
- });
3748
-
3749
3899
  this._registerTooltip({
3750
3900
  name: 'acceleration',
3751
3901
  chart: function chart(item) {
@@ -3753,7 +3903,8 @@
3753
3903
  },
3754
3904
  marker: function marker(item) {
3755
3905
  return Math.round(item.acceleration) + " " + acceleration.label;
3756
- }
3906
+ },
3907
+ order: 60
3757
3908
  });
3758
3909
 
3759
3910
  this._registerSummary({
@@ -3761,19 +3912,22 @@
3761
3912
  label: "Min Acceleration: ",
3762
3913
  value: function value(track) {
3763
3914
  return Math.round(track.acceleration_min || 0) + '&nbsp;' + acceleration.label;
3764
- }
3915
+ },
3916
+ order: 60
3765
3917
  },
3766
3918
  "maxacceleration": {
3767
3919
  label: "Max Acceleration: ",
3768
3920
  value: function value(track) {
3769
3921
  return Math.round(track.acceleration_max || 0) + '&nbsp;' + acceleration.label;
3770
- }
3922
+ },
3923
+ order: 60
3771
3924
  },
3772
3925
  "avgacceleration": {
3773
3926
  label: "Avg Acceleration: ",
3774
3927
  value: function value(track) {
3775
3928
  return Math.round(track.acceleration_avg || 0) + '&nbsp;' + acceleration.label;
3776
- }
3929
+ },
3930
+ order: 60
3777
3931
  }
3778
3932
  });
3779
3933
  });