@abi-software/flatmap-viewer 2.2.0-beta.3 → 2.2.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/flatmap-viewer.js +70 -5
- package/src/interactions.js +26 -4
- package/src/styling.js +39 -12
package/package.json
CHANGED
package/src/flatmap-viewer.js
CHANGED
|
@@ -22,7 +22,7 @@ limitations under the License.
|
|
|
22
22
|
|
|
23
23
|
//==============================================================================
|
|
24
24
|
|
|
25
|
-
import
|
|
25
|
+
import maplibregl from 'maplibre-gl';
|
|
26
26
|
import 'maplibre-gl/dist/maplibre-gl.css';
|
|
27
27
|
|
|
28
28
|
//==============================================================================
|
|
@@ -131,7 +131,7 @@ class FlatMap
|
|
|
131
131
|
|
|
132
132
|
// Create the map
|
|
133
133
|
|
|
134
|
-
this._map = new
|
|
134
|
+
this._map = new maplibregl.Map(mapOptions);
|
|
135
135
|
|
|
136
136
|
// Show tile boundaries if debugging
|
|
137
137
|
|
|
@@ -146,7 +146,7 @@ class FlatMap
|
|
|
146
146
|
// Do we want a fullscreen control?
|
|
147
147
|
|
|
148
148
|
if (mapDescription.options.fullscreenControl === true) {
|
|
149
|
-
this._map.addControl(new
|
|
149
|
+
this._map.addControl(new maplibregl.FullscreenControl(), 'top-right');
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
// Disable map rotation
|
|
@@ -176,7 +176,11 @@ class FlatMap
|
|
|
176
176
|
this.setupUserInteractions_();
|
|
177
177
|
} else if (this._initialState === null) {
|
|
178
178
|
this._bounds = this._map.getBounds();
|
|
179
|
-
|
|
179
|
+
this._map.setMaxBounds(this._bounds);
|
|
180
|
+
const sw = maplibregl.MercatorCoordinate.fromLngLat(this._bounds.toArray()[0]);
|
|
181
|
+
const ne = maplibregl.MercatorCoordinate.fromLngLat(this._bounds.toArray()[1]);
|
|
182
|
+
this.__normalised_origin = [sw.x, ne.y];
|
|
183
|
+
this.__normalised_size = [ne.x - sw.x, sw.y - ne.y];
|
|
180
184
|
if ('state' in this._options) {
|
|
181
185
|
this._userInteractions.setState(this._options.state);
|
|
182
186
|
}
|
|
@@ -559,7 +563,7 @@ class FlatMap
|
|
|
559
563
|
//==================
|
|
560
564
|
{
|
|
561
565
|
if ('bounds' in this._options) {
|
|
562
|
-
this._map.fitBounds(this._options['bounds']);
|
|
566
|
+
this._map.fitBounds(this._options['bounds'], {animate: false});
|
|
563
567
|
}
|
|
564
568
|
if ('center' in this._options) {
|
|
565
569
|
this._map.setCenter(this._options['center']);
|
|
@@ -784,6 +788,7 @@ class FlatMap
|
|
|
784
788
|
const exportedProperties = [
|
|
785
789
|
'connectivity',
|
|
786
790
|
'dataset',
|
|
791
|
+
'kind',
|
|
787
792
|
'label',
|
|
788
793
|
'models',
|
|
789
794
|
'nodeId',
|
|
@@ -822,6 +827,66 @@ class FlatMap
|
|
|
822
827
|
});
|
|
823
828
|
}
|
|
824
829
|
|
|
830
|
+
/**
|
|
831
|
+
* Generate callbacks as a result of panning/zooming the map.
|
|
832
|
+
*
|
|
833
|
+
* @param {boolean} enabled Generate callbacks when ``true``,
|
|
834
|
+
* otherwise disable them.
|
|
835
|
+
*/
|
|
836
|
+
enablePanZoomEvents(enabled=true)
|
|
837
|
+
//===============================
|
|
838
|
+
{
|
|
839
|
+
if (this._userInteractions !== null) {
|
|
840
|
+
this._userInteractions.enablePanZoomEvents(enabled);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Generate a callback as a result of panning/zooming the map.
|
|
846
|
+
*
|
|
847
|
+
* @param {string} type The event type, ``pan`` or ``zoom``.
|
|
848
|
+
* @param {Array.<float>} origin The map's normalised top-left corner
|
|
849
|
+
* @param {Array.<float>} size The map's normalised size
|
|
850
|
+
*/
|
|
851
|
+
panZoomEvent(type)
|
|
852
|
+
//================
|
|
853
|
+
{
|
|
854
|
+
const bounds = this._map.getBounds();
|
|
855
|
+
if (this.__normalised_origin !== undefined) {
|
|
856
|
+
const sw = maplibregl.MercatorCoordinate.fromLngLat(bounds.toArray()[0]);
|
|
857
|
+
const ne = maplibregl.MercatorCoordinate.fromLngLat(bounds.toArray()[1]);
|
|
858
|
+
const top_left = [(sw.x - this.__normalised_origin[0])/this.__normalised_size[0],
|
|
859
|
+
(ne.y - this.__normalised_origin[1])/this.__normalised_size[1]];
|
|
860
|
+
const size = [(ne.x - sw.x)/this.__normalised_size[0],
|
|
861
|
+
(sw.y - ne.y)/this.__normalised_size[1]];
|
|
862
|
+
this.callback('pan-zoom', {
|
|
863
|
+
type: type,
|
|
864
|
+
origin: top_left,
|
|
865
|
+
size: size
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* Pan/zoom the map to a new view
|
|
872
|
+
*
|
|
873
|
+
* @param {Array.<float>} origin The map's normalised top-left corner
|
|
874
|
+
* @param {Array.<float>} size The map's normalised size
|
|
875
|
+
*/
|
|
876
|
+
panZoomTo(origin, size)
|
|
877
|
+
//=====================
|
|
878
|
+
{
|
|
879
|
+
if (this.__normalised_origin !== undefined) {
|
|
880
|
+
const sw_x = origin[0]*this.__normalised_size[0] + this.__normalised_origin[0];
|
|
881
|
+
const ne_y = origin[1]*this.__normalised_size[1] + this.__normalised_origin[1];
|
|
882
|
+
const ne_x = sw_x + size[0]*this.__normalised_size[0];
|
|
883
|
+
const sw_y = ne_y + size[1]*this.__normalised_size[1];
|
|
884
|
+
const sw = (new maplibregl.MercatorCoordinate(sw_x, sw_y, 0)).toLngLat();
|
|
885
|
+
const ne = (new maplibregl.MercatorCoordinate(ne_x, ne_y, 0)).toLngLat();
|
|
886
|
+
this._map.fitBounds([sw, ne], {animate: false});
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
|
|
825
890
|
//==========================================================================
|
|
826
891
|
|
|
827
892
|
search(text)
|
package/src/interactions.js
CHANGED
|
@@ -224,6 +224,11 @@ export class UserInteractions
|
|
|
224
224
|
this._map.on('mousemove', this.mouseMoveEvent_.bind(this));
|
|
225
225
|
this._lastFeatureMouseEntered = null;
|
|
226
226
|
this._lastFeatureModelsMouse = null;
|
|
227
|
+
|
|
228
|
+
// Handle pan/zoom events
|
|
229
|
+
this._map.on('move', this.panZoomEvent_.bind(this, 'pan'));
|
|
230
|
+
this._map.on('zoom', this.panZoomEvent_.bind(this, 'zoom'));
|
|
231
|
+
this.__pan_zoom_enabled = false;
|
|
227
232
|
}
|
|
228
233
|
|
|
229
234
|
getState()
|
|
@@ -289,12 +294,12 @@ export class UserInteractions
|
|
|
289
294
|
return this._selectedFeatureIds.has(+featureId);
|
|
290
295
|
}
|
|
291
296
|
|
|
292
|
-
selectFeature_(featureId)
|
|
293
|
-
|
|
297
|
+
selectFeature_(featureId, dim=true)
|
|
298
|
+
//=================================
|
|
294
299
|
{
|
|
295
300
|
featureId = +featureId; // Ensure numeric
|
|
296
301
|
if (this._selectedFeatureIds.size === 0) {
|
|
297
|
-
this._layerManager.setColour({...this.__colourOptions, dimmed:
|
|
302
|
+
this._layerManager.setColour({...this.__colourOptions, dimmed: dim});
|
|
298
303
|
}
|
|
299
304
|
if (this._selectedFeatureIds.has(featureId)) {
|
|
300
305
|
this._selectedFeatureIds.set(featureId, this._selectedFeatureIds.get(featureId) + 1);
|
|
@@ -837,7 +842,10 @@ export class UserInteractions
|
|
|
837
842
|
}
|
|
838
843
|
}
|
|
839
844
|
} else if (selecting) {
|
|
840
|
-
|
|
845
|
+
const dim = !('properties' in feature
|
|
846
|
+
&& 'kind' in feature.properties
|
|
847
|
+
&& ['cell-type', 'scaffold', 'tissue'].indexOf(feature.properties.kind) >= 0);
|
|
848
|
+
this.selectFeature_(featureId, dim);
|
|
841
849
|
} else {
|
|
842
850
|
this.unselectFeature_(featureId);
|
|
843
851
|
}
|
|
@@ -1103,6 +1111,20 @@ export class UserInteractions
|
|
|
1103
1111
|
|
|
1104
1112
|
return true;
|
|
1105
1113
|
}
|
|
1114
|
+
|
|
1115
|
+
enablePanZoomEvents(enabled=true)
|
|
1116
|
+
//===============================
|
|
1117
|
+
{
|
|
1118
|
+
this.__pan_zoom_enabled = enabled;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
panZoomEvent_(type)
|
|
1122
|
+
//=================
|
|
1123
|
+
{
|
|
1124
|
+
if (this.__pan_zoom_enabled) {
|
|
1125
|
+
this._flatmap.panZoomEvent(type);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1106
1128
|
}
|
|
1107
1129
|
|
|
1108
1130
|
//==============================================================================
|
package/src/styling.js
CHANGED
|
@@ -117,12 +117,22 @@ export class FeatureFillLayer extends VectorStyleLayer
|
|
|
117
117
|
const paintStyle = {
|
|
118
118
|
'fill-color': [
|
|
119
119
|
'case',
|
|
120
|
+
['any',
|
|
121
|
+
['==', ['get', 'kind'], 'scaffold'],
|
|
122
|
+
['==', ['get', 'kind'], 'tissue'],
|
|
123
|
+
['==', ['get', 'kind'], 'cell-type']
|
|
124
|
+
], "white",
|
|
120
125
|
['boolean', ['feature-state', 'selected'], false], '#0F0',
|
|
121
126
|
['boolean', ['feature-state', 'active'], false], coloured ? '#D88' : '#CCC',
|
|
122
127
|
'white' // background colour? body colour ??
|
|
123
128
|
],
|
|
124
129
|
'fill-opacity': [
|
|
125
130
|
'case',
|
|
131
|
+
['any',
|
|
132
|
+
['==', ['get', 'kind'], 'scaffold'],
|
|
133
|
+
['==', ['get', 'kind'], 'tissue'],
|
|
134
|
+
['==', ['get', 'kind'], 'cell-type']
|
|
135
|
+
], 0.1,
|
|
126
136
|
['boolean', ['feature-state', 'selected'], false], 1.0,
|
|
127
137
|
['boolean', ['feature-state', 'active'], false], 0.8,
|
|
128
138
|
(coloured && !dimmed) ? 0.01 : 0.5
|
|
@@ -164,12 +174,12 @@ export class FeatureBorderLayer extends VectorStyleLayer
|
|
|
164
174
|
const outlined = !('outline' in options) || options.outline;
|
|
165
175
|
const dimmed = 'dimmed' in options && options.dimmed;
|
|
166
176
|
const lineColour = [ 'case' ];
|
|
177
|
+
lineColour.push(['boolean', ['feature-state', 'selected'], false]);
|
|
178
|
+
lineColour.push('red');
|
|
167
179
|
if (coloured && outlined) {
|
|
168
180
|
lineColour.push(['boolean', ['feature-state', 'active'], false]);
|
|
169
181
|
lineColour.push('blue');
|
|
170
182
|
}
|
|
171
|
-
lineColour.push(['boolean', ['feature-state', 'selected'], false]);
|
|
172
|
-
lineColour.push('red');
|
|
173
183
|
lineColour.push('#444');
|
|
174
184
|
|
|
175
185
|
const lineOpacity = [
|
|
@@ -254,7 +264,17 @@ export class PathLineLayer extends VectorStyleLayer
|
|
|
254
264
|
{
|
|
255
265
|
const filterType = dashed ? 'line-dash' : 'line';
|
|
256
266
|
super(mapLayerId, sourceLayer, filterType);
|
|
257
|
-
this.
|
|
267
|
+
this.__filter = dashed ?
|
|
268
|
+
[
|
|
269
|
+
'any',
|
|
270
|
+
['==', 'type', `line-dash`]
|
|
271
|
+
]
|
|
272
|
+
:
|
|
273
|
+
[
|
|
274
|
+
'any',
|
|
275
|
+
['==', 'type', 'bezier'],
|
|
276
|
+
['==', 'type', `line`]
|
|
277
|
+
];
|
|
258
278
|
this.__dashed = dashed;
|
|
259
279
|
}
|
|
260
280
|
|
|
@@ -278,7 +298,7 @@ export class PathLineLayer extends VectorStyleLayer
|
|
|
278
298
|
],
|
|
279
299
|
'line-opacity': [
|
|
280
300
|
'case',
|
|
281
|
-
['==', ['get', 'type'], 'bezier'], 0
|
|
301
|
+
['==', ['get', 'type'], 'bezier'], 1.0,
|
|
282
302
|
['boolean', ['get', 'invisible'], false], 0.001,
|
|
283
303
|
['boolean', ['feature-state', 'selected'], false], 1.0,
|
|
284
304
|
['boolean', ['feature-state', 'active'], false], 0.8,
|
|
@@ -289,7 +309,7 @@ export class PathLineLayer extends VectorStyleLayer
|
|
|
289
309
|
'let',
|
|
290
310
|
'width', [
|
|
291
311
|
'case',
|
|
292
|
-
['==', ['get', 'type'], 'bezier'], 0.
|
|
312
|
+
['==', ['get', 'type'], 'bezier'], 0.1,
|
|
293
313
|
['boolean', ['get', 'centreline'], false], 0.5,
|
|
294
314
|
['boolean', ['get', 'invisible'], false], 0.1,
|
|
295
315
|
['boolean', ['feature-state', 'selected'], false], 1.2,
|
|
@@ -319,10 +339,7 @@ export class PathLineLayer extends VectorStyleLayer
|
|
|
319
339
|
'filter': [
|
|
320
340
|
'all',
|
|
321
341
|
['==', '$type', 'LineString'],
|
|
322
|
-
|
|
323
|
-
['==', 'type', 'bezier'],
|
|
324
|
-
['==', 'type', `${this.__filterType}`]
|
|
325
|
-
]
|
|
342
|
+
this.__filter
|
|
326
343
|
],
|
|
327
344
|
'paint': this.paintStyle(options)
|
|
328
345
|
};
|
|
@@ -455,6 +472,7 @@ export class NervePolygonFill extends VectorStyleLayer
|
|
|
455
472
|
['==', '$type', 'Polygon'],
|
|
456
473
|
['any',
|
|
457
474
|
['==', 'type', 'bezier'],
|
|
475
|
+
['==', 'type', 'junction'],
|
|
458
476
|
['==', 'type', 'nerve'],
|
|
459
477
|
['==', 'type', 'nerve-section']
|
|
460
478
|
]
|
|
@@ -462,13 +480,22 @@ export class NervePolygonFill extends VectorStyleLayer
|
|
|
462
480
|
'paint': {
|
|
463
481
|
'fill-color': [
|
|
464
482
|
'case',
|
|
465
|
-
['==', ['get', 'kind'], 'bezier-
|
|
466
|
-
['==', ['get', 'kind'], 'bezier-
|
|
483
|
+
['==', ['get', 'kind'], 'bezier-end'], 'red',
|
|
484
|
+
['==', ['get', 'kind'], 'bezier-control'], 'green',
|
|
485
|
+
['==', ['get', 'kind'], 'cns'], '#9B1FC1',
|
|
486
|
+
['==', ['get', 'kind'], 'lcn'], '#F19E38',
|
|
487
|
+
['==', ['get', 'kind'], 'para-post'], '#3F8F4A',
|
|
488
|
+
['==', ['get', 'kind'], 'para-pre'], '#3F8F4A',
|
|
489
|
+
['==', ['get', 'kind'], 'somatic'], '#98561D',
|
|
490
|
+
['==', ['get', 'kind'], 'sensory'], '#2A62F6',
|
|
491
|
+
['==', ['get', 'kind'], 'symp-post'], '#EA3423',
|
|
492
|
+
['==', ['get', 'kind'], 'symp-pre'], '#EA3423',
|
|
467
493
|
'white'
|
|
468
494
|
],
|
|
469
495
|
'fill-opacity': [
|
|
470
496
|
'case',
|
|
471
|
-
['==', ['get', 'type'], 'bezier'], 0.
|
|
497
|
+
['==', ['get', 'type'], 'bezier'], 0.9,
|
|
498
|
+
['==', ['get', 'type'], 'junction'], 0.4,
|
|
472
499
|
0.01
|
|
473
500
|
]
|
|
474
501
|
}
|