@raruto/leaflet-elevation 2.0.0 → 2.0.3
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 +2 -1
- package/dist/leaflet-elevation.css +3 -1
- package/dist/leaflet-elevation.js +148 -189
- package/dist/leaflet-elevation.js.map +1 -1
- package/dist/leaflet-elevation.min.css +1 -1
- package/dist/leaflet-elevation.min.js +1 -1
- package/dist/leaflet-elevation.min.js.map +1 -1
- package/libs/leaflet-distance-marker.js +97 -92
- package/libs/leaflet-distance-marker.min.js +1 -1
- package/package.json +1 -1
- package/src/{chart.js → components/chart.js} +78 -54
- package/src/{components.js → components/d3.js} +74 -16
- package/src/{marker.js → components/marker.js} +1 -1
- package/src/{summary.js → components/summary.js} +0 -0
- package/src/control.js +141 -184
- package/src/handlers/altitude.js +4 -1
- package/src/handlers/heart.js +2 -2
- package/src/index.css +3 -1
- package/src/utils.js +5 -5
- package/src/handlers/acceleration.min.js +0 -1
- package/src/handlers/altitude.min.js +0 -1
- package/src/handlers/distance.min.js +0 -1
- package/src/handlers/slope.min.js +0 -1
- package/src/handlers/speed.min.js +0 -1
- package/src/handlers/time.min.js +0 -1
|
@@ -143,102 +143,107 @@ L.DistanceMarkers = L.LayerGroup.extend({
|
|
|
143
143
|
// Get line coords as an array
|
|
144
144
|
let coords = typeof line.getLatLngs == 'function' ? line.getLatLngs() : line;
|
|
145
145
|
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
146
|
+
// Handle "MultiLineString" features
|
|
147
|
+
coords = L.LineUtil.isFlat(coords) ? [coords] : coords;
|
|
148
|
+
|
|
149
|
+
coords.forEach(latlngs => {
|
|
150
|
+
// Get accumulated line lengths as well as overall length
|
|
151
|
+
let accumulated = L.GeometryUtil.accumulatedLengths(latlngs);
|
|
152
|
+
let length = accumulated.length > 0 ? accumulated[accumulated.length - 1] : 0;
|
|
153
|
+
|
|
154
|
+
// count = Number of distance markers to be added
|
|
155
|
+
// j = Position in accumulated line length array
|
|
156
|
+
for (let i = 1, count = Math.floor(length / options.offset), j = 0; i <= count; ++i) {
|
|
157
|
+
|
|
158
|
+
let distance = options.offset * i;
|
|
159
|
+
|
|
160
|
+
// Find the first accumulated distance that is greater than the distance of this marker
|
|
161
|
+
while (j < accumulated.length - 1 && accumulated[j] < distance) ++j;
|
|
162
|
+
|
|
163
|
+
// Grab two nearest points either side marker position
|
|
164
|
+
let p1 = latlngs[j - 1];
|
|
165
|
+
let p2 = latlngs[j];
|
|
166
|
+
let m_line = L.polyline([p1, p2]);
|
|
167
|
+
|
|
168
|
+
// and create a simple line to interpolate on
|
|
169
|
+
let ratio = (distance - accumulated[j - 1]) / (accumulated[j] - accumulated[j - 1]);
|
|
170
|
+
let position = L.GeometryUtil.interpolateOnLine(map, m_line, ratio);
|
|
171
|
+
let delta = map.project(p2).subtract(map.project(p1));
|
|
172
|
+
let angle = Math.atan2(delta.y, delta.x);
|
|
173
|
+
|
|
174
|
+
// Generate distance marker label
|
|
175
|
+
let text = options.textFunction.call(this, distance, i, options.offset);
|
|
176
|
+
|
|
177
|
+
// Grouping layer of visible layers at zoom level (arrow + distance)
|
|
178
|
+
let zoom = this._minimumZoomLevelForItem(i, showAll);
|
|
179
|
+
let markers = this._zoomLayers[zoom] = this._zoomLayers[zoom] || L.layerGroup()
|
|
180
|
+
|
|
181
|
+
// create arrow markers
|
|
182
|
+
if (options.direction && ((options.distance && i % 2 == 1) || !options.distance)) {
|
|
183
|
+
if (preferCanvas) {
|
|
184
|
+
markers.addLayer(
|
|
185
|
+
new L.DistanceMarker(p1, {
|
|
186
|
+
radius: 0,
|
|
187
|
+
icon: {
|
|
188
|
+
url: options.arrowUrl, //image link
|
|
189
|
+
size: options.arrowSize, //image size ( default [40, 40] )
|
|
190
|
+
rotate: 0, //image base rotate ( default 0 )
|
|
191
|
+
offset: { x: 0, y: 0 }, //image offset ( default { x: 0, y: 0 } )
|
|
192
|
+
},
|
|
193
|
+
rotation: angle,
|
|
194
|
+
interactive: false,
|
|
195
|
+
// label: '⮞', //'➜',
|
|
196
|
+
// font: 'normal 20pt "Helvetica Neue", Arial, Helvetica, sans-serif',
|
|
197
|
+
// fillStyle: 'white',//'#3366CC',
|
|
198
|
+
// strokeStyle: 'black',
|
|
199
|
+
})
|
|
200
|
+
);
|
|
201
|
+
} else {
|
|
202
|
+
markers.addLayer(
|
|
203
|
+
L.marker(position.latLng, {
|
|
204
|
+
icon: L.icon({
|
|
205
|
+
iconUrl: options.arrowUrl,
|
|
206
|
+
iconSize: options.arrowSize,
|
|
207
|
+
}),
|
|
208
|
+
// NB the following option is added by "leaflet-rotate"
|
|
209
|
+
rotation: angle * L.DomUtil.RAD_TO_DEG,
|
|
210
|
+
interactive: false,
|
|
211
|
+
})
|
|
212
|
+
);
|
|
213
|
+
}
|
|
209
214
|
}
|
|
210
|
-
}
|
|
211
215
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
216
|
+
// create distance markers
|
|
217
|
+
if (options.distance && i % 2 == 0) {
|
|
218
|
+
if (preferCanvas) {
|
|
219
|
+
markers.addLayer(
|
|
220
|
+
new L.DistanceMarker(position.latLng, {
|
|
221
|
+
label: text, // TODO: handle text rotation (leaflet-rotate)
|
|
222
|
+
radius: 7,
|
|
223
|
+
fillColor: '#fff',
|
|
224
|
+
fillOpacity: 1,
|
|
225
|
+
fillStyle: 'black',
|
|
226
|
+
color: '#777',
|
|
227
|
+
weight: 1,
|
|
228
|
+
interactive: false,
|
|
229
|
+
})
|
|
230
|
+
);
|
|
231
|
+
} else {
|
|
232
|
+
markers.addLayer(
|
|
233
|
+
L.marker(position.latLng, {
|
|
234
|
+
title: text,
|
|
235
|
+
icon: L.divIcon({
|
|
236
|
+
className: options.cssClass,
|
|
237
|
+
html: text,
|
|
238
|
+
iconSize: options.iconSize
|
|
239
|
+
}),
|
|
240
|
+
interactive: false,
|
|
241
|
+
})
|
|
242
|
+
);
|
|
243
|
+
}
|
|
239
244
|
}
|
|
240
245
|
}
|
|
241
|
-
}
|
|
246
|
+
});
|
|
242
247
|
|
|
243
248
|
const updateMarkerVisibility = () => {
|
|
244
249
|
let oldZoom = this._lastZoomLevel || 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
L.DistanceMarker=L.CircleMarker.extend({_updatePath:function(){let ctx=this._renderer._ctx,p=this._point;if(this.options.rotation=this.options.rotation||0,this.options.radius&&this._renderer._updateCircle&&this._renderer._updateCircle(this),this.options.icon&&this.options.icon.url)if(this.options.icon.element){const icon=this.options.icon;let cx=p.x+icon.offset.x,cy=p.y+icon.offset.y;ctx.save(),icon.rotate&&(ctx.translate(p.x,p.y),ctx.rotate(icon.rotate),cx=0,cy=0),ctx.drawImage(icon.element,cx-icon.size[0]/2,cy-icon.size[1]/2,icon.size[0],icon.size[1]),ctx.restore()}else{const icon=document.createElement("img");this.options.icon=L.extend({rotate:0,size:[40,40],offset:{x:0,y:0}},this.options.icon),this.options.icon.rotate+=this.options.rotation,this.options.icon.element=icon,icon.src=this.options.icon.url,icon.onload=()=>this.redraw(),icon.onerror=()=>this.options.icon=null}if(this.options.label){let cx=p.x,cy=p.y;ctx.save(),ctx.font=this.options.font||'normal 7pt "Helvetica Neue", Arial, Helvetica, sans-serif',ctx.textAlign="center",ctx.textBaseline="middle",ctx.fillStyle=this.options.fillStyle||"black",this.options.rotation&&(ctx.translate(p.x,p.y),ctx.rotate(this.options.rotation),cx=0,cy=0),this._map.getZoom()>17&&(ctx.fillStyle=this.options.strokeStyle||"black"),ctx.fillText(this.options.label,cx,cy),this.options.strokeStyle&&this._map.getZoom()<=17&&(ctx.strokeStyle=this.options.strokeStyle,ctx.strokeText(this.options.label,cx,cy)),ctx.restore()}}}),L.DistanceMarkers=L.LayerGroup.extend({options:{cssClass:"dist-marker",iconSize:[12,12],arrowSize:[10,10],arrowUrl:"data:image/svg+xml,%3Csvg transform='rotate(90)' xmlns='http://www.w3.org/2000/svg' width='560px' height='560px' viewBox='0 0 560 560'%3E%3Cpath stroke-width='35' fill='%23000' stroke='%23FFF' d='M280,40L522,525L280,420L38,525z'/%3E%3C/svg%3E",offset:1e3,showAll:12,textFunction:(distance,i,offset)=>i,distance:!0,direction:!0},initialize:function(line,map,options){this._layers={},this._zoomLayers={},options=L.setOptions(this,options);let preferCanvas=map.options.preferCanvas,showAll=Math.min(map.getMaxZoom(),options.showAll);preferCanvas||map.options.rotate||console.warn('Missing dependency: "leaflet-rotate"');let coords="function"==typeof line.getLatLngs?line.getLatLngs():line,accumulated=L.GeometryUtil.accumulatedLengths(
|
|
1
|
+
L.DistanceMarker=L.CircleMarker.extend({_updatePath:function(){let ctx=this._renderer._ctx,p=this._point;if(this.options.rotation=this.options.rotation||0,this.options.radius&&this._renderer._updateCircle&&this._renderer._updateCircle(this),this.options.icon&&this.options.icon.url)if(this.options.icon.element){const icon=this.options.icon;let cx=p.x+icon.offset.x,cy=p.y+icon.offset.y;ctx.save(),icon.rotate&&(ctx.translate(p.x,p.y),ctx.rotate(icon.rotate),cx=0,cy=0),ctx.drawImage(icon.element,cx-icon.size[0]/2,cy-icon.size[1]/2,icon.size[0],icon.size[1]),ctx.restore()}else{const icon=document.createElement("img");this.options.icon=L.extend({rotate:0,size:[40,40],offset:{x:0,y:0}},this.options.icon),this.options.icon.rotate+=this.options.rotation,this.options.icon.element=icon,icon.src=this.options.icon.url,icon.onload=()=>this.redraw(),icon.onerror=()=>this.options.icon=null}if(this.options.label){let cx=p.x,cy=p.y;ctx.save(),ctx.font=this.options.font||'normal 7pt "Helvetica Neue", Arial, Helvetica, sans-serif',ctx.textAlign="center",ctx.textBaseline="middle",ctx.fillStyle=this.options.fillStyle||"black",this.options.rotation&&(ctx.translate(p.x,p.y),ctx.rotate(this.options.rotation),cx=0,cy=0),this._map.getZoom()>17&&(ctx.fillStyle=this.options.strokeStyle||"black"),ctx.fillText(this.options.label,cx,cy),this.options.strokeStyle&&this._map.getZoom()<=17&&(ctx.strokeStyle=this.options.strokeStyle,ctx.strokeText(this.options.label,cx,cy)),ctx.restore()}}}),L.DistanceMarkers=L.LayerGroup.extend({options:{cssClass:"dist-marker",iconSize:[12,12],arrowSize:[10,10],arrowUrl:"data:image/svg+xml,%3Csvg transform='rotate(90)' xmlns='http://www.w3.org/2000/svg' width='560px' height='560px' viewBox='0 0 560 560'%3E%3Cpath stroke-width='35' fill='%23000' stroke='%23FFF' d='M280,40L522,525L280,420L38,525z'/%3E%3C/svg%3E",offset:1e3,showAll:12,textFunction:(distance,i,offset)=>i,distance:!0,direction:!0},initialize:function(line,map,options){this._layers={},this._zoomLayers={},options=L.setOptions(this,options);let preferCanvas=map.options.preferCanvas,showAll=Math.min(map.getMaxZoom(),options.showAll);preferCanvas||map.options.rotate||console.warn('Missing dependency: "leaflet-rotate"');let coords="function"==typeof line.getLatLngs?line.getLatLngs():line;coords=L.LineUtil.isFlat(coords)?[coords]:coords,coords.forEach(latlngs=>{let accumulated=L.GeometryUtil.accumulatedLengths(latlngs),length=accumulated.length>0?accumulated[accumulated.length-1]:0;for(let i=1,count=Math.floor(length/options.offset),j=0;i<=count;++i){let distance=options.offset*i;for(;j<accumulated.length-1&&accumulated[j]<distance;)++j;let p1=latlngs[j-1],p2=latlngs[j],m_line=L.polyline([p1,p2]),ratio=(distance-accumulated[j-1])/(accumulated[j]-accumulated[j-1]),position=L.GeometryUtil.interpolateOnLine(map,m_line,ratio),delta=map.project(p2).subtract(map.project(p1)),angle=Math.atan2(delta.y,delta.x),text=options.textFunction.call(this,distance,i,options.offset),zoom=this._minimumZoomLevelForItem(i,showAll),markers=this._zoomLayers[zoom]=this._zoomLayers[zoom]||L.layerGroup();options.direction&&(options.distance&&i%2==1||!options.distance)&&(preferCanvas?markers.addLayer(new L.DistanceMarker(p1,{radius:0,icon:{url:options.arrowUrl,size:options.arrowSize,rotate:0,offset:{x:0,y:0}},rotation:angle,interactive:!1})):markers.addLayer(L.marker(position.latLng,{icon:L.icon({iconUrl:options.arrowUrl,iconSize:options.arrowSize}),rotation:angle*L.DomUtil.RAD_TO_DEG,interactive:!1}))),options.distance&&i%2==0&&(preferCanvas?markers.addLayer(new L.DistanceMarker(position.latLng,{label:text,radius:7,fillColor:"#fff",fillOpacity:1,fillStyle:"black",color:"#777",weight:1,interactive:!1})):markers.addLayer(L.marker(position.latLng,{title:text,icon:L.divIcon({className:options.cssClass,html:text,iconSize:options.iconSize}),interactive:!1})))}});const updateMarkerVisibility=()=>{let oldZoom=this._lastZoomLevel||0,newZoom=map.getZoom();if(newZoom>oldZoom)for(let i=oldZoom+1;i<=newZoom;++i)void 0!==this._zoomLayers[i]&&this.addLayer(this._zoomLayers[i]);else if(newZoom<oldZoom)for(let i=oldZoom;i>newZoom;--i)void 0!==this._zoomLayers[i]&&this.removeLayer(this._zoomLayers[i]);this._lastZoomLevel=newZoom};map.on("zoomend",updateMarkerVisibility),updateMarkerVisibility()},_minimumZoomLevelForItem:function(i,zoom){for(;i>0&&i%2==0;)--zoom,i=Math.floor(i/2);return zoom}}),L.Polyline.include({_originalOnAdd:L.Polyline.prototype.onAdd,_originalOnRemove:L.Polyline.prototype.onRemove,addDistanceMarkers:function(){this._map&&this._distanceMarkers&&this._map.addLayer(this._distanceMarkers)},removeDistanceMarkers:function(){this._map&&this._distanceMarkers&&this._map.removeLayer(this._distanceMarkers)},onAdd:function(map){this._originalOnAdd(map);let opts=this.options.distanceMarkers||{};this.options.distanceMarkers&&(this._distanceMarkers=this._distanceMarkers||new L.DistanceMarkers(this,map,opts)),void 0!==opts.lazy&&!1!==opts.lazy||this.addDistanceMarkers()},onRemove:function(map){this.removeDistanceMarkers(),this._originalOnRemove(map)}});
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as D3 from './
|
|
1
|
+
import * as D3 from './d3.js';
|
|
2
2
|
|
|
3
3
|
const _ = L.Control.Elevation.Utils;
|
|
4
4
|
|
|
@@ -85,6 +85,7 @@ export var Chart = L.Control.Elevation.Chart = L.Class.extend({
|
|
|
85
85
|
this._updateScale();
|
|
86
86
|
this._updateArea();
|
|
87
87
|
this._updateAxis();
|
|
88
|
+
this._updateMargins();
|
|
88
89
|
this._updateLegend();
|
|
89
90
|
this._updateClipper();
|
|
90
91
|
|
|
@@ -536,80 +537,88 @@ export var Chart = L.Control.Elevation.Chart = L.Class.extend({
|
|
|
536
537
|
},
|
|
537
538
|
|
|
538
539
|
_updateLegend: function () {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
const legendOpts = {
|
|
543
|
-
width : this._width(),
|
|
544
|
-
height : this._height(),
|
|
545
|
-
margins: this.options.margins,
|
|
546
|
-
};
|
|
547
|
-
|
|
548
|
-
// Reset legend items
|
|
549
|
-
this._legend.selectAll('g').remove();
|
|
550
|
-
_.each(this._props.legendItems, (legend) => {
|
|
551
|
-
this._legend.append("g").call(D3.LegendItem(L.extend(legendOpts, legend)));
|
|
552
|
-
});
|
|
553
|
-
|
|
540
|
+
let xAxesB = this._axis.selectAll('.x.axis.bottom').nodes().length;
|
|
541
|
+
|
|
554
542
|
// Get legend items
|
|
555
|
-
let items
|
|
543
|
+
let items = Object.keys(this._paths);
|
|
556
544
|
|
|
557
545
|
// Calculate legend item positions
|
|
558
|
-
let n = items.
|
|
546
|
+
let n = items.length;
|
|
559
547
|
let v = Array(Math.floor(n / 2)).fill(null).map((d, i) => (i + 1) * 2 - (1 - Math.sign(n % 2)));
|
|
560
548
|
let rev = v.slice().reverse().map((d) => -(d));
|
|
561
549
|
|
|
550
|
+
// push a fake element to handle center alignment (odd numbers)
|
|
562
551
|
if (n % 2 !== 0) {
|
|
563
552
|
rev.push(0);
|
|
564
553
|
}
|
|
565
554
|
v = rev.concat(v);
|
|
566
555
|
|
|
556
|
+
// Reset legend items
|
|
557
|
+
this._legend.selectAll('g').remove();
|
|
558
|
+
_.each(this._props.legendItems, (legend) => {
|
|
559
|
+
this._legend.append("g").call(
|
|
560
|
+
D3.LegendItem(L.extend({
|
|
561
|
+
width : this._width(),
|
|
562
|
+
height : this._height(),
|
|
563
|
+
margins: this.options.margins,
|
|
564
|
+
}, legend))
|
|
565
|
+
);
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
// Reset legend items
|
|
569
|
+
this._legend.append("g").call(
|
|
570
|
+
D3.LegendSmall({
|
|
571
|
+
width : this._width(),
|
|
572
|
+
height : this._height(),
|
|
573
|
+
items : items,
|
|
574
|
+
onClick: (selected) => {
|
|
575
|
+
_.each(items, name => this._togglePath(name, selected == name, true));
|
|
576
|
+
this._updateArea();
|
|
577
|
+
}
|
|
578
|
+
})
|
|
579
|
+
);
|
|
580
|
+
|
|
581
|
+
_.each(items, (name, i) => {
|
|
582
|
+
// Adjust legend item positions
|
|
583
|
+
this._legend.select('[data-name=' + name + ']').attr("transform", "translate(" + (v[i] * 55) + ", " + (xAxesB * 2) + ")");
|
|
584
|
+
// Set initial state (disabled controls)
|
|
585
|
+
this._togglePath(name, !(name in this.options && this.options[name] == 'disabled'), true);
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
},
|
|
589
|
+
|
|
590
|
+
_updateMargins: function() {
|
|
567
591
|
// Get chart margins
|
|
568
592
|
let xAxesB = this._axis.selectAll('.x.axis.bottom').nodes().length;
|
|
569
|
-
let
|
|
570
|
-
let
|
|
593
|
+
let xAxesL = this._axis.selectAll('.y.axis.left').nodes().length;
|
|
594
|
+
let xAxesR = this._axis.selectAll('.y.axis.right').nodes().length;
|
|
595
|
+
let marginB = 60 + (xAxesB * 2);
|
|
596
|
+
let marginL = 10 + (xAxesL * 30);
|
|
597
|
+
let marginR = 40 + (xAxesR * 30);
|
|
598
|
+
|
|
599
|
+
let marginsUpdated = false
|
|
571
600
|
|
|
572
|
-
// Adjust
|
|
573
|
-
if (
|
|
601
|
+
// Adjust right margin
|
|
602
|
+
if (xAxesR && this.options.margins.right < marginR) {
|
|
574
603
|
this.options.margins.right = marginR;
|
|
575
|
-
|
|
604
|
+
marginsUpdated = true;
|
|
576
605
|
}
|
|
577
606
|
|
|
578
|
-
// Adjust
|
|
607
|
+
// Adjust left margin
|
|
608
|
+
if(xAxesL && this.options.margins.left < marginL) {
|
|
609
|
+
this.options.margins.left = marginL;
|
|
610
|
+
marginsUpdated = true;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// Adjust bottom margin
|
|
579
614
|
if(xAxesB && this.options.margins.bottom < marginB) {
|
|
580
615
|
this.options.margins.bottom = marginB;
|
|
581
|
-
|
|
616
|
+
marginsUpdated = true;
|
|
582
617
|
}
|
|
583
618
|
|
|
584
|
-
|
|
585
|
-
.
|
|
586
|
-
|
|
587
|
-
let legend = d3.select(n[i]);
|
|
588
|
-
let rect = legend.select('rect');
|
|
589
|
-
let name = legend.attr('data-name');
|
|
590
|
-
let path = this._paths[name];
|
|
591
|
-
|
|
592
|
-
let tx = v[i] * 55;
|
|
593
|
-
let ty = xAxesB * 2;
|
|
594
|
-
|
|
595
|
-
legend
|
|
596
|
-
|
|
597
|
-
// Adjust legend item positions
|
|
598
|
-
.attr("transform", "translate(" + tx + ", " + ty + ")");
|
|
599
|
-
|
|
600
|
-
// Set initial state (disabled controls)
|
|
601
|
-
if (name in this.options && this.options[name] == 'disabled') {
|
|
602
|
-
path.classed('leaflet-hidden', true);
|
|
603
|
-
legend.select('text').style('text-decoration-line', 'line-through');
|
|
604
|
-
legend.select('rect').style('fill-opacity', '0');
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// Apply d3-zoom (bind <clipPath> mask)
|
|
608
|
-
if (this._mask) {
|
|
609
|
-
path.attr('mask', 'url(#' + this._mask.attr('id') + ')');
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
});
|
|
619
|
+
if (marginsUpdated) {
|
|
620
|
+
this.fire('margins_updated');
|
|
621
|
+
}
|
|
613
622
|
},
|
|
614
623
|
|
|
615
624
|
_updateScale: function() {
|
|
@@ -733,6 +742,21 @@ export var Chart = L.Control.Elevation.Chart = L.Class.extend({
|
|
|
733
742
|
}));
|
|
734
743
|
},
|
|
735
744
|
|
|
745
|
+
_togglePath(name, enabled = true, lazy = false) {
|
|
746
|
+
let path = this._paths[name];
|
|
747
|
+
let legend = this._container.select('.legend [data-name=' + name + ']');
|
|
748
|
+
path.classed('leaflet-hidden', !enabled);
|
|
749
|
+
legend.select('text').style('text-decoration-line', enabled ? '' : 'line-through');
|
|
750
|
+
legend.select('rect').style('fill-opacity', enabled ? '': '0');
|
|
751
|
+
// Apply d3-zoom (bind <clipPath> mask)
|
|
752
|
+
if (this._mask) {
|
|
753
|
+
path.attr('mask', 'url(#' + this._mask.attr('id') + ')');
|
|
754
|
+
}
|
|
755
|
+
if (!lazy) {
|
|
756
|
+
this._updateArea();
|
|
757
|
+
}
|
|
758
|
+
},
|
|
759
|
+
|
|
736
760
|
_hideDiagramIndicator: function() {
|
|
737
761
|
this._tooltip.attr("display", 'none');
|
|
738
762
|
},
|
|
@@ -214,6 +214,70 @@ export const LegendItem = ({
|
|
|
214
214
|
}
|
|
215
215
|
};
|
|
216
216
|
|
|
217
|
+
export const LegendSmall = ({
|
|
218
|
+
width,
|
|
219
|
+
height,
|
|
220
|
+
items,
|
|
221
|
+
onClick
|
|
222
|
+
}) => {
|
|
223
|
+
return g => {
|
|
224
|
+
let idx = 0;
|
|
225
|
+
|
|
226
|
+
g.data([{
|
|
227
|
+
x: width,
|
|
228
|
+
y: height + 40
|
|
229
|
+
}]).attr("transform", d => "translate(" + d.x + "," + d.y + ")").classed('legend-switcher');
|
|
230
|
+
|
|
231
|
+
// let label = g.selectAll(".legend-switcher-label") .data([{ idx: 0 }]);
|
|
232
|
+
let label = g.append('svg:text')
|
|
233
|
+
.attr("class", "legend-switcher-label")
|
|
234
|
+
.attr("text-anchor", "end")
|
|
235
|
+
.attr("x", -25)
|
|
236
|
+
.attr("y", 5)
|
|
237
|
+
.on("mousedown", (e, d) => setIdx(L.Util.wrapNum((idx + 1), [0, items.length])));
|
|
238
|
+
|
|
239
|
+
let symbol = g.selectAll(".legend-switcher-symbol").data([
|
|
240
|
+
{ type: d3.symbolTriangle, x: 0, y: 3, angle: 0, size: 50, id: "down" },
|
|
241
|
+
{ type: d3.symbolTriangle, x: -13, y: 0, angle: 180, size: 50, id: "up" }
|
|
242
|
+
]);
|
|
243
|
+
|
|
244
|
+
symbol.exit().remove();
|
|
245
|
+
label.exit().remove();
|
|
246
|
+
|
|
247
|
+
symbol.enter()
|
|
248
|
+
.append("svg:path")
|
|
249
|
+
.attr("class", "legend-switcher-symbol")
|
|
250
|
+
.attr("cursor", 'pointer')
|
|
251
|
+
.attr("fill", "#000")
|
|
252
|
+
.merge(symbol)
|
|
253
|
+
.attr("d",
|
|
254
|
+
d3.symbol()
|
|
255
|
+
.type(d => d.type)
|
|
256
|
+
.size(d => d.size)
|
|
257
|
+
)
|
|
258
|
+
.attr("transform", d => "translate(" + d.x + "," + d.y + ") rotate(" + d.angle + ")")
|
|
259
|
+
.on("mousedown", (e, d) => setIdx(L.Util.wrapNum((d.id === "up" ? idx + 1 : idx - 1), [0, items.length])));
|
|
260
|
+
|
|
261
|
+
const setIdx = (id) => {
|
|
262
|
+
idx = id;
|
|
263
|
+
// label.enter()
|
|
264
|
+
// .append('text')
|
|
265
|
+
// .attr("class", "legend-switcher-label")
|
|
266
|
+
// .attr("text-anchor", "end")
|
|
267
|
+
// .attr("x", -25)
|
|
268
|
+
// .attr("y", 5)
|
|
269
|
+
// .merge(label.data([{ idx: id }]))
|
|
270
|
+
// .text(d => items.length ? (items[idx][0].toUpperCase() + items[idx].slice(1)) : '')
|
|
271
|
+
// .on("mousedown", (e, d) => setIdx(L.Util.wrapNum((idx + 1), [0, items.length])));
|
|
272
|
+
label.text(items.length ? (items[idx][0].toUpperCase() + items[idx].slice(1)) : '');
|
|
273
|
+
onClick(items[idx]);
|
|
274
|
+
};
|
|
275
|
+
setIdx(0);
|
|
276
|
+
|
|
277
|
+
return g;
|
|
278
|
+
};
|
|
279
|
+
};
|
|
280
|
+
|
|
217
281
|
export const Tooltip = ({
|
|
218
282
|
xCoord,
|
|
219
283
|
yCoord,
|
|
@@ -300,27 +364,21 @@ export const Ruler = ({
|
|
|
300
364
|
return g => {
|
|
301
365
|
|
|
302
366
|
g.data([{
|
|
303
|
-
|
|
304
|
-
|
|
367
|
+
x: 0,
|
|
368
|
+
y: height,
|
|
305
369
|
}])
|
|
306
370
|
.attr("transform", d => "translate(" + d.x + "," + d.y + ")");
|
|
307
371
|
|
|
308
|
-
let rect = g.selectAll('.horizontal-drag-rect')
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
let line = g.selectAll('.horizontal-drag-line')
|
|
312
|
-
.data([{ w: width }]);
|
|
313
|
-
|
|
314
|
-
let label = g.selectAll('.horizontal-drag-label')
|
|
315
|
-
.data([{ w: width - 8 }]);
|
|
316
|
-
|
|
372
|
+
let rect = g.selectAll('.horizontal-drag-rect').data([{ w: width }]);
|
|
373
|
+
let line = g.selectAll('.horizontal-drag-line').data([{ w: width }]);
|
|
374
|
+
let label = g.selectAll('.horizontal-drag-label').data([{ w: width - 8 }]);
|
|
317
375
|
let symbol = g.selectAll('.horizontal-drag-symbol')
|
|
318
376
|
.data([{
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
377
|
+
type: d3.symbolTriangle,
|
|
378
|
+
x: width + 7,
|
|
379
|
+
y: 0,
|
|
380
|
+
angle: -90,
|
|
381
|
+
size: 50
|
|
324
382
|
}]);
|
|
325
383
|
|
|
326
384
|
rect.exit().remove();
|
|
File without changes
|