@abi-software/flatmapvuer 1.13.5-demo.8 → 1.14.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/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "name": "@abi-software/flatmapvuer",
3
- "version": "1.13.5-demo.8",
3
+ "version": "1.14.0",
4
4
  "license": "Apache-2.0",
5
+ "engines": {
6
+ "node": ">=20"
7
+ },
5
8
  "files": [
6
9
  "dist/*",
7
10
  "src/*",
@@ -44,9 +47,9 @@
44
47
  "./src/*": "./src/*"
45
48
  },
46
49
  "dependencies": {
47
- "@abi-software/map-utilities": "1.8.3",
50
+ "@abi-software/map-utilities": "1.9.0",
48
51
  "@abi-software/sparc-annotation": "0.3.2",
49
- "@abi-software/svg-sprite": "1.0.3",
52
+ "@abi-software/svg-sprite": "1.1.0",
50
53
  "@element-plus/icons-vue": "^2.3.1",
51
54
  "css-element-queries": "^1.2.2",
52
55
  "element-plus": "2.8.4",
@@ -77,7 +80,9 @@
77
80
  },
78
81
  "optionalDependencies": {
79
82
  "@esbuild/linux-x64": "0.25.3",
80
- "@rollup/rollup-linux-x64-gnu": "4.23.0"
83
+ "@rollup/rollup-darwin-arm64": "4.59.0",
84
+ "@rollup/rollup-linux-x64-gnu": "4.59.0",
85
+ "@rollup/rollup-win32-x64-msvc": "4.59.0"
81
86
  },
82
87
  "eslintConfig": {
83
88
  "root": true,
@@ -634,7 +634,6 @@ import { capitalise, normaliseAlertToStringArray } from './utilities.js'
634
634
  import yellowstar from '../icons/yellowstar'
635
635
  import ResizeSensor from 'css-element-queries/src/ResizeSensor'
636
636
  import flatmap from '../services/flatmapLoader.js'
637
- import { attachSomaLocationMarkerMethods } from '../services/somaLocationMarkers.js'
638
637
  import { AnnotationService } from '@abi-software/sparc-annotation'
639
638
  import { mapState } from 'pinia'
640
639
  import { useMainStore } from '@/store/index'
@@ -1738,9 +1737,6 @@ export default {
1738
1737
  provenanceTaxonomy: taxons,
1739
1738
  alert: featuresAlert
1740
1739
  }]
