@abi-software/flatmapvuer 0.4.0 → 0.4.1-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.
@@ -1,15 +1,15 @@
1
1
  <template>
2
2
  <div class="tooltip-container">
3
- <el-main v-if="content" class="main" v-loading="loading">
4
- <div class="block" v-if="content.title">
5
- <span class="title">{{capitalise(content.title)}}</span>
3
+ <el-main v-if="entry" class="main" v-loading="loading">
4
+ <div class="block" v-if="entry.title">
5
+ <span class="title">{{capitalise(entry.title)}}</span>
6
6
  </div>
7
7
  <div class="block" v-else>
8
- <span class="title">{{content.featureId}}</span>
8
+ <span class="title">{{entry.featureId}}</span>
9
9
  </div>
10
10
  <div class="content-container scrollbar">
11
- {{content.paths}}
12
- <div v-if="origins && origins.length > 0" class="block">
11
+ {{entry.paths}}
12
+ <div v-if="entry.origins && entry.origins.length > 0" class="block">
13
13
  <div>
14
14
  <span class="attribute-title">Origin</span>
15
15
  <el-popover
@@ -24,22 +24,22 @@
24
24
  </span>
25
25
  </el-popover>
26
26
  </div>
27
- <div v-for="(origin, i) in origins" class="attribute-content" :key="origin">
27
+ <div v-for="(origin, i) in entry.origins" class="attribute-content" :key="origin">
28
28
  {{ capitalise(origin) }}
29
- <div v-if="i != origins.length - 1" class="seperator"></div>
29
+ <div v-if="i != entry.origins.length - 1" class="seperator"></div>
30
30
  </div>
31
- <el-button v-show="originsWithDatasets.length > 0" class="button" @click="openDendrites">
31
+ <el-button v-show="entry.originsWithDatasets && entry.originsWithDatasets.length > 0" class="button" @click="openDendrites">
32
32
  Explore origin data
33
33
  </el-button>
34
34
  </div>
35
- <div v-if="components && components.length > 0" class="block">
35
+ <div v-if="entry.components && entry.components.length > 0" class="block">
36
36
  <div class="attribute-title">Components</div>
37
- <div v-for="(component, i) in components" class="attribute-content" :key="component">
37
+ <div v-for="(component, i) in entry.components" class="attribute-content" :key="component">
38
38
  {{ capitalise(component) }}
39
- <div v-if="i != components.length - 1" class="seperator"></div>
39
+ <div v-if="i != entry.components.length - 1" class="seperator"></div>
40
40
  </div>
41
41
  </div>
42
- <div v-if="destinations && destinations.length > 0" class="block">
42
+ <div v-if="entry.destinations && entry.destinations.length > 0" class="block">
43
43
  <div>
44
44
  <span class="attribute-title">Destination</span>
45
45
  <el-popover
@@ -54,24 +54,21 @@
54
54
  </span>
55
55
  </el-popover>
56
56
  </div>
57
- <div v-for="(destination, i) in destinations" class="attribute-content" :key="destination">
57
+ <div v-for="(destination, i) in entry.destinations" class="attribute-content" :key="destination">
58
58
  {{ capitalise(destination) }}
59
- <div v-if="i != destinations.length - 1" class="seperator"></div>
59
+ <div v-if="i != entry.destinations.length - 1" class="seperator"></div>
60
60
  </div>
61
- <el-button v-show="destinationsWithDatasets.length > 0" class="button" @click="openAxons">
61
+ <el-button v-show="entry.destinationsWithDatasets && entry.destinationsWithDatasets.length > 0" class="button" @click="openAxons">
62
62
  Explore destination data
63
63
  </el-button>
64
64
  </div>
65
65
 
66
- <el-button v-show="componentsWithDatasets.length > 0" class="button" @click="openAll">
66
+ <el-button v-show="entry.componentsWithDatasets && entry.componentsWithDatasets.length > 0" class="button" @click="openAll">
67
67
  Search for data on components
