@abi-software/flatmapvuer 0.4.4 → 0.4.5

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.
Files changed (35) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +105 -105
  3. package/babel.config.js +14 -14
  4. package/dist/flatmapvuer.common.js +142 -102
  5. package/dist/flatmapvuer.common.js.map +1 -1
  6. package/dist/flatmapvuer.css +1 -1
  7. package/dist/flatmapvuer.umd.js +142 -102
  8. package/dist/flatmapvuer.umd.js.map +1 -1
  9. package/dist/flatmapvuer.umd.min.js +2 -2
  10. package/dist/flatmapvuer.umd.min.js.map +1 -1
  11. package/package-lock.json +14228 -14228
  12. package/package.json +72 -72
  13. package/public/index.html +17 -17
  14. package/src/App.vue +221 -221
  15. package/src/assets/_variables.scss +43 -43
  16. package/src/assets/styles.scss +7 -7
  17. package/src/components/EventBus.js +2 -2
  18. package/src/components/ExternalResourceCard.vue +98 -98
  19. package/src/components/FlatmapVuer.vue +1647 -1627
  20. package/src/components/MultiFlatmapVuer.vue +509 -509
  21. package/src/components/SelectionsGroup.vue +248 -248
  22. package/src/components/Tooltip.vue +405 -405
  23. package/src/components/index.js +9 -9
  24. package/src/components/legends/DynamicLegends.vue +112 -112
  25. package/src/components/legends/SvgLegends.vue +66 -66
  26. package/src/icons/fonts/mapicon-species.eot +0 -0
  27. package/src/icons/fonts/mapicon-species.svg +14 -14
  28. package/src/icons/fonts/mapicon-species.ttf +0 -0
  29. package/src/icons/fonts/mapicon-species.woff +0 -0
  30. package/src/icons/mapicon-species-style.css +42 -42
  31. package/src/legends/legend.svg +25 -25
  32. package/src/main.js +8 -8
  33. package/src/services/flatmapQueries.js +384 -384
  34. package/vue.config.js +31 -31
  35. package/src/nerve-map.js +0 -99
