@abi-software/flatmap-viewer 2.3.4 → 2.4.0-a.2
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/info.js +3 -1
- package/src/controls/minimap.js +1 -1
- package/src/flatmap-viewer.js +24 -6
- package/src/interactions.js +7 -7
- package/src/layers.js +4 -5
- package/src/main.js +0 -1
- package/src/search.js +1 -1
- package/src/systems.js +35 -5
- package/src/utils.js +3 -3
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.
|
|
41
|
+
* ``npm install @abi-software/flatmap-viewer@2.4.0-a.2``
|
|
42
42
|
|
|
43
43
|
Documentation
|
|
44
44
|
-------------
|
package/package.json
CHANGED
package/src/controls/info.js
CHANGED
|
@@ -25,6 +25,7 @@ import { indexedProperties } from '../search.js';
|
|
|
25
25
|
export const displayedProperties = [
|
|
26
26
|
'id',
|
|
27
27
|
'class',
|
|
28
|
+
'cd-class',
|
|
28
29
|
'fc-class',
|
|
29
30
|
'fc-kind',
|
|
30
31
|
'name',
|
|
@@ -138,6 +139,7 @@ export class InfoControl
|
|
|
138
139
|
this._active = true;
|
|
139
140
|
button.classList.add('control-button-active');
|
|
140
141
|
} else {
|
|
142
|
+
this.reset();
|
|
141
143
|
this._active = false;
|
|
142
144
|
button.classList.remove('control-button-active');
|
|
143
145
|
}
|
|
@@ -195,7 +197,7 @@ export class InfoControl
|
|
|
195
197
|
const featureIds = [];
|
|
196
198
|
const displayFeatures = [];
|
|
197
199
|
for (const feat of featureList) {
|
|
198
|
-
if (featureIds.
|
|
200
|
+
if (!featureIds.includes(feat.id)) {
|
|
199
201
|
featureIds.push(feat.id);
|
|
200
202
|
const displayFeat = {};
|
|
201
203
|
displayProperties.forEach(prop => {
|
package/src/controls/minimap.js
CHANGED
|
@@ -132,7 +132,7 @@ export class MinimapControl
|
|
|
132
132
|
let width = DEFAULTS.width;
|
|
133
133
|
if (typeof this._options.width === 'string') {
|
|
134
134
|
width = parseInt(this._options.width);
|
|
135
|
-
if (this._options.width.
|
|
135
|
+
if (this._options.width.includes('%')) {
|
|
136
136
|
width = width*mapCanvasElement.width/100;
|
|
137
137
|
}
|
|
138
138
|
} else if (typeof this._options.width === 'number') {
|
package/src/flatmap-viewer.js
CHANGED
|
@@ -60,8 +60,9 @@ class FlatMap
|
|
|
60
60
|
this._baseUrl = mapBaseUrl;
|
|
61
61
|
this.__id = mapDescription.id;
|
|
62
62
|
this.__uuid = mapDescription.uuid;
|
|
63
|
-
this.
|
|
64
|
-
this.
|
|
63
|
+
this.__details = mapDescription.details;
|
|
64
|
+
this.__provenance = mapDescription.provenance;
|
|
65
|
+
this.__created = mapDescription.created;
|
|
65
66
|
this.__taxon = mapDescription.taxon;
|
|
66
67
|
this.__biologicalSex = mapDescription.biologicalSex;
|
|
67
68
|
this._mapNumber = mapDescription.number;
|
|
@@ -169,7 +170,7 @@ class FlatMap
|
|
|
169
170
|
if (mapDescription.options.navigationControl) {
|
|
170
171
|
const value = mapDescription.options.navigationControl;
|
|
171
172
|
const position = ((typeof value === 'string')
|
|
172
|
-
&&
|
|
173
|
+
&& ['top-left', 'top-right', 'bottom-right', 'bottom-left'].includes(value))
|
|
173
174
|
? value : 'bottom-right';
|
|
174
175
|
this._map.addControl(new NavigationControl(this), position);
|
|
175
176
|
}
|
|
@@ -424,7 +425,7 @@ class FlatMap
|
|
|
424
425
|
get created()
|
|
425
426
|
//===========
|
|
426
427
|
{
|
|
427
|
-
return this.
|
|
428
|
+
return this.__created;
|
|
428
429
|
}
|
|
429
430
|
|
|
430
431
|
/**
|
|
@@ -460,7 +461,18 @@ class FlatMap
|
|
|
460
461
|
get details()
|
|
461
462
|
//===========
|
|
462
463
|
{
|
|
463
|
-
return this.
|
|
464
|
+
return this.__details;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* The map's provenance as returned from the map server.
|
|
469
|
+
*
|
|
470
|
+
* @type Object
|
|
471
|
+
*/
|
|
472
|
+
get provenance()
|
|
473
|
+
//==============
|
|
474
|
+
{
|
|
475
|
+
return this.__provenance;
|
|
464
476
|
}
|
|
465
477
|
|
|
466
478
|
/**
|
|
@@ -958,6 +970,7 @@ class FlatMap
|
|
|
958
970
|
'models',
|
|
959
971
|
'nodeId',
|
|
960
972
|
'source',
|
|
973
|
+
'taxon',
|
|
961
974
|
'hyperlinks'
|
|
962
975
|
];
|
|
963
976
|
const jsonProperties = [
|
|
@@ -967,7 +980,7 @@ class FlatMap
|
|
|
967
980
|
if (property in properties) {
|
|
968
981
|
const value = properties[property];
|
|
969
982
|
if (value !== undefined) {
|
|
970
|
-
if (jsonProperties.
|
|
983
|
+
if (jsonProperties.includes(property)) {
|
|
971
984
|
data[property] = JSON.parse(properties[property])
|
|
972
985
|
} else {
|
|
973
986
|
data[property] = properties[property];
|
|
@@ -1405,6 +1418,10 @@ export class MapManager
|
|
|
1405
1418
|
|
|
1406
1419
|
const annotations = await this._mapServer.loadJSON(`flatmap/${mapId}/annotations`);
|
|
1407
1420
|
|
|
1421
|
+
// Get the map's provenance
|
|
1422
|
+
|
|
1423
|
+
const provenance = await this._mapServer.loadJSON(`flatmap/${mapId}/metadata`);
|
|
1424
|
+
|
|
1408
1425
|
// Get additional marker details for the map
|
|
1409
1426
|
|
|
1410
1427
|
const mapMarkers = await this._mapServer.loadJSON(`flatmap/${mapId}/markers`);
|
|
@@ -1458,6 +1475,7 @@ export class MapManager
|
|
|
1458
1475
|
annotations: annotations,
|
|
1459
1476
|
number: this._mapNumber,
|
|
1460
1477
|
pathways: pathways,
|
|
1478
|
+
provenance, provenance,
|
|
1461
1479
|
callback: callback
|
|
1462
1480
|
},
|
|
1463
1481
|
resolve);
|
package/src/interactions.js
CHANGED
|
@@ -261,7 +261,7 @@ export class UserInteractions
|
|
|
261
261
|
const feature = this.mapFeature(mapId);
|
|
262
262
|
if (feature !== undefined) {
|
|
263
263
|
this._map.setFeatureState(feature, { 'map-annotation': true });
|
|
264
|
-
if (annotated_features.
|
|
264
|
+
if (annotated_features.includes(ann.id)) {
|
|
265
265
|
this._map.setFeatureState(feature, { 'annotated': true });
|
|
266
266
|
}
|
|
267
267
|
}
|
|
@@ -902,7 +902,7 @@ export class UserInteractions
|
|
|
902
902
|
const htmlList = [];
|
|
903
903
|
const featureIds = [];
|
|
904
904
|
for (const feature of labelledFeatures) {
|
|
905
|
-
if (featureIds.
|
|
905
|
+
if (!featureIds.includes(feature.id)) {
|
|
906
906
|
featureIds.push(feature.id);
|
|
907
907
|
for (const prop of debugProperties) {
|
|
908
908
|
if (prop in feature.properties) {
|
|
@@ -976,7 +976,7 @@ export class UserInteractions
|
|
|
976
976
|
const clickedFeatureId = feature.id;
|
|
977
977
|
const dim = !('properties' in feature
|
|
978
978
|
&& 'kind' in feature.properties
|
|
979
|
-
&& ['cell-type', 'scaffold', 'tissue'].
|
|
979
|
+
&& ['cell-type', 'scaffold', 'tissue'].includes(feature.properties.kind));
|
|
980
980
|
if (!(event.ctrlKey || event.metaKey)) {
|
|
981
981
|
let selecting = true;
|
|
982
982
|
for (const featureId of this._selectedFeatureIds.keys()) {
|
|
@@ -1177,7 +1177,7 @@ export class UserInteractions
|
|
|
1177
1177
|
|
|
1178
1178
|
for (const featureId of featureIds) {
|
|
1179
1179
|
const annotation = this._flatmap.annotation(featureId);
|
|
1180
|
-
if (annotation.geometry.
|
|
1180
|
+
if (!annotation.geometry.includes('Polygon')) {
|
|
1181
1181
|
continue;
|
|
1182
1182
|
}
|
|
1183
1183
|
if (!('marker' in annotation)) {
|
|
@@ -1258,7 +1258,7 @@ export class UserInteractions
|
|
|
1258
1258
|
for (const [marker, id] of this.__markerIdByMarker.entries()) {
|
|
1259
1259
|
if (visibleBounds.contains(marker.getLngLat())) {
|
|
1260
1260
|
const annotation = this.__annotationByMarkerId.get(id);
|
|
1261
|
-
if (anatomicalIds.
|
|
1261
|
+
if (!anatomicalIds.includes(annotation.models)) {
|
|
1262
1262
|
anatomicalIds.push(annotation.models);
|
|
1263
1263
|
}
|
|
1264
1264
|
}
|
|
@@ -1275,7 +1275,7 @@ export class UserInteractions
|
|
|
1275
1275
|
return;
|
|
1276
1276
|
}
|
|
1277
1277
|
|
|
1278
|
-
if (['mouseenter', 'mouseleave', 'click'].
|
|
1278
|
+
if (['mouseenter', 'mouseleave', 'click'].includes(event.type)) {
|
|
1279
1279
|
this.__activeMarker = marker;
|
|
1280
1280
|
|
|
1281
1281
|
// Remove any existing tooltips
|
|
@@ -1285,7 +1285,7 @@ export class UserInteractions
|
|
|
1285
1285
|
// Reset cursor
|
|
1286
1286
|
marker.getElement().style.cursor = 'default';
|
|
1287
1287
|
|
|
1288
|
-
if (['mouseenter', 'click'].
|
|
1288
|
+
if (['mouseenter', 'click'].includes(event.type)) {
|
|
1289
1289
|
const markerId = this.__markerIdByMarker.get(marker);
|
|
1290
1290
|
const annotation = this.__annotationByMarkerId.get(markerId);
|
|
1291
1291
|
// The marker's feature
|
package/src/layers.js
CHANGED
|
@@ -115,8 +115,7 @@ class MapFeatureLayers extends MapStylingLayers
|
|
|
115
115
|
// if no image layers then make feature borders (and lines?) more visible...??
|
|
116
116
|
if (haveVectorLayers) {
|
|
117
117
|
const featuresVectorSource = this.vectorSourceId(FEATURES_LAYER);
|
|
118
|
-
const vectorFeatures = vectorTileSource.vectorLayerIds
|
|
119
|
-
.indexOf(featuresVectorSource) >= 0;
|
|
118
|
+
const vectorFeatures = vectorTileSource.vectorLayerIds.includes(featuresVectorSource);
|
|
120
119
|
if (vectorFeatures) {
|
|
121
120
|
this.__addStyleLayer(style.FeatureFillLayer);
|
|
122
121
|
this.__addStyleLayer(style.FeatureDashLineLayer);
|
|
@@ -152,7 +151,7 @@ class MapFeatureLayers extends MapStylingLayers
|
|
|
152
151
|
const pathwaysVectorSource = this.vectorSourceId(PATHWAYS_LAYER);
|
|
153
152
|
if (this.__map.getSource('vector-tiles')
|
|
154
153
|
.vectorLayerIds
|
|
155
|
-
.
|
|
154
|
+
.includes(pathwaysVectorSource)) {
|
|
156
155
|
this.__addStyleLayer(style.AnnotatedPathLayer, PATHWAYS_LAYER);
|
|
157
156
|
|
|
158
157
|
this.__addStyleLayer(style.CentrelineEdgeLayer, PATHWAYS_LAYER);
|
|
@@ -343,8 +342,8 @@ export class LayerManager
|
|
|
343
342
|
//=======================================
|
|
344
343
|
{
|
|
345
344
|
const currentState = this.__layerOptions.sckan;
|
|
346
|
-
const validEnabled = ['valid', 'all'].
|
|
347
|
-
const invalidEnabled = ['invalid', 'all'].
|
|
345
|
+
const validEnabled = ['valid', 'all'].includes(currentState);
|
|
346
|
+
const invalidEnabled = ['invalid', 'all'].includes(currentState);
|
|
348
347
|
let newState = sckanState.toLowerCase();
|
|
349
348
|
if (newState === 'valid') {
|
|
350
349
|
if (enable && !validEnabled) {
|
package/src/main.js
CHANGED
package/src/search.js
CHANGED
|
@@ -96,7 +96,7 @@ export class SearchIndex
|
|
|
96
96
|
const options = {};
|
|
97
97
|
let results = [];
|
|
98
98
|
text = text.trim()
|
|
99
|
-
if (text.length > 2 && ["'", '"'].
|
|
99
|
+
if (text.length > 2 && ["'", '"'].includes(text.slice(0, 1))) {
|
|
100
100
|
text = text.replaceAll(text.slice(0, 1), '');
|
|
101
101
|
results = this._searchEngine.search(text, {prefix: true, combineWith: 'AND'});
|
|
102
102
|
} else if (text.length > 1) {
|
package/src/systems.js
CHANGED
|
@@ -16,18 +16,26 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
16
16
|
See the License for the specific language governing permissions and
|
|
17
17
|
limitations under the License.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
******************************************************************************/
|
|
20
|
+
|
|
21
|
+
const FC_KIND = {
|
|
22
|
+
SYSTEM: ['fc:System', 'fc-class:System'],
|
|
23
|
+
ORGAN: ['fc:Organ', 'fc-class:Organ'],
|
|
24
|
+
FTU: ['fc:Ftu', 'fc-class:Ftu']
|
|
25
|
+
};
|
|
26
|
+
|
|
20
27
|
//==============================================================================
|
|
21
28
|
|
|
22
29
|
export class SystemsManager
|
|
23
30
|
{
|
|
24
31
|
constructor(flatmap, ui, enabled=false)
|
|
25
32
|
{
|
|
33
|
+
this.__flatmap = flatmap;
|
|
26
34
|
this.__ui = ui;
|
|
27
35
|
this.__systems = new Map();
|
|
28
36
|
this.__enabledChildren = new Map();
|
|
29
|
-
for (const [
|
|
30
|
-
if (ann['fc-class']
|
|
37
|
+
for (const [_, ann] of flatmap.annotations) {
|
|
38
|
+
if (FC_KIND.SYSTEM.includes(ann['fc-class'])) {
|
|
31
39
|
const systemId = ann.name.replaceAll(' ', '_');
|
|
32
40
|
if (this.__systems.has(systemId)) {
|
|
33
41
|
this.__systems.get(systemId).featureIds.push(ann.featureId)
|
|
@@ -37,7 +45,8 @@ export class SystemsManager
|
|
|
37
45
|
colour: ann.colour,
|
|
38
46
|
featureIds: [ ann.featureId ],
|
|
39
47
|
enabled: false,
|
|
40
|
-
pathIds: ('path-ids' in ann) ? ann['path-ids'] : []
|
|
48
|
+
pathIds: ('path-ids' in ann) ? ann['path-ids'] : [],
|
|
49
|
+
organs: this.__children(ann.children, FC_KIND.ORGAN)
|
|
41
50
|
});
|
|
42
51
|
this.__ui.enableFeature(ann.featureId, false, true);
|
|
43
52
|
}
|
|
@@ -57,6 +66,26 @@ export class SystemsManager
|
|
|
57
66
|
}
|
|
58
67
|
}
|
|
59
68
|
|
|
69
|
+
__children(childFeatureIds, childClass)
|
|
70
|
+
//=====================================
|
|
71
|
+
{
|
|
72
|
+
const children = [];
|
|
73
|
+
for (const childFeatureId of childFeatureIds || []) {
|
|
74
|
+
const childAnnotation = this.__flatmap.annotation(childFeatureId);
|
|
75
|
+
if (childAnnotation !== undefined && childClass.includes(childAnnotation['fc-class'])) {
|
|
76
|
+
const child = {
|
|
77
|
+
label: childAnnotation.label,
|
|
78
|
+
models: childAnnotation.models
|
|
79
|
+
};
|
|
80
|
+
if (childClass === FC_KIND.ORGAN) {
|
|
81
|
+
child.ftus = this.__children(childAnnotation.children, FC_KIND.FTU)
|
|
82
|
+
};
|
|
83
|
+
children.push(child);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return children;
|
|
87
|
+
}
|
|
88
|
+
|
|
60
89
|
get systems()
|
|
61
90
|
//===========
|
|
62
91
|
{
|
|
@@ -66,7 +95,8 @@ export class SystemsManager
|
|
|
66
95
|
id: systemId,
|
|
67
96
|
name: system.name,
|
|
68
97
|
colour: system.colour,
|
|
69
|
-
enabled: system.enabled
|
|
98
|
+
enabled: system.enabled,
|
|
99
|
+
organs: system.organs
|
|
70
100
|
});
|
|
71
101
|
}
|
|
72
102
|
return systems;
|
package/src/utils.js
CHANGED
|
@@ -35,7 +35,7 @@ export class List extends Array {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
contains(element) {
|
|
38
|
-
return (super.
|
|
38
|
+
return (super.includes(element));
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
extend(other) {
|
|
@@ -96,12 +96,12 @@ export class Mutex
|
|
|
96
96
|
|
|
97
97
|
export function normaliseId(id)
|
|
98
98
|
{
|
|
99
|
-
if (id.
|
|
99
|
+
if (!id.includes(':')) {
|
|
100
100
|
return id;
|
|
101
101
|
}
|
|
102
102
|
const parts = id.split(':')
|
|
103
103
|
const lastPart = parts[parts.length - 1]
|
|
104
|
-
if (['http', 'https', 'urn'].
|
|
104
|
+
if (['http', 'https', 'urn'].includes(parts[0]) || !'0123456789'.includes(lastPart[0])) {
|
|
105
105
|
return id;
|
|
106
106
|
}
|
|
107
107
|
parts[parts.length - 1] = lastPart.padStart(8, '0');
|