Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
cae7e23
Add cell cards api
akhuoa Apr 1, 2026
fe2f258
Merge branch 'ABI-Software:main' into feature/cell-card-explorer
akhuoa Apr 17, 2026
4709507
Merge branch 'ABI-Software:main' into feature/cell-card-explorer
akhuoa May 1, 2026
7cec108
Add cell cards explorer show hide toggle
akhuoa May 6, 2026
1a0967a
Update split-flow entries resource with correct species information
akhuoa May 7, 2026
a260a95
Filter and emit active species from entries
akhuoa May 7, 2026
6eb227e
Merge branch 'ABI-Software:main' into feature/cell-card-explorer
akhuoa May 15, 2026
5112de1
Merge branch 'ABI-Software:main' into feature/cell-card-explorer
akhuoa May 18, 2026
4304c03
Add show soma location tooltip on map
akhuoa May 18, 2026
102b62d
Update the app's show cell card explorer button
akhuoa May 18, 2026
f9d0dc6
Disable the show cell card explorer before the map is loaded
akhuoa May 18, 2026
13e040f
Merge branch 'ABI-Software:main' into feature/cell-card-explorer
akhuoa May 26, 2026
93a89ed
Add cell card exploration viewing mode
akhuoa May 29, 2026
c7cf51d
Add cell type viewing mode for cell cards
akhuoa May 29, 2026
66db74c
Receive soma locations from sidebar cell cards
akhuoa May 29, 2026
3fec3a1
Receive soma locations from cell card explorer
akhuoa May 31, 2026
42c1ae0
Show dataset markers on cell type exploration mode
akhuoa May 31, 2026
6f0d9ce
Refactor
akhuoa May 31, 2026
a93328b
Add cell types count in soma location receiver
akhuoa May 31, 2026
8311867
Show cell types markers on flatmap
akhuoa May 31, 2026
e468476
Show cell types markers for cell card explorer
akhuoa May 31, 2026
ba230ed
Fix soma location marker click
akhuoa Jun 1, 2026
e8ea9bf
Remove query from cell card filters
akhuoa Jun 1, 2026
c3812c3
Fix cell card soma location cascader isssue
akhuoa Jun 1, 2026
e006935
Merge branch 'ABI-Software:main' into feature/cell-card-explorer
akhuoa Jun 2, 2026
cbf3797
Merge branch 'main' into feature/cell-card-explorer
akhuoa Jun 8, 2026
89104aa
Merge branch 'feature/cell-card-explorer' of github.com:akhuoa/mapint…
akhuoa Jun 8, 2026
e7e74d6
Fix switching viewing mode between exploration and cell type
akhuoa Jun 8, 2026
074674d
Refactor cell card soma location markers emit
akhuoa Jun 11, 2026
ebe0e4e
Merge branch 'ABI-Software:main' into feature/cell-card-explorer
akhuoa Jun 18, 2026
3827ded
Clean spaces
akhuoa Jun 19, 2026
f7e99be
Restore cell card explorer tab if available
akhuoa Jun 19, 2026
3b97b17
Remove show cell card explorer option from demo app
akhuoa Jun 19, 2026
61ab40b
Add event tracking for cell card explorer fitlers and search
akhuoa Jun 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
//VITE_PENNSIEVE_API_LOCATION=https://api.pennsieve.io
#VITE_API_LOCATION=https://sparc-api.herokuapp.com/
VITE_SPARC_API=https://alan-wu-portal-api.herokuapp.com/
VITE_APP_CELL_CARDS_API=http://localhost:8787/cellCardsData.json
4 changes: 3 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ export default {
ElIconSetting: shallowRef(ElIconSetting),
routerIsReady: false,
showLongLabel: true,
isMapLoaded: false,
}
},
computed: {
Expand All @@ -177,6 +178,7 @@ export default {
algoliaId: import.meta.env.VITE_ALGOLIA_ID,
pennsieveApi: import.meta.env.VITE_PENNSIEVE_API_LOCATION,
flatmapAPI: this.$route.query.flatmapserver ? this.$route.query.flatmapserver : import.meta.env.VITE_FLATMAPAPI_LOCATION,
cellCardsApi: import.meta.env.VITE_APP_CELL_CARDS_API,
rootUrl: import.meta.env.VITE_ROOT_URL,
}
}
Expand Down Expand Up @@ -251,7 +253,6 @@ export default {
}
getShareLink(1)
});

},
setFlatmap: function() {
this.$refs.map.setCurrentEntry(
Expand Down Expand Up @@ -317,6 +318,7 @@ export default {
},
mapIsLoaded: function(map) {
console.log("map is loaded", map)
this.isMapLoaded = true;
// map.changeViewingMode('Annotation')
},
viewerIsReady: function() {
Expand Down
5 changes: 5 additions & 0 deletions src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ declare module 'vue' {
ElButton: typeof import('element-plus/es')['ElButton']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
Expand All @@ -28,8 +30,11 @@ declare module 'vue' {
ElIconArrowDown: typeof import('@element-plus/icons-vue')['ArrowDown']
ElIconArrowUp: typeof import('@element-plus/icons-vue')['ArrowUp']
ElIconCompass: typeof import('@element-plus/icons-vue')['Compass']
ElIconCpu: typeof import('@element-plus/icons-vue')['Cpu']
ElIconDocument: typeof import('@element-plus/icons-vue')['Document']
ElIconEditPen: typeof import('@element-plus/icons-vue')['EditPen']
ElIconMoreFilled: typeof import('@element-plus/icons-vue')['MoreFilled']
ElIconSGrid: typeof import('@element-plus/icons-vue')['SGrid']
ElIconShare: typeof import('@element-plus/icons-vue')['Share']
ElInput: typeof import('element-plus/es')['ElInput']
ElMain: typeof import('element-plus/es')['ElMain']
Expand Down
3 changes: 3 additions & 0 deletions src/components/ContentVuer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ export default {
onShowConnectivityTooltips: function(payload) {
this.$refs.viewer?.showConnectivityTooltips(payload);
},
onShowFeatureInFlatmap: function(payload) {
this.$refs.viewer?.showFeatureInFlatmap(payload);
},
onShowReferenceConnectivity: function(payload) {
this.$refs.viewer?.showConnectivitiesByReference(payload);
},
Expand Down
21 changes: 18 additions & 3 deletions src/components/DialogToolbarContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
<el-icon class="el-icon--left" v-if="globalSettings.viewingMode === 'Annotation'">
<el-icon-edit-pen />
</el-icon>
<el-icon class="el-icon--left" v-if="globalSettings.viewingMode === 'Cell Type'">
<el-icon-cpu />
</el-icon>
{{ globalSettings.viewingMode }}
<template v-if="globalSettings.viewingMode === 'Neuron Connection'">
&nbsp;
Expand Down Expand Up @@ -56,6 +59,9 @@
<el-icon class="el-icon--left" v-if="key === 'Annotation'">
<el-icon-edit-pen />
</el-icon>
<el-icon class="el-icon--left" v-if="key === 'Cell Type'">
<el-icon-cpu />
</el-icon>
{{ key }}
</h5>
<small class="el-option__description">
Expand Down Expand Up @@ -268,7 +274,7 @@
</el-row>
</template>
</el-popover>
<el-popover class="tooltip" content="Get permalink" placement="bottom-end"
<el-popover class="tooltip" content="Get permalink" placement="bottom-end"
:show-after="helpDelay" :teleported=false trigger="hover"
popper-class="header-popper"
>
Expand Down Expand Up @@ -435,6 +441,7 @@ import {
ElButton as Button,
ElCheckbox as Checkbox,
ElCol as Col,
ElIcon,
ElIcon as Icon,
ElInput as Input,
ElPopover as Popover,
Expand Down Expand Up @@ -520,7 +527,8 @@ export default {
viewingModes: {
'Exploration': 'Find relevant research and view detail of neural pathways by selecting a pathway to view its connections and data sources',
'Neuron Connection': 'Discover neuron connections by selecting a feature and viewing its associated network connections',
'Annotation': ['View feature annotations', 'Add, comment on and view feature annotations']
'Annotation': ['View feature annotations', 'Add, comment on and view feature annotations'],
'Cell Type': 'Explore cell cards for different cell types and their associated data',
},
authorisedUser: false,
mapLoaded: false,
Expand All @@ -546,20 +554,27 @@ export default {
} else if (value === 'Annotation') {
this.globalSettings.displayMarkers = false;
this.globalSettings.interactiveMode = 'dataset';
} else if (value === 'Cell Type') {
this.globalSettings.displayMarkers = true;
this.globalSettings.interactiveMode = 'connectivity';
} else {
this.globalSettings.displayMarkers = false;
this.globalSettings.interactiveMode = 'connectivity';
}

this.updateGlobalSettings('viewingMode');

if (value === 'Cell Type') {
this.$emit('open-cell-card-explorer');
}
}
},
updateGlobalSettings: function(changedKey) {
const updatedSettings = this.settingsStore.getUpdatedGlobalSettingsKey(this.globalSettings);
this.settingsStore.updateGlobalSettings(this.globalSettings);

// display marker update
if (updatedSettings.includes('displayMarkers')) {
if (updatedSettings.includes('displayMarkers') || updatedSettings.includes('interactiveMode')) {
EventBus.emit('markerUpdate');
}
if (updatedSettings.includes('interactiveMode')) {
Expand Down
1 change: 1 addition & 0 deletions src/components/MapContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ export default {
this.options.algoliaId ? this.settingsStore.updateAlgoliaId(this.options.algoliaId) : null;
this.options.pennsieveApi ? this.settingsStore.updatePennsieveApi(this.options.pennsieveApi) : null;
this.options.flatmapAPI ? this.settingsStore.updateFlatmapAPI(this.options.flatmapAPI) : null;
this.options.cellCardsApi ? this.settingsStore.updateCellCardsApi(this.options.cellCardsApi) : null;
this.options.rootUrl ? this.settingsStore.updateRootUrl(this.options.rootUrl) : null;
}
this.settingsStore.updateAllClosable(this.allClosable);
Expand Down
10 changes: 10 additions & 0 deletions src/components/SplitDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ export default {
const wholeBodyScaffoldIDs = [307, '307'];
const sckanVersion = Object.keys(this.connectivitiesStore.globalConnectivities)
.find(key => key.includes('sckan'));
// Filter active entries and emit their resources (species)
const activeEntries = this.entries.filter((entry) => activePaneIDs.includes(entry.id));
const activeSpecies = activeEntries.map((entry) => entry.resource);
this.$emit('update-active-species', activeSpecies);
const uuids = Array.from(
new Set(
this.entries
Expand Down Expand Up @@ -639,6 +643,12 @@ export default {
content.onShowConnectivityTooltips(payload);
});
});
EventBus.on('soma-location-hovered', (payload) => {
const contents = this.getActiveContents();
contents.forEach((content) => {
content.onShowFeatureInFlatmap(payload);
});
});
EventBus.on('connectivity-source-change', (payload) => {
const contents = this.getActiveContents();
//Use ongoingSource array to make sure, the knowledge
Expand Down
79 changes: 79 additions & 0 deletions src/components/SplitFlow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
@onFullscreen="onFullscreen"
@local-search="onDisplaySearch"
@fetch-suggestions="fetchSuggestions"
@open-cell-card-explorer="openCellCardExplorerFromToolbar"
ref="dialogToolbar"
/>
</el-header>
Expand All @@ -31,6 +32,7 @@
:filterOptions="filterOptions"
:showVisibilityFilter="showVisibilityFilter"
:showLongLabel="showLongLabel"
:showCellCards="showCellCards"
@tabClicked="onSidebarTabClicked"
@tabClosed="onSidebarTabClosed"
@actionClick="actionClick"
Expand All @@ -52,13 +54,16 @@
@show-connectivity-graph="onShowConnectivityGraph"
@filter-visibility="onFilterVisibility"
@connectivity-item-close="onConnectivityItemClose"
@soma-location-hovered="showSomaLocation"
@soma-locations-ready="onSomaLocationsReady"
@trackEvent="trackEvent"
/>
<SplitDialog
:entries="entries"
ref="splitdialog"
@resource-selected="resourceSelected"
@species-changed="speciesChanged"
@update-active-species="updateActiveSpeciesForEntries"
/>
</div>
</el-main>
Expand Down Expand Up @@ -186,6 +191,8 @@ export default {
filterVisibility: true,
filterOptions: [],
annotationHighlight: [],
showCellCards: false,
cellCardSomaLocations: [],
}
},
watch: {
Expand All @@ -212,6 +219,20 @@ export default {
},
},
methods: {
openCellCardExplorerFromToolbar: function () {
this.openCellCardExplorer();
},
openCellCardExplorer: function (payload = {}) {
this.showCellCards = true;

if (this.$refs.sideBar) {
this.$refs.sideBar.tabClicked({ id: 4, type: 'cellCardExplorer' });
this.$refs.sideBar.setDrawerOpen(true);
if (payload && (payload.filters?.length || payload.query)) {
this.$refs.sideBar.openCellCardExplorerSearch(payload.filters || [], payload.query || '');
}
}
},
onFilterVisibility: function (state) {
this.filterVisibility = state;
const filterExpression = {
Expand Down Expand Up @@ -321,6 +342,8 @@ export default {
});
this.filterTriggered = true;
}
} else if (action.type === "OpenCellCardExplorer") {
this.openCellCardExplorer(action);
} else if (action.type == "URL") {
window.open(action.resource, "_blank");
} else if (action.type == "Facet") {
Expand Down Expand Up @@ -595,6 +618,25 @@ export default {
onConnectivityHovered: function (data) {
EventBus.emit('connectivity-hovered', data);
},
showSomaLocation: function (name) {
EventBus.emit('soma-location-hovered', name);
},
onSomaLocationsReady: function (somaLocations) {
const normalizedSomaLocations = (Array.isArray(somaLocations) ? somaLocations : [])
.map((item) => {
return {
label: String(item?.label || '').trim(),
curie: String(item?.curie || '').trim(),
count: Number(item?.count || 0),
};
})
.filter((item) => item.label);

this.cellCardSomaLocations = [...new Map(
normalizedSomaLocations.map((item) => [item.label.toLowerCase(), item])
).values()];
this.updateSomaLocationMarkers(this.cellCardSomaLocations);
},
onConnectivitySourceChange: function (data) {
this.connectivityExplorerClicked.push(true);
EventBus.emit('connectivity-source-change', data);
Expand Down Expand Up @@ -727,8 +769,35 @@ export default {
});
}
}
} else if (data.tabType === 'cellType') {
const filterValues = data.filter.filter(f => (f.facet && f.facet.toLowerCase() !== 'show all'))
.map((f) => f.tagLabel)
.join(', ');
const searchValue = data.query;

if (filterValues) {
Tagging.sendEvent({
'event': 'interaction_event',
'event_name': 'portal_maps_action_filter',
'category': filterValues,
'location': 'map_sidebar_cell_card_filter'
});
}

if (searchValue) {
Tagging.sendEvent({
'event': 'interaction_event',
'event_name': 'portal_maps_action_search',
'category': searchValue,
'location': 'map_sidebar_cell_card_search'
});
}
}
},
updateSomaLocationMarkers: function (data) {
this.settingsStore.updateCellCardSomaLocations(data);
EventBus.emit("markerUpdate");
},
updateMarkers: function (data) {
this.settingsStore.updateMarkers(data);
EventBus.emit("markerUpdate");
Expand Down Expand Up @@ -818,6 +887,10 @@ export default {
// - connectivity knowledge is loaded
// - if sidebar state is not restored yet
const sidebarState = state?.sidebar;
// Restore Cell Card Explorer
if (sidebarState?.activeTabId === 4) {
this.showCellCards = true;
}
if (!this.sidebarStateRestored && sidebarState && this.$refs.sideBar && this.connectivityKnowledge?.length) {
if (sidebarState.connectivityEntries?.length) {
this.restoreConnectivityEntries(sidebarState.connectivityEntries);
Expand Down Expand Up @@ -890,6 +963,11 @@ export default {
})
}
},
updateActiveSpeciesForEntries: function (activeSpecies) {
if (this.$refs.sideBar) {
this.$refs.sideBar.updateActiveSpeciesForEntries(activeSpecies);
}
},
contextUpdate: function (payload) {
EventBus.emit("contextUpdate", payload);
},
Expand Down Expand Up @@ -1089,6 +1167,7 @@ export default {
PENNSIEVE_API_LOCATION: this.settingsStore.pennsieveApi,
ROOT_URL: this.settingsStore.rootUrl,
FLATMAPAPI_LOCATION: this.settingsStore.flatmapAPI,
CELL_CARDS_API: this.settingsStore.cellCardsApi,
};
},
entries: function() {
Expand Down
22 changes: 22 additions & 0 deletions src/components/viewers/Flatmap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,28 @@ export default {
flatmap.showConnectivityTooltips(payload);
}
},
showFeatureInFlatmap: function (payload) {
if (this?.alive && this.flatmapReady) {
const flatmap = this.$refs.flatmap;

if (payload) {
const searchResults = flatmap.searchSuggestions(payload);
let geoJSONID = undefined;

if (searchResults?.results.length) {
const featureId = searchResults?.results[0].featureId;
geoJSONID = featureId;
}

if (geoJSONID) {
flatmap.showPopup(geoJSONID, payload);
}
} else {
flatmap.closeTooltip();
this.showConnectivityTooltips({connectivityInfo: null, data: []});
}
}
},
showConnectivitiesByReference: function (payload) {
if (this?.alive) {
const currentFlatmap = this.$refs.flatmap;
Expand Down
Loading