@abi-software/flatmapvuer 1.8.1-beta.4 → 1.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/flatmapvuer",
3
- "version": "1.8.1-beta.4",
3
+ "version": "1.8.2",
4
4
  "license": "Apache-2.0",
5
5
  "files": [
6
6
  "dist/*",
@@ -43,8 +43,8 @@
43
43
  "./src/*": "./src/*"
44
44
  },
45
45
  "dependencies": {
46
- "@abi-software/flatmap-viewer": "^4.0.4",
47
- "@abi-software/map-utilities": "^1.4.0",
46
+ "@abi-software/flatmap-viewer": "3.2.13",
47
+ "@abi-software/map-utilities": "^1.4.2",
48
48
  "@abi-software/sparc-annotation": "0.3.2",
49
49
  "@abi-software/svg-sprite": "^1.0.1",
50
50
  "@element-plus/icons-vue": "^2.3.1",
package/src/App.vue CHANGED
@@ -283,6 +283,10 @@ export default {
283
283
  taxo: 'FunctionalConnectivity',
284
284
  displayWarning: true,
285
285
  },
286
+ Test: {
287
+ "taxo": "NCBITaxon:1",
288
+ "displayWarning": true
289
+ },
286
290
  },
287
291
  tooltipContent: undefined,
288
292
  tStyle: {
@@ -693,6 +693,18 @@ const processFTUs = (parent, key) => {
693
693
  return ftus
694
694
  }
695
695
 
696
+ const createUnfilledTooltipData = function () {
697
+ return {
698
+ destinations: [],
699
+ origins: [],
700
+ components: [],
701
+ destinationsWithDatasets: [],
702
+ originsWithDatasets: [],
703
+ componentsWithDatasets: [],
704
+ resource: undefined,
705
+ }
706
+ }
707
+
696
708
  /**
697
709
  * A vue component of the flatmap viewer.
698
710
  */
@@ -1161,7 +1173,7 @@ export default {
1161
1173
  },
1162
1174
  setInitMapState: function () {
1163
1175
  if (this.mapImp) {
1164
- const map = this.mapImp.map;
1176
+ const map = this.mapImp._map;
1165
1177
  const bounds = this.mapImp.options.bounds;
1166
1178
  const initBounds = [
1167
1179
  [bounds[0], bounds[1]],
@@ -1183,7 +1195,7 @@ export default {
1183
1195
  resetView: function () {
1184
1196
  if (this.mapImp) {
1185
1197
  // fit to window
1186
- const map = this.mapImp.map;
1198
+ const map = this.mapImp._map;
1187
1199
  const { initBounds } = this.initMapState;
1188
1200
  // reset rotation
1189
1201
  map.resetNorthPitch({
@@ -1610,7 +1622,6 @@ export default {
1610
1622
  const resource = [data.models]
1611
1623
  const taxonomy = this.entry
1612
1624
  const biologicalSex = this.biologicalSex
1613
- const featuresAlert = data.alert
1614
1625
  let taxons = undefined
1615
1626
  if (data.taxons) {
1616
1627
  // check if data.taxons is string or array
@@ -1620,7 +1631,7 @@ export default {
1620
1631
  taxons = data.taxons
1621
1632
  }
1622
1633
  }
1623
- let payload = [{
1634
+ const payload = {
1624
1635
  dataset: data.dataset,
1625
1636
  biologicalSex: biologicalSex,
1626
1637
  taxonomy: taxonomy,
@@ -1630,36 +1641,10 @@ export default {
1630
1641
  userData: args,
1631
1642
  eventType: eventType,
1632
1643
  provenanceTaxonomy: taxons,
1633
- alert: featuresAlert
1634
- }]
1635
- if (Array.isArray(data)) {
1636
- payload = []
1637
- data.forEach((d) => {
1638
- const label = d.label
1639
- const resource = [d.models]
1640
- let taxons = undefined
1641
- if (d.taxons) {
1642
- // check if data.taxons is string or array
1643
- if (typeof d.taxons !== 'object') {
1644
- taxons = JSON.parse(d.taxons)
1645
- } else {
1646
- taxons = d.taxons
1647
- }
1648
- }
1649
- payload.push({
1650
- dataset: d.dataset,
1651
- biologicalSex: biologicalSex,
1652
- taxonomy: taxonomy,
1653
- resource: resource,
1654
- label: label,
1655
- feature: d,
1656
- userData: args,
1657
- eventType: eventType,
1658
- provenanceTaxonomy: taxons,
1659
- alert: d.alert
1660
- })
1661
- })
1644
+ }
1645
+ if (eventType === 'click') {
1662
1646
  this.setConnectivityDataSource(this.viewingMode, data);
1647
+ this.featuresAlert = data.alert
1663
1648
  //The following will be used to track either a feature is selected
1664
1649
  this.statesTracking.activeClick = true
1665
1650
  this.statesTracking.activeTerm = data?.models
@@ -1940,32 +1925,22 @@ export default {
1940
1925
  this.annotation = {}
1941
1926
  }
1942
1927
  } else {
1928
+ //require data.resource && data.feature.source
1929
+ let results = await this.flatmapQueries.retrieveFlatmapKnowledgeForEvent(this.mapImp, data)
1943
1930
  // load and store knowledge
1944
1931
  loadAndStoreKnowledge(this.mapImp, this.flatmapQueries);
1945
- let prom1 = []
1946
- for (let index = 0; index < data.length; index++) {
1947
- const entry = data[index]
1948
- prom1.push(await this.getKnowledgeTooltip(entry))
1949
- }
1950
- this.tooltipEntry = await Promise.all(prom1)
1951
- const featureIds = this.tooltipEntry.filter(tooltip => tooltip).map(tooltip => tooltip.featureId[0])
1952
- if (featureIds.length > 0) {
1953
- this.displayTooltip(featureIds)
1932
+ // The line below only creates the tooltip if some data was found on the path
1933
+ // the pubmed URLs are in knowledge response.references
1934
+ if (
1935
+ (results && results[0]) ||
1936
+ (data.feature.hyperlinks && data.feature.hyperlinks.length > 0)
1937
+ ) {
1938
+ this.resourceForTooltip = data.resource[0]
1939
+ data.resourceForTooltip = this.resourceForTooltip
1940
+ this.createTooltipFromNeuronCuration(data)
1954
1941
  }
1955
1942
  }
1956
1943
  },
1957
- getKnowledgeTooltip: async function (data) {
1958
- //require data.resource && data.feature.source
1959
- let results = await this.flatmapQueries.retrieveFlatmapKnowledgeForEvent(this.mapImp, data)
1960
- // The line below only creates the tooltip if some data was found on the path
1961
- // the pubmed URLs are in knowledge response.references
1962
- if ((results && results[0]) || (data.feature.hyperlinks && data.feature.hyperlinks.length > 0)) {
1963
- let tooltip = await this.flatmapQueries.createTooltipData(this.mapImp, data)
1964
- tooltip['featuresAlert'] = data.alert;
1965
- tooltip['knowledgeSource'] = getKnowledgeSource(this.mapImp);
1966
- return tooltip;
1967
- }
1968
- },
1969
1944
  /**
1970
1945
  * A hack to remove flatmap tooltips while popup is open
1971
1946
  */
@@ -2210,18 +2185,25 @@ export default {
2210
2185
  featureId = feature
2211
2186
  options.annotationFeatureGeometry = geometry
2212
2187
  } else {
2213
- const entry = Array.isArray(feature) ? feature[0] : feature
2214
- featureId = this.mapImp.modelFeatureIds(entry)[0]
2188
+ featureId = this.mapImp.modelFeatureIds(feature)[0]
2215
2189
  if (!this.activeDrawTool) {
2216
2190
  options.positionAtLastClick = true
2217
2191
  }
2218
2192
  }
2219
2193
  // If connectivityInfoSidebar is set to `true`
2220
2194
  // Connectivity info will show in sidebar
2221
- if (
2222
- (this.connectivityInfoSidebar && this.tooltipEntry.length) &&
2223
- this.viewingMode !== 'Annotation'
2224
- ) {
2195
+ if ((this.connectivityInfoSidebar && this.hasTooltipEntry()) && this.viewingMode !== 'Annotation') {
2196
+ // move the map center to highlighted area
2197
+ // this method is moved to sidebar connectivity info
2198
+ // const featureIds = [feature];
2199
+ // this.moveMap(featureIds);
2200
+ if (this.featuresAlert) {
2201
+ this.tooltipEntry['featuresAlert'] = this.featuresAlert;
2202
+ }
2203
+ // Get connectivity knowledge source | SCKAN release
2204
+ if (this.mapImp.provenance?.connectivity) {
2205
+ this.tooltipEntry['knowledge-source'] = getKnowledgeSource(this.mapImp);
2206
+ }
2225
2207
  this.$emit('connectivity-info-open', this.tooltipEntry);
2226
2208
  }
2227
2209
  if (this.annotationSidebar && this.viewingMode === 'Annotation') {
@@ -2232,10 +2214,16 @@ export default {
2232
2214
  // Provenance popup will be shown on map
2233
2215
  // Tooltip will be shown for Annotation view
2234
2216
  if (
2235
- !this.disableUI &&
2236
- (
2237
- (this.viewingMode === 'Annotation' && !this.annotationSidebar) ||
2238
- (this.viewingMode === 'Exploration' && !this.connectivityInfoSidebar)
2217
+ !this.disableUI && (
2218
+ (
2219
+ this.viewingMode === 'Annotation' &&
2220
+ !this.annotationSidebar
2221
+ ) ||
2222
+ (
2223
+ this.viewingMode === 'Exploration' &&
2224
+ !this.connectivityInfoSidebar &&
2225
+ this.hasTooltipEntry()
2226
+ )
2239
2227
  )
2240
2228
  ) {
2241
2229
  this.tooltipDisplay = true;
@@ -2245,6 +2233,23 @@ export default {
2245
2233
  });
2246
2234
  }
2247
2235
  },
2236
+ hasTooltipEntry: function () {
2237
+ const {
2238
+ components,
2239
+ destinations,
2240
+ origins,
2241
+ provenanceTaxonomy,
2242
+ provenanceTaxonomyLabel
2243
+ } = this.tooltipEntry;
2244
+
2245
+ return Boolean(
2246
+ components?.length ||
2247
+ destinations?.length ||
2248
+ origins?.length ||
2249
+ provenanceTaxonomy?.length ||
2250
+ provenanceTaxonomyLabel?.length
2251
+ );
2252
+ },
2248
2253
  /**
2249
2254
  * Move the map to the left side
2250
2255
  * to the visible area of the feature IDs
@@ -2254,8 +2259,8 @@ export default {
2254
2259
  moveMap: function (featureIds, options = {}) {
2255
2260
  if (this.mapImp) {
2256
2261
  const { offsetX = 0, offsetY = 0, zoom = 4 } = options;
2257
- const Map = this.mapImp.map;
2258
- const bbox = this.mapImp.bounds.toArray();
2262
+ const Map = this.mapImp._map;
2263
+ const bbox = this.mapImp._bounds.toArray();
2259
2264
 
2260
2265
  // Zoom the map to features first
2261
2266
  this.mapImp.zoomToFeatures(featureIds, { noZoomIn: true });
@@ -2509,6 +2514,7 @@ export default {
2509
2514
 
2510
2515
  let promise1 = this.mapManagerRef.loadMap(
2511
2516
  identifier,
2517
+ this.$refs.display,
2512
2518
  this.eventCallback(),
2513
2519
  {
2514
2520
  //fullscreenControl: false,
@@ -2517,7 +2523,6 @@ export default {
2517
2523
  minZoom: this.minZoom,
2518
2524
  tooltips: this.tooltips,
2519
2525
  minimap: minimap,
2520
- container: this.$refs.display,
2521
2526
  // tooltipDelay: 15, // new feature to delay tooltips showing
2522
2527
  }
2523
2528
  )
@@ -2563,6 +2568,9 @@ export default {
2563
2568
  if (this.mapImp) {
2564
2569
  this.mapImp.resize()
2565
2570
  this.showMinimap(this.displayMinimap)
2571
+ if (this.mapImp._minimap) {
2572
+ this.mapImp._minimap._miniMap.resize()
2573
+ }
2566
2574
  }
2567
2575
  } catch {
2568
2576
  console.error('Map resize error')
@@ -2578,6 +2586,7 @@ export default {
2578
2586
  if (this.mapImp.options?.style === 'functional') {
2579
2587
  this.isFC = true
2580
2588
  }
2589
+ console.log(this.mapImp)
2581
2590
  this.mapImp.setBackgroundOpacity(1)
2582
2591
  this.backgroundChangeCallback(this.currentBackground)
2583
2592
  this.pathways = this.mapImp.pathTypes()
@@ -2605,7 +2614,7 @@ export default {
2605
2614
  * after the map is loaded.
2606
2615
  */
2607
2616
  handleMapClick: function () {
2608
- const _map = this.mapImp.map;
2617
+ const _map = this.mapImp._map;
2609
2618
  if (_map) {
2610
2619
  _map.on('click', (e) => {
2611
2620
  //A little logic to make sure we are keeping track
@@ -2913,6 +2922,7 @@ export default {
2913
2922
  return {
2914
2923
  flatmapAPI: this.flatmapAPI,
2915
2924
  sparcAPI: this.sparcAPI,
2925
+ getFeaturesAlert: () => this.featuresAlert,
2916
2926
  userApiKey: this.userToken,
2917
2927
  }
2918
2928
  },
@@ -2966,10 +2976,11 @@ export default {
2966
2976
  availableBackground: ['white', 'lightskyblue', 'black'],
2967
2977
  loading: false,
2968
2978
  flatmapMarker: flatmapMarker,
2969
- tooltipEntry: [],
2979
+ tooltipEntry: createUnfilledTooltipData(),
2970
2980
  connectivityDataSource: '',
2971
2981
  connectivityTooltipVisible: false,
2972
2982
  drawerOpen: false,
2983
+ featuresAlert: undefined,
2973
2984
  flightPath3DRadio: false,
2974
2985
  displayFlightPathOption: false,
2975
2986
  colourRadio: true,
@@ -3164,7 +3175,7 @@ export default {
3164
3175
  if (this.mapManager) {
3165
3176
  this.mapManagerRef = this.mapManager;
3166
3177
  } else {
3167
- this.mapManagerRef = markRaw(new flatmap.MapViewer(this.flatmapAPI, { container: undefined }));
3178
+ this.mapManagerRef = markRaw(new flatmap.MapManager(this.flatmapAPI));
3168
3179
  /**
3169
3180
  * The event emitted after a new mapManager is loaded.
3170
3181
  * This mapManager can be used to create new flatmaps.
@@ -231,7 +231,7 @@ export default {
231
231
  if (this.mapManager) {
232
232
  this.mapManagerRef = this.mapManager;
233
233
  } else {
234
- this.mapManagerRef = markRaw(new flatmap.MapViewer(this.flatmapAPI, { container: undefined }));
234
+ this.mapManagerRef = markRaw(new flatmap.MapManager(this.flatmapAPI));
235
235
  /**
236
236
  * The event emitted after a new mapManager is loaded.
237
237
  * This mapManager can be used to create new flatmaps.
@@ -193,7 +193,7 @@ let FlatmapQueries = function () {
193
193
  return [...new Set(found.flat())]
194
194
  }
195
195
 
196
- this.flattenConntectivity = function (connectivity) {
196
+ this.flattenConnectivity = function (connectivity) {
197
197
  let dnodes = connectivity.flat() // get nodes from edgelist
198
198
  let nodes = [...new Set(dnodes)] // remove duplicates
199
199
  let found = []
@@ -207,7 +207,7 @@ let FlatmapQueries = function () {
207
207
  return found.flat()
208
208
  }
209
209
 
210
- this.findComponents = function (connectivity) {
210
+ this.findComponents = function (connectivity, axons, dendrites, somas) {
211
211
  let dnodes = connectivity.connectivity.flat() // get nodes from edgelist
212
212
  let nodes = removeDuplicates(dnodes)
213
213
 
@@ -216,13 +216,13 @@ let FlatmapQueries = function () {
216
216
  nodes.forEach((node) => {
217
217
  terminal = false
218
218
  // Check if the node is an destination or origin (note that they are labelled dendrite and axon as opposed to origin and destination)
219
- if (inArray(connectivity.axons, node)) {
219
+ if (inArray(axons, node)) {
220
220
  terminal = true
221
221
  }
222
- if (connectivity.somas && inArray(connectivity.somas, node)) {
222
+ if (somas && inArray(somas, node)) {
223
223
  terminal = true
224
224
  }
225
- if (inArray(connectivity.dendrites, node)) {
225
+ if (inArray(dendrites, node)) {
226
226
  terminal = true
227
227
  }
228
228
  if (!terminal) {
@@ -246,16 +246,16 @@ let FlatmapQueries = function () {
246
246
  this.origins = []
247
247
  this.components = []
248
248
  this.rawURLs = []
249
- if (!keastIds || keastIds.length === 0 || !keastIds[0]) return
249
+ if (!keastIds || keastIds.length == 0 || !keastIds[0]) return
250
250
 
251
- let prom1 = this.queryForConnectivityNew(mapImp, keastIds[0]) // This on returns a promise so dont need 'await'
251
+ let prom1 = this.queryForConnectivityNew(mapImp, keastIds, signal) // This on returns a promise so dont need 'await'
252
252
  let results = await Promise.all([prom1])
253
253
  return results
254
254
  }
255
255
 
256
- this.queryForConnectivityNew = function (mapImp, keastId, processConnectivity = true) {
256
+ this.queryForConnectivityNew = function (mapImp, keastIds, signal, processConnectivity=true) {
257
257
  return new Promise((resolve) => {
258
- mapImp.queryKnowledge(keastId)
258
+ mapImp.queryKnowledge(keastIds[0])
259
259
  .then((response) => {
260
260
  if (this.checkConnectivityExists(response)) {
261
261
  let connectivity = response;
@@ -265,8 +265,11 @@ let FlatmapQueries = function () {
265
265
  if (response.references) {
266
266
  // with publications from both PubMed and Others
267
267
  this.rawURLs = [...response.references];
268
+ resolve(processedConnectivity)
269
+ } else {
270
+ // without publications
271
+ resolve(processedConnectivity)
268
272
  }
269
- resolve(processedConnectivity)
270
273
  })
271
274
  }
272
275
  else resolve(connectivity)
@@ -280,7 +283,7 @@ let FlatmapQueries = function () {
280
283
  } else {
281
284
  // console.error('Error:', error)
282
285
  // TODO: to update after queryKnowledge method update
283
- console.warn(`Unable to get the knowledge for the entity ${keastId}.`)
286
+ console.warn(`Unable to get the knowledge for the entity ${keastIds[0]}.`)
284
287
  }
285
288
  resolve(false)
286
289
  })
@@ -380,86 +383,84 @@ let FlatmapQueries = function () {
380
383
  return label
381
384
  }
382
385
 
383
- this.flattenAndFindDatasets = function (components, axons, dendrites) {
386
+ this.flattenAndFindDatasets = function (dendrites, components, axons) {
384
387
  // process the nodes for finding datasets (Note this is not critical to the tooltip, only for the 'search on components' button)
385
- let componentsFlat = this.flattenConntectivity(components)
386
- let axonsFlat = this.flattenConntectivity(axons)
387
- let dendritesFlat = this.flattenConntectivity(dendrites)
388
+ let dendritesFlat = this.flattenConnectivity(dendrites)
389
+ let componentsFlat = this.flattenConnectivity(components)
390
+ let axonsFlat = this.flattenConnectivity(axons)
388
391
 
389
392
  // Filter for the anatomy which is annotated on datasets
390
- this.destinationsWithDatasets = this.uberons.filter(
391
- (ub) => axonsFlat.indexOf(ub.id) !== -1
392
- )
393
393
  this.originsWithDatasets = this.uberons.filter(
394
394
  (ub) => dendritesFlat.indexOf(ub.id) !== -1
395
395
  )
396
396
  this.componentsWithDatasets = this.uberons.filter(
397
397
  (ub) => componentsFlat.indexOf(ub.id) !== -1
398
398
  )
399
+ this.destinationsWithDatasets = this.uberons.filter(
400
+ (ub) => axonsFlat.indexOf(ub.id) !== -1
401
+ )
399
402
  }
400
403
 
401
404
  this.processConnectivity = function (mapImp, connectivity) {
402
405
  return new Promise((resolve) => {
403
- // Filter the origin and destinations from components
404
- let components = this.findComponents(connectivity)
405
-
406
- // Remove duplicates
407
- let axons = removeDuplicates(connectivity.axons)
408
- //Somas will become part of origins, support this for future proof
409
406
  let dendrites = []
410
- if (connectivity.somas && connectivity.somas.length > 0) {
411
- dendrites.push(...connectivity.somas)
412
- }
413
- if (connectivity.dendrites && connectivity.dendrites.length > 0) {
414
- dendrites.push(...connectivity.dendrites)
407
+ let axons = []
408
+ let somas = undefined
409
+ if (connectivity && connectivity["node-phenotypes"]) {
410
+ const sourceKey = ["ilxtr:hasSomaLocatedIn"]
411
+ const destinationKey = ["ilxtr:hasAxonPresynapticElementIn", "ilxtr:hasAxonSensorySubcellularElementIn"]
412
+ sourceKey.forEach((key)=>{
413
+ dendrites.push(...connectivity["node-phenotypes"][key])
414
+ })
415
+ dendrites = removeDuplicates(dendrites)
416
+ destinationKey.forEach((key)=>{
417
+ axons.push(...connectivity["node-phenotypes"][key])
418
+ })
419
+ axons = removeDuplicates(axons)
420
+ } else {
421
+ // Remove duplicates
422
+ axons = removeDuplicates(connectivity.axons)
423
+ //Somas will become part of origins, support this for future proof
424
+ if (connectivity.somas && connectivity.somas.length > 0) {
425
+ dendrites.push(...connectivity.somas)
426
+ }
427
+ if (connectivity.dendrites && connectivity.dendrites.length > 0) {
428
+ dendrites.push(...connectivity.dendrites)
429
+ }
430
+ somas = connectivity.somas
415
431
  }
416
- dendrites = removeDuplicates(dendrites)
417
432
 
433
+ const components = this.findComponents(connectivity, axons, dendrites, somas)
418
434
  // Create list of ids to get labels for
419
- let conIds = this.findAllIdsFromConnectivity(connectivity)
420
-
435
+ const conIds = this.findAllIdsFromConnectivity(connectivity)
421
436
  // Create readable labels from the nodes. Setting this to 'this.origins' updates the display
422
437
  this.createLabelLookup(mapImp, conIds).then((lookUp) => {
423
- this.destinations = axons.map((a) =>
424
- this.createLabelFromNeuralNode(a, lookUp)
425
- )
426
438
  this.origins = dendrites.map((d) =>
427
439
  this.createLabelFromNeuralNode(d, lookUp)
428
440
  )
429
441
  this.components = components.map((c) =>
430
442
  this.createLabelFromNeuralNode(c, lookUp)
431
443
  )
432
- this.flattenAndFindDatasets(components, axons, dendrites)
444
+ this.destinations = axons.map((a) =>
445
+ this.createLabelFromNeuralNode(a, lookUp)
446
+ )
447
+ this.flattenAndFindDatasets(dendrites, components, axons)
433
448
  resolve({
434
449
  ids: {
435
- axons: axons,
436
450
  dendrites: dendrites,
437
451
  components: components,
452
+ axons: axons,
438
453
  },
439
454
  labels: {
440
- destinations: this.destinations,
441
455
  origins: this.origins,
442
456
  components: this.components,
457
+ destinations: this.destinations,
443
458
  }
444
459
  })
445
460
  })
446
461
  })
447
462
  }
448
463
 
449
- this.flattenConntectivity = function (connectivity) {
450
- let dnodes = connectivity.flat() // get nodes from edgelist
451
- let nodes = [...new Set(dnodes)] // remove duplicates
452
- let found = []
453
- nodes.forEach((n) => {
454
- if (Array.isArray(n)) {
455
- found.push(n.flat())
456
- } else {
457
- found.push(n)
458
- }
459
- })
460
- return found.flat()
461
- }
462
-
463
464
  this.buildPubmedSqlStatement = function (keastIds) {
464
465
  let sql = 'select distinct publication from publications where entity in ('
465
466
  if (keastIds.length === 1) {