@abi-software/flatmap-viewer 2.2.12-b.3 → 2.2.13-b.1
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.rst +1 -1
- package/package.json +1 -1
- package/src/controls.js +117 -0
- package/src/flatmap-viewer.js +26 -10
- package/src/interactions.js +92 -84
- package/src/layers.js +4 -5
- package/src/styling.js +3 -15
- package/src/systems.js +76 -0
package/README.rst
CHANGED
|
@@ -38,7 +38,7 @@ The map server endpoint is specified as ``MAP_ENDPOINT`` in ``src/main.js``. It
|
|
|
38
38
|
Package Installation
|
|
39
39
|
====================
|
|
40
40
|
|
|
41
|
-
* ``npm install @abi-software/flatmap-viewer@2.2.
|
|
41
|
+
* ``npm install @abi-software/flatmap-viewer@2.2.13-b.1``
|
|
42
42
|
|
|
43
43
|
Documentation
|
|
44
44
|
-------------
|
package/package.json
CHANGED
package/src/controls.js
CHANGED
|
@@ -324,6 +324,123 @@ export class LayerControl
|
|
|
324
324
|
|
|
325
325
|
//==============================================================================
|
|
326
326
|
|
|
327
|
+
export class Control
|
|
328
|
+
{
|
|
329
|
+
constructor(flatmap, id, name)
|
|
330
|
+
{
|
|
331
|
+
this.__flatmap = flatmap;
|
|
332
|
+
this.__id = id;
|
|
333
|
+
this.__name = name;
|
|
334
|
+
this.__map = undefined;
|
|
335
|
+
this.__prefix = `${this.__id}-`
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
getDefaultPosition()
|
|
339
|
+
//==================
|
|
340
|
+
{
|
|
341
|
+
return 'top-right';
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
__innerLinesHTML()
|
|
345
|
+
//================
|
|
346
|
+
{
|
|
347
|
+
return [];
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
__enableAll(enable)
|
|
351
|
+
//=================
|
|
352
|
+
{
|
|
353
|
+
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
onAdd(map)
|
|
357
|
+
//========
|
|
358
|
+
{
|
|
359
|
+
this.__map = map;
|
|
360
|
+
this.__container = document.createElement('div');
|
|
361
|
+
this.__container.className = 'maplibregl-ctrl flatmap-control';
|
|
362
|
+
this.__control = document.createElement('div');
|
|
363
|
+
this.__control.className = 'flatmap-control-grid';
|
|
364
|
+
|
|
365
|
+
const innerHTML = this.__innerLinesHTML();
|
|
366
|
+
this.__totalCount = innerHTML.length;
|
|
367
|
+
innerHTML.splice(0, 0, `<label for="control-all-${this.__id}">ALL ${this.__name.toUpperCase()}:</label><input id="control-all-${this.__id}" type="checkbox" checked/>`);
|
|
368
|
+
this.__control.innerHTML = innerHTML.join('\n');
|
|
369
|
+
|
|
370
|
+
this.__checkedCount = this.__totalCount;
|
|
371
|
+
this.__halfCount = Math.trunc(this.__checkedCount/2);
|
|
372
|
+
|
|
373
|
+
this.__button = document.createElement('button');
|
|
374
|
+
this.__button.id = `flatmap-${this.__id}-button`;
|
|
375
|
+
this.__button.className = 'control-button text-button';
|
|
376
|
+
this.__button.setAttribute('type', 'button');
|
|
377
|
+
this.__button.setAttribute('aria-label', `Show/hide map's ${this.__name}`);
|
|
378
|
+
this.__button.setAttribute('control-visible', 'false');
|
|
379
|
+
this.__button.textContent = this.__name.toUpperCase().substring(0, 6);
|
|
380
|
+
this.__button.title = `Show/hide map's ${this.__name}`;
|
|
381
|
+
this.__container.appendChild(this.__button);
|
|
382
|
+
|
|
383
|
+
this.__container.addEventListener('click', this.onClick_.bind(this));
|
|
384
|
+
return this.__container;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
onRemove()
|
|
388
|
+
//========
|
|
389
|
+
{
|
|
390
|
+
this.__container.parentNode.removeChild(this.__container);
|
|
391
|
+
this.__map = undefined;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
onClick_(event)
|
|
395
|
+
//=============
|
|
396
|
+
{
|
|
397
|
+
if (event.target.id === `flatmap-${this.__id}-button`) {
|
|
398
|
+
if (this.__button.getAttribute('control-visible') === 'false') {
|
|
399
|
+
this.__container.appendChild(this.__control);
|
|
400
|
+
this.__button.setAttribute('control-visible', 'true');
|
|
401
|
+
this.__control.focus();
|
|
402
|
+
} else {
|
|
403
|
+
this.__control = this.__container.removeChild(this.__control);
|
|
404
|
+
this.__button.setAttribute('control-visible', 'false');
|
|
405
|
+
}
|
|
406
|
+
} else if (event.target.tagName === 'INPUT') {
|
|
407
|
+
if (event.target.id === `control-all-${this.__id}`) {
|
|
408
|
+
if (event.target.indeterminate) {
|
|
409
|
+
event.target.checked = (this.__checkedCount >= this.__halfCount);
|
|
410
|
+
event.target.indeterminate = false;
|
|
411
|
+
}
|
|
412
|
+
if (event.target.checked) {
|
|
413
|
+
this.__checkedCount = this.__totalCount;
|
|
414
|
+
} else {
|
|
415
|
+
this.__checkedCount = 0;
|
|
416
|
+
}
|
|
417
|
+
this.__enableAll(event.target.checked);
|
|
418
|
+
} else if (event.target.id.startsWith(`${this.__id}-`)) {
|
|
419
|
+
this.__enableControl(event.target.id.substring(this.__prefix.length),
|
|
420
|
+
event.target.checked);
|
|
421
|
+
if (event.target.checked) {
|
|
422
|
+
this.__checkedCount += 1;
|
|
423
|
+
} else {
|
|
424
|
+
this.__checkedCount -= 1;
|
|
425
|
+
}
|
|
426
|
+
const allCheckbox = document.getElementById(`control-all-${this.__id}`);
|
|
427
|
+
if (this.__checkedCount === 0) {
|
|
428
|
+
allCheckbox.checked = false;
|
|
429
|
+
allCheckbox.indeterminate = false;
|
|
430
|
+
} else if (this.__checkedCount === this.__totalCount) {
|
|
431
|
+
allCheckbox.checked = true;
|
|
432
|
+
allCheckbox.indeterminate = false;
|
|
433
|
+
} else {
|
|
434
|
+
allCheckbox.indeterminate = true;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
event.stopPropagation();
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
//==============================================================================
|
|
443
|
+
|
|
327
444
|
const SCKAN_STATES = [
|
|
328
445
|
{
|
|
329
446
|
'id': 'VALID',
|
package/src/flatmap-viewer.js
CHANGED
|
@@ -797,24 +797,40 @@ class FlatMap
|
|
|
797
797
|
return this._userInteractions.getSystems();
|
|
798
798
|
}
|
|
799
799
|
}
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* @param {string} systemName The name of the system to enable
|
|
803
|
+
* @param {boolean} enable Show or hide the system. Defaults to ``true`` (show)
|
|
804
|
+
*
|
|
805
|
+
*/
|
|
806
|
+
enableSystem(systemName, enable=true)
|
|
807
|
+
//===================================
|
|
808
|
+
{
|
|
809
|
+
if (this._userInteractions !== null) {
|
|
810
|
+
return this._userInteractions.enableSystem(systemName, enable);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
|
|
800
814
|
//==========================================================================
|
|
801
815
|
|
|
802
816
|
/**
|
|
803
817
|
* Add a marker to the map.
|
|
804
818
|
*
|
|
805
|
-
* @param
|
|
806
|
-
*
|
|
807
|
-
* @
|
|
808
|
-
*
|
|
809
|
-
*
|
|
810
|
-
* @
|
|
811
|
-
*
|
|
819
|
+
* @param {string} anatomicalId The anatomical identifier of the feature on which
|
|
820
|
+
* to place the marker.
|
|
821
|
+
* @arg {Object} options Configurable options for the marker.
|
|
822
|
+
* @arg {string} options.colour Colour of the default marker. Defaults to ``'#005974'``
|
|
823
|
+
* (dark blue).
|
|
824
|
+
* @arg {string} options.element The DOM element to use as a marker. The default is
|
|
825
|
+
* a dark blue droplet-shaped SVG marker.
|
|
826
|
+
* @return {integer} The identifier for the resulting marker. -1 is returned if the
|
|
827
|
+
* map doesn't contain a feature with the given anatomical identifier
|
|
812
828
|
*/
|
|
813
|
-
addMarker(anatomicalId,
|
|
814
|
-
|
|
829
|
+
addMarker(anatomicalId, options={})
|
|
830
|
+
//==================================
|
|
815
831
|
{
|
|
816
832
|
if (this._userInteractions !== null) {
|
|
817
|
-
return this._userInteractions.addMarker(anatomicalId,
|
|
833
|
+
return this._userInteractions.addMarker(anatomicalId, options);
|
|
818
834
|
}
|
|
819
835
|
return -1;
|
|
820
836
|
}
|
package/src/interactions.js
CHANGED
|
@@ -38,9 +38,11 @@ import {displayedProperties} from './info.js';
|
|
|
38
38
|
import {InfoControl} from './info.js';
|
|
39
39
|
import {LayerManager} from './layers.js';
|
|
40
40
|
import {PATHWAYS_LAYER, Pathways} from './pathways.js';
|
|
41
|
-
import {BackgroundControl, LayerControl, NerveControl,
|
|
41
|
+
import {BackgroundControl, LayerControl, NerveControl,
|
|
42
|
+
PathControl, SCKANControl} from './controls.js';
|
|
42
43
|
import {SearchControl} from './search.js';
|
|
43
44
|
import {VECTOR_TILES_SOURCE} from './styling.js';
|
|
45
|
+
import {SystemsControl, SystemsManager} from './systems';
|
|
44
46
|
|
|
45
47
|
import * as pathways from './pathways.js';
|
|
46
48
|
import * as utils from './utils.js';
|
|
@@ -115,6 +117,7 @@ export class UserInteractions
|
|
|
115
117
|
this.__activeMarker = null;
|
|
116
118
|
this.__lastMarkerId = 900000;
|
|
117
119
|
this.__markerIdByMarker = new Map();
|
|
120
|
+
this.__markerIdByFeatureId = new Map();
|
|
118
121
|
this.__annotationByMarkerId = new Map();
|
|
119
122
|
|
|
120
123
|
// Where to put labels and popups on a feature
|
|
@@ -142,6 +145,27 @@ export class UserInteractions
|
|
|
142
145
|
}
|
|
143
146
|
}
|
|
144
147
|
|
|
148
|
+
// Flag features that have annotations and note which are FC systems
|
|
149
|
+
|
|
150
|
+
this.__systems = new Map();
|
|
151
|
+
for (const [id, ann] of flatmap.annotations) {
|
|
152
|
+
const feature = this.mapFeature_(id);
|
|
153
|
+
if (feature !== undefined) {
|
|
154
|
+
this._map.setFeatureState(feature, { 'annotated': true });
|
|
155
|
+
}
|
|
156
|
+
if (ann['fc-class'] === 'fc-class:System') {
|
|
157
|
+
if (this.__systems.has(ann.name)) {
|
|
158
|
+
this.__systems.get(ann.name).featureIds.push(ann.featureId)
|
|
159
|
+
} else {
|
|
160
|
+
this.__systems.set(ann.name, {
|
|
161
|
+
id: ann.name.replaceAll(' ', '_'),
|
|
162
|
+
colour: ann.colour,
|
|
163
|
+
featureIds: [ ann.featureId ]
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
145
169
|
// Add various controls when running standalone
|
|
146
170
|
|
|
147
171
|
if (flatmap.options.standalone) {
|
|
@@ -167,48 +191,13 @@ export class UserInteractions
|
|
|
167
191
|
this.enableCentrelines(false);
|
|
168
192
|
}
|
|
169
193
|
|
|
170
|
-
//
|
|
194
|
+
// SCKAN path and SYSTEMS controls for FC maps
|
|
171
195
|
if (flatmap.options.style === 'functional') {
|
|
196
|
+
this._map.addControl(new SystemsControl(flatmap, this.__systems));
|
|
172
197
|
this._map.addControl(new SCKANControl(flatmap, flatmap.options.layerOptions));
|
|
173
198
|
}
|
|
174
199
|
}
|
|
175
200
|
|
|
176
|
-
// Flag features that have annotations and not which are FC systems
|
|
177
|
-
|
|
178
|
-
this.__systems = [];
|
|
179
|
-
const seenSystems = [];
|
|
180
|
-
for (const [id, ann] of flatmap.annotations) {
|
|
181
|
-
const feature = this.mapFeature_(id);
|
|
182
|
-
if (feature !== undefined) {
|
|
183
|
-
this._map.setFeatureState(feature, { 'annotated': true });
|
|
184
|
-
}
|
|
185
|
-
if (ann['fc-class'] === 'FC_CLASS.SYSTEM') {
|
|
186
|
-
if (seenSystems.indexOf(ann['name']) < 0) {
|
|
187
|
-
seenSystems.push(ann['name']);
|
|
188
|
-
this.__systems.push({
|
|
189
|
-
name: ann['name'],
|
|
190
|
-
colour: ann['colour']
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Display a context menu on right-click
|
|
197
|
-
|
|
198
|
-
this._lastContextTime = 0;
|
|
199
|
-
this._contextMenu = new ContextMenu(flatmap, this.__clearModal.bind(this));
|
|
200
|
-
this._map.on('contextmenu', this.contextMenuEvent_.bind(this));
|
|
201
|
-
|
|
202
|
-
// Display a context menu with a touch longer than 0.5 second
|
|
203
|
-
|
|
204
|
-
this._lastTouchTime = 0;
|
|
205
|
-
this._map.on('touchstart', (e) => { this._lastTouchTime = Date.now(); });
|
|
206
|
-
this._map.on('touchend', (e) => {
|
|
207
|
-
if (Date.now() > (this._lastTouchTime + 500)) {
|
|
208
|
-
this.contextMenuEvent_(e);
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
|
|
212
201
|
// Handle mouse events
|
|
213
202
|
|
|
214
203
|
this._map.on('click', this.clickEvent_.bind(this));
|
|
@@ -284,7 +273,61 @@ export class UserInteractions
|
|
|
284
273
|
getSystems()
|
|
285
274
|
//==========
|
|
286
275
|
{
|
|
287
|
-
|
|
276
|
+
const systems = [];
|
|
277
|
+
for (const system of this.__systems.values()) {
|
|
278
|
+
systems.push({
|
|
279
|
+
name: system.name,
|
|
280
|
+
colour: system.colour,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
return systems;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
enableSystem(systemName, enable=true)
|
|
287
|
+
//===================================
|
|
288
|
+
{
|
|
289
|
+
if (this.__systems.has(systemName)) {
|
|
290
|
+
for (const featureId of this.__systems.get(systemName).featureIds) {
|
|
291
|
+
this.__enableFeatureWithChildren(featureId, enable);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
__enableFeatureWithChildren(featureId, enable=true)
|
|
297
|
+
//=================================================
|
|
298
|
+
{
|
|
299
|
+
const feature = this.mapFeature_(featureId);
|
|
300
|
+
if (feature !== undefined) {
|
|
301
|
+
this.__enableFeature(feature, enable);
|
|
302
|
+
for (const childFeatureId of feature.children) {
|
|
303
|
+
this.__enableFeatureWithChildren(childFeatureId, enable);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
__enableFeatureMarker(featureId, enable=true)
|
|
309
|
+
//===========================================
|
|
310
|
+
{
|
|
311
|
+
const markerId = this.__markerIdByFeatureId.get(+featureId);
|
|
312
|
+
if (markerId !== undefined) {
|
|
313
|
+
const markerDiv = document.getElementById(`marker-${markerId}`);
|
|
314
|
+
if (markerDiv) {
|
|
315
|
+
markerDiv.style.visibility = enable ? 'visible' : 'hidden';
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
__enableFeature(feature, enable=true)
|
|
321
|
+
//===================================
|
|
322
|
+
{
|
|
323
|
+
if (feature !== undefined) {
|
|
324
|
+
if (enable) {
|
|
325
|
+
this._map.removeFeatureState(feature, 'hidden');
|
|
326
|
+
} else {
|
|
327
|
+
this._map.setFeatureState(feature, { 'hidden': true });
|
|
328
|
+
}
|
|
329
|
+
this.__enableFeatureMarker(feature.id, enable);
|
|
330
|
+
}
|
|
288
331
|
}
|
|
289
332
|
|
|
290
333
|
mapFeature_(featureId)
|
|
@@ -297,9 +340,11 @@ export class UserInteractions
|
|
|
297
340
|
source: VECTOR_TILES_SOURCE,
|
|
298
341
|
sourceLayer: this._flatmap.options.separateLayers
|
|
299
342
|
? `${ann['layer']}_${ann['tile-layer']}`
|
|
300
|
-
: ann['tile-layer']
|
|
343
|
+
: ann['tile-layer'],
|
|
344
|
+
children: ann.children || []
|
|
301
345
|
};
|
|
302
346
|
}
|
|
347
|
+
return undefined;
|
|
303
348
|
}
|
|
304
349
|
|
|
305
350
|
featureSelected_(featureId)
|
|
@@ -424,45 +469,6 @@ export class UserInteractions
|
|
|
424
469
|
return smallestFeature;
|
|
425
470
|
}
|
|
426
471
|
|
|
427
|
-
contextMenuEvent_(event)
|
|
428
|
-
//======================
|
|
429
|
-
{
|
|
430
|
-
event.preventDefault();
|
|
431
|
-
|
|
432
|
-
// Chrome on Android sends both touch and contextmenu events
|
|
433
|
-
// so ignore duplicate
|
|
434
|
-
|
|
435
|
-
if (Date.now() < (this._lastContextTime + 100)) {
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
this._lastContextTime = Date.now();
|
|
439
|
-
|
|
440
|
-
if (this._activeFeatures.length > 0) {
|
|
441
|
-
const feature = this._activeFeatures[0];
|
|
442
|
-
|
|
443
|
-
// Remove any tooltip
|
|
444
|
-
this.removeTooltip_();
|
|
445
|
-
|
|
446
|
-
const featureId = feature.id;
|
|
447
|
-
if (this._pathways.isNode(featureId)) {
|
|
448
|
-
const items = [
|
|
449
|
-
{
|
|
450
|
-
featureId: featureId,
|
|
451
|
-
prompt: 'Show paths',
|
|
452
|
-
action: this.enablePaths_.bind(this, true)
|
|
453
|
-
},
|
|
454
|
-
{
|
|
455
|
-
featureId: featureId,
|
|
456
|
-
prompt: 'Hide paths',
|
|
457
|
-
action: this.enablePaths_.bind(this, false)
|
|
458
|
-
}
|
|
459
|
-
];
|
|
460
|
-
this.setModal_();
|
|
461
|
-
this._contextMenu.show(event.lngLat, items, feature.properties.label);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
|
|
466
472
|
setModal_(event)
|
|
467
473
|
//==============
|
|
468
474
|
{
|
|
@@ -982,7 +988,6 @@ export class UserInteractions
|
|
|
982
988
|
enablePaths_(enable, event)
|
|
983
989
|
//=========================
|
|
984
990
|
{
|
|
985
|
-
this._contextMenu.hide();
|
|
986
991
|
const nodeId = event.target.getAttribute('featureId');
|
|
987
992
|
this.enablePathFeatures_(enable, this._pathways.pathFeatureIds(nodeId));
|
|
988
993
|
this.__clearModal();
|
|
@@ -1086,8 +1091,8 @@ export class UserInteractions
|
|
|
1086
1091
|
return position;
|
|
1087
1092
|
}
|
|
1088
1093
|
|
|
1089
|
-
addMarker(anatomicalId,
|
|
1090
|
-
|
|
1094
|
+
addMarker(anatomicalId, options={})
|
|
1095
|
+
//=================================
|
|
1091
1096
|
{
|
|
1092
1097
|
const featureIds = this._flatmap.modelFeatureIds(anatomicalId);
|
|
1093
1098
|
let markerId = -1;
|
|
@@ -1106,13 +1111,15 @@ export class UserInteractions
|
|
|
1106
1111
|
// MapLibre dynamically sets a transform on marker elements so in
|
|
1107
1112
|
// order to apply a scale transform we need to create marker icons
|
|
1108
1113
|
// inside the marker container <div>.
|
|
1109
|
-
const
|
|
1110
|
-
|
|
1114
|
+
const colour = options.colour || '#005974';
|
|
1115
|
+
const markerHTML = options.element ? new maplibre.Marker({element: options.element})
|
|
1116
|
+
: new maplibre.Marker({color: colour});
|
|
1111
1117
|
|
|
1112
1118
|
const markerElement = document.createElement('div');
|
|
1113
1119
|
const markerIcon = document.createElement('div');
|
|
1114
1120
|
markerIcon.innerHTML = markerHTML.getElement().innerHTML;
|
|
1115
1121
|
markerIcon.className = 'flatmap-marker';
|
|
1122
|
+
markerElement.id = `marker-${markerId}`;
|
|
1116
1123
|
markerElement.appendChild(markerIcon);
|
|
1117
1124
|
|
|
1118
1125
|
const markerPosition = this.__markerPosition(featureId, annotation);
|
|
@@ -1129,6 +1136,7 @@ export class UserInteractions
|
|
|
1129
1136
|
this.markerMouseEvent_.bind(this, marker, anatomicalId));
|
|
1130
1137
|
|
|
1131
1138
|
this.__markerIdByMarker.set(marker, markerId);
|
|
1139
|
+
this.__markerIdByFeatureId.set(+featureId, markerId);
|
|
1132
1140
|
this.__annotationByMarkerId.set(markerId, annotation);
|
|
1133
1141
|
}
|
|
1134
1142
|
}
|
package/src/layers.js
CHANGED
|
@@ -65,7 +65,7 @@ class MapStylingLayers
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
addLayer(styleLayer, options)
|
|
68
|
-
|
|
68
|
+
//===========================
|
|
69
69
|
{
|
|
70
70
|
this.__map.addLayer(styleLayer.style(options));
|
|
71
71
|
this.__layers.push(styleLayer);
|
|
@@ -89,8 +89,8 @@ class MapStylingLayers
|
|
|
89
89
|
vectorSourceId(sourceLayer)
|
|
90
90
|
//=========================
|
|
91
91
|
{
|
|
92
|
-
return this.__separateLayers ? `${this.__id}_${sourceLayer}`
|
|
93
|
-
|
|
92
|
+
return (this.__separateLayers ? `${this.__id}_${sourceLayer}`
|
|
93
|
+
: sourceLayer).replaceAll('/', '_');
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
setPaint(options)
|
|
@@ -144,8 +144,7 @@ class MapFeatureLayers extends MapStylingLayers
|
|
|
144
144
|
{
|
|
145
145
|
const styleLayer = new styleClass(`${this.__id}_${sourceLayer}`,
|
|
146
146
|
this.vectorSourceId(sourceLayer));
|
|
147
|
-
this.
|
|
148
|
-
this.__layers.push(styleLayer);
|
|
147
|
+
this.addLayer(styleLayer, this.__layerOptions);
|
|
149
148
|
}
|
|
150
149
|
|
|
151
150
|
__addPathwayStyleLayers()
|
package/src/styling.js
CHANGED
|
@@ -123,31 +123,21 @@ export class FeatureFillLayer extends VectorStyleLayer
|
|
|
123
123
|
{
|
|
124
124
|
const coloured = !('colour' in options) || options.colour;
|
|
125
125
|
const dimmed = 'dimmed' in options && options.dimmed;
|
|
126
|
-
const activeRasterLayer = 'activeRasterLayer' in options && options.activeRasterLayer;
|
|
127
126
|
const paintStyle = {
|
|
128
127
|
'fill-color': [
|
|
129
128
|
'case',
|
|
130
129
|
['boolean', ['feature-state', 'selected'], false], '#0F0',
|
|
131
130
|
['has', 'colour'], ['get', 'colour'],
|
|
132
131
|
['boolean', ['feature-state', 'active'], false], coloured ? '#D88' : '#CCC',
|
|
133
|
-
['any',
|
|
134
|
-
['==', ['get', 'kind'], 'scaffold']
|
|
135
|
-
], 'white',
|
|
136
|
-
['has', 'node'], '#AFA202',
|
|
137
132
|
'white' // background colour? body colour ??
|
|
138
133
|
],
|
|
139
134
|
'fill-opacity': [
|
|
140
135
|
'case',
|
|
136
|
+
['boolean', ['feature-state', 'hidden'], false], 0.01,
|
|
141
137
|
['boolean', ['feature-state', 'selected'], false], 0.7,
|
|
142
138
|
['has', 'opacity'], ['get', 'opacity'],
|
|
143
139
|
['has', 'colour'], 1.0,
|
|
144
140
|
['boolean', ['feature-state', 'active'], false], 0.7,
|
|
145
|
-
['has', 'node'], 0.3,
|
|
146
|
-
['any',
|
|
147
|
-
['==', ['get', 'kind'], 'scaffold'],
|
|
148
|
-
['==', ['get', 'kind'], 'tissue'],
|
|
149
|
-
['==', ['get', 'kind'], 'cell-type'],
|
|
150
|
-
], 0.1,
|
|
151
141
|
(coloured && !dimmed) ? 0.01 : 0.1
|
|
152
142
|
]
|
|
153
143
|
};
|
|
@@ -196,14 +186,12 @@ export class FeatureBorderLayer extends VectorStyleLayer
|
|
|
196
186
|
lineColour.push('blue');
|
|
197
187
|
}
|
|
198
188
|
lineColour.push(['has', 'colour']);
|
|
199
|
-
lineColour.push('
|
|
200
|
-
lineColour.push(['has', 'node']);
|
|
201
|
-
lineColour.push('#AFA202');
|
|
189
|
+
lineColour.push(['get', 'colour']);
|
|
202
190
|
lineColour.push('#444');
|
|
203
191
|
|
|
204
192
|
const lineOpacity = [
|
|
205
193
|
'case',
|
|
206
|
-
['boolean', ['
|
|
194
|
+
['boolean', ['feature-state', 'hidden'], false], 0.05,
|
|
207
195
|
];
|
|
208
196
|
if (coloured && outlined) {
|
|
209
197
|
lineOpacity.push(['boolean', ['feature-state', 'active'], false]);
|
package/src/systems.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
|
|
3
|
+
Flatmap viewer and annotation tool
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2019 - 2023 David Brooks
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
|
18
|
+
|
|
19
|
+
******************************************************************************/
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
import { Control } from './controls';
|
|
23
|
+
|
|
24
|
+
//==============================================================================
|
|
25
|
+
|
|
26
|
+
export class SystemsManager
|
|
27
|
+
{
|
|
28
|
+
constructor()
|
|
29
|
+
{
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//==============================================================================
|
|
35
|
+
|
|
36
|
+
export class SystemsControl extends Control
|
|
37
|
+
{
|
|
38
|
+
constructor(flatmap, systems)
|
|
39
|
+
{
|
|
40
|
+
super(flatmap, 'system', 'systems');
|
|
41
|
+
this.__systems = systems;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
__innerLinesHTML()
|
|
45
|
+
//================
|
|
46
|
+
{
|
|
47
|
+
const html = [];
|
|
48
|
+
for (const [name, system] of this.__systems.entries()) {
|
|
49
|
+
html.push(`<label for="${this.__prefix}${system.id}" style="background: ${system.colour};">${name}</label><input id="${this.__prefix}${system.id}" type="checkbox" checked/>`);
|
|
50
|
+
}
|
|
51
|
+
return html;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
__enableAll(enable)
|
|
55
|
+
//=================
|
|
56
|
+
{
|
|
57
|
+
for (const [name, system] of this.__systems.entries()) {
|
|
58
|
+
const checkbox = document.getElementById(`${this.__prefix}${system.id}`);
|
|
59
|
+
if (checkbox) {
|
|
60
|
+
checkbox.checked = enable;
|
|
61
|
+
this.__flatmap.enableSystem(name, enable);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
__enableControl(id, enable)
|
|
67
|
+
//=========================
|
|
68
|
+
{
|
|
69
|
+
for (const [name, system] of this.__systems.entries()) {
|
|
70
|
+
if (id === system.id) {
|
|
71
|
+
this.__flatmap.enableSystem(name, enable);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
}
|