@@ -1,384 +1,384 @@
1
- /* eslint-disable no-alert, no-console */
2
- // remove duplicates by stringifying the objects
3
- const removeDuplicates = function(arrayOfAnything){
4
- return [...new Set(arrayOfAnything.map(e => JSON.stringify(e)))].map(e => JSON.parse(e))
5
- }
6
-
7
- const inArray = function(ar1, ar2){
8
- let as1 = JSON.stringify(ar1)
9
- let as2 = JSON.stringify(ar2)
10
- return as1.indexOf(as2) !== -1
11
- }
12
-
13
- let FlatmapQueries = function(){
14
-
15
- this.initialise = function(sparcApi, flatmapApi){
16
- this.sparcApi = sparcApi
17
- this.flatmapApi = flatmapApi
18
- this.destinations = []
19
- this.origins = []
20
- this.components = []
21
- this.uberons = []
22
- this.urls = []
23
- this.controller = undefined
24
- this.getOrganCuries().then(uberons=>{
25
- this.uberons = uberons
26
- this.createLabelLookup(uberons).then(lookUp=>{
27
- this.lookUp = lookUp
28
- })
29
- })
30
- }
31
-
32
- this.createTooltipData = function (eventData) {
33
- let hyperlinks = []
34
- if (eventData.feature.hyperlinks && eventData.feature.hyperlinks.length > 0) {
35
- hyperlinks = eventData.feature.hyperlinks
36
- } else {
37
- hyperlinks = this.urls.map(url=>({url: url, id: "pubmed"}))
38
- }
39
- let tooltipData = {
40
- destinations: this.destinations,
41
- origins: this.origins,
42
- components: this.components,
43
- destinationsWithDatasets: this.destinationsWithDatasets,
44
- originsWithDatasets: this.originsWithDatasets,
45
- componentsWithDatasets: this.componentsWithDatasets,
46
- title: eventData.label,
47
- featureId: eventData.resource,
48
- hyperlinks: hyperlinks,
49
- }
50
- return tooltipData
51
- }
52
-
53
- this.getOrganCuries = function(){
54
- return new Promise(resolve=> {
55
- fetch(`${this.sparcAPI}get-organ-curies/`)
56
- .then(response=>response.json())
57
- .then(data=>{
58
- resolve(data.uberon.array)
59
- })
60
- })
61
- }
62
-
63
- this.createComponentsLabelList = function(components, lookUp){
64
- let labelList = []
65
- components.forEach(n=>{
66
- labelList.push(this.createLabelFromNeuralNode(n[0]), lookUp)
67
- if (n.length === 2){
68
- labelList.push(this.createLabelFromNeuralNode(n[1]), lookUp)
69
- }
70
- })
71
- return labelList
72
- }
73
-
74
- this.createLabelLookup = function(uberons) {
75
- return new Promise(resolve=> {
76
- let uberonMap = {}
77
- const data = { sql: this.buildLabelSqlStatement(uberons)}
78
- fetch(`${this.flatmapApi}knowledge/query/`, {
79
- method: 'POST',
80
- headers: {
81
- 'Content-Type': 'application/json',
82
- },
83
- body: JSON.stringify(data),
84
- })
85
- .then(response => response.json())
86
- .then(payload => {
87
- const entity = payload.keys.indexOf("entity");
88
- const label = payload.keys.indexOf("label");
89
- if (entity > -1 && label > -1) {
90
- payload.values.forEach(pair => {
91
- uberonMap[pair[entity]] = pair[label];
92
- });
93
- }
94
- resolve(uberonMap)
95
- })
96
- })
97
- }
98
-
99
- this.buildConnectivitySqlStatement = function (keastIds) {
100
- let sql = 'select knowledge from knowledge where entity in ('
101
- if (keastIds.length === 1) {
102
- sql += `'${keastIds[0]}')`
103
- } else if (keastIds.length > 1) {
104
- for (let i in keastIds) {
105
- sql += `'${keastIds[i]}'${i >= keastIds.length - 1 ? ')' : ','} `
106
- }
107
- }
108
- return sql
109
- }
110
-
111
- this.buildLabelSqlStatement = function (uberons) {
112
- let sql = 'select entity, label from labels where entity in ('
113
- if (uberons.length === 1) {
114
- sql += `'${uberons[0]}')`
115
- } else if (uberons.length > 1) {
116
- for (let i in uberons) {
117
- sql += `'${uberons[i]}'${i >= uberons.length - 1 ? ')' : ','} `
118
- }
119
- }
120
- return sql
121
- }
122
-
123
- this.findAllIdsFromConnectivity = function (connectivity) {
124
- let dnodes = connectivity.connectivity.flat() // get nodes from edgelist
125
- let nodes = [...new Set(dnodes)] // remove duplicates
126
- let found = []
127
- nodes.forEach(n => {
128
- if (Array.isArray(n)) {
129
- found.push(n.flat())
130
- } else {
131
- found.push(n)
132
- }
133
- })
134
- return [... new Set(found.flat())]
135
- }
136
-
137
- this.flattenConntectivity = function (connectivity) {
138
- let dnodes = connectivity.flat() // get nodes from edgelist
139
- let nodes = [...new Set(dnodes)] // remove duplicates
140
- let found = []
141
- nodes.forEach(n => {
142
- if (Array.isArray(n)) {
143
- found.push(n.flat())
144
- } else {
145
- found.push(n)
146
- }
147
- })
148
- return found.flat()
149
- }
150
-
151
- this.findComponents = function (connectivity) {
152
- let dnodes = connectivity.connectivity.flat() // get nodes from edgelist
153
- let nodes = removeDuplicates(dnodes)
154
-
155
- let found = []
156
- let terminal = false
157
- nodes.forEach(node => {
158
- terminal = false
159
- // Check if the node is an destination or origin (note that they are labelled dendrite and axon as opposed to origin and destination)
160
- if (inArray(connectivity.axons, node)) {
161
- terminal = true
162
- }
163
- if (inArray(connectivity.dendrites, node)) {
164
- terminal = true
165
- }
166
- if (!terminal) {
167
- found.push(node)
168
- }
169
- })
170
-
171
- return found
172
- }
173
-
174
- this.retrieveFlatmapKnowledgeForEvent = async function(eventData){
175
- // check if there is an existing query
176
- if (this.controller) this.controller.abort();
177
-
178
- // set up the abort controller
179
- this.controller = new AbortController();
180
- const signal = this.controller.signal;
181
-
182
- const keastIds = eventData.resource
183
- this.destinations = []
184
- this.origins = []
185
- this.components = []
186
- if (!keastIds || keastIds.length == 0) return
187
- const data = { sql: this.buildConnectivitySqlStatement(keastIds)};
188
- let prom1 = new Promise(resolve=>{
189
- fetch(`${this.flatmapApi}knowledge/query/`, {
190
- method: 'POST',
191
- headers: {
192
- 'Content-Type': 'application/json',
193
- },
194
- body: JSON.stringify(data),
195
- signal: signal
196
- })
197
- .then(response => response.json())
198
- .then(data => {
199
- if(this.connectivityExists(data)){
200
- let connectivity = JSON.parse(data.values[0][0])
201
- this.processConnectivity(connectivity).then(()=>{
202
- resolve(true)
203
- })
204
- } else {
205
- resolve(false)
206
- }
207
- })
208
- .catch((error) => {
209
- console.error('Error:', error);
210
- resolve(false)
211
- })
212
- })
213
- let prom2 = this.pubmedQueryOnIds(eventData)
214
- let results = await Promise.all([prom1, prom2])
215
- return results.every(Boolean)
216
- }
217
-
218
- this.connectivityExists = function(data){
219
- if (data.values && data.values.length > 0 && JSON.parse(data.values[0][0]).connectivity && JSON.parse(data.values[0][0]).connectivity.length > 0) {
220
- return true
221
- } else {
222
- return false
223
- }
224
- }
225
-
226
- this.createLabelFromNeuralNode = function(node, lookUp){
227
- let label = lookUp[node[0]]
228
- if (node.length === 2 && node[1].length > 0){
229
- node[1].forEach(n=>{
230
- if (lookUp[n] == undefined){
231
- label += `, ${n}`
232
- } else {
233
- label += `, ${lookUp[n]}`
234
- }
235
- })
236
- }
237
- return label
238
- }
239
-
240
- this.flattenAndFindDatasets = function(components, axons, dendrites){
241
-
242
- // process the nodes for finding datasets (Note this is not critical to the tooltip, only for the 'search on components' button)
243
- let componentsFlat = this.flattenConntectivity(components)
244
- let axonsFlat = this.flattenConntectivity(axons)
245
- let dendritesFlat = this.flattenConntectivity(dendrites)
246
-
247
- // Filter for the anatomy which is annotated on datasets
248
- this.destinationsWithDatasets = this.uberons.filter(ub => axonsFlat.indexOf(ub.id) !== -1)
249
- this.originsWithDatasets = this.uberons.filter(ub => dendritesFlat.indexOf(ub.id) !== -1)
250
- this.componentsWithDatasets = this.uberons.filter(ub => componentsFlat.indexOf(ub.id) !== -1)
251
- }
252
-
253
- this.processConnectivity = function(connectivity){
254
- return new Promise (resolve=>{
255
- // Filter the origin and destinations from components
256
- let components = this.findComponents(connectivity)
257
-
258
- // Remove duplicates
259
- let axons = removeDuplicates(connectivity.axons)
260
- let dendrites = removeDuplicates(connectivity.dendrites)
261
-
262
- // Create list of ids to get labels for
263
- let conIds = this.findAllIdsFromConnectivity(connectivity)
264
-
265
- // Create readable labels from the nodes. Setting this to 'this.origins' updates the display
266
- this.createLabelLookup(conIds).then(lookUp=>{
267
- this.destinations = axons.map(a=>this.createLabelFromNeuralNode(a,lookUp))
268
- this.origins = dendrites.map(d=>this.createLabelFromNeuralNode(d,lookUp))
269
- this.components = components.map(c=>this.createLabelFromNeuralNode(c, lookUp))
270
- this.flattenAndFindDatasets(components, axons, dendrites)
271
- resolve(true)
272
- })
273
- })
274
- }
275
-
276
- this.flattenConntectivity = function(connectivity){
277
- let dnodes = connectivity.flat() // get nodes from edgelist
278
- let nodes = [...new Set(dnodes)] // remove duplicates
279
- let found = []
280
- nodes.forEach(n=>{
281
- if (Array.isArray(n)){
282
- found.push(n.flat())
283
- } else {
284
- found.push(n)
285
- }
286
- })
287
- return found.flat()
288
- }
289
-
290
- this.findComponents = function(connectivity){
291
- let dnodes = connectivity.connectivity.flat() // get nodes from edgelist
292
- let nodes = removeDuplicates(dnodes)
293
-
294
- let found = []
295
- let terminal = false
296
- nodes.forEach(node=>{
297
- terminal = false
298
- // Check if the node is an destination or origin (note that they are labelled dendrite and axon as opposed to origin and destination)
299
- if(inArray(connectivity.axons,node)){
300
- terminal = true
301
- }
302
- if(inArray(connectivity.dendrites, node)){
303
- terminal = true
304
- }
305
- if (!terminal){
306
- found.push(node)
307
- }
308
- })
309
-
310
- return found
311
- }
312
-
313
- this.stripPMIDPrefix = function (pubmedId){
314
- return pubmedId.split(':')[1]
315
- }
316
-
317
- this.buildPubmedSqlStatement = function(keastIds) {
318
- let sql = 'select distinct publication from publications where entity in ('
319
- if (keastIds.length === 1) {
320
- sql += `'${keastIds[0]}')`
321
- } else if (keastIds.length > 1) {
322
- for (let i in keastIds) {
323
- sql += `'${keastIds[i]}'${i >= keastIds.length - 1 ? ')' : ','} `
324
- }
325
- }
326
- return sql
327
- }
328
-
329
- this.buildPubmedSqlStatementForModels = function(model) {
330
- return `select distinct publication from publications where entity = '${model}'`
331
- }
332
-
333
- this.flatmapQuery = function(sql){
334
- const data = { sql: sql}
335
- return fetch(`${this.flatmapApi}knowledge/query/`, {
336
- method: 'POST',
337
- headers: {
338
- 'Content-Type': 'application/json',
339
- },
340
- body: JSON.stringify(data),
341
- })
342
- .then(response => response.json())
343
- .catch((error) => {
344
- console.error('Error:', error)
345
- })
346
- }
347
-
348
- this.pubmedQueryOnIds = function(eventData){
349
- const keastIds = eventData.resource
350
- const source = eventData.feature.source
351
- if(!keastIds || keastIds.length === 0) return
352
- const sql = this.buildPubmedSqlStatement(keastIds)
353
- return this.flatmapQuery(sql).then(data=>{
354
- // Create pubmed url on paths if we have them
355
- if (data.values.length > 0){
356
- this.urls = [this.pubmedSearchUrl(data.values.map(id=>this.stripPMIDPrefix(id[0])))]
357
- return true
358
- } else { // Create pubmed url on models
359
- this.pubmedQueryOnModels(source).then(()=>{return true})
360
- }
361
- return false
362
- })
363
- }
364
-
365
- this.pubmedQueryOnModels = function(source){
366
- return this.flatmapQuery(this.buildPubmedSqlStatementForModels(source)).then(data=>{
367
- if (Array.isArray(data.values) && data.values.length > 0){
368
- this.urls = [this.pubmedSearchUrl(data.values.map(id=>this.stripPMIDPrefix(id[0])))]
369
- } else {
370
- this.urls = [] // Clears the pubmed search button
371
- }
372
- return
373
- })
374
- }
375
-
376
- this.pubmedSearchUrl = function(ids) {
377
- let url = 'https://pubmed.ncbi.nlm.nih.gov/?'
378
- let params = new URLSearchParams()
379
- params.append('term', ids)
380
- return url + params.toString()
381
- }
382
- }
383
-
384
- export {FlatmapQueries}
1
+ /* eslint-disable no-alert, no-console */
2
+ // remove duplicates by stringifying the objects
3
+ const removeDuplicates = function(arrayOfAnything){
4
+ return [...new Set(arrayOfAnything.map(e => JSON.stringify(e)))].map(e => JSON.parse(e))
5
+ }
6
+
7
+ const inArray = function(ar1, ar2){
8
+ let as1 = JSON.stringify(ar1)
9
+ let as2 = JSON.stringify(ar2)
10
+ return as1.indexOf(as2) !== -1
11
+ }
12
+
13
+ let FlatmapQueries = function(){
14
+
15
+ this.initialise = function(sparcApi, flatmapApi){
16
+ this.sparcApi = sparcApi
17
+ this.flatmapApi = flatmapApi
18
+ this.destinations = []
19
+ this.origins = []
20
+ this.components = []
21
+ this.uberons = []
22
+ this.urls = []
23
+ this.controller = undefined
24
+ this.getOrganCuries().then(uberons=>{
25
+ this.uberons = uberons
26
+ this.createLabelLookup(uberons).then(lookUp=>{
27
+ this.lookUp = lookUp
28
+ })
29
+ })
30
+ }
31
+
32
+ this.createTooltipData = function (eventData) {
33
+ let hyperlinks = []
34
+ if (eventData.feature.hyperlinks && eventData.feature.hyperlinks.length > 0) {
35
+ hyperlinks = eventData.feature.hyperlinks
36
+ } else {
37
+ hyperlinks = this.urls.map(url=>({url: url, id: "pubmed"}))
38
+ }
39
+ let tooltipData = {
40
+ destinations: this.destinations,
41
+ origins: this.origins,
42
+ components: this.components,
43
+ destinationsWithDatasets: this.destinationsWithDatasets,
44
+ originsWithDatasets: this.originsWithDatasets,
45
+ componentsWithDatasets: this.componentsWithDatasets,
46
+ title: eventData.label,
47
+ featureId: eventData.resource,
48
+ hyperlinks: hyperlinks,
49
+ }
50
+ return tooltipData
51
+ }
52
+
53
+ this.getOrganCuries = function(){
54
+ return new Promise(resolve=> {
55
+ fetch(`${this.sparcAPI}get-organ-curies/`)
56
+ .then(response=>response.json())
57
+ .then(data=>{
58
+ resolve(data.uberon.array)
59
+ })
60
+ })
61
+ }
62
+
63
+ this.createComponentsLabelList = function(components, lookUp){
64
+ let labelList = []
65
+ components.forEach(n=>{
66
+ labelList.push(this.createLabelFromNeuralNode(n[0]), lookUp)
67
+ if (n.length === 2){
68
+ labelList.push(this.createLabelFromNeuralNode(n[1]), lookUp)
69
+ }
70
+ })
71
+ return labelList
72
+ }
73
+
74
+ this.createLabelLookup = function(uberons) {
75
+ return new Promise(resolve=> {
76
+ let uberonMap = {}
77
+ const data = { sql: this.buildLabelSqlStatement(uberons)}
78
+ fetch(`${this.flatmapApi}knowledge/query/`, {
79
+ method: 'POST',
80
+ headers: {
81
+ 'Content-Type': 'application/json',
82
+ },
83
+ body: JSON.stringify(data),
84
+ })
85
+ .then(response => response.json())
86
+ .then(payload => {
87
+ const entity = payload.keys.indexOf("entity");
88
+ const label = payload.keys.indexOf("label");
89
+ if (entity > -1 && label > -1) {
90
+ payload.values.forEach(pair => {
91
+ uberonMap[pair[entity]] = pair[label];
92
+ });
93
+ }
94
+ resolve(uberonMap)
95
+ })
96
+ })
97
+ }
98
+
99
+ this.buildConnectivitySqlStatement = function (keastIds) {
100
+ let sql = 'select knowledge from knowledge where entity in ('
101
+ if (keastIds.length === 1) {
102
+ sql += `'${keastIds[0]}')`
103
+ } else if (keastIds.length > 1) {
104
+ for (let i in keastIds) {
105
+ sql += `'${keastIds[i]}'${i >= keastIds.length - 1 ? ')' : ','} `
106
+ }
107
+ }
108
+ return sql
109
+ }
110
+
111
+ this.buildLabelSqlStatement = function (uberons) {
112
+ let sql = 'select entity, label from labels where entity in ('
113
+ if (uberons.length === 1) {
114
+ sql += `'${uberons[0]}')`
115
+ } else if (uberons.length > 1) {
116
+ for (let i in uberons) {
117
+ sql += `'${uberons[i]}'${i >= uberons.length - 1 ? ')' : ','} `
118
+ }
119
+ }
120
+ return sql
121
+ }
122
+
123
+ this.findAllIdsFromConnectivity = function (connectivity) {
124
+ let dnodes = connectivity.connectivity.flat() // get nodes from edgelist
125
+ let nodes = [...new Set(dnodes)] // remove duplicates
126
+ let found = []
127
+ nodes.forEach(n => {
128
+ if (Array.isArray(n)) {
129
+ found.push(n.flat())
130
+ } else {
131
+ found.push(n)
132
+ }
133
+ })
134
+ return [... new Set(found.flat())]
135
+ }
136
+
137
+ this.flattenConntectivity = function (connectivity) {
138
+ let dnodes = connectivity.flat() // get nodes from edgelist
139
+ let nodes = [...new Set(dnodes)] // remove duplicates
140
+ let found = []
141
+ nodes.forEach(n => {
142
+ if (Array.isArray(n)) {
143
+ found.push(n.flat())
144
+ } else {
145
+ found.push(n)
146
+ }
147
+ })
148
+ return found.flat()
149
+ }
150
+
151
+ this.findComponents = function (connectivity) {
152
+ let dnodes = connectivity.connectivity.flat() // get nodes from edgelist
153
+ let nodes = removeDuplicates(dnodes)
154
+
155
+ let found = []
156
+ let terminal = false
157
+ nodes.forEach(node => {
158
+ terminal = false
159
+ // Check if the node is an destination or origin (note that they are labelled dendrite and axon as opposed to origin and destination)
160
+ if (inArray(connectivity.axons, node)) {
161
+ terminal = true
162
+ }
163
+ if (inArray(connectivity.dendrites, node)) {
164
+ terminal = true
165
+ }
166
+ if (!terminal) {
167
+ found.push(node)
168
+ }
169
+ })
170
+
171
+ return found
172
+ }
173
+
174
+ this.retrieveFlatmapKnowledgeForEvent = async function(eventData){
175
+ // check if there is an existing query
176
+ if (this.controller) this.controller.abort();
177
+
178
+ // set up the abort controller
179
+ this.controller = new AbortController();
180
+ const signal = this.controller.signal;
181
+
182
+ const keastIds = eventData.resource
183
+ this.destinations = []
184
+ this.origins = []
185
+ this.components = []
186
+ if (!keastIds || keastIds.length == 0) return
187
+ const data = { sql: this.buildConnectivitySqlStatement(keastIds)};
188
+ let prom1 = new Promise(resolve=>{
189
+ fetch(`${this.flatmapApi}knowledge/query/`, {
190
+ method: 'POST',
191
+ headers: {
192
+ 'Content-Type': 'application/json',
193
+ },
194
+ body: JSON.stringify(data),
195
+ signal: signal
196
+ })
197
+ .then(response => response.json())
198
+ .then(data => {
199
+ if(this.connectivityExists(data)){
200
+ let connectivity = JSON.parse(data.values[0][0])
201
+ this.processConnectivity(connectivity).then(()=>{
202
+ resolve(true)
203
+ })
204
+ } else {
205
+ resolve(false)
206
+ }
207
+ })
208
+ .catch((error) => {
209
+ console.error('Error:', error);
210
+ resolve(false)
211
+ })
212
+ })
213
+ let prom2 = this.pubmedQueryOnIds(eventData)
214
+ let results = await Promise.all([prom1, prom2])
215
+ return results.every(Boolean)
216
+ }
217
+
218
+ this.connectivityExists = function(data){
219
+ if (data.values && data.values.length > 0 && JSON.parse(data.values[0][0]).connectivity && JSON.parse(data.values[0][0]).connectivity.length > 0) {
220
+ return true
221
+ } else {
222
+ return false
223
+ }
224
+ }
225
+
226
+ this.createLabelFromNeuralNode = function(node, lookUp){
227
+ let label = lookUp[node[0]]
228
+ if (node.length === 2 && node[1].length > 0){
229
+ node[1].forEach(n=>{
230
+ if (lookUp[n] == undefined){
231
+ label += `, ${n}`
232
+ } else {
233
+ label += `, ${lookUp[n]}`
234
+ }
235
+ })
236
+ }
237
+ return label
238
+ }
239
+
240
+ this.flattenAndFindDatasets = function(components, axons, dendrites){
241
+
242
+ // process the nodes for finding datasets (Note this is not critical to the tooltip, only for the 'search on components' button)
243
+ let componentsFlat = this.flattenConntectivity(components)
244
+ let axonsFlat = this.flattenConntectivity(axons)
245
+ let dendritesFlat = this.flattenConntectivity(dendrites)
246
+
247
+ // Filter for the anatomy which is annotated on datasets
248
+ this.destinationsWithDatasets = this.uberons.filter(ub => axonsFlat.indexOf(ub.id) !== -1)
249
+ this.originsWithDatasets = this.uberons.filter(ub => dendritesFlat.indexOf(ub.id) !== -1)
250
+ this.componentsWithDatasets = this.uberons.filter(ub => componentsFlat.indexOf(ub.id) !== -1)
251
+ }
252
+
253
+ this.processConnectivity = function(connectivity){
254
+ return new Promise (resolve=>{
255
+ // Filter the origin and destinations from components
256
+ let components = this.findComponents(connectivity)
257
+
258
+ // Remove duplicates
259
+ let axons = removeDuplicates(connectivity.axons)
260
+ let dendrites = removeDuplicates(connectivity.dendrites)
261
+
262
+ // Create list of ids to get labels for
263
+ let conIds = this.findAllIdsFromConnectivity(connectivity)
264
+
265
+ // Create readable labels from the nodes. Setting this to 'this.origins' updates the display
266
+ this.createLabelLookup(conIds).then(lookUp=>{
267
+ this.destinations = axons.map(a=>this.createLabelFromNeuralNode(a,lookUp))
268
+ this.origins = dendrites.map(d=>this.createLabelFromNeuralNode(d,lookUp))
269
+ this.components = components.map(c=>this.createLabelFromNeuralNode(c, lookUp))
270
+ this.flattenAndFindDatasets(components, axons, dendrites)
271
+ resolve(true)
272
+ })
273
+ })
274
+ }
275
+
276
+ this.flattenConntectivity = function(connectivity){
277
+ let dnodes = connectivity.flat() // get nodes from edgelist
278
+ let nodes = [...new Set(dnodes)] // remove duplicates
279
+ let found = []
280
+ nodes.forEach(n=>{
281
+ if (Array.isArray(n)){
282
+ found.push(n.flat())
283
+ } else {
284
+ found.push(n)
285
+ }
286
+ })
287
+ return found.flat()
288
+ }
289
+
290
+ this.findComponents = function(connectivity){
291
+ let dnodes = connectivity.connectivity.flat() // get nodes from edgelist
292
+ let nodes = removeDuplicates(dnodes)
293
+
294
+ let found = []
295
+ let terminal = false
296
+ nodes.forEach(node=>{
297
+ terminal = false
298
+ // Check if the node is an destination or origin (note that they are labelled dendrite and axon as opposed to origin and destination)
299
+ if(inArray(connectivity.axons,node)){
300
+ terminal = true
301
+ }
302
+ if(inArray(connectivity.dendrites, node)){
303
+ terminal = true
304
+ }
305
+ if (!terminal){
306
+ found.push(node)
307
+ }
308
+ })
309
+
310
+ return found
311
+ }
312
+
313
+ this.stripPMIDPrefix = function (pubmedId){
314
+ return pubmedId.split(':')[1]
315
+ }
316
+
317
+ this.buildPubmedSqlStatement = function(keastIds) {
318
+ let sql = 'select distinct publication from publications where entity in ('
319
+ if (keastIds.length === 1) {
320
+ sql += `'${keastIds[0]}')`
321
+ } else if (keastIds.length > 1) {
322
+ for (let i in keastIds) {
323
+ sql += `'${keastIds[i]}'${i >= keastIds.length - 1 ? ')' : ','} `
324
+ }
325
+ }
326
+ return sql
327
+ }
328
+
329
+ this.buildPubmedSqlStatementForModels = function(model) {
330
+ return `select distinct publication from publications where entity = '${model}'`
331
+ }
332
+
333
+ this.flatmapQuery = function(sql){
334
+ const data = { sql: sql}
335
+ return fetch(`${this.flatmapApi}knowledge/query/`, {
336
+ method: 'POST',
337
+ headers: {
338
+ 'Content-Type': 'application/json',
339
+ },
340
+ body: JSON.stringify(data),
341
+ })
342
+ .then(response => response.json())
343
+ .catch((error) => {
344
+ console.error('Error:', error)
345
+ })
346
+ }
347
+
348
+ this.pubmedQueryOnIds = function(eventData){
349
+ const keastIds = eventData.resource
350
+ const source = eventData.feature.source
351
+ if(!keastIds || keastIds.length === 0) return
352
+ const sql = this.buildPubmedSqlStatement(keastIds)
353
+ return this.flatmapQuery(sql).then(data=>{
354
+ // Create pubmed url on paths if we have them
355
+ if (data.values.length > 0){
356
+ this.urls = [this.pubmedSearchUrl(data.values.map(id=>this.stripPMIDPrefix(id[0])))]
357
+ return true
358
+ } else { // Create pubmed url on models
359
+ this.pubmedQueryOnModels(source).then(()=>{return true})
360
+ }
361
+ return false
362
+ })
363
+ }
364
+
365
+ this.pubmedQueryOnModels = function(source){
366
+ return this.flatmapQuery(this.buildPubmedSqlStatementForModels(source)).then(data=>{
367
+ if (Array.isArray(data.values) && data.values.length > 0){
368
+ this.urls = [this.pubmedSearchUrl(data.values.map(id=>this.stripPMIDPrefix(id[0])))]
369
+ } else {
370
+ this.urls = [] // Clears the pubmed search button
371
+ }
372
+ return
373
+ })
374
+ }
375
+
376
+ this.pubmedSearchUrl = function(ids) {
377
+ let url = 'https://pubmed.ncbi.nlm.nih.gov/?'
378
+ let params = new URLSearchParams()
379
+ params.append('term', ids)
380
+ return url + params.toString()
381
+ }
382
+ }
383
+
384
+ export {FlatmapQueries}