68
68
  </el-button>
69
69
 
70
- <!-- pubmed-viewer is just used for processing pubmed requests (no display) -->
71
- <pubmed-viewer v-if="content.featureIds" v-show="false" :entry="content" @pubmedSearchUrl="pubmedSearchUrlUpdate"/>
72
- <el-button v-if="pubmedSearchUrl != ''" class="button" icon="el-icon-notebook-2" @click="openUrl(pubmedSearchUrl)">
73
- Open publications in pubmed
74
- </el-button>
70
+ <external-resource-card :resources="resources"></external-resource-card>
71
+
75
72
  </div>
76
73
  </el-main>
77
74
  </div>
@@ -97,25 +94,13 @@ Vue.use(Header);
97
94
  Vue.use(Icon);
98
95
  Vue.use(Main);
99
96
 
100
- // pubmedviewer is currently not in use, but still under review so not ready to delete yet
101
- import PubmedViewer from './PubmedViewer.vue'
102
97
  import EventBus from './EventBus'
98
+ import ExternalResourceCard from './ExternalResourceCard.vue';
103
99
 
104
100
  const titleCase = (str) => {
105
101
  return str.replace(/\w\S*/g, (t) => { return t.charAt(0).toUpperCase() + t.substr(1).toLowerCase() });
106
102
  }
107
103
 
