@abi-software/flatmapvuer 1.7.2-beta.0 → 1.7.3-beta.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,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/flatmapvuer",
3
- "version": "1.7.2-beta.0",
3
+ "version": "1.7.3-beta.0",
4
4
  "license": "Apache-2.0",
5
5
  "files": [
6
6
  "dist/*",
@@ -43,7 +43,7 @@
43
43
  "./src/*": "./src/*"
44
44
  },
45
45
  "dependencies": {
46
- "@abi-software/flatmap-viewer": "3.2.10",
46
+ "@abi-software/flatmap-viewer": "3.2.12",
47
47
  "@abi-software/map-utilities": "^1.3.1",
48
48
  "@abi-software/sparc-annotation": "0.3.2",
49
49
  "@abi-software/svg-sprite": "^1.0.1",
@@ -473,35 +473,18 @@ Please use `const` to assign meaningful names to them...
473
473
  </el-select>
474
474
  </el-row>
475
475
  </template>
476
- <div v-if="viewingMode === 'Neuron Connection'">
477
- <el-row class="backgroundSpacer"></el-row>
478
- <el-row class="backgroundText">Connection path display</el-row>
479
- <el-row class="backgroundControl">
480
- <el-radio-group
481
- v-model="connectionPathRadio"
482
- class="flatmap-radio"
483
- @change="setConnectionPath"
484
- >
485
- <el-radio value="origins">Origin</el-radio>
486
- <el-radio value="components">Component</el-radio>
487
- <el-radio value="destinations">Destination</el-radio>
488
- </el-radio-group>
489
- </el-row>
490
- </div>
491
- <div v-else>
492
- <el-row class="backgroundSpacer" v-if="displayFlightPathOption"></el-row>
493
- <el-row class="backgroundText" v-if="displayFlightPathOption">Flight path display</el-row>
494
- <el-row class="backgroundControl" v-if="displayFlightPathOption">
495
- <el-radio-group
496
- v-model="flightPath3DRadio"
497
- class="flatmap-radio"
498
- @change="setFlightPath3D"
499
- >
500
- <el-radio :value="false">2D</el-radio>
501
- <el-radio :value="true">3D</el-radio>
502
- </el-radio-group>
503
- </el-row>
504
- </div>
476
+ <el-row class="backgroundSpacer" v-if="displayFlightPathOption"></el-row>
477
+ <el-row class="backgroundText" v-if="displayFlightPathOption">Flight path display</el-row>
478
+ <el-row class="backgroundControl" v-if="displayFlightPathOption">
479
+ <el-radio-group
480
+ v-model="flightPath3DRadio"
481
+ class="flatmap-radio"
482
+ @change="setFlightPath3D"
483
+ >
484
+ <el-radio :value="false">2D</el-radio>
485
+ <el-radio :value="true">3D</el-radio>
486
+ </el-radio-group>
487
+ </el-row>
505
488
  <el-row class="backgroundSpacer"></el-row>
506
489
  <el-row class="backgroundText">Organs display</el-row>
507
490
  <el-row class="backgroundControl">
@@ -661,7 +644,7 @@ const centroid = (geometry) => {
661
644
  } else {
662
645
  coordinates = geometry.coordinates
663
646
  }
664
- if (coordinates) {
647
+ if (coordinates) {
665
648
  if (!(geometry.type === 'Point')) {
666
649
  coordinates.map((coor) => {
667
650
  featureGeometry.lng += parseFloat(coor[0])
@@ -1060,17 +1043,6 @@ export default {
1060
1043
  this.addAnnotationFeature()
1061
1044
  }
1062
1045
  },
1063
- /**
1064
- * @public
1065
- * Function to switch the type of connection path display
1066
- * @arg {Boolean} `flag`
1067
- */
1068
- setConnectionPath: function (flag) {
1069
- this.connectionPathRadio = flag
1070
- if (this.mapImp && this.currentActive) {
1071
- this.highlightConnectedPaths([this.currentActive])
1072
- }
1073
- },
1074
1046
  /**
1075
1047
  * @public
1076
1048
  * Function to switch from 2D to 3D
@@ -1291,60 +1263,47 @@ export default {
1291
1263
  /**
1292
1264
  * @public
1293
1265
  * Function to highlight the connected paths
1294
- * by providing path model identifier, ``pathId`` or ``anatomicalId``.
1295
- * @arg {String} `pathId` or `anatomicalId`
1266
+ * by providing path model identifier, ``pathId``.
1267
+ * @arg {String} `pathId`
1296
1268
  */
1297
- highlightConnectedPaths: async function (payload, options = {}) {
1269
+ highlightConnectedPaths: async function (payload) {
1298
1270
  if (this.mapImp) {
1271
+ let paths = [...this.mapImp.pathModelNodes(payload)]
1272
+
1299
1273
  // The line below is to get the path features from the geojson ids
1300
- const connectedType = options.type || this.connectionPathRadio
1301
- const nodeFeatureIds = [...this.mapImp.pathModelNodes(payload)]
1302
- const pathsOfEntities = await this.mapImp.queryPathsForFeatures(payload)
1274
+ let pathFeatures = paths.map((p) => this.mapImp.featureProperties(p))
1275
+
1276
+ // Query the flatmap knowledge graph for connectivity, we use this to grab the origins
1277
+ let connectivity = await this.flatmapQueries.queryForConnectivityNew(this.mapImp, payload)
1278
+
1279
+ // Check and flatten the origins node graph
1280
+ let originsFlat = connectivity?.ids?.dendrites?.flat().flat()
1281
+
1303
1282
  let toHighlight = []
1304
1283
  let highlight = false
1305
1284
 
1306
- if (nodeFeatureIds.length) {
1307
- let target = options.target || []
1308
- if (!target.length) {
1309
- // Query the flatmap knowledge graph for connectivity, we use this to grab the origins
1310
- const connectivity = await this.flatmapQueries.queryForConnectivityNew(this.mapImp, payload)
1311
- // Check and flatten the origins node graph
1312
- const originsFlat = connectivity?.ids?.dendrites?.flat().flat()
1313
- const componentsFlat = connectivity?.ids?.components?.flat().flat()
1314
- const destinationsFlat = connectivity?.ids?.axons?.flat().flat()
1315
- target = connectedType === "origins" ?
1316
- originsFlat : connectedType === "components" ?
1317
- componentsFlat : connectedType === "destinations" ?
1318
- destinationsFlat : []
1319
- }
1320
-
1321
- // Loop through the node features and check if we have certain nodes
1322
- nodeFeatureIds.forEach((featureId) => {
1323
- // Get the paths from each node feature
1324
- const pathsL2 = this.mapImp.nodePathModels(featureId)
1325
- pathsL2.forEach((path) => {
1326
- highlight = true
1327
- // nodes of the second level path
1328
- const nodeFeatureIdsL2 = this.mapImp.pathModelNodes(path)
1329
- const nodeModelsL2 = nodeFeatureIdsL2.map((featureIdL2) => {
1330
- return this.mapImp.featureProperties(featureIdL2).models
1331
- })
1332
- const intersection = target.filter(element => nodeModelsL2.includes(element))
1333
- if (!intersection.length) highlight = false
1334
- if (highlight && !toHighlight.includes(path)) toHighlight.push(path)
1335
- })
1336
- })
1337
- toHighlight = [...new Set([...toHighlight, ...payload])]
1338
- } else if (pathsOfEntities.length) {
1339
- pathsOfEntities.forEach((path) => {
1340
- const nodeFeatureIds = this.mapImp.pathModelNodes(path)
1341
- const nodeModels = nodeFeatureIds.map((featureId) => {
1342
- return this.mapImp.featureProperties(featureId).models
1285
+ // Loop through the path features and check if we have origin nodes
1286
+ pathFeatures.forEach((p) => {
1287
+
1288
+ // Get the nodes from each path feature
1289
+ this.mapImp.nodePathModels(p.featureId).forEach((f) => {
1290
+ highlight = true
1291
+ // s2 here is the second level paths
1292
+ let s2 = this.mapImp.pathModelNodes(f)
1293
+ s2.forEach((s) => {
1294
+ let s2Feature = this.mapImp.featureProperties([s]) // get the feature properties for s2
1295
+ if (originsFlat.includes(s2Feature.models)) {
1296
+ highlight = false // if we have an origin node, we don't want to highlight the path
1297
+ return
1298
+ }
1343
1299
  })
1344
- if (nodeModels.includes(options.target[0])) toHighlight.push(path)
1300
+
1301
+ if (highlight) {
1302
+ toHighlight.push(f)
1303
+ }
1345
1304
  })
1346
- if (!toHighlight.length) toHighlight = options.target
1347
- }
1305
+ })
1306
+
1348
1307
  // display connected paths
1349
1308
  this.mapImp.zoomToFeatures(toHighlight, { noZoomIn: true })
1350
1309
  }
@@ -1680,10 +1639,10 @@ export default {
1680
1639
  //The following will be used to track either a feature is selected
1681
1640
  this.statesTracking.activeClick = true
1682
1641
  this.statesTracking.activeTerm = data?.models
1683
- this.currentActive = data.models ? data.models : ''
1684
1642
  if (this.viewingMode === 'Neuron Connection') {
1685
1643
  this.highlightConnectedPaths([data.models])
1686
1644
  } else {
1645
+ this.currentActive = data.models ? data.models : ''
1687
1646
  // Drawing connectivity between features
1688
1647
  if (this.activeDrawTool && !this.isValidDrawnCreated) {
1689
1648
  // Check if flatmap features or existing drawn features
@@ -1744,6 +1703,12 @@ export default {
1744
1703
  * Function to remove active tooltips on map.
1745
1704
  */
1746
1705
  removeActiveTooltips: function () {
1706
+ // Remove active tooltip/popup on map
1707
+ if (this.mapImp) {
1708
+ this.mapImp.removePopup();
1709
+ }
1710
+
1711
+ // Fallback: remove any existing toolitp on DOM
1747
1712
  const tooltips = this.$el.querySelectorAll('.flatmap-tooltip-popup');
1748
1713
  tooltips.forEach((tooltip) => tooltip.remove());
1749
1714
  },
@@ -1751,7 +1716,7 @@ export default {
1751
1716
  * Function to create tooltip for the provided connectivity data.
1752
1717
  * @arg {Array} `connectivityData`
1753
1718
  */
1754
- createTooltipForConnectivity: function (connectivityData) {
1719
+ createTooltipForConnectivity: function (connectivityData, geojsonId) {
1755
1720
  // combine all labels to show together
1756
1721
  // content type must be DOM object to use HTML
1757
1722
  const labelsContainer = document.createElement('div');
@@ -1768,7 +1733,7 @@ export default {
1768
1733
  });
1769
1734
 
1770
1735
  this.mapImp.showPopup(
1771
- connectivityData[0].featureId,
1736
+ geojsonId,
1772
1737
  labelsContainer,
1773
1738
  {
1774
1739
  className: 'custom-popup flatmap-tooltip-popup',
@@ -1785,6 +1750,7 @@ export default {
1785
1750
  showConnectivityTooltips: function (payload) {
1786
1751
  const { connectivityInfo, data } = payload;
1787
1752
  const featuresToHighlight = [];
1753
+ const geojsonHighlights = [];
1788
1754
  const connectivityData = [];
1789
1755
  const filteredConnectivityData = [];
1790
1756
  const errorData = [];
@@ -1820,16 +1786,31 @@ export default {
1820
1786
  id,
1821
1787
  label,
1822
1788
  });
1823
- featuresToHighlight.push(id);
1824
1789
  } else {
1825
1790
  errorData.push(connectivity);
1826
1791
  }
1827
1792
  });
1828
1793
 
1829
1794
  if (filteredConnectivityData.length) {
1830
- // show tooltip of the first item
1831
- // with all labels
1832
- this.createTooltipForConnectivity(filteredConnectivityData);
1795
+ let geojsonId = filteredConnectivityData[0].featureId;
1796
+
1797
+ this.mapImp.annotations.forEach((annotation) => {
1798
+ const anatomicalNodes = annotation['anatomical-nodes'];
1799
+
1800
+ if (anatomicalNodes) {
1801
+ const anatomicalNodesString = anatomicalNodes.join('');
1802
+ const foundItem = filteredConnectivityData.every((item) =>
1803
+ anatomicalNodesString.indexOf(item.id) !== -1
1804
+ );
1805
+
1806
+ if (foundItem) {
1807
+ geojsonId = annotation.featureId;
1808
+ geojsonHighlights.push(geojsonId);
1809
+ }
1810
+ }
1811
+ });
1812
+
1813
+ this.createTooltipForConnectivity(filteredConnectivityData, geojsonId);
1833
1814
  } else {
1834
1815
  errorData.push(...connectivityData);
1835
1816
  // Close all tooltips on the current flatmap element
@@ -1843,6 +1824,10 @@ export default {
1843
1824
 
1844
1825
  // highlight all available features
1845
1826
  this.mapImp.selectFeatures(featuresToHighlight);
1827
+
1828
+ if (geojsonHighlights.length) {
1829
+ this.mapImp.selectGeoJSONFeatures(geojsonHighlights);
1830
+ }
1846
1831
  }
1847
1832
  },
1848
1833
  emitConnectivityGraphError: function (errorData) {
@@ -1897,7 +1882,8 @@ export default {
1897
1882
  }
1898
1883
  } else {
1899
1884
  //require data.resource && data.feature.source
1900
- const results = await this.flatmapQueries.retrieveFlatmapKnowledgeForEvent(this.mapImp, data)
1885
+ let results =
1886
+ await this.flatmapQueries.retrieveFlatmapKnowledgeForEvent(this.mapImp, data)
1901
1887
  // The line below only creates the tooltip if some data was found on the path
1902
1888
  // the pubmed URLs are in knowledge response.references
1903
1889
  if (
@@ -1907,8 +1893,6 @@ export default {
1907
1893
  this.resourceForTooltip = data.resource[0]
1908
1894
  data.resourceForTooltip = this.resourceForTooltip
1909
1895
  this.createTooltipFromNeuronCuration(data)
1910
- } else {
1911
- this.createTooltipFromEntityCuration(data)
1912
1896
  }
1913
1897
  }
1914
1898
  },
@@ -1950,43 +1934,8 @@ export default {
1950
1934
  */
1951
1935
  createTooltipFromNeuronCuration: async function (data) {
1952
1936
  this.tooltipEntry = await this.flatmapQueries.createTooltipData(this.mapImp, data)
1953
- this.tooltipEntry.neuronCuration = true
1954
1937
  this.displayTooltip(data.resource[0])
1955
1938
  },
1956
- /**
1957
- * @public
1958
- * Function to create tooltip from Neuron Curation ``data``.
1959
- * @arg {Object} `data`
1960
- */
1961
- createTooltipFromEntityCuration: async function (data) {
1962
- this.tooltipEntry = await this.flatmapQueries.createTooltipData(this.mapImp, data)
1963
- this.tooltipEntry.entityCuration = true
1964
- let labels = []
1965
- const pathsOfEntities = await this.mapImp.queryPathsForFeatures(data.resource)
1966
- if (pathsOfEntities.length) {
1967
- let componentsWithDatasets = []
1968
- pathsOfEntities.forEach((path) => {
1969
- const featureIds = this.mapImp.pathModelNodes(path)
1970
- featureIds.forEach((id) => {
1971
- const feature = this.mapImp.featureProperties(id)
1972
- if (!labels.includes(feature.label)) {
1973
- labels.push(feature.label)
1974
- componentsWithDatasets.push({ id: feature.models, name: feature.label })
1975
- }
1976
- })
1977
- })
1978
- this.tooltipEntry = {
1979
- ...this.tooltipEntry,
1980
- origins: [data.label],
1981
- originsWithDatasets: [{ id: data.resource[0], name: data.label }],
1982
- components: labels,
1983
- componentsWithDatasets: componentsWithDatasets,
1984
- destinations: [],
1985
- destinationsWithDatasets: [],
1986
- }
1987
- this.displayTooltip(data.resource[0])
1988
- }
1989
- },
1990
1939
  /**
1991
1940
  * @public
1992
1941
  * Function to show popup on map.
@@ -2388,7 +2337,6 @@ export default {
2388
2337
  if (identifier && identifier.uuid) state['uuid'] = identifier.uuid
2389
2338
  state['viewingMode'] = this.viewingMode
2390
2339
  state['searchTerm'] = this.statesTracking.activeTerm
2391
- state['connectionPath'] = this.connectionPathRadio
2392
2340
  state['flightPath3D'] = this.flightPath3DRadio
2393
2341
  state['colour'] = this.colourRadio
2394
2342
  state['outlinesRadio'] = this.outlinesRadio
@@ -2985,7 +2933,6 @@ export default {
2985
2933
  connectivityTooltipVisible: false,
2986
2934
  drawerOpen: false,
2987
2935
  featuresAlert: undefined,
2988
- connectionPathRadio: 'origins',
2989
2936
  flightPath3DRadio: false,
2990
2937
  displayFlightPathOption: false,
2991
2938
  colourRadio: true,
@@ -3484,6 +3431,12 @@ export default {
3484
3431
  border-style: solid;
3485
3432
  flex-shrink: 0;
3486
3433
  }
3434
+
3435
+ hr {
3436
+ margin: 0.5rem 0;
3437
+ border: 0;
3438
+ border-top: 1px solid var(--el-border-color);
3439
+ }
3487
3440
  }
3488
3441
  .maplibregl-popup-tip {
3489
3442
  display: none;