@abi-software/flatmap-viewer 2.7.0-a.1 → 2.7.0

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/lib/index.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  //==============================================================================
2
2
 
3
3
  import {FlatMap, MapManager} from '../src/flatmap-viewer'
4
+ import {standaloneViewer} from '../src/main'
4
5
 
5
6
  //==============================================================================
6
7
 
7
- export {FlatMap, MapManager}
8
+ export {FlatMap, MapManager, standaloneViewer}
8
9
 
9
10
  //==============================================================================
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@abi-software/flatmap-viewer",
3
- "version": "2.7.0-a.1",
3
+ "version": "2.7.0",
4
4
  "description": "Flatmap viewer using Maplibre GL",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/AnatomicMaps/flatmap-viewer.git"
8
8
  },
9
9
  "type": "module",
10
- "main": "src/main.js",
10
+ "main": "lib/index.ts",
11
11
  "files": [
12
12
  "lib",
13
13
  "src",
@@ -43,6 +43,7 @@
43
43
  "devDependencies": {
44
44
  "@types/node": "^20.12.7",
45
45
  "eslint": "^8.7.0",
46
+ "glob": "^10.3.12",
46
47
  "typescript": "^5.2.2",
47
48
  "vite": "^5.1.4",
48
49
  "vite-plugin-dts": "^3.8.1"
@@ -955,8 +955,10 @@ export class FlatMap
955
955
  * to place the marker.
956
956
  * @arg {Object} options Configurable options for the marker.
957
957
  * @arg {string} options.className Space-separated CSS class names to add to marker element.
958
- * @arg {string} options.colour Colour of the default marker. Defaults to ``'#005974'``
959
- * (dark blue).
958
+ * @arg {string} options.cluster The marker will be clustered together with other geographically
959
+ * close markers. Defaults to ``true``.
960
+ * @arg {string} options.colour Colour of the marker. Defaults to ``'#005974'``
961
+ * (dark cyan).
960
962
  * @arg {string} options.element The DOM element to use as a marker. The default is
961
963
  * a dark blue droplet-shaped SVG marker.
962
964
  * @return {integer} The identifier for the resulting marker. -1 is returned if the
@@ -965,15 +967,33 @@ export class FlatMap
965
967
  addMarker(anatomicalId, options={})
966
968
  //==================================
967
969
  {
970
+ options = Object.assign({cluster: true}, options)
968
971
  if (this._userInteractions !== null) {
969
972
  return this._userInteractions.addMarker(anatomicalId, options);
970
973
  }
971
974
  return -1;
972
975
  }
973
976
 
977
+ /**
978
+ * Add a list of markers to the map.
979
+ *
980
+ * @param {Array.<string>} anatomicalId Anatomical identifiers of features on which
981
+ * to place markers.
982
+ * @arg {Object} options Configurable options for the markers.
983
+ * @arg {string} options.className Space-separated CSS class names to add to marker elemens.
984
+ * @arg {string} options.cluster The markers will be clustered together with other geographically
985
+ * close markers. Defaults to ``true``.
986
+ * @arg {string} options.colour Colour of the markers. Defaults to ``'#005974'``
987
+ * (dark cyan).
988
+ * @arg {string} options.element The DOM element to use as a marker. The default is
989
+ * a dark blue droplet-shaped SVG marker.
990
+ * @return {array.<integer>} The identifiers of the resulting markers. -1 is returned if the
991
+ * map doesn't contain a feature with the given anatomical identifier
992
+ */
974
993
  addMarkers(anatomicalIds, options={})
975
994
  //====================================
976
995
  {
996
+ options = Object.assign({cluster: true}, options)
977
997
  const markerIds = []
978
998
  for (const anatomicalId of anatomicalIds) {
979
999
  if (this._userInteractions !== null) {
@@ -985,7 +1005,6 @@ export class FlatMap
985
1005
  return markerIds
986
1006
  }
987
1007
 
988
-
989
1008
  /**
990
1009
  * Remove a marker from the map.
991
1010
  *
@@ -1028,7 +1047,7 @@ export class FlatMap
1028
1047
  * Shows a popup at a marker.
1029
1048
  *
1030
1049
  * This method should only be called in response to a ``mouseenter`` event
1031
- * passed to the map's ``callback`` function as a popup won't be shown.
1050
+ * passed to the map's ``callback`` function otherwise a popup won't be shown.
1032
1051
  *
1033
1052
  * @param {integer} markerId The identifier of the marker
1034
1053
  * @param {string | DOMElement} content The popup's content
@@ -1378,8 +1378,6 @@ export class UserInteractions
1378
1378
  const marker = new maplibregl.Marker(markerOptions)
1379
1379
  .setLngLat(markerPosition)
1380
1380
  .addTo(this._map);
1381
-
1382
-
1383
1381
  markerElement.addEventListener('mouseenter',
1384
1382
  this.markerMouseEvent_.bind(this, marker, anatomicalId));
1385
1383
  markerElement.addEventListener('mousemove',
@@ -1443,10 +1441,6 @@ export class UserInteractions
1443
1441
  return anatomicalIds;
1444
1442
  }
1445
1443
 
1446
- // Separate out MapLibre specific code and result of mouse event (tooltip,
1447
- // client message, etc) so clustering code can also use this to process
1448
- // events.
1449
-
1450
1444
  markerMouseEvent_(marker, anatomicalId, event)
1451
1445
  //============================================
1452
1446
  {
@@ -1456,7 +1450,7 @@ export class UserInteractions
1456
1450
  return
1457
1451
  }
1458
1452
 
1459
- if (['mouseenter', 'mouseleave', 'click'].includes(event.type)) {
1453
+ if (['mouseenter', 'mousemove', 'click'].includes(event.type)) {
1460
1454
  this.__activeMarker = marker
1461
1455
 
1462
1456
  // Remove any tooltip
@@ -1465,24 +1459,24 @@ export class UserInteractions
1465
1459
  // Reset cursor
1466
1460
  marker.getElement().style.cursor = 'default';
1467
1461
 
1468
-
1469
1462
  const markerId = this.__markerIdByMarker.get(marker)
1470
1463
  const annotation = this.__annotationByMarkerId.get(markerId)
1471
1464
 
1472
1465
  this.markerEvent_(event, markerId, marker.getLngLat(),
1473
- anatomicalId, annotation)
1466
+ anatomicalId, annotation)
1467
+ event.stopPropagation()
1474
1468
  }
1475
1469
  }
1476
1470
 
1477
1471
  markerEvent_(event, markerId, markerPosition, anatomicalId, annotation)
1478
1472
  //=====================================================================
1479
1473
  {
1480
- if (['mouseenter', 'mouseleave', 'click'].includes(event.type)) {
1474
+ if (['mousemove', 'click'].includes(event.type)) {
1481
1475
 
1482
- // Remove any existing tooltips
1476
+ // Remove any tooltips
1483
1477
  this.removeTooltip_();
1484
1478
 
1485
- if (['mouseenter', 'click'].includes(event.type)) {
1479
+ if (['mouseenter', 'mousemove', 'click'].includes(event.type)) {
1486
1480
  // The marker's feature
1487
1481
  const feature = this.mapFeature(annotation.featureId);
1488
1482
  if (feature !== undefined) {
@@ -1499,7 +1493,7 @@ export class UserInteractions
1499
1493
  this.__showToolTip(html, markerPosition);
1500
1494
 
1501
1495
  // Send marker event message
1502
- this._flatmap.markerEvent(event.type, markerId, anatomicalId);
1496
+ this._flatmap.markerEvent(event.type, markerId, anatomicalId)
1503
1497
  }
1504
1498
  }
1505
1499
  }
@@ -63,8 +63,6 @@ export class ClusteredMarkerLayer
63
63
  }
64
64
  #ui
65
65
 
66
- seenmove = false
67
-
68
66
  constructor(flatmap, ui)
69
67
  {
70
68
  this.#flatmap = flatmap
@@ -115,7 +113,6 @@ export class ClusteredMarkerLayer
115
113
  const features = this.#map.queryRenderedFeatures(e.point, {
116
114
  layers: ['clustered-markers']
117
115
  })
118
- console.log('Cluster marker', features)
119
116
  const clusterId = features[0].properties.cluster_id
120
117
  const zoom = await this.#map.getSource('markers').getClusterExpansionZoom(clusterId)
121
118
  this.#map.easeTo({
@@ -124,10 +121,10 @@ export class ClusteredMarkerLayer
124
121
  })
125
122
  })
126
123
 
124
+ console.log('Unclustered click', e, features)
127
125
  this.#map.on('click', 'single-points', this.singleMarkerEvent.bind(this))
128
126
  this.#map.on('mouseenter', 'single-points', this.singleMarkerEvent.bind(this))
129
127
  this.#map.on('mousemove', 'single-points', this.singleMarkerEvent.bind(this))
130
- // this.#map.on('mouseleave', 'single-points', this.singleMarkerEvent.bind(this))
131
128
 
132
129
  this.#map.on('mouseenter', 'clustered-markers', () => {
133
130
  this.#map.getCanvas().style.cursor = 'pointer'
@@ -136,8 +133,6 @@ export class ClusteredMarkerLayer
136
133
  this.#map.on('mouseleave', 'clustered-markers', () => {
137
134
  this.#map.getCanvas().style.cursor = ''
138
135
  })
139
-
140
- // Also 'mousemove'...
141
136
  }
142
137
 
143
138
  singleMarkerEvent(event)
@@ -147,14 +142,6 @@ export class ClusteredMarkerLayer
147
142
  layers: ['single-points']
148
143
  })
149
144
  for (const feature of features) {
150
- if (event.type === 'mousemove' && !this.seenMove) {
151
- console.log('Single marker', event.type, feature)
152
- this.seenMove = true
153
- } else if (event.type !== 'mousemove') {
154
- console.log('Single marker', event.type, feature)
155
- this.seenMove = false
156
- }
157
-
158
145
  const properties = feature.properties
159
146
  const position = properties.markerPosition.slice(1, -1).split(',').map(p => +p)
160
147
  this.#ui.markerEvent_(event, feature.id, position, properties.models, properties)
@@ -425,14 +425,10 @@ export class LayerManager
425
425
  mapLayer.setFilter(this.__layerOptions);
426
426
  }
427
427
  if (this.#flightPathLayer) {
428
- // * @arg options.layerOptions.sckan {string} Show neuron paths known to SCKAN: values are ``valid`` (default),
429
- // * ``invalid``, ``all`` or ``none``.
430
-
431
-
432
428
  const sckanState = options.sckan || 'valid'
433
429
  const sckanFilter = (sckanState == 'none') ? {NOT: {HAS: 'sckan'}} :
434
430
  (sckanState == 'valid') ? {sckan: true} :
435
- (sckanState == 'invalid') ? {NOT: {sckan: true}} : // {sckan: false} is different...
431
+ (sckanState == 'invalid') ? {NOT: {sckan: true}} :
436
432
  true
437
433
  const featureFilter = new PropertiesFilter(sckanFilter)
438
434
  if ('taxons' in options) {
package/src/main.js CHANGED
@@ -55,9 +55,6 @@ const ALL_MARKERS = [
55
55
  'UBERON:0001155', // Colon
56
56
  'UBERON:0001255', // Bladder
57
57
  'UBERON:0001759', // Vagus
58
-
59
- 'UBERON:0016508', // Pelvic ganglion
60
-
61
58
  ]
62
59
 
63
60
  //==============================================================================
@@ -175,8 +172,6 @@ export async function standaloneViewer(map_endpoint=null, options={})
175
172
  mapOptions.background = args[0].value;
176
173
  } else if (eventType === 'annotation') {
177
174
  drawControl.handleEvent(...args)
178
- } else {
179
- //console.log(eventType, ...args)
180
175
  }
181
176
  }, mapOptions)
182
177
  .then(map => {
package/src/utils.js CHANGED
@@ -120,7 +120,6 @@ export function normaliseId(id)
120
120
 
121
121
  export function setDefaults(options, defaultOptions)
122
122
  {
123
- // c.f. Object.assign({}, defaultOptions, options)
124
123
  if (options === undefined || options === null) {
125
124
  return defaultOptions;
126
125
  }
package/src/types.ts DELETED
@@ -1,26 +0,0 @@
1
- /******************************************************************************
2
-
3
- Flatmap viewer and annotation tool
4
-
5
- Copyright (c) 2019 - 2024 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
- export type Constructor<T> = new(...args: any[]) => T
22
-
23
- export type ObjectRecord = Record<string, any>
24
-
25
- //==============================================================================
26
-