@abi-software/map-utilities 1.4.0 → 1.4.1-beta.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/dist/map-utilities.js +33818 -16673
- package/dist/map-utilities.umd.cjs +246 -67
- package/dist/style.css +1 -1
- package/package.json +6 -1
- package/src/components/ConnectivityGraph/ConnectivityGraph.vue +46 -16
- package/src/components/ConnectivityList/ConnectivityList.vue +395 -0
- package/src/components/Tooltip/ExternalResourceCard.vue +69 -39
- package/src/components/Tooltip/ProvenancePopup.vue +10 -0
- package/src/components/index.js +2 -0
- package/src/components/utilities.js +40 -0
- package/src/components.d.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abi-software/map-utilities",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.1-beta.1",
|
|
4
4
|
"files": [
|
|
5
5
|
"dist/*",
|
|
6
6
|
"src/*",
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@abi-software/svg-sprite": "^1.0.1",
|
|
33
|
+
"@citation-js/core": "^0.7.14",
|
|
34
|
+
"@citation-js/plugin-bibtex": "^0.7.17",
|
|
35
|
+
"@citation-js/plugin-csl": "^0.7.14",
|
|
36
|
+
"@citation-js/plugin-doi": "^0.7.16",
|
|
37
|
+
"@citation-js/plugin-pubmed": "^0.3.0",
|
|
33
38
|
"@element-plus/icons-vue": "^2.3.1",
|
|
34
39
|
"cytoscape": "^3.30.2",
|
|
35
40
|
"element-plus": "2.8.4",
|
|
@@ -160,6 +160,10 @@ export default {
|
|
|
160
160
|
type: Array,
|
|
161
161
|
default: [],
|
|
162
162
|
},
|
|
163
|
+
connectivityFromMap: {
|
|
164
|
+
type: Object,
|
|
165
|
+
default: () => null,
|
|
166
|
+
},
|
|
163
167
|
},
|
|
164
168
|
data: function () {
|
|
165
169
|
return {
|
|
@@ -184,26 +188,19 @@ export default {
|
|
|
184
188
|
connectivityGraphContainer: null,
|
|
185
189
|
};
|
|
186
190
|
},
|
|
191
|
+
watch: {
|
|
192
|
+
connectivityFromMap: function (oldVal, newVal) {
|
|
193
|
+
if (oldVal != newVal) {
|
|
194
|
+
this.start();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
},
|
|
187
198
|
mounted() {
|
|
188
199
|
this.showSpinner();
|
|
189
200
|
this.updateTooltipContainer();
|
|
190
201
|
this.refreshCache();
|
|
191
202
|
this.loadCacheData();
|
|
192
|
-
this.
|
|
193
|
-
.then((res) => {
|
|
194
|
-
if (res?.success) {
|
|
195
|
-
this.showGraph(this.entry);
|
|
196
|
-
} else if (res?.error) {
|
|
197
|
-
this.loadingError = res.error;
|
|
198
|
-
} else {
|
|
199
|
-
this.loadingError = 'Loading error!';
|
|
200
|
-
}
|
|
201
|
-
this.hideSpinner();
|
|
202
|
-
})
|
|
203
|
-
.catch((error) => {
|
|
204
|
-
this.loadingError = 'Loading error!';
|
|
205
|
-
this.hideSpinner();
|
|
206
|
-
});
|
|
203
|
+
this.start();
|
|
207
204
|
},
|
|
208
205
|
methods: {
|
|
209
206
|
updateTooltipContainer: function () {
|
|
@@ -275,6 +272,23 @@ export default {
|
|
|
275
272
|
|
|
276
273
|
sessionStorage.setItem('connectivity-graph-expiry', expiry);
|
|
277
274
|
},
|
|
275
|
+
start: function () {
|
|
276
|
+
this.run()
|
|
277
|
+
.then((res) => {
|
|
278
|
+
if (res?.success) {
|
|
279
|
+
this.showGraph(this.entry);
|
|
280
|
+
} else if (res?.error) {
|
|
281
|
+
this.loadingError = res.error;
|
|
282
|
+
} else {
|
|
283
|
+
this.loadingError = 'Loading error!';
|
|
284
|
+
}
|
|
285
|
+
this.hideSpinner();
|
|
286
|
+
})
|
|
287
|
+
.catch((error) => {
|
|
288
|
+
this.loadingError = 'Loading error!';
|
|
289
|
+
this.hideSpinner();
|
|
290
|
+
});
|
|
291
|
+
},
|
|
278
292
|
run: async function () {
|
|
279
293
|
if (!this.schemaVersion) {
|
|
280
294
|
this.schemaVersion = await this.getSchemaVersion();
|
|
@@ -305,8 +319,24 @@ export default {
|
|
|
305
319
|
showGraph: async function (neuronPath) {
|
|
306
320
|
const graphCanvas = this.$refs.graphCanvas;
|
|
307
321
|
|
|
322
|
+
// Update label data
|
|
323
|
+
if (this.connectivityFromMap) {
|
|
324
|
+
this.cacheLabels(this.connectivityFromMap);
|
|
325
|
+
await this.getCachedTermLabels();
|
|
326
|
+
}
|
|
327
|
+
|
|
308
328
|
this.connectivityGraph = new ConnectivityGraph(this.labelCache, graphCanvas);
|
|
309
|
-
|
|
329
|
+
const connectivityInfo = this.knowledgeByPath.get(neuronPath);
|
|
330
|
+
|
|
331
|
+
// Update connectivity
|
|
332
|
+
if (this.connectivityFromMap) {
|
|
333
|
+
connectivityInfo.axons = this.connectivityFromMap.axons;
|
|
334
|
+
connectivityInfo.connectivity = this.connectivityFromMap.connectivity;
|
|
335
|
+
connectivityInfo.dendrites = this.connectivityFromMap.dendrites;
|
|
336
|
+
connectivityInfo.somas = this.connectivityFromMap.somas;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
await this.connectivityGraph.addConnectivity(connectivityInfo);
|
|
310
340
|
|
|
311
341
|
this.connectivityGraph.showConnectivity(graphCanvas);
|
|
312
342
|
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="connectivity-list">
|
|
3
|
+
{{ entry.paths }}
|
|
4
|
+
<div v-if="origins && origins.length > 0" class="block">
|
|
5
|
+
<div class="attribute-title-container">
|
|
6
|
+
<span class="attribute-title">Origin</span>
|
|
7
|
+
<el-popover
|
|
8
|
+
width="250"
|
|
9
|
+
trigger="hover"
|
|
10
|
+
:teleported="false"
|
|
11
|
+
popper-class="popover-origin-help"
|
|
12
|
+
>
|
|
13
|
+
<template #reference>
|
|
14
|
+
<el-icon class="info"><el-icon-warning /></el-icon>
|
|
15
|
+
</template>
|
|
16
|
+
<span style="word-break: keep-all">
|
|
17
|
+
<i>Origin</i> {{ originDescription }}
|
|
18
|
+
</span>
|
|
19
|
+
|
|
20
|
+
</el-popover>
|
|
21
|
+
</div>
|
|
22
|
+
<div
|
|
23
|
+
v-for="(origin, i) in origins"
|
|
24
|
+
class="attribute-content"
|
|
25
|
+
:origin-item-label="origin"
|
|
26
|
+
:key="origin"
|
|
27
|
+
@mouseenter="toggleConnectivityTooltip(origin, {show: true})"
|
|
28
|
+
@mouseleave="toggleConnectivityTooltip(origin, {show: false})"
|
|
29
|
+
>
|
|
30
|
+
{{ capitalise(origin) }}
|
|
31
|
+
</div>
|
|
32
|
+
<el-button
|
|
33
|
+
v-show="
|
|
34
|
+
originsWithDatasets && originsWithDatasets.length > 0 &&
|
|
35
|
+
shouldShowExploreButton(originsWithDatasets)
|
|
36
|
+
"
|
|
37
|
+
class="button"
|
|
38
|
+
id="open-dendrites-button"
|
|
39
|
+
@click="openDendrites"
|
|
40
|
+
>
|
|
41
|
+
Explore origin data
|
|
42
|
+
</el-button>
|
|
43
|
+
</div>
|
|
44
|
+
<div
|
|
45
|
+
v-if="components && components.length > 0"
|
|
46
|
+
class="block"
|
|
47
|
+
>
|
|
48
|
+
<div class="attribute-title-container">
|
|
49
|
+
<div class="attribute-title">Components</div>
|
|
50
|
+
</div>
|
|
51
|
+
<div
|
|
52
|
+
v-for="(component, i) in components"
|
|
53
|
+
class="attribute-content"
|
|
54
|
+
:component-item-label="component"
|
|
55
|
+
:key="component"
|
|
56
|
+
@mouseenter="toggleConnectivityTooltip(component, {show: true})"
|
|
57
|
+
@mouseleave="toggleConnectivityTooltip(component, {show: false})"
|
|
58
|
+
>
|
|
59
|
+
{{ capitalise(component) }}
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
<div
|
|
63
|
+
v-if="destinations && destinations.length > 0"
|
|
64
|
+
class="block"
|
|
65
|
+
>
|
|
66
|
+
<div class="attribute-title-container">
|
|
67
|
+
<span class="attribute-title">Destination</span>
|
|
68
|
+
<el-popover
|
|
69
|
+
width="250"
|
|
70
|
+
trigger="hover"
|
|
71
|
+
:teleported="false"
|
|
72
|
+
popper-class="popover-origin-help"
|
|
73
|
+
>
|
|
74
|
+
<template #reference>
|
|
75
|
+
<el-icon class="info"><el-icon-warning /></el-icon>
|
|
76
|
+
</template>
|
|
77
|
+
<span style="word-break: keep-all">
|
|
78
|
+
<i>Destination</i> is where the axons terminate
|
|
79
|
+
</span>
|
|
80
|
+
</el-popover>
|
|
81
|
+
</div>
|
|
82
|
+
<div
|
|
83
|
+
v-for="(destination, i) in destinations"
|
|
84
|
+
class="attribute-content"
|
|
85
|
+
:destination-item-label="destination"
|
|
86
|
+
:key="destination"
|
|
87
|
+
@mouseenter="toggleConnectivityTooltip(destination, {show: true})"
|
|
88
|
+
@mouseleave="toggleConnectivityTooltip(destination, {show: false})"
|
|
89
|
+
>
|
|
90
|
+
{{ capitalise(destination) }}
|
|
91
|
+
</div>
|
|
92
|
+
<el-button
|
|
93
|
+
v-show="
|
|
94
|
+
destinationsWithDatasets &&
|
|
95
|
+
destinationsWithDatasets.length > 0 &&
|
|
96
|
+
shouldShowExploreButton(destinationsWithDatasets)
|
|
97
|
+
"
|
|
98
|
+
class="button"
|
|
99
|
+
@click="openAxons"
|
|
100
|
+
>
|
|
101
|
+
Explore destination data
|
|
102
|
+
</el-button>
|
|
103
|
+
</div>
|
|
104
|
+
<div
|
|
105
|
+
v-show="
|
|
106
|
+
componentsWithDatasets &&
|
|
107
|
+
componentsWithDatasets.length > 0 &&
|
|
108
|
+
shouldShowExploreButton(componentsWithDatasets)
|
|
109
|
+
"
|
|
110
|
+
class="block"
|
|
111
|
+
>
|
|
112
|
+
<el-button
|
|
113
|
+
class="button"
|
|
114
|
+
@click="openAll"
|
|
115
|
+
>
|
|
116
|
+
Search for data on components
|
|
117
|
+
</el-button>
|
|
118
|
+
</div>
|
|
119
|
+
|
|
120
|
+
<div class="connectivity-error-container">
|
|
121
|
+
<div class="connectivity-error" v-if="connectivityError">
|
|
122
|
+
<strong v-if="connectivityError.errorConnectivities">
|
|
123
|
+
{{ connectivityError.errorConnectivities }}
|
|
124
|
+
</strong>
|
|
125
|
+
{{ connectivityError.errorMessage }}
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</template>
|
|
130
|
+
|
|
131
|
+
<script>
|
|
132
|
+
import {
|
|
133
|
+
Warning as ElIconWarning,
|
|
134
|
+
} from '@element-plus/icons-vue'
|
|
135
|
+
import {
|
|
136
|
+
ElButton as Button,
|
|
137
|
+
ElContainer as Container,
|
|
138
|
+
ElIcon as Icon,
|
|
139
|
+
} from 'element-plus'
|
|
140
|
+
import { capitalise } from '../utilities'
|
|
141
|
+
|
|
142
|
+
export default {
|
|
143
|
+
name: 'ConnectivityList',
|
|
144
|
+
components: {
|
|
145
|
+
Button,
|
|
146
|
+
Container,
|
|
147
|
+
Icon,
|
|
148
|
+
ElIconWarning,
|
|
149
|
+
},
|
|
150
|
+
props: {
|
|
151
|
+
entry: {
|
|
152
|
+
type: Object,
|
|
153
|
+
default: () => ({
|
|
154
|
+
destinations: [],
|
|
155
|
+
origins: [],
|
|
156
|
+
components: [],
|
|
157
|
+
destinationsWithDatasets: [],
|
|
158
|
+
originsWithDatasets: [],
|
|
159
|
+
componentsWithDatasets: [],
|
|
160
|
+
resource: undefined,
|
|
161
|
+
featuresAlert: undefined,
|
|
162
|
+
}),
|
|
163
|
+
},
|
|
164
|
+
origins: {
|
|
165
|
+
type: Array,
|
|
166
|
+
default: () => []
|
|
167
|
+
},
|
|
168
|
+
components: {
|
|
169
|
+
type: Array,
|
|
170
|
+
default: () => []
|
|
171
|
+
},
|
|
172
|
+
destinations: {
|
|
173
|
+
type: Array,
|
|
174
|
+
default: () => []
|
|
175
|
+
},
|
|
176
|
+
originsWithDatasets: {
|
|
177
|
+
type: Array,
|
|
178
|
+
default: () => []
|
|
179
|
+
},
|
|
180
|
+
componentsWithDatasets: {
|
|
181
|
+
type: Array,
|
|
182
|
+
default: () => []
|
|
183
|
+
},
|
|
184
|
+
destinationsWithDatasets: {
|
|
185
|
+
type: Array,
|
|
186
|
+
default: () => []
|
|
187
|
+
},
|
|
188
|
+
availableAnatomyFacets: {
|
|
189
|
+
type: Array,
|
|
190
|
+
default: () => [],
|
|
191
|
+
},
|
|
192
|
+
connectivityError: {
|
|
193
|
+
type: Object,
|
|
194
|
+
default: () => null,
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
data: function () {
|
|
198
|
+
return {
|
|
199
|
+
originDescriptions: {
|
|
200
|
+
motor: 'is the location of the initial cell body of the circuit',
|
|
201
|
+
sensory: 'is the location of the initial cell body in the PNS circuit',
|
|
202
|
+
},
|
|
203
|
+
facetList: [],
|
|
204
|
+
sckanVersion: '',
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
watch: {
|
|
208
|
+
availableAnatomyFacets: {
|
|
209
|
+
handler: function (val) {
|
|
210
|
+
this.convertFacetsToList(val)
|
|
211
|
+
},
|
|
212
|
+
immediate: true,
|
|
213
|
+
deep: true,
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
computed: {
|
|
217
|
+
originDescription: function () {
|
|
218
|
+
if (
|
|
219
|
+
this.entry &&
|
|
220
|
+
this.entry.title &&
|
|
221
|
+
this.entry.title.toLowerCase().includes('motor')
|
|
222
|
+
) {
|
|
223
|
+
return this.originDescriptions.motor
|
|
224
|
+
} else {
|
|
225
|
+
return this.originDescriptions.sensory
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
methods: {
|
|
230
|
+
capitalise: function (text) {
|
|
231
|
+
return capitalise(text)
|
|
232
|
+
},
|
|
233
|
+
toggleConnectivityTooltip: function (name, option) {
|
|
234
|
+
this.$emit('toggle-connectivity-tooltip', {
|
|
235
|
+
name,
|
|
236
|
+
option
|
|
237
|
+
});
|
|
238
|
+
},
|
|
239
|
+
// shouldShowExploreButton: Checks if the feature is in the list of available anatomy facets
|
|
240
|
+
shouldShowExploreButton: function (features) {
|
|
241
|
+
for (let i = 0; i < features.length; i++) {
|
|
242
|
+
if (this.facetList.includes(features[i].name.toLowerCase())) {
|
|
243
|
+
return true
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return false
|
|
247
|
+
},
|
|
248
|
+
// convertFacetsToList: Converts the available anatomy facets to a list for easy searching
|
|
249
|
+
convertFacetsToList: function (facets) {
|
|
250
|
+
facets.forEach((facet) => {
|
|
251
|
+
if(facet.children) {
|
|
252
|
+
this.convertFacetsToList(facet.children)
|
|
253
|
+
} else {
|
|
254
|
+
this.facetList.push(facet.label.toLowerCase())
|
|
255
|
+
}
|
|
256
|
+
})
|
|
257
|
+
},
|
|
258
|
+
openAll: function () {
|
|
259
|
+
this.$emit('connectivity-action-click', {
|
|
260
|
+
type: 'Facets',
|
|
261
|
+
labels: this.componentsWithDatasets.map((a) => a.name.toLowerCase()),
|
|
262
|
+
})
|
|
263
|
+
},
|
|
264
|
+
openAxons: function () {
|
|
265
|
+
this.$emit('connectivity-action-click', {
|
|
266
|
+
type: 'Facets',
|
|
267
|
+
labels: this.destinationsWithDatasets.map((a) => a.name.toLowerCase()),
|
|
268
|
+
})
|
|
269
|
+
},
|
|
270
|
+
openDendrites: function () {
|
|
271
|
+
this.$emit('connectivity-action-click', {
|
|
272
|
+
type: 'Facets',
|
|
273
|
+
labels: this.originsWithDatasets.map((a) => a.name.toLowerCase()),
|
|
274
|
+
})
|
|
275
|
+
},
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
</script>
|
|
279
|
+
|
|
280
|
+
<style lang="scss" scoped>
|
|
281
|
+
.connectivity-list {
|
|
282
|
+
display: flex;
|
|
283
|
+
flex-direction: column;
|
|
284
|
+
gap: 1rem;
|
|
285
|
+
position: relative;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.button {
|
|
289
|
+
margin-left: 0px !important;
|
|
290
|
+
margin-top: 0px !important;
|
|
291
|
+
font-size: 14px !important;
|
|
292
|
+
background-color: $app-primary-color;
|
|
293
|
+
color: #fff;
|
|
294
|
+
|
|
295
|
+
&:hover {
|
|
296
|
+
color: #fff !important;
|
|
297
|
+
background-color: #ac76c5 !important;
|
|
298
|
+
border: 1px solid #ac76c5 !important;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
& + .button {
|
|
302
|
+
margin-top: 10px !important;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.icon {
|
|
307
|
+
right: 0px;
|
|
308
|
+
position: absolute;
|
|
309
|
+
top: 10px;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.icon:hover {
|
|
313
|
+
cursor: pointer;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
:deep(.popover-origin-help.el-popover) {
|
|
317
|
+
text-transform: none !important; // need to overide the tooltip text transform
|
|
318
|
+
border: 1px solid $app-primary-color;
|
|
319
|
+
font-weight: 400;
|
|
320
|
+
font-family: Asap, sans-serif, Helvetica;
|
|
321
|
+
|
|
322
|
+
.el-popper__arrow {
|
|
323
|
+
&:before {
|
|
324
|
+
border-color: $app-primary-color;
|
|
325
|
+
background-color: #ffffff;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.info {
|
|
331
|
+
color: #8300bf;
|
|
332
|
+
transform: rotate(180deg);
|
|
333
|
+
margin-left: 8px;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.attribute-title-container {
|
|
337
|
+
margin-bottom: 0.5em;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.attribute-title {
|
|
341
|
+
font-size: 16px;
|
|
342
|
+
font-weight: 600;
|
|
343
|
+
/* font-weight: bold; */
|
|
344
|
+
text-transform: uppercase;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.attribute-content {
|
|
348
|
+
font-size: 14px;
|
|
349
|
+
font-weight: 500;
|
|
350
|
+
transition: color 0.25s ease;
|
|
351
|
+
position: relative;
|
|
352
|
+
cursor: default;
|
|
353
|
+
|
|
354
|
+
&:hover {
|
|
355
|
+
color: $app-primary-color;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
+ .attribute-content {
|
|
359
|
+
&::before {
|
|
360
|
+
content: "";
|
|
361
|
+
width: 90%;
|
|
362
|
+
height: 1px;
|
|
363
|
+
background-color: var(--el-border-color);
|
|
364
|
+
position: absolute;
|
|
365
|
+
top: 0;
|
|
366
|
+
left: 0;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
&:last-of-type {
|
|
371
|
+
margin-bottom: 0.5em;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.connectivity-error-container {
|
|
376
|
+
position: sticky;
|
|
377
|
+
bottom: 0.5rem;
|
|
378
|
+
width: 100%;
|
|
379
|
+
min-height: 31px; // placeholder
|
|
380
|
+
margin-top: -10px !important;
|
|
381
|
+
display: flex;
|
|
382
|
+
flex-direction: row;
|
|
383
|
+
align-items: center;
|
|
384
|
+
justify-content: center;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.connectivity-error {
|
|
388
|
+
width: fit-content;
|
|
389
|
+
font-size: 12px;
|
|
390
|
+
padding: 0.25rem 0.5rem;
|
|
391
|
+
background-color: var(--el-color-error-light-9);
|
|
392
|
+
border-radius: var(--el-border-radius-small);
|
|
393
|
+
border: 1px solid var(--el-color-error);
|
|
394
|
+
}
|
|
395
|
+
</style>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<CopyToClipboard label="Copy list to clipboard" :content="referecesListContent" />
|
|
7
7
|
</div>
|
|
8
8
|
</div>
|
|
9
|
-
<div class="citation-tabs" v-if="referencesWithDOI">
|
|
9
|
+
<div class="citation-tabs" v-if="useDOIFormatter ? referencesWithDOI : pubMedReferences.length">
|
|
10
10
|
<el-button
|
|
11
11
|
link
|
|
12
12
|
v-for="citationOption of citationOptions"
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
|
|
103
103
|
<script>
|
|
104
104
|
import CopyToClipboard from '../CopyToClipboard/CopyToClipboard.vue';
|
|
105
|
-
import { delay } from '../utilities';
|
|
105
|
+
import { delay, getCitationById } from '../utilities';
|
|
106
106
|
|
|
107
107
|
const CROSSCITE_API_HOST = 'https://citation.doi.org';
|
|
108
108
|
const CITATION_OPTIONS = [
|
|
@@ -128,11 +128,18 @@ const LOADING_DELAY = 600;
|
|
|
128
128
|
|
|
129
129
|
export default {
|
|
130
130
|
name: "ExternalResourceCard",
|
|
131
|
+
components: {
|
|
132
|
+
CopyToClipboard,
|
|
133
|
+
},
|
|
131
134
|
props: {
|
|
132
135
|
resources: {
|
|
133
136
|
type: Array,
|
|
134
137
|
default: () => [],
|
|
135
138
|
},
|
|
139
|
+
useDOIFormatter: {
|
|
140
|
+
type: Boolean,
|
|
141
|
+
default: true,
|
|
142
|
+
}
|
|
136
143
|
},
|
|
137
144
|
data: function () {
|
|
138
145
|
return {
|
|
@@ -338,7 +345,14 @@ export default {
|
|
|
338
345
|
|
|
339
346
|
if (type === 'doi' || doi) {
|
|
340
347
|
const doiID = type === 'doi' ? id : doi;
|
|
341
|
-
this.
|
|
348
|
+
const fetchCitationFromAPI = this.useDOIFormatter ?
|
|
349
|
+
this.getCitationTextByDOI(doiID) :
|
|
350
|
+
getCitationById(doiID, {
|
|
351
|
+
type: 'doi',
|
|
352
|
+
format: citationType
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
fetchCitationFromAPI.then((text) => {
|
|
342
356
|
const formattedText = this.replaceLinkInText(text);
|
|
343
357
|
reference.citation[citationType] = formattedText;
|
|
344
358
|
this.updateCopyContents();
|
|
@@ -349,45 +363,61 @@ export default {
|
|
|
349
363
|
};
|
|
350
364
|
});
|
|
351
365
|
} else if (type === 'pmid') {
|
|
352
|
-
this.
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
366
|
+
if (this.useDOIFormatter) {
|
|
367
|
+
this.getDOIFromPubMedID(id).then((data) => {
|
|
368
|
+
if (data?.result) {
|
|
369
|
+
const resultObj = data.result[id];
|
|
370
|
+
const articleIDs = resultObj?.articleids || [];
|
|
371
|
+
const doiObj = articleIDs.find((item) => item.idtype === 'doi');
|
|
372
|
+
const doiID = doiObj?.value;
|
|
373
|
+
|
|
374
|
+
if (doiID) {
|
|
375
|
+
reference['doi'] = doiID;
|
|
376
|
+
this.getCitationTextByDOI(doiID).then((text) => {
|
|
377
|
+
const formattedText = this.replaceLinkInText(text);
|
|
378
|
+
reference.citation[citationType] = formattedText;
|
|
379
|
+
this.updateCopyContents();
|
|
380
|
+
}).catch((error) => {
|
|
381
|
+
reference.citation['error'] = {
|
|
382
|
+
type: citationType,
|
|
383
|
+
ref: 'doi',
|
|
384
|
+
};
|
|
385
|
+
});
|
|
386
|
+
} else {
|
|
387
|
+
// If there has no doi in PubMed
|
|
388
|
+
const { title, pubdate, authors } = resultObj;
|
|
389
|
+
const authorNames = authors ? authors.map((author) => author.name) : [];
|
|
390
|
+
const formattedText = this.formatCopyReference({
|
|
391
|
+
title: title || '',
|
|
392
|
+
date: pubdate || '',
|
|
393
|
+
authors: authorNames,
|
|
394
|
+
url: `https://pubmed.ncbi.nlm.nih.gov/${id}`,
|
|
395
|
+
});
|
|
363
396
|
reference.citation[citationType] = formattedText;
|
|
364
397
|
this.updateCopyContents();
|
|
365
|
-
}
|
|
366
|
-
reference.citation['error'] = {
|
|
367
|
-
type: citationType,
|
|
368
|
-
ref: 'doi',
|
|
369
|
-
};
|
|
370
|
-
});
|
|
371
|
-
} else {
|
|
372
|
-
// If there has no doi in PubMed
|
|
373
|
-
const { title, pubdate, authors } = resultObj;
|
|
374
|
-
const authorNames = authors ? authors.map((author) => author.name) : [];
|
|
375
|
-
const formattedText = this.formatCopyReference({
|
|
376
|
-
title: title || '',
|
|
377
|
-
date: pubdate || '',
|
|
378
|
-
authors: authorNames,
|
|
379
|
-
url: `https://pubmed.ncbi.nlm.nih.gov/${id}`,
|
|
380
|
-
});
|
|
381
|
-
reference.citation[citationType] = formattedText;
|
|
382
|
-
this.updateCopyContents();
|
|
398
|
+
}
|
|
383
399
|
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
};
|
|
390
|
-
}
|
|
400
|
+
}).catch((error) => {
|
|
401
|
+
reference.citation['error'] = {
|
|
402
|
+
type: citationType,
|
|
403
|
+
ref: 'pubmed',
|
|
404
|
+
};
|
|
405
|
+
});
|
|
406
|
+
} else {
|
|
407
|
+
getCitationById(id, {
|
|
408
|
+
type: 'pmid',
|
|
409
|
+
format: citationType
|
|
410
|
+
}).then((text) => {
|
|
411
|
+
const formattedText = this.replaceLinkInText(text);
|
|
412
|
+
reference.citation[citationType] = formattedText;
|
|
413
|
+
this.updateCopyContents();
|
|
414
|
+
}).catch((error) => {
|
|
415
|
+
reference.citation['error'] = {
|
|
416
|
+
type: citationType,
|
|
417
|
+
ref: 'pubmed',
|
|
418
|
+
};
|
|
419
|
+
});
|
|
420
|
+
}
|
|
391
421
|
}
|
|
392
422
|
}
|
|
393
423
|
},
|
|
@@ -171,6 +171,11 @@
|
|
|
171
171
|
</template>
|
|
172
172
|
|
|
173
173
|
<script>
|
|
174
|
+
import {
|
|
175
|
+
ArrowUp as ElIconArrowUp,
|
|
176
|
+
ArrowDown as ElIconArrowDown,
|
|
177
|
+
Warning as ElIconWarning,
|
|
178
|
+
} from '@element-plus/icons-vue'
|
|
174
179
|
import EventBus from "../EventBus.js";
|
|
175
180
|
|
|
176
181
|
const titleCase = (str) => {
|
|
@@ -186,6 +191,11 @@ const capitalise = function (str) {
|
|
|
186
191
|
|
|
187
192
|
export default {
|
|
188
193
|
name: "ProvenancePopup",
|
|
194
|
+
components: {
|
|
195
|
+
ElIconArrowUp,
|
|
196
|
+
ElIconArrowDown,
|
|
197
|
+
ElIconWarning,
|
|
198
|
+
},
|
|
189
199
|
props: {
|
|
190
200
|
tooltipEntry: {
|
|
191
201
|
type: Object,
|
package/src/components/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import AnnotationPopup from "./Tooltip/AnnotationPopup.vue";
|
|
2
2
|
import CreateTooltipContent from "./Tooltip/CreateTooltipContent.vue";
|
|
3
3
|
import ConnectivityGraph from "./ConnectivityGraph/ConnectivityGraph.vue";
|
|
4
|
+
import ConnectivityList from "./ConnectivityList/ConnectivityList.vue";
|
|
4
5
|
import CopyToClipboard from "./CopyToClipboard/CopyToClipboard.vue";
|
|
5
6
|
import DrawToolbar from "./DrawToolbar/DrawToolbar.vue";
|
|
6
7
|
import HelpModeDialog from "./HelpModeDialog/HelpModeDialog.vue";
|
|
@@ -12,6 +13,7 @@ export {
|
|
|
12
13
|
AnnotationPopup,
|
|
13
14
|
CreateTooltipContent,
|
|
14
15
|
ConnectivityGraph,
|
|
16
|
+
ConnectivityList,
|
|
15
17
|
CopyToClipboard,
|
|
16
18
|
DrawToolbar,
|
|
17
19
|
HelpModeDialog,
|