@abi-software/scaffoldvuer 1.4.0 → 1.4.1-image.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.
- package/dist/scaffoldvuer.js +14834 -14121
- package/dist/scaffoldvuer.umd.cjs +184 -179
- package/dist/style.css +1 -1
- package/package.json +8 -5
- package/src/App.vue +14 -3
- package/src/components/ScaffoldTooltip.vue +37 -12
- package/src/components/ScaffoldVuer.vue +189 -22
- package/src/components.d.ts +2 -0
- package/src/main.js +1 -1
- package/src/mixins/imageMixin.js +87 -0
- package/src/services/scicrunchQueries.js +280 -0
- package/src/stores/settings.js +46 -0
- /package/src/{store → stores}/index.js +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
methods: {
|
|
3
|
+
populateMapWithImages: async function (images, type) {
|
|
4
|
+
let imageMarkerLabels = {};
|
|
5
|
+
for (const [key, list] of Object.entries(images)) {
|
|
6
|
+
const response = await this.downloadImageThumbnail(key, list, type);
|
|
7
|
+
if (response) {
|
|
8
|
+
imageMarkerLabels[key] = response;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return imageMarkerLabels;
|
|
12
|
+
},
|
|
13
|
+
downloadImageThumbnail: async function (key, list, type) {
|
|
14
|
+
const count = list.length;
|
|
15
|
+
if (count > 0) {
|
|
16
|
+
//Pick a random image
|
|
17
|
+
const index = Math.floor(Math.random() * count);
|
|
18
|
+
const thumbnail = list[index].thumbnail;
|
|
19
|
+
try {
|
|
20
|
+
const response = await this.getImageThumbnail(thumbnail, type);
|
|
21
|
+
const markerObject = await this.addImageThumbnailMarker(key, response);
|
|
22
|
+
return markerObject;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
// Failed to download, pick another one
|
|
25
|
+
list.splice(index);
|
|
26
|
+
this.downloadImageThumbnail(key, list, type);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
getImageThumbnail: async function (url, type) {
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
if (type === "Image" || type === "Segmentation") {
|
|
33
|
+
this.getBinaryThumbnail(url)
|
|
34
|
+
.then((response) => resolve(response))
|
|
35
|
+
.catch((response) => reject(response));
|
|
36
|
+
} else {
|
|
37
|
+
this.getGenericThumbnail(url)
|
|
38
|
+
.then((response) => resolve(response))
|
|
39
|
+
.catch((response) => reject(response));
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
getBinaryThumbnail: async function (url) {
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
fetch(url)
|
|
46
|
+
.then((response) => {
|
|
47
|
+
if (response.status >= 200 && response.status < 300) {
|
|
48
|
+
return response.text();
|
|
49
|
+
} else {
|
|
50
|
+
reject();
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
.then((data) => {
|
|
54
|
+
if (data) {
|
|
55
|
+
let img = new Image();
|
|
56
|
+
img.onload = function () {
|
|
57
|
+
resolve(`data:'image/png';base64,${data}`);
|
|
58
|
+
};
|
|
59
|
+
img.onerror = function () {
|
|
60
|
+
reject(new Error("Failed to load image at " + url));
|
|
61
|
+
};
|
|
62
|
+
img.src = `data:'image/png';base64,${data}`;
|
|
63
|
+
} else {
|
|
64
|
+
reject(new Error("Failed to load image at " + url));
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
getGenericThumbnail: async function (url) {
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
let img = new Image();
|
|
72
|
+
img.onload = function () {
|
|
73
|
+
resolve(url);
|
|
74
|
+
};
|
|
75
|
+
img.onerror = function () {
|
|
76
|
+
reject(new Error("Failed to load image at " + url));
|
|
77
|
+
};
|
|
78
|
+
img.src = url;
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
addImageThumbnailMarker: async function (id, source) {
|
|
82
|
+
const blob = await (await fetch(source)).blob();
|
|
83
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
84
|
+
return { number: this.markerLabels[id], imgURL: blobUrl };
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
const getOrganCuries = async (sparcApi, filetypes = [], species = []) => {
|
|
2
|
+
let params = new URLSearchParams();
|
|
3
|
+
filetypes.forEach((type) => {
|
|
4
|
+
params.append("filetypes", type);
|
|
5
|
+
});
|
|
6
|
+
species.forEach((name) => {
|
|
7
|
+
params.append("species", name);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const response = await fetch(`${sparcApi}/get-organ-curies/?${params}`);
|
|
11
|
+
const data = await response.json();
|
|
12
|
+
|
|
13
|
+
let organCuries = [];
|
|
14
|
+
data.uberon.array.forEach((pair) => {
|
|
15
|
+
const organCurie = {
|
|
16
|
+
id: pair.id.toUpperCase(),
|
|
17
|
+
name: pair.name,
|
|
18
|
+
};
|
|
19
|
+
organCuries.push(organCurie);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return organCuries;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const getFilesInfoForCuries = async (sparcApi, organCuries, filetypes) => {
|
|
26
|
+
const response = await fetch(`${sparcApi}/get-files-info-for-curies`, {
|
|
27
|
+
method: "POST",
|
|
28
|
+
body: JSON.stringify({
|
|
29
|
+
curies: organCuries.map((item) => item.id),
|
|
30
|
+
filetypes: filetypes,
|
|
31
|
+
}),
|
|
32
|
+
headers: {
|
|
33
|
+
"Content-Type": "application/json",
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
const data = await response.json();
|
|
37
|
+
|
|
38
|
+
return data;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const getFileNameFromPath = (filePath) => {
|
|
42
|
+
return filePath.substring(filePath.lastIndexOf("/") + 1);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const getBiolucidaThumbnailURL = (sparcApi, biolucidaId) => {
|
|
46
|
+
return `${sparcApi}/thumbnail/${biolucidaId}`;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const getBiolucidaThumbnails = async (sparcApi, organCuries, type) => {
|
|
50
|
+
try {
|
|
51
|
+
const data = await getFilesInfoForCuries(sparcApi, organCuries, [
|
|
52
|
+
"biolucida-2d",
|
|
53
|
+
"biolucida-3d",
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
if (data["files_info"]) {
|
|
57
|
+
let images = {};
|
|
58
|
+
for (const [key, value] of Object.entries(data["files_info"])) {
|
|
59
|
+
if (value.length > 0) {
|
|
60
|
+
let list = [];
|
|
61
|
+
value.forEach((entry) => {
|
|
62
|
+
const thumbnailURL = getBiolucidaThumbnailURL(
|
|
63
|
+
sparcApi,
|
|
64
|
+
entry.biolucida_id
|
|
65
|
+
);
|
|
66
|
+
if (entry.biolucida_id) {
|
|
67
|
+
let image = {
|
|
68
|
+
thumbnail: thumbnailURL,
|
|
69
|
+
resource: entry.file_path,
|
|
70
|
+
id: entry.id,
|
|
71
|
+
title: getFileNameFromPath(entry.file_path),
|
|
72
|
+
type: type,
|
|
73
|
+
link: thumbnailURL,
|
|
74
|
+
mimetype: entry.mimetype,
|
|
75
|
+
species: entry.species,
|
|
76
|
+
version: entry.version,
|
|
77
|
+
};
|
|
78
|
+
list.push(image);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
images[key] = list;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return images;
|
|
85
|
+
}
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error("Error:", error);
|
|
88
|
+
}
|
|
89
|
+
return {};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const getSegmentationThumbnailURL = (
|
|
93
|
+
sparcApi,
|
|
94
|
+
datasetId,
|
|
95
|
+
datasetVersion,
|
|
96
|
+
filePath
|
|
97
|
+
) => {
|
|
98
|
+
return `${sparcApi}/thumbnail/neurolucida?datasetId=${datasetId}&version=${datasetVersion}&path=files/${filePath}`;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const getSegmentationThumbnails = async (sparcApi, organCuries, type) => {
|
|
102
|
+
try {
|
|
103
|
+
const data = await getFilesInfoForCuries(sparcApi, organCuries, [
|
|
104
|
+
"mbf-segmentation",
|
|
105
|
+
]);
|
|
106
|
+
|
|
107
|
+
if (data["files_info"]) {
|
|
108
|
+
let images = {};
|
|
109
|
+
for (const [key, value] of Object.entries(data["files_info"])) {
|
|
110
|
+
if (value.length > 0) {
|
|
111
|
+
let list = [];
|
|
112
|
+
value.forEach((entry) => {
|
|
113
|
+
const thumbnailURL = getSegmentationThumbnailURL(
|
|
114
|
+
sparcApi,
|
|
115
|
+
entry.id,
|
|
116
|
+
entry.version,
|
|
117
|
+
entry.file_path
|
|
118
|
+
);
|
|
119
|
+
let image = {
|
|
120
|
+
thumbnail: thumbnailURL,
|
|
121
|
+
resource: entry.file_path,
|
|
122
|
+
id: entry.id,
|
|
123
|
+
title: getFileNameFromPath(entry.file_path),
|
|
124
|
+
type: type,
|
|
125
|
+
link: thumbnailURL,
|
|
126
|
+
mimetype: entry.mimetype,
|
|
127
|
+
species: entry.species,
|
|
128
|
+
version: entry.version,
|
|
129
|
+
};
|
|
130
|
+
list.push(image);
|
|
131
|
+
});
|
|
132
|
+
images[key] = list;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return images;
|
|
136
|
+
}
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error("Error:", error);
|
|
139
|
+
}
|
|
140
|
+
return {};
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const findEntryWithPathInArray = (entry, list, type) => {
|
|
144
|
+
if (entry && list) {
|
|
145
|
+
for (let i = 0; i < entry.isSourceOf.length; i++) {
|
|
146
|
+
for (let l = 0; l < list.length; l++) {
|
|
147
|
+
const item = list[l];
|
|
148
|
+
if (
|
|
149
|
+
entry.id === item.id &&
|
|
150
|
+
(!type || item.type === type) &&
|
|
151
|
+
entry.isSourceOf[i] === item.file_path
|
|
152
|
+
) {
|
|
153
|
+
return item;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return undefined;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const getScaffoldThumbnailURL = (sparcApi, entry, list) => {
|
|
162
|
+
const viewEntry = findEntryWithPathInArray(
|
|
163
|
+
entry,
|
|
164
|
+
list,
|
|
165
|
+
"abi-scaffold-view-file"
|
|
166
|
+
);
|
|
167
|
+
const thumbnailEntry = findEntryWithPathInArray(
|
|
168
|
+
viewEntry,
|
|
169
|
+
list,
|
|
170
|
+
"abi-thumbnail"
|
|
171
|
+
);
|
|
172
|
+
if (thumbnailEntry) {
|
|
173
|
+
return `${sparcApi}/s3-resource/${thumbnailEntry.id}/files/${thumbnailEntry.file_path}`;
|
|
174
|
+
}
|
|
175
|
+
return undefined;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const getScaffoldThumbnails = async (sparcApi, organCuries, type) => {
|
|
179
|
+
try {
|
|
180
|
+
const data = await getFilesInfoForCuries(sparcApi, organCuries, [
|
|
181
|
+
"abi-thumbnail",
|
|
182
|
+
"abi-scaffold-metadata-file",
|
|
183
|
+
"abi-scaffold-view-file",
|
|
184
|
+
]);
|
|
185
|
+
|
|
186
|
+
if (data["files_info"]) {
|
|
187
|
+
let images = {};
|
|
188
|
+
for (const [key, value] of Object.entries(data["files_info"])) {
|
|
189
|
+
if (value.length > 0) {
|
|
190
|
+
let list = [];
|
|
191
|
+
value.forEach((entry) => {
|
|
192
|
+
if (entry.type === "abi-scaffold-metadata-file") {
|
|
193
|
+
const thumbnailURL = getScaffoldThumbnailURL(
|
|
194
|
+
sparcApi,
|
|
195
|
+
entry,
|
|
196
|
+
value
|
|
197
|
+
);
|
|
198
|
+
if (thumbnailURL) {
|
|
199
|
+
let image = {
|
|
200
|
+
thumbnail: thumbnailURL,
|
|
201
|
+
resource: entry.file_path,
|
|
202
|
+
id: entry.id,
|
|
203
|
+
title: getFileNameFromPath(entry.file_path),
|
|
204
|
+
type: type,
|
|
205
|
+
link: thumbnailURL,
|
|
206
|
+
species: entry.species,
|
|
207
|
+
version: entry.version,
|
|
208
|
+
};
|
|
209
|
+
list.push(image);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
images[key] = list;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return images;
|
|
217
|
+
}
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.error("Error:", error);
|
|
220
|
+
}
|
|
221
|
+
return {};
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const getPlotThumbnailURL = (sparcApi, entry) => {
|
|
225
|
+
//None of the thumbnail for plot is properly annotated.
|
|
226
|
+
//We will use the first in is source of for testing.
|
|
227
|
+
if (entry.isSourceOf.length > 0) {
|
|
228
|
+
return `${sparcApi}/s3-resource/${entry.id}/files/${entry.isSourceOf[0]}`;
|
|
229
|
+
}
|
|
230
|
+
return undefined;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const getPlotThumbnails = async (sparcApi, organCuries, type) => {
|
|
234
|
+
try {
|
|
235
|
+
const data = await getFilesInfoForCuries(sparcApi, organCuries, [
|
|
236
|
+
"abi-plot",
|
|
237
|
+
"abi-thumbnail",
|
|
238
|
+
]);
|
|
239
|
+
|
|
240
|
+
if (data["files_info"]) {
|
|
241
|
+
let images = {};
|
|
242
|
+
for (const [key, value] of Object.entries(data["files_info"])) {
|
|
243
|
+
if (value.length > 0) {
|
|
244
|
+
let list = [];
|
|
245
|
+
value.forEach((entry) => {
|
|
246
|
+
if (entry.type === "abi-plot") {
|
|
247
|
+
const thumbnailURL = getPlotThumbnailURL(sparcApi, entry);
|
|
248
|
+
if (thumbnailURL) {
|
|
249
|
+
let image = {
|
|
250
|
+
thumbnail: thumbnailURL,
|
|
251
|
+
resource: entry.file_path,
|
|
252
|
+
id: entry.id,
|
|
253
|
+
title: getFileNameFromPath(entry.file_path),
|
|
254
|
+
type: type,
|
|
255
|
+
link: thumbnailURL,
|
|
256
|
+
species: entry.species,
|
|
257
|
+
version: entry.version,
|
|
258
|
+
};
|
|
259
|
+
list.push(image);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
images[key] = list;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return images;
|
|
267
|
+
}
|
|
268
|
+
} catch (error) {
|
|
269
|
+
console.error("Error:", error);
|
|
270
|
+
}
|
|
271
|
+
return {};
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export {
|
|
275
|
+
getOrganCuries,
|
|
276
|
+
getBiolucidaThumbnails,
|
|
277
|
+
getSegmentationThumbnails,
|
|
278
|
+
getScaffoldThumbnails,
|
|
279
|
+
getPlotThumbnails,
|
|
280
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { defineStore } from "pinia";
|
|
2
|
+
|
|
3
|
+
/* eslint-disable no-alert, no-console */
|
|
4
|
+
|
|
5
|
+
export const useSettingsStore = defineStore("settings", {
|
|
6
|
+
state: () => {
|
|
7
|
+
return {
|
|
8
|
+
organCuries: [],
|
|
9
|
+
imageTypes: [],
|
|
10
|
+
imageThumbnails: {},
|
|
11
|
+
};
|
|
12
|
+
},
|
|
13
|
+
getters: {
|
|
14
|
+
imageTypeCached: (state) => (imageType) => {
|
|
15
|
+
return state.imageTypes.includes(imageType);
|
|
16
|
+
},
|
|
17
|
+
getImageThumbnails:
|
|
18
|
+
(state) =>
|
|
19
|
+
(imageType, uberonIds = undefined) => {
|
|
20
|
+
if (uberonIds) {
|
|
21
|
+
let thumbnails = {};
|
|
22
|
+
Object.entries(state.imageThumbnails).forEach(([key, value]) => {
|
|
23
|
+
if (uberonIds.includes(key)) {
|
|
24
|
+
thumbnails[key] = value.filter((item) => item.type === imageType);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return thumbnails;
|
|
28
|
+
}
|
|
29
|
+
return state.imageThumbnails;
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
actions: {
|
|
33
|
+
updateOrganCuries(organCuries) {
|
|
34
|
+
this.organCuries = organCuries;
|
|
35
|
+
},
|
|
36
|
+
updateImageThumbnails(imageType, imageThumbnails) {
|
|
37
|
+
this.imageTypes.push(imageType);
|
|
38
|
+
Object.keys(imageThumbnails).forEach((key) => {
|
|
39
|
+
if (!(key in this.imageThumbnails)) {
|
|
40
|
+
this.imageThumbnails[key] = [];
|
|
41
|
+
}
|
|
42
|
+
this.imageThumbnails[key].push(...imageThumbnails[key]);
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
});
|
|
File without changes
|