1741
- if (eventType === 'mouseenter') {
1742
- this.lastHoveredFeature = data;
1743
- }
1744
1740
  if (eventType === 'click') {
1745
1741
  // If multiple paths overlap at the click location,
1746
1742
  // `data` is an object with numeric keys for each feature (e.g., {0: {...}, 1: {...}, ..., mapUUID: '...'}).
@@ -1860,7 +1856,6 @@ export default {
1860
1856
  // Fallback: remove any existing toolitp on DOM
1861
1857
  const tooltips = this.$el.querySelectorAll('.flatmap-tooltip-popup');
1862
1858
  tooltips.forEach((tooltip) => tooltip.remove());
1863
- this.lastHoveredFeature = null;
1864
1859
  },
1865
1860
  /**
1866
1861
  * Function to create tooltip for the provided connectivity data.
@@ -1904,9 +1899,6 @@ export default {
1904
1899
  const connectivityData = [];
1905
1900
  const errorData = [];
1906
1901
 
1907
- // Remove last hovered feature to avoid showing tooltip for the last hovered feature.
1908
- this.lastHoveredFeature = null;
1909
-
1910
1902
  // to keep the highlighted path on map
1911
1903
  if (connectivityInfo && connectivityInfo.featureId) {
1912
1904
  featuresToHighlight.push(...connectivityInfo.featureId);
@@ -2310,7 +2302,6 @@ export default {
2310
2302
  document.querySelectorAll('.maplibregl-popup').forEach((item) => {
2311
2303
  item.style.display = 'none'
2312
2304
  })
2313
- this.lastHoveredFeature = null;
2314
2305
  },
2315
2306
  /**
2316
2307
  * @public
@@ -2846,7 +2837,7 @@ export default {
2846
2837
  }
2847
2838
  )
2848
2839
  promise1.then((returnedObject) => {
2849
- this.mapImp = attachSomaLocationMarkerMethods(returnedObject)
2840
+ this.mapImp = returnedObject
2850
2841
  this.serverURL = this.mapImp.makeServerUrl('').slice(0, -1)
2851
2842
  let mapVersion = this.mapImp.details.version
2852
2843
  this.setFlightPathInfo(mapVersion)
@@ -3115,22 +3106,10 @@ export default {
3115
3106
  provenanceTaxonomy: feature.taxons,
3116
3107
  alert: normaliseAlertToStringArray(feature.alert),
3117
3108
  }
3118
-
3119
3109
  // Show popup for all modes
3120
3110
  this.checkAndCreatePopups([data], mapclick)
3121
-
3122
- // Check pathway fetures and set lastHoveredFeature for tooltip content replacement.
3123
- const isPathwayFeature = (feature.id.startsWith('ilxtr:') || feature.id.startsWith('ilx:'));
3124
- if (isPathwayFeature) {
3125
- this.lastHoveredFeature = feature;
3126
- this.lastHoveredFeature.mapUUID = this.mapImp.uuid;
3127
- } else {
3128
- this.lastHoveredFeature = null;
3129
- }
3130
-
3131
- // flatmap-tooltip-popup is used for custom tooltip content replacement.
3132
3111
  this.mapImp.showPopup(featureId, capitalise(feature.label), {
3133
- className: isPathwayFeature ? 'flatmap-tooltip-popup' : 'custom-popup',
3112
+ className: 'custom-popup',
3134
3113
  positionAtLastClick: false,
3135
3114
  preserveSelection: true,
3136
3115
  })
@@ -3174,62 +3153,6 @@ export default {
3174
3153
  setConnectionType: function (type) {
3175
3154
  this.connectionType = type;
3176
3155
  },
3177
- /**
3178
- * MutationObserver callback to intercept tooltip popup DOM elements
3179
- * and customize their content before the browser renders them.
3180
- */
3181
- _handleTooltipMutation: function (mutations) {
3182
- for (const mutation of mutations) {
3183
- for (const node of mutation.addedNodes) {
3184
- if (node.nodeType === 1) {
3185
- // Check if the added node itself is the tooltip popup
3186
- if (node.matches && node.matches('.flatmap-tooltip-popup')) {
3187
- this._applyCustomTooltipContent(node);
3188
- } else if (node.querySelector) {
3189
- // Check if it contains a tooltip popup
3190
- const popup = node.querySelector('.flatmap-tooltip-popup');
3191
- if (popup) {
3192
- this._applyCustomTooltipContent(popup);
3193
- }
3194
- }
3195
- }
3196
- }
3197
- }
3198
- },
3199
- /**
3200
- * Replace the default tooltip content with custom content from
3201
- * the tooltipContentProvider prop, if available.
3202
- */
3203
- _applyCustomTooltipContent: function (popupEl) {
3204
- if (!this.tooltipContentProvider || !this.lastHoveredFeature) return;
3205
- try {
3206
- const featureData = this.lastHoveredFeature;
3207
- // Detect multi-feature data format used by click events when multiple
3208
- // paths overlap: {0: {...}, 1: {...}, ..., mapUUID: '...'}
3209
- const isMultiFeature = featureData[0] && typeof featureData[0] === 'object';
3210
- let customHtml;
3211
- if (isMultiFeature) {
3212
- const features = [];
3213
- const mapUUID = featureData.mapUUID;
3214
- for (const [key, value] of Object.entries(featureData)) {
3215
- if (key !== 'mapUUID' && value && typeof value === 'object') {
3216
- features.push({ ...value, mapUUID });
3217
- }
3218
- }
3219
- customHtml = this.tooltipContentProvider(features.length > 1 ? features : features[0]);
3220
- } else {
3221
- customHtml = this.tooltipContentProvider(featureData);
3222
- }
3223
- if (customHtml) {
3224
- const contentEl = popupEl.querySelector('.maplibregl-popup-content');
3225
- if (contentEl) {
3226
- contentEl.innerHTML = customHtml;
3227
- }
3228
- }
3229
- } catch (e) {
3230
- console.warn('[flatmapvuer] Error in tooltipContentProvider:', e);
3231
- }
3232
- },
3233
3156
  },
3234
3157
  props: {
3235
3158
  /**
@@ -3470,17 +3393,6 @@ export default {
3470
3393
  return []
3471
3394
  },
3472
3395
  },
3473
- /**
3474
- * A function that provides custom tooltip HTML content for path features.
3475
- * The function receives the feature data from the mouseenter event (including `id`, `label`, etc.)
3476
- * and should return an HTML string to display in the tooltip, or return null/undefined
3477
- * to keep the default tooltip.
3478
- * This is used by mapintegratedvuer to show 'long-label' from connectivity knowledge.
3479
- */
3480
- tooltipContentProvider: {
3481
- type: Function,
3482
- default: null,
3483
- },
3484
3396
  },
