@abi-software/mapintegratedvuer 0.7.2-vue3.0-alpha.0 → 1.0.1
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/LICENSE +201 -201
- package/README.md +150 -150
- package/assets/styleguide.css +19 -19
- package/cypress.config.js +23 -23
- package/dist/index.html +17 -17
- package/dist/mapintegratedvuer.js +74289 -73840
- package/dist/mapintegratedvuer.umd.cjs +878 -515
- package/dist/style.css +1 -1
- package/package.json +134 -135
- package/public/index.html +17 -17
- package/reporter-config.json +9 -9
- package/src/App.vue +245 -245
- package/src/assets/_variables.scss +43 -43
- package/src/assets/fonts/mapicon-species.eot +0 -0
- package/src/assets/fonts/mapicon-species.ttf +0 -0
- package/src/assets/fonts/mapicon-species.woff +0 -0
- package/src/assets/header-icon.scss +67 -67
- package/src/assets/mapicon-species-style.css +41 -41
- package/src/assets/styles.scss +9 -9
- package/src/components/ContentBar.vue +376 -376
- package/src/components/ContentVuer.vue +217 -217
- package/src/components/ContextCard.vue +385 -385
- package/src/components/ContextHelp.vue +73 -73
- package/src/components/CustomSplitter.vue +151 -151
- package/src/components/DatasetHeader.vue +97 -97
- package/src/components/DialogToolbarContent.vue +464 -464
- package/src/components/EventBus.js +3 -3
- package/src/components/FlatmapContextCard.vue +134 -134
- package/src/components/MapContent.vue +328 -333
- package/src/components/ResizeSensor.vue +47 -47
- package/src/components/SearchControls.vue +115 -115
- package/src/components/SimulatedData.js +721 -721
- package/src/components/SplitDialog.vue +287 -287
- package/src/components/SplitFlow.vue +414 -414
- package/src/components/index.js +7 -7
- package/src/components/markerZoomLevelsHardCoded.js +255 -255
- package/src/components/scripts/utilities.js +173 -173
- package/src/components/viewers/Flatmap.vue +145 -145
- package/src/components/viewers/Iframe.vue +31 -31
- package/src/components/viewers/MultiFlatmap.vue +384 -384
- package/src/components/viewers/Plot.vue +23 -23
- package/src/components/viewers/Scaffold.vue +198 -198
- package/src/components/viewers/Simulation.vue +21 -21
- package/src/icons/yellowstar.js +1 -1
- package/src/main.js +31 -31
- package/src/mixins/ContentMixin.js +438 -438
- package/src/mixins/DynamicMarkerMixin.js +88 -88
- package/src/mixins/S3Bucket.vue +37 -37
- package/src/stores/entries.js +40 -40
- package/src/stores/index.js +23 -23
- package/src/stores/settings.js +144 -144
- package/src/stores/splitFlow.js +523 -523
- package/static.json +7 -7
- package/vite.config.js +70 -70
- package/vite.static-build.js +12 -12
- package/vitest.workspace.js +3 -3
- package/vuese-generator.js +65 -65
- package/assets/gazelle-icons-no-background.css +0 -32
- package/dist/matterport.pdf +0 -0
- package/dist/test.txt +0 -0
- package/public/matterport.pdf +0 -0
- package/public/test.txt +0 -0
- package/q.json +0 -690
- package/src/mixins/RetrieveContextCardMixin.js +0 -82
- package/tsconfig.json +0 -19
@@ -1,438 +1,438 @@
|
|
1
|
-
import {
|
2
|
-
getAvailableTermsForSpecies,
|
3
|
-
getInteractiveAction,
|
4
|
-
getNerveNames,
|
5
|
-
getParentsRegion,
|
6
|
-
} from "../components/SimulatedData.js";
|
7
|
-
import EventBus from "../components/EventBus";
|
8
|
-
import markerZoomLevels from "../components/markerZoomLevelsHardCoded.js";
|
9
|
-
import { mapStores } from 'pinia';
|
10
|
-
import { useSettingsStore } from '../stores/settings';
|
11
|
-
import { useSplitFlowStore } from '../stores/splitFlow';
|
12
|
-
|
13
|
-
function capitalise(text) {
|
14
|
-
return text[0].toUpperCase() + text.substring(1)
|
15
|
-
}
|
16
|
-
|
17
|
-
/* eslint-disable no-alert, no-console */
|
18
|
-
export default {
|
19
|
-
props: {
|
20
|
-
/**
|
21
|
-
* Object containing information for
|
22
|
-
* the required viewing.
|
23
|
-
*/
|
24
|
-
entry: Object,
|
25
|
-
visible: {
|
26
|
-
type: Boolean,
|
27
|
-
default: true,
|
28
|
-
},
|
29
|
-
mouseHovered: {
|
30
|
-
type: Boolean,
|
31
|
-
default: false,
|
32
|
-
},
|
33
|
-
},
|
34
|
-
computed: {
|
35
|
-
...mapStores(useSettingsStore, useSplitFlowStore),
|
36
|
-
syncMode() {
|
37
|
-
return this.splitFlowStore.syncMode;
|
38
|
-
},
|
39
|
-
},
|
40
|
-
mounted: function () {
|
41
|
-
EventBus.on("startHelp", () => {
|
42
|
-
this.startHelp();
|
43
|
-
});
|
44
|
-
},
|
45
|
-
methods: {
|
46
|
-
toggleSyncMode: function () {
|
47
|
-
return;
|
48
|
-
},
|
49
|
-
getState: function () {
|
50
|
-
return undefined;
|
51
|
-
},
|
52
|
-
openMap: function (type) {
|
53
|
-
if (type === "SYNC") {
|
54
|
-
this.toggleSyncMode();
|
55
|
-
} else {
|
56
|
-
EventBus.emit("OpenNewMap", type);
|
57
|
-
}
|
58
|
-
},
|
59
|
-
updateWithViewUrl: function() {
|
60
|
-
return;
|
61
|
-
},
|
62
|
-
/**
|
63
|
-
* Perform a local search on this contentvuer
|
64
|
-
*/
|
65
|
-
search: function () {
|
66
|
-
return false;
|
67
|
-
},
|
68
|
-
/**
|
69
|
-
* Get a list of search suggestions on this contentvuer
|
70
|
-
*/
|
71
|
-
searchSuggestions: function () {
|
72
|
-
return;
|
73
|
-
},
|
74
|
-
/**
|
75
|
-
* Callback when the vuers emit a selected event.
|
76
|
-
*/
|
77
|
-
resourceSelected: function (type, resource, augmented) {
|
78
|
-
// Skip processing if resources already has actions
|
79
|
-
if (this.resourceHasAction(resource)) {
|
80
|
-
EventBus.emit("PopoverActionClick", resource);
|
81
|
-
return;
|
82
|
-
}
|
83
|
-
|
84
|
-
let returnedAction = undefined;
|
85
|
-
let action = "none";
|
86
|
-
let fireResourceSelected = false;
|
87
|
-
const result = {
|
88
|
-
paneIndex: this.entry.id,
|
89
|
-
type: type,
|
90
|
-
resource: resource,
|
91
|
-
internalName: undefined,
|
92
|
-
eventType: undefined,
|
93
|
-
};
|
94
|
-
|
95
|
-
if (type == "MultiFlatmap" || type == "Flatmap") {
|
96
|
-
result.internalName = this.idNamePair[resource.feature.models];
|
97
|
-
if (resource.eventType == "click") {
|
98
|
-
result.eventType = "selected";
|
99
|
-
if (resource.feature.type == "marker") {
|
100
|
-
let label = this.idNamePair[resource.feature.models];
|
101
|
-
let hardcodedAnnotation = markerZoomLevels.filter(
|
102
|
-
mz => mz.id === resource.feature.models
|
103
|
-
);
|
104
|
-
|
105
|
-
if (
|
106
|
-
this.settingsStore.isFeaturedMarkerIdentifier(
|
107
|
-
resource.feature.id
|
108
|
-
)
|
109
|
-
) {
|
110
|
-
// It is a featured dataset search for DOI.
|
111
|
-
returnedAction = {
|
112
|
-
type: "Search",
|
113
|
-
term: this.settingsStore.featuredMarkerDoi(
|
114
|
-
resource.feature.id
|
115
|
-
),
|
116
|
-
};
|
117
|
-
} else if (hardcodedAnnotation.filter(h => h.keyword).length > 0) {
|
118
|
-
// if it matches our stored keywords, it is a keyword search
|
119
|
-
// Keyword searches do not contain labels, so switch to keyword search if no label exists
|
120
|
-
returnedAction = {
|
121
|
-
type: "Search",
|
122
|
-
term:
|
123
|
-
"http://purl.obolibrary.org/obo/" +
|
124
|
-
resource.feature.models.replace(":", "_"),
|
125
|
-
};
|
126
|
-
} else {
|
127
|
-
// Facet search on anatomy if it is not a keyword search
|
128
|
-
returnedAction = {
|
129
|
-
type: "Facet",
|
130
|
-
facet: label,
|
131
|
-
facetPropPath: "anatomy.organ.category.name",
|
132
|
-
term: "Anatomical structure",
|
133
|
-
};
|
134
|
-
}
|
135
|
-
|
136
|
-
fireResourceSelected = true;
|
137
|
-
if (type == "MultiFlatmap") {
|
138
|
-
const flatmap =
|
139
|
-
this.$refs.multiflatmap.getCurrentFlatmap().mapImp;
|
140
|
-
flatmap.clearSearchResults();
|
141
|
-
}
|
142
|
-
} else if (resource.feature.type == "feature") {
|
143
|
-
// Do no open scaffold in sync map
|
144
|
-
if (this.syncMode) {
|
145
|
-
fireResourceSelected = true;
|
146
|
-
} else {
|
147
|
-
action = "scaffold";
|
148
|
-
}
|
149
|
-
}
|
150
|
-
} else if (resource.eventType == "mouseenter") {
|
151
|
-
result.eventType = "highlighted";
|
152
|
-
fireResourceSelected = true;
|
153
|
-
}
|
154
|
-
} else if (type == "Scaffold") {
|
155
|
-
if (resource && resource[0]) {
|
156
|
-
result.internalName = resource[0].data.id;
|
157
|
-
// Facet search if marker is clicked
|
158
|
-
if (resource[0].data.lastActionOnMarker === true) {
|
159
|
-
returnedAction = {
|
160
|
-
type: "Facet",
|
161
|
-
facet: capitalise(resource[0].data.id),
|
162
|
-
facetPropPath: "anatomy.organ.category.name",
|
163
|
-
term: "Anatomical structure",
|
164
|
-
};
|
165
|
-
}
|
166
|
-
}
|
167
|
-
result.eventType = "selected";
|
168
|
-
fireResourceSelected = true;
|
169
|
-
action = "search";
|
170
|
-
}
|
171
|
-
if ((returnedAction === undefined) && augmented) {
|
172
|
-
returnedAction = getInteractiveAction(result, action);
|
173
|
-
}
|
174
|
-
if (returnedAction) EventBus.emit("PopoverActionClick", returnedAction);
|
175
|
-
if (fireResourceSelected) this.$emit("resource-selected", result);
|
176
|
-
},
|
177
|
-
resourceHasAction: function (resource) {
|
178
|
-
return (
|
179
|
-
resource.type === "URL" ||
|
180
|
-
resource.type === "Search" ||
|
181
|
-
resource.type === "Neuron Search" ||
|
182
|
-
resource.type == "Facet" ||
|
183
|
-
resource.type == "Facets"
|
184
|
-
);
|
185
|
-
},
|
186
|
-
/**
|
187
|
-
* Check if this viewer is currently visible
|
188
|
-
*/
|
189
|
-
isVisible: function() {
|
190
|
-
const paneName = this.splitFlowStore.getPaneNameById(this.entry.id);
|
191
|
-
return paneName !== undefined;
|
192
|
-
},
|
193
|
-
displayTooltip: function() {
|
194
|
-
return;
|
195
|
-
},
|
196
|
-
/**
|
197
|
-
* Get the term to zoom/highlight in a synchronisation event,
|
198
|
-
* if it cannot be found in the map, it will perform several
|
199
|
-
* calls to try to ge a valid name/id.
|
200
|
-
*/
|
201
|
-
getNameAndIdFromSyncData: async function (data) {
|
202
|
-
let name = data.internalName;
|
203
|
-
if (name === undefined && data.resource) {
|
204
|
-
name = data.resource.label;
|
205
|
-
}
|
206
|
-
let id = undefined;
|
207
|
-
if (data.resource && data.resource.resource) {
|
208
|
-
id = data.resource.resource[0];
|
209
|
-
}
|
210
|
-
if (this.entry.type === "Scaffold") {
|
211
|
-
const objects = this.$refs.scaffold.findObjectsWithGroupName(name);
|
212
|
-
// If a region is not found use a hardcoded list to determine
|
213
|
-
// its parents region first
|
214
|
-
if (objects.length === 0) {
|
215
|
-
//Use nerve mapping
|
216
|
-
if (data.resource && data.resource.feature) {
|
217
|
-
const matched = getNerveNames(data.resource.feature.models);
|
218
|
-
if (matched.length > 0) return matched;
|
219
|
-
}
|
220
|
-
let matched = getParentsRegion(name);
|
221
|
-
if (matched) {
|
222
|
-
return matched;
|
223
|
-
}
|
224
|
-
// Hardcoded list failed - use an endpoint to find its parents
|
225
|
-
if (id && data.eventType === "selected") {
|
226
|
-
return fetch(`${this.apiLocation}get-related-terms/${id}`)
|
227
|
-
.then(response => response.json())
|
228
|
-
.then(data => {
|
229
|
-
if (data.uberon.array.length > 0) {
|
230
|
-
name =
|
231
|
-
data.uberon.array[0].name.charAt(0).toUpperCase() +
|
232
|
-
data.uberon.array[0].name.slice(1);
|
233
|
-
id = data.uberon.array[0].id.toUpperCase();
|
234
|
-
return { id, name };
|
235
|
-
}
|
236
|
-
});
|
237
|
-
}
|
238
|
-
}
|
239
|
-
} else if (this.entry.type === "MultiFlatmap") {
|
240
|
-
if (name === "Bladder") {
|
241
|
-
name = "Urinary Bladder";
|
242
|
-
} else {
|
243
|
-
const matched = getNerveNames(name);
|
244
|
-
if (matched.length > 0) name = matched[0];
|
245
|
-
}
|
246
|
-
}
|
247
|
-
return { id, name };
|
248
|
-
},
|
249
|
-
getDatasetAnatomyInfo: function (identifier) {
|
250
|
-
fetch(`${this.apiLocation}dataset_info/anatomy?identifier=${identifier}`)
|
251
|
-
.then(response => response.json())
|
252
|
-
.then(data => {
|
253
|
-
const resultPayload = data.result[0];
|
254
|
-
let markerCurie;
|
255
|
-
try {
|
256
|
-
markerCurie = resultPayload.anatomy.organ[0].curie;
|
257
|
-
} catch (error) {
|
258
|
-
markerCurie = undefined;
|
259
|
-
}
|
260
|
-
let markerDoi;
|
261
|
-
try {
|
262
|
-
markerDoi = resultPayload.item.curie;
|
263
|
-
} catch (error) {
|
264
|
-
markerDoi = undefined;
|
265
|
-
}
|
266
|
-
let markerSpecies;
|
267
|
-
try {
|
268
|
-
let index = 0;
|
269
|
-
let found = false;
|
270
|
-
while (!found && index < resultPayload.organisms.subject.length) {
|
271
|
-
const entry = resultPayload.organisms.subject[index];
|
272
|
-
if (entry.species) {
|
273
|
-
markerSpecies = entry.species.name;
|
274
|
-
found = true;
|
275
|
-
}
|
276
|
-
index += 1;
|
277
|
-
}
|
278
|
-
} catch (error) {
|
279
|
-
markerSpecies = undefined;
|
280
|
-
}
|
281
|
-
this.updateFeatureMarkers([markerCurie], undefined)
|
282
|
-
this.settingsStore.updateFeaturedMarker({
|
283
|
-
identifier,
|
284
|
-
marker: markerCurie,
|
285
|
-
doi: markerDoi,
|
286
|
-
species: markerSpecies,
|
287
|
-
});
|
288
|
-
});
|
289
|
-
},
|
290
|
-
// Check if the old featured dataset api has any info
|
291
|
-
oldFeaturedDatasetApiHasInfo: async function () {
|
292
|
-
let response = await fetch(`${this.apiLocation}get_featured_datasets_identifiers`)
|
293
|
-
let data = await response.json()
|
294
|
-
if (!data.identifiers || data.identifiers.length == 0) {
|
295
|
-
return false;
|
296
|
-
} else {
|
297
|
-
return data.identifiers;
|
298
|
-
}
|
299
|
-
},
|
300
|
-
// Check if the new featured dataset api has any info
|
301
|
-
newFeaturedDatasetApiHasInfo: async function () {
|
302
|
-
let response = await fetch(`${this.apiLocation}get_featured_dataset`)
|
303
|
-
let data = await response.json()
|
304
|
-
if (!data.datasets || data.datasets.length == 0) {
|
305
|
-
return false;
|
306
|
-
} else {
|
307
|
-
return data.datasets.map(d => d.id);
|
308
|
-
}
|
309
|
-
},
|
310
|
-
|
311
|
-
/**
|
312
|
-
* Get a list of featured datasets to display.
|
313
|
-
*/
|
314
|
-
getFeaturedDatasets: async function () {
|
315
|
-
let datasetIds = [];
|
316
|
-
|
317
|
-
// Check the two api endpoints for featured datasets, old one first
|
318
|
-
let oldInfo = await this.oldFeaturedDatasetApiHasInfo();
|
319
|
-
if (oldInfo) datasetIds = oldInfo;
|
320
|
-
else {
|
321
|
-
let newInfo = await this.newFeaturedDatasetApiHasInfo();
|
322
|
-
if (newInfo) datasetIds = newInfo;
|
323
|
-
}
|
324
|
-
// Update the store with the new list of featured datasets
|
325
|
-
this.settingsStore.updateFeatured(datasetIds);
|
326
|
-
datasetIds.forEach(element => {
|
327
|
-
this.getDatasetAnatomyInfo(element)
|
328
|
-
});
|
329
|
-
},
|
330
|
-
zoomToFeatures: function () {
|
331
|
-
return;
|
332
|
-
},
|
333
|
-
handleSyncMouseEvent: async function (data) {
|
334
|
-
let info = await this.getNameAndIdFromSyncData(data);
|
335
|
-
if (data.eventType === "highlighted") {
|
336
|
-
this.highlightFeatures(info);
|
337
|
-
} else if (data.eventType === "selected") {
|
338
|
-
this.displayTooltip(info);
|
339
|
-
//this.zoomToFeatures(info, true);
|
340
|
-
}
|
341
|
-
},
|
342
|
-
/**
|
343
|
-
* Handle sync pan zoom event
|
344
|
-
*/
|
345
|
-
handleSyncPanZoomEvent: function () {
|
346
|
-
return;
|
347
|
-
},
|
348
|
-
highlightFeatures: function () {
|
349
|
-
return;
|
350
|
-
},
|
351
|
-
receiveSynchronisedEvent: async function (data) {
|
352
|
-
if (data.paneIndex !== this.entry.id) {
|
353
|
-
if (data.eventType == "panZoom") {
|
354
|
-
//this.handleSyncPanZoomEvent(data);
|
355
|
-
} else {
|
356
|
-
this.handleSyncMouseEvent(data);
|
357
|
-
}
|
358
|
-
} else {
|
359
|
-
if (data.eventType == "selected") {
|
360
|
-
let info = await this.getNameAndIdFromSyncData(data);
|
361
|
-
this.zoomToFeatures(info, false);
|
362
|
-
}
|
363
|
-
}
|
364
|
-
},
|
365
|
-
requestSynchronisedEvent: function () {
|
366
|
-
return;
|
367
|
-
},
|
368
|
-
getAvailableTerms: function () {
|
369
|
-
//Use the default list of uberons before we get the list from
|
370
|
-
//the api
|
371
|
-
let terms = getAvailableTermsForSpecies();
|
372
|
-
for (let i = 0; i < terms.length; i++) {
|
373
|
-
this.idNamePair[terms[i].id] = terms[i].name;
|
374
|
-
}
|
375
|
-
if (this.apiLocation) {
|
376
|
-
if (this._controller) this._controller.abort();
|
377
|
-
this._controller = new AbortController();
|
378
|
-
let signal = this._controller.signal;
|
379
|
-
fetch(`${this.apiLocation}get-organ-curies`, {
|
380
|
-
signal,
|
381
|
-
})
|
382
|
-
.then(response => response.json())
|
383
|
-
.then(data => {
|
384
|
-
this._controller = undefined;
|
385
|
-
data.uberon.array.forEach(pair => {
|
386
|
-
this.idNamePair[pair.id.toUpperCase()] =
|
387
|
-
pair.name.charAt(0).toUpperCase() + pair.name.slice(1);
|
388
|
-
});
|
389
|
-
return;
|
390
|
-
});
|
391
|
-
}
|
392
|
-
},
|
393
|
-
flatmapMarkerZoomUpdate() {
|
394
|
-
return;
|
395
|
-
},
|
396
|
-
onResize: function () {
|
397
|
-
return;
|
398
|
-
},
|
399
|
-
startHelp: function () {
|
400
|
-
if (this.isInHelp === false) {
|
401
|
-
this.helpMode = true;
|
402
|
-
window.addEventListener("mousedown", this.endHelp);
|
403
|
-
this.isInHelp = true;
|
404
|
-
}
|
405
|
-
},
|
406
|
-
endHelp: function () {
|
407
|
-
window.removeEventListener("mousedown", this.endHelp);
|
408
|
-
this.helpMode = false;
|
409
|
-
setTimeout(() => {
|
410
|
-
this.isInHelp = false;
|
411
|
-
}, 200);
|
412
|
-
},
|
413
|
-
},
|
414
|
-
data: function () {
|
415
|
-
return {
|
416
|
-
apiLocation: undefined,
|
417
|
-
activeSpecies: "Rat",
|
418
|
-
scaffoldCamera: undefined,
|
419
|
-
mainStyle: {
|
420
|
-
height: this.entry.datasetTitle ? "calc(100% - 30px)" : "100%",
|
421
|
-
width: "100%",
|
422
|
-
bottom: "0px",
|
423
|
-
},
|
424
|
-
helpMode: false,
|
425
|
-
idNamePair: {},
|
426
|
-
scaffoldLoaded: false,
|
427
|
-
isInHelp: false,
|
428
|
-
};
|
429
|
-
},
|
430
|
-
created: function () {
|
431
|
-
this.flatmapAPI = undefined;
|
432
|
-
this.apiLocation = undefined;
|
433
|
-
if (this.settingsStore.flatmapAPI)
|
434
|
-
this.flatmapAPI = this.settingsStore.flatmapAPI;
|
435
|
-
if (this.settingsStore.sparcApi)
|
436
|
-
this.apiLocation = this.settingsStore.sparcApi;
|
437
|
-
},
|
438
|
-
};
|
1
|
+
import {
|
2
|
+
getAvailableTermsForSpecies,
|
3
|
+
getInteractiveAction,
|
4
|
+
getNerveNames,
|
5
|
+
getParentsRegion,
|
6
|
+
} from "../components/SimulatedData.js";
|
7
|
+
import EventBus from "../components/EventBus";
|
8
|
+
import markerZoomLevels from "../components/markerZoomLevelsHardCoded.js";
|
9
|
+
import { mapStores } from 'pinia';
|
10
|
+
import { useSettingsStore } from '../stores/settings';
|
11
|
+
import { useSplitFlowStore } from '../stores/splitFlow';
|
12
|
+
|
13
|
+
function capitalise(text) {
|
14
|
+
return text[0].toUpperCase() + text.substring(1)
|
15
|
+
}
|
16
|
+
|
17
|
+
/* eslint-disable no-alert, no-console */
|
18
|
+
export default {
|
19
|
+
props: {
|
20
|
+
/**
|
21
|
+
* Object containing information for
|
22
|
+
* the required viewing.
|
23
|
+
*/
|
24
|
+
entry: Object,
|
25
|
+
visible: {
|
26
|
+
type: Boolean,
|
27
|
+
default: true,
|
28
|
+
},
|
29
|
+
mouseHovered: {
|
30
|
+
type: Boolean,
|
31
|
+
default: false,
|
32
|
+
},
|
33
|
+
},
|
34
|
+
computed: {
|
35
|
+
...mapStores(useSettingsStore, useSplitFlowStore),
|
36
|
+
syncMode() {
|
37
|
+
return this.splitFlowStore.syncMode;
|
38
|
+
},
|
39
|
+
},
|
40
|
+
mounted: function () {
|
41
|
+
EventBus.on("startHelp", () => {
|
42
|
+
this.startHelp();
|
43
|
+
});
|
44
|
+
},
|
45
|
+
methods: {
|
46
|
+
toggleSyncMode: function () {
|
47
|
+
return;
|
48
|
+
},
|
49
|
+
getState: function () {
|
50
|
+
return undefined;
|
51
|
+
},
|
52
|
+
openMap: function (type) {
|
53
|
+
if (type === "SYNC") {
|
54
|
+
this.toggleSyncMode();
|
55
|
+
} else {
|
56
|
+
EventBus.emit("OpenNewMap", type);
|
57
|
+
}
|
58
|
+
},
|
59
|
+
updateWithViewUrl: function() {
|
60
|
+
return;
|
61
|
+
},
|
62
|
+
/**
|
63
|
+
* Perform a local search on this contentvuer
|
64
|
+
*/
|
65
|
+
search: function () {
|
66
|
+
return false;
|
67
|
+
},
|
68
|
+
/**
|
69
|
+
* Get a list of search suggestions on this contentvuer
|
70
|
+
*/
|
71
|
+
searchSuggestions: function () {
|
72
|
+
return;
|
73
|
+
},
|
74
|
+
/**
|
75
|
+
* Callback when the vuers emit a selected event.
|
76
|
+
*/
|
77
|
+
resourceSelected: function (type, resource, augmented) {
|
78
|
+
// Skip processing if resources already has actions
|
79
|
+
if (this.resourceHasAction(resource)) {
|
80
|
+
EventBus.emit("PopoverActionClick", resource);
|
81
|
+
return;
|
82
|
+
}
|
83
|
+
|
84
|
+
let returnedAction = undefined;
|
85
|
+
let action = "none";
|
86
|
+
let fireResourceSelected = false;
|
87
|
+
const result = {
|
88
|
+
paneIndex: this.entry.id,
|
89
|
+
type: type,
|
90
|
+
resource: resource,
|
91
|
+
internalName: undefined,
|
92
|
+
eventType: undefined,
|
93
|
+
};
|
94
|
+
|
95
|
+
if (type == "MultiFlatmap" || type == "Flatmap") {
|
96
|
+
result.internalName = this.idNamePair[resource.feature.models];
|
97
|
+
if (resource.eventType == "click") {
|
98
|
+
result.eventType = "selected";
|
99
|
+
if (resource.feature.type == "marker") {
|
100
|
+
let label = this.idNamePair[resource.feature.models];
|
101
|
+
let hardcodedAnnotation = markerZoomLevels.filter(
|
102
|
+
mz => mz.id === resource.feature.models
|
103
|
+
);
|
104
|
+
|
105
|
+
if (
|
106
|
+
this.settingsStore.isFeaturedMarkerIdentifier(
|
107
|
+
resource.feature.id
|
108
|
+
)
|
109
|
+
) {
|
110
|
+
// It is a featured dataset search for DOI.
|
111
|
+
returnedAction = {
|
112
|
+
type: "Search",
|
113
|
+
term: this.settingsStore.featuredMarkerDoi(
|
114
|
+
resource.feature.id
|
115
|
+
),
|
116
|
+
};
|
117
|
+
} else if (hardcodedAnnotation.filter(h => h.keyword).length > 0) {
|
118
|
+
// if it matches our stored keywords, it is a keyword search
|
119
|
+
// Keyword searches do not contain labels, so switch to keyword search if no label exists
|
120
|
+
returnedAction = {
|
121
|
+
type: "Search",
|
122
|
+
term:
|
123
|
+
"http://purl.obolibrary.org/obo/" +
|
124
|
+
resource.feature.models.replace(":", "_"),
|
125
|
+
};
|
126
|
+
} else {
|
127
|
+
// Facet search on anatomy if it is not a keyword search
|
128
|
+
returnedAction = {
|
129
|
+
type: "Facet",
|
130
|
+
facet: label,
|
131
|
+
facetPropPath: "anatomy.organ.category.name",
|
132
|
+
term: "Anatomical structure",
|
133
|
+
};
|
134
|
+
}
|
135
|
+
|
136
|
+
fireResourceSelected = true;
|
137
|
+
if (type == "MultiFlatmap") {
|
138
|
+
const flatmap =
|
139
|
+
this.$refs.multiflatmap.getCurrentFlatmap().mapImp;
|
140
|
+
flatmap.clearSearchResults();
|
141
|
+
}
|
142
|
+
} else if (resource.feature.type == "feature") {
|
143
|
+
// Do no open scaffold in sync map
|
144
|
+
if (this.syncMode) {
|
145
|
+
fireResourceSelected = true;
|
146
|
+
} else {
|
147
|
+
action = "scaffold";
|
148
|
+
}
|
149
|
+
}
|
150
|
+
} else if (resource.eventType == "mouseenter") {
|
151
|
+
result.eventType = "highlighted";
|
152
|
+
fireResourceSelected = true;
|
153
|
+
}
|
154
|
+
} else if (type == "Scaffold") {
|
155
|
+
if (resource && resource[0]) {
|
156
|
+
result.internalName = resource[0].data.id;
|
157
|
+
// Facet search if marker is clicked
|
158
|
+
if (resource[0].data.lastActionOnMarker === true) {
|
159
|
+
returnedAction = {
|
160
|
+
type: "Facet",
|
161
|
+
facet: capitalise(resource[0].data.id),
|
162
|
+
facetPropPath: "anatomy.organ.category.name",
|
163
|
+
term: "Anatomical structure",
|
164
|
+
};
|
165
|
+
}
|
166
|
+
}
|
167
|
+
result.eventType = "selected";
|
168
|
+
fireResourceSelected = true;
|
169
|
+
action = "search";
|
170
|
+
}
|
171
|
+
if ((returnedAction === undefined) && augmented) {
|
172
|
+
returnedAction = getInteractiveAction(result, action);
|
173
|
+
}
|
174
|
+
if (returnedAction) EventBus.emit("PopoverActionClick", returnedAction);
|
175
|
+
if (fireResourceSelected) this.$emit("resource-selected", result);
|
176
|
+
},
|
177
|
+
resourceHasAction: function (resource) {
|
178
|
+
return (
|
179
|
+
resource.type === "URL" ||
|
180
|
+
resource.type === "Search" ||
|
181
|
+
resource.type === "Neuron Search" ||
|
182
|
+
resource.type == "Facet" ||
|
183
|
+
resource.type == "Facets"
|
184
|
+
);
|
185
|
+
},
|
186
|
+
/**
|
187
|
+
* Check if this viewer is currently visible
|
188
|
+
*/
|
189
|
+
isVisible: function() {
|
190
|
+
const paneName = this.splitFlowStore.getPaneNameById(this.entry.id);
|
191
|
+
return paneName !== undefined;
|
192
|
+
},
|
193
|
+
displayTooltip: function() {
|
194
|
+
return;
|
195
|
+
},
|
196
|
+
/**
|
197
|
+
* Get the term to zoom/highlight in a synchronisation event,
|
198
|
+
* if it cannot be found in the map, it will perform several
|
199
|
+
* calls to try to ge a valid name/id.
|
200
|
+
*/
|
201
|
+
getNameAndIdFromSyncData: async function (data) {
|
202
|
+
let name = data.internalName;
|
203
|
+
if (name === undefined && data.resource) {
|
204
|
+
name = data.resource.label;
|
205
|
+
}
|
206
|
+
let id = undefined;
|
207
|
+
if (data.resource && data.resource.resource) {
|
208
|
+
id = data.resource.resource[0];
|
209
|
+
}
|
210
|
+
if (this.entry.type === "Scaffold") {
|
211
|
+
const objects = this.$refs.scaffold.findObjectsWithGroupName(name);
|
212
|
+
// If a region is not found use a hardcoded list to determine
|
213
|
+
// its parents region first
|
214
|
+
if (objects.length === 0) {
|
215
|
+
//Use nerve mapping
|
216
|
+
if (data.resource && data.resource.feature) {
|
217
|
+
const matched = getNerveNames(data.resource.feature.models);
|
218
|
+
if (matched.length > 0) return matched;
|
219
|
+
}
|
220
|
+
let matched = getParentsRegion(name);
|
221
|
+
if (matched) {
|
222
|
+
return matched;
|
223
|
+
}
|
224
|
+
// Hardcoded list failed - use an endpoint to find its parents
|
225
|
+
if (id && data.eventType === "selected") {
|
226
|
+
return fetch(`${this.apiLocation}get-related-terms/${id}`)
|
227
|
+
.then(response => response.json())
|
228
|
+
.then(data => {
|
229
|
+
if (data.uberon.array.length > 0) {
|
230
|
+
name =
|
231
|
+
data.uberon.array[0].name.charAt(0).toUpperCase() +
|
232
|
+
data.uberon.array[0].name.slice(1);
|
233
|
+
id = data.uberon.array[0].id.toUpperCase();
|
234
|
+
return { id, name };
|
235
|
+
}
|
236
|
+
});
|
237
|
+
}
|
238
|
+
}
|
239
|
+
} else if (this.entry.type === "MultiFlatmap") {
|
240
|
+
if (name === "Bladder") {
|
241
|
+
name = "Urinary Bladder";
|
242
|
+
} else {
|
243
|
+
const matched = getNerveNames(name);
|
244
|
+
if (matched.length > 0) name = matched[0];
|
245
|
+
}
|
246
|
+
}
|
247
|
+
return { id, name };
|
248
|
+
},
|
249
|
+
getDatasetAnatomyInfo: function (identifier) {
|
250
|
+
fetch(`${this.apiLocation}dataset_info/anatomy?identifier=${identifier}`)
|
251
|
+
.then(response => response.json())
|
252
|
+
.then(data => {
|
253
|
+
const resultPayload = data.result[0];
|
254
|
+
let markerCurie;
|
255
|
+
try {
|
256
|
+
markerCurie = resultPayload.anatomy.organ[0].curie;
|
257
|
+
} catch (error) {
|
258
|
+
markerCurie = undefined;
|
259
|
+
}
|
260
|
+
let markerDoi;
|
261
|
+
try {
|
262
|
+
markerDoi = resultPayload.item.curie;
|
263
|
+
} catch (error) {
|
264
|
+
markerDoi = undefined;
|
265
|
+
}
|
266
|
+
let markerSpecies;
|
267
|
+
try {
|
268
|
+
let index = 0;
|
269
|
+
let found = false;
|
270
|
+
while (!found && index < resultPayload.organisms.subject.length) {
|
271
|
+
const entry = resultPayload.organisms.subject[index];
|
272
|
+
if (entry.species) {
|
273
|
+
markerSpecies = entry.species.name;
|
274
|
+
found = true;
|
275
|
+
}
|
276
|
+
index += 1;
|
277
|
+
}
|
278
|
+
} catch (error) {
|
279
|
+
markerSpecies = undefined;
|
280
|
+
}
|
281
|
+
this.updateFeatureMarkers([markerCurie], undefined)
|
282
|
+
this.settingsStore.updateFeaturedMarker({
|
283
|
+
identifier,
|
284
|
+
marker: markerCurie,
|
285
|
+
doi: markerDoi,
|
286
|
+
species: markerSpecies,
|
287
|
+
});
|
288
|
+
});
|
289
|
+
},
|
290
|
+
// Check if the old featured dataset api has any info
|
291
|
+
oldFeaturedDatasetApiHasInfo: async function () {
|
292
|
+
let response = await fetch(`${this.apiLocation}get_featured_datasets_identifiers`)
|
293
|
+
let data = await response.json()
|
294
|
+
if (!data.identifiers || data.identifiers.length == 0) {
|
295
|
+
return false;
|
296
|
+
} else {
|
297
|
+
return data.identifiers;
|
298
|
+
}
|
299
|
+
},
|
300
|
+
// Check if the new featured dataset api has any info
|
301
|
+
newFeaturedDatasetApiHasInfo: async function () {
|
302
|
+
let response = await fetch(`${this.apiLocation}get_featured_dataset`)
|
303
|
+
let data = await response.json()
|
304
|
+
if (!data.datasets || data.datasets.length == 0) {
|
305
|
+
return false;
|
306
|
+
} else {
|
307
|
+
return data.datasets.map(d => d.id);
|
308
|
+
}
|
309
|
+
},
|
310
|
+
|
311
|
+
/**
|
312
|
+
* Get a list of featured datasets to display.
|
313
|
+
*/
|
314
|
+
getFeaturedDatasets: async function () {
|
315
|
+
let datasetIds = [];
|
316
|
+
|
317
|
+
// Check the two api endpoints for featured datasets, old one first
|
318
|
+
let oldInfo = await this.oldFeaturedDatasetApiHasInfo();
|
319
|
+
if (oldInfo) datasetIds = oldInfo;
|
320
|
+
else {
|
321
|
+
let newInfo = await this.newFeaturedDatasetApiHasInfo();
|
322
|
+
if (newInfo) datasetIds = newInfo;
|
323
|
+
}
|
324
|
+
// Update the store with the new list of featured datasets
|
325
|
+
this.settingsStore.updateFeatured(datasetIds);
|
326
|
+
datasetIds.forEach(element => {
|
327
|
+
this.getDatasetAnatomyInfo(element)
|
328
|
+
});
|
329
|
+
},
|
330
|
+
zoomToFeatures: function () {
|
331
|
+
return;
|
332
|
+
},
|
333
|
+
handleSyncMouseEvent: async function (data) {
|
334
|
+
let info = await this.getNameAndIdFromSyncData(data);
|
335
|
+
if (data.eventType === "highlighted") {
|
336
|
+
this.highlightFeatures(info);
|
337
|
+
} else if (data.eventType === "selected") {
|
338
|
+
this.displayTooltip(info);
|
339
|
+
//this.zoomToFeatures(info, true);
|
340
|
+
}
|
341
|
+
},
|
342
|
+
/**
|
343
|
+
* Handle sync pan zoom event
|
344
|
+
*/
|
345
|
+
handleSyncPanZoomEvent: function () {
|
346
|
+
return;
|
347
|
+
},
|
348
|
+
highlightFeatures: function () {
|
349
|
+
return;
|
350
|
+
},
|
351
|
+
receiveSynchronisedEvent: async function (data) {
|
352
|
+
if (data.paneIndex !== this.entry.id) {
|
353
|
+
if (data.eventType == "panZoom") {
|
354
|
+
//this.handleSyncPanZoomEvent(data);
|
355
|
+
} else {
|
356
|
+
this.handleSyncMouseEvent(data);
|
357
|
+
}
|
358
|
+
} else {
|
359
|
+
if (data.eventType == "selected") {
|
360
|
+
let info = await this.getNameAndIdFromSyncData(data);
|
361
|
+
this.zoomToFeatures(info, false);
|
362
|
+
}
|
363
|
+
}
|
364
|
+
},
|
365
|
+
requestSynchronisedEvent: function () {
|
366
|
+
return;
|
367
|
+
},
|
368
|
+
getAvailableTerms: function () {
|
369
|
+
//Use the default list of uberons before we get the list from
|
370
|
+
//the api
|
371
|
+
let terms = getAvailableTermsForSpecies();
|
372
|
+
for (let i = 0; i < terms.length; i++) {
|
373
|
+
this.idNamePair[terms[i].id] = terms[i].name;
|
374
|
+
}
|
375
|
+
if (this.apiLocation) {
|
376
|
+
if (this._controller) this._controller.abort();
|
377
|
+
this._controller = new AbortController();
|
378
|
+
let signal = this._controller.signal;
|
379
|
+
fetch(`${this.apiLocation}get-organ-curies`, {
|
380
|
+
signal,
|
381
|
+
})
|
382
|
+
.then(response => response.json())
|
383
|
+
.then(data => {
|
384
|
+
this._controller = undefined;
|
385
|
+
data.uberon.array.forEach(pair => {
|
386
|
+
this.idNamePair[pair.id.toUpperCase()] =
|
387
|
+
pair.name.charAt(0).toUpperCase() + pair.name.slice(1);
|
388
|
+
});
|
389
|
+
return;
|
390
|
+
});
|
391
|
+
}
|
392
|
+
},
|
393
|
+
flatmapMarkerZoomUpdate() {
|
394
|
+
return;
|
395
|
+
},
|
396
|
+
onResize: function () {
|
397
|
+
return;
|
398
|
+
},
|
399
|
+
startHelp: function () {
|
400
|
+
if (this.isInHelp === false) {
|
401
|
+
this.helpMode = true;
|
402
|
+
window.addEventListener("mousedown", this.endHelp);
|
403
|
+
this.isInHelp = true;
|
404
|
+
}
|
405
|
+
},
|
406
|
+
endHelp: function () {
|
407
|
+
window.removeEventListener("mousedown", this.endHelp);
|
408
|
+
this.helpMode = false;
|
409
|
+
setTimeout(() => {
|
410
|
+
this.isInHelp = false;
|
411
|
+
}, 200);
|
412
|
+
},
|
413
|
+
},
|
414
|
+
data: function () {
|
415
|
+
return {
|
416
|
+
apiLocation: undefined,
|
417
|
+
activeSpecies: "Rat",
|
418
|
+
scaffoldCamera: undefined,
|
419
|
+
mainStyle: {
|
420
|
+
height: this.entry.datasetTitle ? "calc(100% - 30px)" : "100%",
|
421
|
+
width: "100%",
|
422
|
+
bottom: "0px",
|
423
|
+
},
|
424
|
+
helpMode: false,
|
425
|
+
idNamePair: {},
|
426
|
+
scaffoldLoaded: false,
|
427
|
+
isInHelp: false,
|
428
|
+
};
|
429
|
+
},
|
430
|
+
created: function () {
|
431
|
+
this.flatmapAPI = undefined;
|
432
|
+
this.apiLocation = undefined;
|
433
|
+
if (this.settingsStore.flatmapAPI)
|
434
|
+
this.flatmapAPI = this.settingsStore.flatmapAPI;
|
435
|
+
if (this.settingsStore.sparcApi)
|
436
|
+
this.apiLocation = this.settingsStore.sparcApi;
|
437
|
+
},
|
438
|
+
};
|