108
- const inArray = function(ar1, ar2){
109
- let as1 = JSON.stringify(ar1)
110
- let as2 = JSON.stringify(ar2)
111
- return as1.indexOf(as2) !== -1
112
- }
113
-
114
- // remove duplicates by stringifying the objects
115
- const removeDuplicates = function(arrayOfAnything){
116
- return [...new Set(arrayOfAnything.map(e => JSON.stringify(e)))].map(e => JSON.parse(e))
117
- }
118
-
119
104
  const capitalise = function(str){
120
105
  if (str)
121
106
  return str.charAt(0).toUpperCase() + str.slice(1)
@@ -123,24 +108,34 @@ const capitalise = function(str){
123
108
  }
124
109
 
125
110
  export default {
126
- components: { PubmedViewer },
111
+ components: { ExternalResourceCard },
127
112
  name: "Tooltip",
128
113
  props: {
129
114
  visible: {
130
115
  type: Boolean,
131
116
  default: false
132
117
  },
133
- content: {
118
+ entry: {
134
119
  type: Object,
135
- default: undefined
120
+ default: () => ({
121
+ destinations: [],
122
+ origins: [],
123
+ components: [],
124
+ destinationsWithDatasets: [],
125
+ originsWithDatasets: [],
126
+ componentsWithDatasets: [],
127
+ resource: undefined
128
+ })
136
129
  },
137
130
  },
138
131
  data: function() {
139
132
  return {
133
+ controller: undefined,
140
134
  activeSpecies: undefined,
141
135
  appendToBody: false,
142
136
  pubmedSearchUrl: '',
143
137
  loading: false,
138
+ showToolip: false,
144
139
  destinations: [],
145
140
  origins: [],
146
141
  components: [],
@@ -154,20 +149,16 @@ export default {
154
149
  uberons: [{id: undefined, name: undefined}]
155
150
  };
156
151
  },
157
- inject: ['sparcAPI', 'flatmapAPI'],
158
- watch: {
159
- 'content.featureIds': {
160
- handler: function(){
161
- this.pathwayQuery(this.content.featureIds)
162
- }
163
- }
164
- },
165
- mounted: function(){
166
- this.getOrganCuries()
167
- },
168
152
  computed: {
153
+ resources: function(){
154
+ let resources = []
155
+ if(this.entry && this.entry.hyperlinks){
156
+ resources = this.entry.hyperlinks
157
+ }
158
+ return resources
159
+ },
169
160
  originDescription: function(){
170
- if(this.content && this.content.title && this.content.title.toLowerCase().includes('motor')){
161
+ if(this.entry && this.entry.title && this.entry.title.toLowerCase().includes('motor')){
171
162
  return this.originDescriptions.motor
172
163
  } else {
173
164
  return this.originDescriptions.sensory
@@ -202,186 +193,6 @@ export default {
202
193
  pubmedSearchUrlUpdate: function (val){
203
194
  this.pubmedSearchUrl = val
204
195
  },
205
- findAllIdsFromConnectivity(connectivity){
206
- let dnodes = connectivity.connectivity.flat() // get nodes from edgelist
207
- let nodes = [...new Set(dnodes)] // remove duplicates
208
- let found = []
209
- nodes.forEach(n=>{
210
- if (Array.isArray(n)){
211
- found.push(n.flat())
212
- } else {
213
- found.push(n)
214
- }
215
- })
216
- return [... new Set(found.flat())]
217
- },
218
- flattenConntectivity(connectivity){
219
- let dnodes = connectivity.flat() // get nodes from edgelist
220
- let nodes = [...new Set(dnodes)] // remove duplicates
221
- let found = []
222
- nodes.forEach(n=>{
223
- if (Array.isArray(n)){
224
- found.push(n.flat())
225
- } else {
226
- found.push(n)
227
- }
228
- })
229
- return found.flat()
230
- },
231
- findComponents: function(connectivity){
232
- let dnodes = connectivity.connectivity.flat() // get nodes from edgelist
233
- let nodes = removeDuplicates(dnodes)
234
-
235
- let found = []
236
- let terminal = false
237
- nodes.forEach(node=>{
238
- terminal = false
239
- // Check if the node is an destination or origin (note that they are labelled dendrite and axon as opposed to origin and destination)
240
- if(inArray(connectivity.axons,node)){
241
- terminal = true
242
- }
243
- if(inArray(connectivity.dendrites, node)){
244
- terminal = true
245
- }
246
- if (!terminal){
247
- found.push(node)
248
- }
249
- })
250
-
251
- return found
252
- },
253
- getOrganCuries: function(){
254
- fetch(`${this.sparcAPI}get-organ-curies/`)
255
- .then(response=>response.json())
256
- .then(data=>{
257
- this.uberons = data.uberon.array
258
- })
259
- },
260
- buildConnectivitySqlStatement: function(keastIds) {
261
- let sql = 'select knowledge from knowledge where entity in ('
262
- if (keastIds.length === 1) {
263
- sql += `'${keastIds[0]}')`
264
- } else if (keastIds.length > 1) {
265
- for (let i in keastIds) {
266
- sql += `'${keastIds[i]}'${i >= keastIds.length - 1 ? ')' : ','} `
267
- }
268
- }
269
- return sql
270
- },
271
- buildLabelSqlStatement: function(uberons) {
272
- let sql = 'select entity, label from labels where entity in ('
273
- if (uberons.length === 1) {
274
- sql += `'${uberons[0]}')`
275
- } else if (uberons.length > 1) {
276
- for (let i in uberons) {
277
- sql += `'${uberons[i]}'${i >= uberons.length - 1 ? ')' : ','} `
278
- }
279
- }
280
- return sql
281
- },
282
- createLabelLookup: function(uberons) {
283
- return new Promise(resolve=> {
284
- let uberonMap = {}
285
- const data = { sql: this.buildLabelSqlStatement(uberons)}
286
- fetch(`${this.flatmapAPI}knowledge/query/`, {
287
- method: 'POST',
288
- headers: {
289
- 'Content-Type': 'application/json',
290
- },
291
- body: JSON.stringify(data),
292
- })
293
- .then(response => response.json())
294
- .then(payload => {
295
- const entity = payload.keys.indexOf("entity");
296
- const label = payload.keys.indexOf("label");
297
- if (entity > -1 && label > -1) {
298
- payload.values.forEach(pair => {
299
- uberonMap[pair[entity]] = pair[label];
300
- });
301
- }
302
- resolve(uberonMap)
303
- })
304
- })
305
- },
306
- createComponentsLabelList: function(components, lookUp){
307
- let labelList = []
308
- components.forEach(n=>{
309
- labelList.push(this.createLabelFromNeuralNode(n[0]), lookUp)
310
- if (n.length === 2){
311
- labelList.push(this.createLabelFromNeuralNode(n[1]), lookUp)
312
- }
313
- })
314
- return labelList
315
- },
316
- createLabelFromNeuralNode: function(node, lookUp){
317
- let label = lookUp[node[0]]
318
- if (node.length === 2 && node[1].length > 0){
319
- node[1].forEach(n=>{
320
- if (lookUp[n] == undefined){
321
- label += `, ${n}`
322
- } else {
323
- label += `, ${lookUp[n]}`
324
- }
325
- })
326
- }
327
- return label
328
- },
329
- processConnectivity(connectivity){
330
- // Filter the origin and destinations from components
331
- let components = this.findComponents(connectivity)
332
-
333
- // Remove duplicates
334
- let axons = removeDuplicates(connectivity.axons)
335
- let dendrites = removeDuplicates(connectivity.dendrites)
336
-
337
- // Create list of ids to get labels for
338
- let conIds = this.findAllIdsFromConnectivity(connectivity)
339
-
340
- // Create readable labels from the nodes. Setting this to 'this.origins' updates the display
341
- this.createLabelLookup(conIds).then(lookUp=>{
342
- this.destinations = axons.map(a=>this.createLabelFromNeuralNode(a,lookUp))
343
- this.origins = dendrites.map(d=>this.createLabelFromNeuralNode(d,lookUp))
344
- this.components = components.map(c=>this.createLabelFromNeuralNode(c, lookUp))
345
- })
346
-
347
- this.flattenAndFindDatasets(components, axons, dendrites)
348
- },
349
- flattenAndFindDatasets(components, axons, dendrites){
350
-
351
- // process the nodes for finding datasets (Note this is not critical to the tooltip, only for the 'search on components' button)
352
- let componentsFlat = this.flattenConntectivity(components)
353
- let axonsFlat = this.flattenConntectivity(axons)
354
- let dendritesFlat = this.flattenConntectivity(dendrites)
355
-
356
- // Filter for the anatomy which is annotated on datasets
357
- this.destinationsWithDatasets = this.uberons.filter(ub => axonsFlat.indexOf(ub.id) !== -1)
358
- this.originsWithDatasets = this.uberons.filter(ub => dendritesFlat.indexOf(ub.id) !== -1)
359
- this.componentsWithDatasets = this.uberons.filter(ub => componentsFlat.indexOf(ub.id) !== -1)
360
- },
361
- pathwayQuery: function(keastIds){
362
- this.destinations = []
363
- this.origins = []
364
- this.components = []
365
- this.loading = true
366
- if (!keastIds || keastIds.length == 0) return
367
- const data = { sql: this.buildConnectivitySqlStatement(keastIds)};
368
- fetch(`${this.flatmapAPI}knowledge/query/`, {
369
- method: 'POST',
370
- headers: {
371
- 'Content-Type': 'application/json',
372
- },
373
- body: JSON.stringify(data),
374
- })
375
- .then(response => response.json())
376
- .then(data => {
377
- let connectivity = JSON.parse(data.values[0][0])
378
- this.processConnectivity(connectivity)
379
- this.loading = false
380
- })
381
- .catch((error) => {
382
- console.error('Error:', error);
383
- })
384
- }
385
196
  }
386
197
  };
387
198
  </script>
@@ -566,7 +377,7 @@ export default {
566
377
  .content-container {
567
378
  overflow-y: scroll;
568
379
  scrollbar-width: thin !important;
569
- height: 200px;
380
+ max-height: 240px;
570
381
  }
571
382
 
572
383
  .scrollbar::-webkit-scrollbar-track {