3485
3397
  provide() {
3486
3398
  return {
@@ -3583,8 +3495,6 @@ export default {
3583
3495
  drawnCreatedEvent: {},
3584
3496
  previousEditEvent: {},
3585
3497
  previousDeletedEvent: {},
3586
- lastHoveredFeature: null,
3587
- tooltipObserver: null,
3588
3498
  connectionEntry: {},
3589
3499
  existDrawnFeatures: [], // Store all exist drawn features
3590
3500
  doubleClickedFeature: false,
@@ -3783,27 +3693,6 @@ export default {
3783
3693
  this.createFlatmap()
3784
3694
  }
3785
3695
  refreshFlatmapKnowledgeCache();
3786
-
3787
- // Set up MutationObserver to customize tooltip content when
3788
- // tooltipContentProvider prop is provided.
3789
- if (this.tooltipContentProvider) {
3790
- this.$nextTick(() => {
3791
- const container = this.$refs.flatmapContainer || this.$el;
3792
- if (container) {
3793
- this.tooltipObserver = new MutationObserver(this._handleTooltipMutation.bind(this));
3794
- this.tooltipObserver.observe(container, {
3795
- childList: true,
3796
- subtree: true,
3797
- });
3798
- }
3799
- });
3800
- }
3801
- },
3802
- beforeUnmount: function () {
3803
- if (this.tooltipObserver) {
3804
- this.tooltipObserver.disconnect();
3805
- this.tooltipObserver = null;
3806
- }
3807
3696
  },
3808
3697
  }
3809
3698
  </script>
@@ -3966,9 +3855,6 @@ export default {
3966
3855
 
3967
3856
  :deep(.flatmap-tooltip-popup),
3968
3857
  :deep(.custom-popup) {
3969
- font-family: Asap, sans-serif !important;
3970
- font-size: 14px !important;
3971
-
3972
3858
  &.maplibregl-popup-anchor-bottom {
3973
3859
  .maplibregl-popup-content {
3974
3860
  margin-bottom: 12px;
@@ -4563,23 +4449,4 @@ export default {
4563
4449
  }
4564
4450
  }
4565
4451
 
4566
- .flatmap-feature-label {
4567
- padding: 6px !important;
4568
- font-family: Asap, sans-serif !important;
4569
- font-size: 14px !important;
4570
-
4571
- // provided by tooltipContentProvider from mapintegratedvuer
4572
- &.flatmap-connectivity-label {
4573
- text-align: left !important;
4574
- }
4575
- }
4576
-
4577
- .id-tag {
4578
- color: #444;
4579
- background: #e0e0e0;
4580
- padding: 2px 4px;
4581
- border-radius: 4px;
4582
- font-size: .75rem !important;
4583
- letter-spacing: 1.05px;
4584
- }
4585
4452
  </style>
@@ -94,7 +94,6 @@
94
94
  :showOpenMapButton="showOpenMapButton"
95
95
  :showPathwayFilter="showPathwayFilter"
96
96
  :externalLegends="externalLegends"
97
- :tooltipContentProvider="tooltipContentProvider"
98
97
  />
99
98
 
100
99
  <!-- multiflatmap-error -->
@@ -894,14 +893,6 @@ export default {
894
893
  return []
895
894
  },
896
895
  },
897
- /**
898
- * A function that provides custom tooltip HTML content for path features.
899
- * Passed through to each FlatmapVuer instance.
900
- */
901
- tooltipContentProvider: {
902
- type: Function,
903
- default: null,
904
- },
905
896
  },
906
897
  data: function () {
907
898
  return {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * a single source for the flatmap-viewer library import
3
3
  */
4
- import * as flatmap from 'https://cdn.jsdelivr.net/npm/@abi-software/flatmap-viewer@4.4.4/+esm';
4
+ import * as flatmap from 'https://cdn.jsdelivr.net/npm/@abi-software/flatmap-viewer@4.4.3/+esm';
5
5
 
6
6
  export default flatmap;
@@ -1,125 +0,0 @@
1
- const SOMA_MARKER_COLOUR = '#1b7f6b'
2
- const SOMA_MARKER_SECONDARY_COLOUR = '#f4f1de'
3
- const SOMA_MARKER_TEXT_COLOUR = '#12312b'
4
- const SOMA_MARKER_MAX_COUNT_LABEL = '99+'
5
-
6
- const normalizeSomaLocations = function (somaLocations) {
7
- return (Array.isArray(somaLocations) ? somaLocations : [])
8
- .map((item) => ({
9
- label: String(item?.label || '').trim(),
10
- curie: String(item?.curie || '').trim(),
11
- count: Number(item?.count || 0),
12
- }))
13
- .filter((item) => item.curie && item.count > 0)
14
- }
15
-
16
- const formatCount = function (count) {
17
- if (count > 99) return SOMA_MARKER_MAX_COUNT_LABEL
18
- return String(count)
19
- }
20
-
21
- const createSomaLocationMarkerElement = function (somaLocation) {
22
- const wrapper = document.createElement('div')
23
- wrapper.className = 'flatmapvuer-soma-location-marker'
24
- wrapper.title = somaLocation.label || somaLocation.curie
25
- wrapper.style.width = '34px'
26
- wrapper.style.height = '48px'
27
- wrapper.style.display = 'flex'
28
- wrapper.style.alignItems = 'center'
29
- wrapper.style.justifyContent = 'center'
30
- wrapper.style.transform = 'translate(-50%, -100%)'
31
-
32
- const countLabel = formatCount(somaLocation.count)
33
- wrapper.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="-1 -1 27 42" width="34" height="48" aria-hidden="true">
34
- <ellipse style="fill: rgb(0, 0, 0); fill-opacity: 0.18;" cx="12" cy="36" rx="8" ry="4"/>
35
- <path d="M12.25.25a12.254 12.254 0 0 0-12 12.494
36
- c0 6.444 6.488 12.109 11.059 22.564.549 1.256 1.333 1.256 1.882 0
37
- C17.762 24.853 24.25 19.186 24.25 12.744A12.254 12.254 0 0 0 12.25.25Z"
38
- style="fill:${SOMA_MARKER_COLOUR};stroke:${SOMA_MARKER_SECONDARY_COLOUR};stroke-width:1.1"/>
39
- <circle cx="12.5" cy="12.5" r="8" fill="${SOMA_MARKER_SECONDARY_COLOUR}"/>
40
- <text x="12.5" y="16.1" text-anchor="middle" style="font-size:7.5px;font-weight:700;fill:${SOMA_MARKER_TEXT_COLOUR};font-family:Arial, sans-serif">${countLabel}</text>
41
- </svg>`
42
-
43
- return wrapper
44
- }
45
-
46
- const resolveMarkerPlacement = function (mapImp, curie) {
47
- const featureIds = Array.isArray(mapImp?.modelFeatureIds?.(curie)) ? mapImp.modelFeatureIds(curie) : []
48
- const placements = []
49
- const seenFeatureUris = new Set()
50
-
51
- for (const featureId of featureIds) {
52
- const annotation = mapImp.annotation(featureId)
53
- const featureUri = String(annotation?.uri || '').trim()
54
- if (featureUri && !seenFeatureUris.has(featureUri)) {
55
- seenFeatureUris.add(featureUri)
56
- placements.push({
57
- type: 'feature-uri',
58
- value: featureUri,
59
- })
60
- }
61
- }
62
-
63
- // Fall back to model placement only when no feature URI can be resolved.
64
- if (!placements.length && featureIds.length) {
65
- placements.push({
66
- type: 'model',
67
- value: curie,
68
- })
69
- }
70
-
71
- return placements
72
- }
73
-
74
- export const attachSomaLocationMarkerMethods = function (mapImp) {
75
- if (!mapImp || mapImp.addSomaLocationMarkers) {
76
- return mapImp
77
- }
78
-
79
- let markerIds = []
80
-
81
- mapImp.clearSomaLocationMarkers = function () {
82
- markerIds.forEach((markerId) => {
83
- mapImp.removeMarker(markerId)
84
- })
85
- markerIds = []
86
- }
87
-
88
- mapImp.addSomaLocationMarkers = function (somaLocations) {
89
- const normalizedSomaLocations = normalizeSomaLocations(somaLocations)
90
- const placedSomaLocations = []
91
-
92
- mapImp.clearSomaLocationMarkers()
93
-
94
- normalizedSomaLocations.forEach((somaLocation) => {
95
- const placements = resolveMarkerPlacement(mapImp, somaLocation.curie)
96
- if (!placements.length) return
97
-
98
- let somaLocationPlaced = false
99
- placements.forEach((placement) => {
100
- const markerElement = createSomaLocationMarkerElement(somaLocation)
101
- let addedMarkerIds = []
102
-
103
- if (placement.type === 'feature-uri') {
104
- addedMarkerIds = mapImp.addMarkerByFeatureUri(placement.value, { element: markerElement })
105
- } else if (placement.type === 'model') {
106
- const markerId = mapImp.addMarker(placement.value, { element: markerElement })
107
- addedMarkerIds = markerId > -1 ? [markerId] : []
108
- }
109
-
110
- if (!addedMarkerIds.length) return
111
-
112
- markerIds.push(...addedMarkerIds)
113
- somaLocationPlaced = true
114
- })
115
-
116
- if (somaLocationPlaced) {
117
- placedSomaLocations.push(somaLocation)
118
- }
119
- })
120
-
121
- return placedSomaLocations
122
- }
123
-
124
- return mapImp
125
- }