@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 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.3.4``
41
+ * ``npm install @abi-software/flatmap-viewer@2.4.0-a.2``
42
42
 
43
43
  Documentation
44
44
  -------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/flatmap-viewer",
3
- "version": "2.3.4",
3
+ "version": "2.4.0-a.2",
4
4
  "description": "Flatmap viewer using Maplibre GL",
5
5
  "repository": "https://github.com/AnatomicMaps/flatmap-viewer.git",
6
6
  "main": "src/main.js",
@@ -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.indexOf(feat.id) < 0) {
200
+ if (!featureIds.includes(feat.id)) {
199
201
  featureIds.push(feat.id);
200
202
  const displayFeat = {};
201
203
  displayProperties.forEach(prop => {
@@ -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.indexOf('%') > 0) {
135
+ if (this._options.width.includes('%')) {
136
136
  width = width*mapCanvasElement.width/100;
137
137
  }
138
138
  } else if (typeof this._options.width === 'number') {
@@ -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._details = mapDescription.details;
64
- this._created = mapDescription.created;
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
- && (['top-left', 'top-right', 'bottom-right', 'bottom-left'].indexOf(value) >= 0))
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._created;
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._details;
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.indexOf(property) >= 0) {
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);
@@ -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.indexOf(ann.id) >= 0) {
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.indexOf(feature.id) < 0) {
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'].indexOf(feature.properties.kind) >= 0);
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.indexOf('Polygon') < 0) {
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.indexOf(annotation.models) < 0) {
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'].indexOf(event.type) >= 0) {
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'].indexOf(event.type) >= 0) {
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
- .indexOf(pathwaysVectorSource) >= 0) {
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'].indexOf(currentState) >= 0;
347
- const invalidEnabled = ['invalid', 'all'].indexOf(currentState) >= 0;
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
@@ -62,7 +62,6 @@ export async function standaloneViewer(map_endpoint=null, options={})
62
62
  showId: true,
63
63
  showPosition: false,
64
64
  standalone: true,
65
- annotator: true
66
65
  }, options);
67
66
 
68
67
  function loadMap(id, taxon, sex)
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 && ["'", '"'].indexOf(text.slice(0, 1)) >= 0) {
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 [id, ann] of flatmap.annotations) {
30
- if (ann['fc-class'] === 'fc-class:System') {
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.indexOf(element) >= 0);
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.indexOf(':') < 0) {
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'].indexOf(parts[0]) >= 0 || '0123456789'.indexOf(lastPart[0]) < 0) {
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');