@abi-software/flatmapvuer 0.2.5-alpha.0 → 0.2.5-upstream-downstream

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-lock.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@abi-software/flatmapvuer",
3
- "version": "0.2.5-alpha.0",
3
+ "version": "0.2.5-beta-0",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
7
7
  "@abi-software/flatmap-viewer": {
8
- "version": "2.2.0-beta.10",
9
- "resolved": "https://registry.npmjs.org/@abi-software/flatmap-viewer/-/flatmap-viewer-2.2.0-beta.10.tgz",
10
- "integrity": "sha512-tq0nOvGUgetK1s8w29bbRGcUvZDwM9Yn7LtGvGcjSViOW1DVSS0owSD0oIO0kN68RpW9w6NCfhIjsaqzYSF8pA==",
8
+ "version": "2.2.0-beta.12",
9
+ "resolved": "https://registry.npmjs.org/@abi-software/flatmap-viewer/-/flatmap-viewer-2.2.0-beta.12.tgz",
10
+ "integrity": "sha512-2bDHZ3DSp3AFsUHYmJ6MPYyj6BHQv0GHU6Q+NSuK8eFUQZwYKJvlw4vkx9x+rPEZwuZUmxv7RrQQdw5FgOU6qA==",
11
11
  "requires": {
12
12
  "@babel/runtime": "^7.10.4",
13
13
  "@turf/area": "^6.0.1",
@@ -1285,7 +1285,7 @@
1285
1285
  "@mapbox/jsonlint-lines-primitives": {
1286
1286
  "version": "2.0.2",
1287
1287
  "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
1288
- "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ=="
1288
+ "integrity": "sha1-zlblOfg1UrWNENZy6k1vya3HsjQ="
1289
1289
  },
1290
1290
  "@mapbox/mapbox-gl-supported": {
1291
1291
  "version": "2.0.1",
@@ -1295,7 +1295,7 @@
1295
1295
  "@mapbox/point-geometry": {
1296
1296
  "version": "0.1.0",
1297
1297
  "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
1298
- "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ=="
1298
+ "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI="
1299
1299
  },
1300
1300
  "@mapbox/tiny-sdf": {
1301
1301
  "version": "2.0.5",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/flatmapvuer",
3
- "version": "0.2.5-alpha.0",
3
+ "version": "0.2.5-upstream-downstream",
4
4
  "main": "./dist/flatmapvuer.common.js",
5
5
  "files": [
6
6
  "dist/*",
@@ -16,7 +16,7 @@
16
16
  "lint": "vue-cli-service lint"
17
17
  },
18
18
  "dependencies": {
19
- "@abi-software/flatmap-viewer": "2.2.0-beta.10",
19
+ "@abi-software/flatmap-viewer": "^2.2.0-beta.12",
20
20
  "@abi-software/svg-sprite": "^0.1.14",
21
21
  "core-js": "^3.3.2",
22
22
  "css-element-queries": "^1.2.2",
package/src/App.vue CHANGED
@@ -54,7 +54,7 @@ export default {
54
54
  },
55
55
  FlatmapSelected: function(resource) {
56
56
  if (resource.eventType != "hover")
57
- console.log(resource);
57
+ console.log('resource', resource);
58
58
  },
59
59
  FlatmapReady: function(component) {
60
60
  let taxon = component.mapImp.describes;
@@ -91,8 +91,10 @@ export default {
91
91
  displayCloseButton: false,
92
92
  initial: "Rat",
93
93
  helpMode: false,
94
+ // flatmapAPI: "https://mapcore-demo.org/current/flatmap/v2/"
95
+ flatmapAPI: "https://mapcore-demo.org/devel/flatmap/v3/"
94
96
  //flatmapAPI: "https://mapcore-demo.org/fccb/flatmap/"
95
- flatmapAPI: "https://mapcore-demo.org/devel/flatmap/v1/"
97
+ // flatmapAPI: "https://mapcore-demo.org/devel/flatmap/v1/"
96
98
  }
97
99
  },
98
100
  mounted: function() {
@@ -0,0 +1,3 @@
1
+ import Vue from 'vue';
2
+ const EventBus = new Vue();
3
+ export default EventBus;
@@ -240,6 +240,7 @@ import {
240
240
  import lang from "element-ui/lib/locale/lang/en";
241
241
  import locale from "element-ui/lib/locale";
242
242
  import flatmapMarker from "../icons/flatmap-marker";
243
+
243
244
  locale.use(lang);
244
245
  Vue.use(Checkbox);
245
246
  Vue.use(CheckboxGroup);
@@ -363,7 +364,7 @@ export default {
363
364
  };
364
365
  // Disable the nueron pop up for now.
365
366
  if (data && data.type !== "marker")
366
- this.checkAndCreatePopups(data);
367
+ this.checkAndCreatePopups(payload);
367
368
  this.$emit("resource-selected", payload);
368
369
  } else {
369
370
  this.$emit("pan-zoom-callback", data);
@@ -412,15 +413,29 @@ export default {
412
413
  let foundAnnotations = false;
413
414
  this.tooltipVisible = false;
414
415
 
416
+ // nerve cuff check
417
+ if (data.feature.nodeId) {
418
+ let paths = this.mapImp.nodePathModels(data.feature.nodeId)
419
+ if (paths.size > 0){
420
+ foundAnnotations = true
421
+ this.tooltipVisible = true
422
+ this.tooltipContent = content
423
+ this.tooltipContent.uberon = feature
424
+ this.tooltipContent.title = data.label
425
+ this.tooltipContent.featureIds = [...paths]
426
+ }
427
+ return true
428
+ }
429
+
415
430
  // neural data check
416
- if (feature) {
417
- if (feature.includes("ilxtr:neuron")) {
418
- foundAnnotations = true;
419
- this.tooltipVisible = true;
420
- this.tooltipContent = content;
421
- this.tooltipContent.uberon = feature;
422
- this.tooltipContent.title = data.label;
423
- this.tooltipContent.featureId = feature;
431
+ if (feature){
432
+ if (feature.includes('ilxtr:neuron')){
433
+ foundAnnotations = true
434
+ this.tooltipVisible = true
435
+ this.tooltipContent = content
436
+ this.tooltipContent.uberon = feature
437
+ this.tooltipContent.title = data.label
438
+ this.tooltipContent.featureIds = [feature]
424
439
  this.tooltipContent.actions.push({
425
440
  title: "Search for dataset",
426
441
  label: "Neuron Datasets",
@@ -691,7 +706,7 @@ export default {
691
706
  loading: false,
692
707
  flatmapMarker: flatmapMarker,
693
708
  drawerOpen: true,
694
- tooltipContent: {},
709
+ tooltipContent: { featureIds: []},
695
710
  colourRadio: true,
696
711
  outlinesRadio: true
697
712
  };
@@ -53,6 +53,7 @@
53
53
 
54
54
  <script>
55
55
  /* eslint-disable no-alert, no-console */
56
+ import EventBus from './EventBus'
56
57
  import Vue from "vue";
57
58
  import FlatmapVuer from "./FlatmapVuer.vue";
58
59
  import { Col, Option, Select, Row, Popover } from "element-ui";
@@ -73,6 +74,9 @@ export default {
73
74
  },
74
75
  mounted: function() {
75
76
  this.initialise();
77
+ EventBus.$on('onActionClick', (action) =>{
78
+ this.FlatmapSelected(action)
79
+ })
76
80
  },
77
81
  methods: {
78
82
  initialise: function() {
@@ -26,7 +26,8 @@ import Vue from "vue";
26
26
  import {
27
27
  Link,
28
28
  Carousel,
29
- CarouselItem
29
+ CarouselItem,
30
+ Button
30
31
  } from "element-ui";
31
32
  import lang from "element-ui/lib/locale/lang/en";
32
33
  import locale from "element-ui/lib/locale";
@@ -34,40 +35,45 @@ locale.use(lang);
34
35
  Vue.use(Link);
35
36
  Vue.use(Carousel);
36
37
  Vue.use(CarouselItem);
38
+ Vue.use(Button);
37
39
 
38
40
 
39
41
  export default {
40
42
  name: "Tooltip",
41
- props: {
42
- featureId: {
43
- type: String,
44
- default: ''
45
- },
46
- /**
43
+ props: {
44
+ /**
47
45
  * Specify the endpoint of the flatmap server.
48
46
  */
49
47
  flatmapAPI: {
50
48
  type: String,
51
- default: "https://mapcore-demo.org/flatmaps/"
52
- }
49
+ default: 'https://mapcore-demo.org/current/flatmap/v2/'
50
+ },
51
+ entry: {
52
+ type: Object,
53
+ default: () => {}
54
+ },
53
55
  },
54
56
  watch: {
55
- 'featureId': function (val){
56
- console.log('feature id watch triggered', val)
57
- this.flatmapQuery(val)
57
+ 'entry.featureId': function (val){
58
+ this.flatmapQuery(val).then(pb => this.pubmeds = pb)
59
+ },
60
+ 'entry.featureIds': {
61
+ handler: function(ids) {
62
+ this.flatmapQuery(ids)
63
+ }
58
64
  }
59
65
  },
60
- computed: {
61
- },
62
66
  data: function() {
63
67
  return {
68
+ data: {},
64
69
  pubmeds: [],
65
70
  pubmedIds: [],
66
71
  loading: {response: true, publications: true}
67
72
  };
68
73
  },
69
74
  mounted: function() {
70
- this.flatmapQuery(this.featureId)
75
+ if (this.entry.featureIds)
76
+ this.flatmapQuery(this.entry.featureIds)
71
77
  },
72
78
  methods: {
73
79
  stripPMIDPrefix: function (pubmedId){
@@ -89,12 +95,26 @@ export default {
89
95
  let split = bibliographyString.split('https')
90
96
  return [split[0], 'https' + split[1]]
91
97
  },
92
- flatmapQuery: function(identifier){
98
+ buildPubmedSqlStatement: function(keastIds) {
99
+ let sql = 'select distinct publication from publications where entity in ('
100
+ if (keastIds.length === 1) {
101
+ sql += `'${keastIds[0]}')`
102
+ } else if (keastIds.length > 1) {
103
+ for (let i in keastIds) {
104
+ sql += `'${keastIds[i]}'${i >= keastIds.length - 1 ? ')' : ','} `
105
+ }
106
+ }
107
+ return sql
108
+ },
109
+ flatmapQuery: function(keastIds){
110
+ if(!keastIds || keastIds.length === 0) return
93
111
  this.pubmeds = []
94
112
  this.loading.response = true
95
- let endpoint = this.flatmapAPI + 'knowledge/query/';
96
- const data = { sql: 'select publication from publications where entity=?', "params": [identifier]};
97
- fetch(endpoint, {
113
+
114
+ // fetch pubmed publications for the given ids
115
+ const data = { sql: this.buildPubmedSqlStatement(keastIds)};
116
+ console.log(data)
117
+ fetch(`${this.flatmapAPI}knowledge/query/`, {
98
118
  method: 'POST',
99
119
  headers: {
100
120
  'Content-Type': 'application/json',
@@ -105,19 +125,20 @@ export default {
105
125
  .then(data => {
106
126
  this.responseData = data
107
127
  this.loading.response = false
128
+
129
+ // create links for each pubmedId
108
130
  data.values.forEach(identifier => {
109
131
  let ids = this.stripPMIDPrefix(identifier[0])
110
132
  this.titleFromPubmed(ids).then( bib=>{
111
133
  let [html, link] = this.splitLink(bib)
112
134
  this.pubmeds.push({identifier: identifier[0] , html: html, url: link})
113
-
114
135
  })
115
136
  });
116
137
  this.$emit('pubmedSearchUrl', this.pubmedSearchUrl(data.values.map(id=>this.stripPMIDPrefix(id[0]))))
117
138
  })
118
139
  .catch((error) => {
119
140
  console.error('Error:', error);
120
- });
141
+ })
121
142
  },
122
143
  pubmedSearchUrl: function(ids) {
123
144
  let url = 'https://pubmed.ncbi.nlm.nih.gov/?'
@@ -1,26 +1,42 @@
1
1
  <template>
2
2
  <div class="tooltip-container">
3
- <el-main v-if="content" class="main">
3
+ <el-main v-if="content" class="main" v-loading="loading">
4
4
  <div class="block" v-if="content.title">
5
- <span class="title">{{titleCase(content.title)}}</span>
5
+ <span class="title">{{capitalise(content.title)}}</span>
6
6
  </div>
7
7
  <div class="block" v-else>
8
8
  <span class="title">{{content.featureId}}</span>
9
9
  </div>
10
-
11
-
12
- <pubmed-viewer v-if="content.featureId" class="block" :flatmapAPI=flatmapAPI :featureId="content.featureId" @pubmedSearchUrl="pubmedSearchUrlUpdate"/>
13
- <div v-if="content.components" class="block">
10
+ <!-- Currently we don't show the pubmed viewer, will remove once we are certain it won't be used -->
11
+ <pubmed-viewer v-if="content.featureIds" v-show="false" class="block" :flatmapAPI="flatmapAPI" :entry="content" @pubmedSearchUrl="pubmedSearchUrlUpdate"/>
12
+ {{content.paths}}
13
+ <div v-if="this.components" class="block">
14
14
  <div class="attribute-title">Components</div>
15
- <span class="attribute-content">{{content.components}}</span>
15
+ <div v-for="component in components" class="attribute-content" :key="component">
16
+ {{ capitalise(component) }}
17
+ </div>
18
+ </div>
19
+ <div v-if="this.dendrites" class="block">
20
+ <div class="attribute-title">Dendrites</div>
21
+ <div v-for="dendrite in dendrites" class="attribute-content" :key="dendrite">
22
+ {{ capitalise(dendrite) }}
23
+ </div>
24
+ <el-button v-show="dendritesWithDatasets.length > 0" class="button" @click="openDendrites">
25
+ Explore dendrite data
26
+ </el-button>
16
27
  </div>
17
- <div v-if="content.start" class="block">
18
- <div class="attribute-title">Origin</div>
19
- <span class="attribute-content">{{content.start}}</span>
28
+ <div v-if="this.axons" class="block">
29
+ <div class="attribute-title">Axons</div>
30
+ <div v-for="axon in axons" class="attribute-content" :key="axon">
31
+ {{ capitalise(axon) }}
32
+ </div>
33
+ <el-button v-show="axonsWithDatasets.length > 0" class="button" @click="openAxons">
34
+ Explore axon data
35
+ </el-button>
20
36
  </div>
21
- <div v-if="content.distribution" class="block">
22
- <div class="attribute-title">Distribution</div>
23
- <span class="attribute-content">{{content.distribution}}</span>
37
+ <div v-if="content.uberon" class="block">
38
+ <div class="attribute-title">Feature Id</div>
39
+ <span class="attribute-content">{{content.uberon}}</span>
24
40
  </div>
25
41
  <el-button v-for="action in content.actions" round :key="action.title"
26
42
  class="button" @click="resourceSelected(action)">
@@ -54,16 +70,26 @@ Vue.use(Header);
54
70
  Vue.use(Icon);
55
71
  Vue.use(Main);
56
72
 
73
+ // pubmedviewer is currently not in use, but still under review so not ready to delete yet
57
74
  import PubmedViewer from './PubmedViewer.vue'
75
+ import EventBus from './EventBus'
58
76
 
59
77
  const titleCase = (str) => {
60
78
  return str.replace(/\w\S*/g, (t) => { return t.charAt(0).toUpperCase() + t.substr(1).toLowerCase() });
61
79
  }
62
80
 
81
+ const capitalise = function(str){
82
+ return str.charAt(0).toUpperCase() + str.slice(1)
83
+ }
84
+
63
85
  export default {
64
86
  components: { PubmedViewer },
65
87
  name: "Tooltip",
66
88
  props: {
89
+ flatmapAPI: {
90
+ type: String,
91
+ default: 'https://mapcore-demo.org/current/flatmap/v2/'
92
+ },
67
93
  visible: {
68
94
  type: Boolean,
69
95
  default: false
@@ -72,21 +98,31 @@ export default {
72
98
  type: Object,
73
99
  default: undefined
74
100
  },
75
- /**
76
- * Specify the endpoint of the flatmap server.
77
- */
78
- flatmapAPI: {
79
- type: String,
80
- default: "https://mapcore-demo.org/flatmaps/"
81
- }
82
101
  },
83
102
  data: function() {
84
103
  return {
85
104
  activeSpecies: undefined,
86
105
  appendToBody: false,
87
- pubmedSearchUrl: ''
106
+ pubmedSearchUrl: '',
107
+ loading: false,
108
+ axons: [],
109
+ dendrites: [],
110
+ components: [],
111
+ axonsWithDatasets: [],
112
+ dendritesWithDatasets: [],
113
+ uberons: [{id: undefined, name: undefined}]
88
114
  };
89
115
  },
116
+ watch: {
117
+ 'content.featureIds': {
118
+ handler: function(){
119
+ this.pathwayQuery(this.content.featureIds)
120
+ }
121
+ }
122
+ },
123
+ mounted: function(){
124
+ this.getOrganCuries()
125
+ },
90
126
  methods: {
91
127
  resourceSelected: function(action) {
92
128
  this.$emit("resource-selected", action);
@@ -94,14 +130,136 @@ export default {
94
130
  titleCase: function(title){
95
131
  return titleCase(title)
96
132
  },
133
+ capitalise: function(text){
134
+ return capitalise(text)
135
+ },
97
136
  onClose: function() {
98
137
  this.$emit("onClose");
99
138
  },
100
139
  openUrl: function(url){
101
140
  window.open(url, '_blank')
102
141
  },
142
+ openAxons: function(){
143
+ EventBus.$emit('onActionClick', {type:'Facets', labels: this.axonsWithDatasets.map(a=>a.name)})
144
+ },
145
+ openDendrites: function(){
146
+ EventBus.$emit('onActionClick', {type:'Facets', labels: this.dendritesWithDatasets.map(a=>a.name)})
147
+ },
103
148
  pubmedSearchUrlUpdate: function (val){
104
149
  this.pubmedSearchUrl = val
150
+ },
151
+ findComponents: function(connectivity){
152
+ let dnodes = connectivity.connectivity.flat() // get nodes from edgelist
153
+ let nodes = [...new Set(dnodes)]; // remove duplicates
154
+
155
+ let found = []
156
+ let terminal = false
157
+ nodes.forEach(node=>{
158
+ let n = node.flat() // Find all terms on the node
159
+ terminal = false
160
+
161
+ // Check if the node is an axon or dendrite
162
+ n.forEach(s=>{
163
+ if(connectivity.axons.includes(s)){
164
+ terminal = true
165
+ }
166
+ if(connectivity.dendrites.includes(s)){
167
+ terminal = true
168
+ }
169
+ })
170
+ if (!terminal){
171
+ found.push(node)
172
+ }
173
+ })
174
+
175
+ // remove duplicates
176
+ let foundUnique = [...new Set(found.map(n=>n[0]))]
177
+ return foundUnique
178
+ },
179
+ getOrganCuries: function(){
180
+ fetch('https://api.sparc.science/get-organ-curies/')
181
+ .then(response=>response.json())
182
+ .then(data=>{
183
+ this.uberons = data.uberon.array
184
+ })
185
+ },
186
+ buildConnectivitySqlStatement: function(keastIds) {
187
+ let sql = 'select knowledge from knowledge where entity in ('
188
+ if (keastIds.length === 1) {
189
+ sql += `'${keastIds[0]}')`
190
+ } else if (keastIds.length > 1) {
191
+ for (let i in keastIds) {
192
+ sql += `'${keastIds[i]}'${i >= keastIds.length - 1 ? ')' : ','} `
193
+ }
194
+ }
195
+ return sql
196
+ },
197
+ buildLabelSqlStatement: function(uberons) {
198
+ let sql = 'select label from labels where entity in ('
199
+ if (uberons.length === 1) {
200
+ sql += `'${uberons[0]}')`
201
+ } else if (uberons.length > 1) {
202
+ for (let i in uberons) {
203
+ sql += `'${uberons[i]}'${i >= uberons.length - 1 ? ')' : ','} `
204
+ }
205
+ }
206
+ return sql
207
+ },
208
+ createLabelLookup: function(uberons) {
209
+ return new Promise(resolve=> {
210
+ let uberonMap = {}
211
+ const data = { sql: this.buildLabelSqlStatement(uberons)}
212
+ fetch(`${this.flatmapAPI}knowledge/query/`, {
213
+ method: 'POST',
214
+ headers: {
215
+ 'Content-Type': 'application/json',
216
+ },
217
+ body: JSON.stringify(data),
218
+ })
219
+ .then(response => response.json())
220
+ .then(data => {
221
+ uberons.forEach((el,i)=>{
222
+ uberonMap[el] = data.values[i][0]
223
+ })
224
+ resolve(uberonMap)
225
+ })
226
+ })
227
+ },
228
+ pathwayQuery: function(keastIds){
229
+ this.axons = []
230
+ this.dendrites = []
231
+ this.components = []
232
+ this.loading = true
233
+ if (!keastIds || keastIds.length == 0) return
234
+ const data = { sql: this.buildConnectivitySqlStatement(keastIds)};
235
+ fetch(`${this.flatmapAPI}knowledge/query/`, {
236
+ method: 'POST',
237
+ headers: {
238
+ 'Content-Type': 'application/json',
239
+ },
240
+ body: JSON.stringify(data),
241
+ })
242
+ .then(response => response.json())
243
+ .then(data => {
244
+ let connectivity = JSON.parse(data.values[0][0])
245
+ let components = this.findComponents(connectivity)
246
+
247
+ // Create list of ids to get labels for
248
+ let conIds = connectivity.axons.concat(connectivity.dendrites.concat(components))
249
+ this.createLabelLookup(conIds).then(lookUp=>{
250
+ this.axons = connectivity.axons.map(a=>lookUp[a])
251
+ this.dendrites = connectivity.dendrites.map(d=>lookUp[d])
252
+ this.components = components.map(c=>lookUp[c])
253
+ })
254
+
255
+ // Filter for the anatomy which is annotated on datasets
256
+ this.axonsWithDatasets = this.uberons.filter(ub => connectivity.axons.indexOf(ub.id) !== -1)
257
+ this.dendritesWithDatasets = this.uberons.filter(ub => connectivity.dendrites.indexOf(ub.id) !== -1)
258
+ this.loading = false
259
+ })
260
+ .catch((error) => {
261
+ console.error('Error:', error);
262
+ })
105
263
  }
106
264
  }
107
265
  };
@@ -171,6 +329,15 @@ export default {
171
329
  min-width: 16rem;
172
330
  }
173
331
 
332
+ .title{
333
+ font-size: 18px;
334
+ font-weight: 500;
335
+ font-weight: bold;
336
+ padding-bottom: 8px;
337
+ color: rgb(131, 0, 191);
338
+
339
+ }
340
+
174
341
  .attribute-title{
175
342
  font-size: 16px;
176
343
  font-weight: 600;
@@ -180,7 +347,7 @@ export default {
180
347
 
181
348
  .attribute-content{
182
349
  font-size: 14px;
183
- font-weight: 400;
350
+ font-weight: 500;
184
351
  }
185
352
 
186
353
  .popover-container {
File without changes