@abi-software/map-utilities 1.1.3-beta.3 → 1.1.3-beta.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.
package/package.json
CHANGED
package/src/App.vue
CHANGED
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
import { ConnectivityGraph } from './graph';
|
|
61
61
|
|
|
62
62
|
const MIN_SCHEMA_VERSION = 1.3;
|
|
63
|
+
const CACHE_LIFETIME = 24 * 60 * 60 * 1000; // One day
|
|
63
64
|
const RESET_LABEL = 'Reset position';
|
|
64
65
|
const ZOOM_LOCK_LABEL = 'Lock zoom (to scroll)';
|
|
65
66
|
const ZOOM_UNLOCK_LABEL = 'Unlock zoom';
|
|
@@ -97,6 +98,7 @@ export default {
|
|
|
97
98
|
};
|
|
98
99
|
},
|
|
99
100
|
mounted() {
|
|
101
|
+
this.refreshCache();
|
|
100
102
|
this.loadCacheData();
|
|
101
103
|
this.run().then((res) => {
|
|
102
104
|
this.showGraph(this.entry);
|
|
@@ -123,10 +125,37 @@ export default {
|
|
|
123
125
|
this.schemaVersion = schemaVersion;
|
|
124
126
|
}
|
|
125
127
|
},
|
|
128
|
+
removeAllCacheData: function () {
|
|
129
|
+
const keys = [
|
|
130
|
+
'connectivity-graph-expiry',
|
|
131
|
+
'connectivity-graph-source',
|
|
132
|
+
'connectivity-graph-labels',
|
|
133
|
+
'connectivity-graph-pathlist',
|
|
134
|
+
'connectivity-graph-schema-version',
|
|
135
|
+
];
|
|
136
|
+
keys.forEach((key) => {
|
|
137
|
+
sessionStorage.removeItem(key);
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
refreshCache: function () {
|
|
141
|
+
const expiry = sessionStorage.getItem('connectivity-graph-expiry');
|
|
142
|
+
const now = new Date();
|
|
143
|
+
|
|
144
|
+
if (now.getTime() > expiry) {
|
|
145
|
+
this.removeAllCacheData();
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
updateCacheExpiry: function () {
|
|
149
|
+
const now = new Date();
|
|
150
|
+
const expiry = now.getTime() + CACHE_LIFETIME;
|
|
151
|
+
|
|
152
|
+
sessionStorage.setItem('connectivity-graph-expiry', expiry);
|
|
153
|
+
},
|
|
126
154
|
run: async function () {
|
|
127
155
|
if (!this.schemaVersion) {
|
|
128
156
|
this.schemaVersion = await this.getSchemaVersion();
|
|
129
157
|
sessionStorage.setItem('connectivity-graph-schema-version', this.schemaVersion);
|
|
158
|
+
this.updateCacheExpiry();
|
|
130
159
|
}
|
|
131
160
|
if (this.schemaVersion < MIN_SCHEMA_VERSION) {
|
|
132
161
|
console.warn('No Server!');
|
|
@@ -136,22 +165,36 @@ export default {
|
|
|
136
165
|
if (!this.selectedSource) {
|
|
137
166
|
this.selectedSource = await this.setSourceList();
|
|
138
167
|
sessionStorage.setItem('connectivity-graph-source', this.selectedSource);
|
|
168
|
+
this.updateCacheExpiry();
|
|
139
169
|
}
|
|
140
|
-
await this.setPathList(this.selectedSource)
|
|
170
|
+
await this.setPathList(this.selectedSource);
|
|
141
171
|
this.hideSpinner();
|
|
142
172
|
},
|
|
143
173
|
showGraph: async function (neuronPath) {
|
|
144
174
|
const graphCanvas = this.$refs.graphCanvas;
|
|
175
|
+
|
|
145
176
|
this.showSpinner();
|
|
177
|
+
|
|
146
178
|
this.connectivityGraph = new ConnectivityGraph(this.labelCache, graphCanvas);
|
|
147
179
|
await this.connectivityGraph.addConnectivity(this.knowledgeByPath.get(neuronPath));
|
|
180
|
+
|
|
148
181
|
this.hideSpinner();
|
|
182
|
+
|
|
149
183
|
this.connectivityGraph.showConnectivity(graphCanvas);
|
|
150
|
-
|
|
184
|
+
|
|
185
|
+
this.connectivityGraph.on('tap-node', (event) => {
|
|
186
|
+
const { label } = event.detail;
|
|
187
|
+
const labels = label.split(`\n`);
|
|
188
|
+
/**
|
|
189
|
+
* This event is triggered after a node on the connectivity graph is clicked.
|
|
190
|
+
*/
|
|
191
|
+
this.$emit('tap-node', labels);
|
|
192
|
+
});
|
|
151
193
|
},
|
|
152
194
|
query: async function (sql, params) {
|
|
153
195
|
const url = `${this.mapServer}knowledge/query/`;
|
|
154
|
-
const query = { sql, params }
|
|
196
|
+
const query = { sql, params };
|
|
197
|
+
|
|
155
198
|
try {
|
|
156
199
|
const response = await fetch(url, {
|
|
157
200
|
method: 'POST',
|
|
@@ -162,9 +205,11 @@ export default {
|
|
|
162
205
|
},
|
|
163
206
|
body: JSON.stringify(query)
|
|
164
207
|
});
|
|
208
|
+
|
|
165
209
|
if (!response.ok) {
|
|
166
210
|
throw new Error(`Cannot access ${url}`);
|
|
167
211
|
}
|
|
212
|
+
|
|
168
213
|
return await response.json();
|
|
169
214
|
} catch {
|
|
170
215
|
return {
|
|
@@ -179,14 +224,17 @@ export default {
|
|
|
179
224
|
// Order with most recent first...
|
|
180
225
|
let firstSource = '';
|
|
181
226
|
const sourceList = [];
|
|
227
|
+
|
|
182
228
|
for (const source of sources) {
|
|
183
229
|
if (source) {
|
|
184
230
|
sourceList.push(source);
|
|
231
|
+
|
|
185
232
|
if (firstSource === '') {
|
|
186
233
|
firstSource = source;
|
|
187
234
|
}
|
|
188
235
|
}
|
|
189
236
|
}
|
|
237
|
+
|
|
190
238
|
return firstSource;
|
|
191
239
|
},
|
|
192
240
|
loadPathData: async function (source) {
|
|
@@ -202,9 +250,12 @@ export default {
|
|
|
202
250
|
if (!this.pathList.length) {
|
|
203
251
|
this.pathList = await this.loadPathData(source);
|
|
204
252
|
sessionStorage.setItem('connectivity-graph-pathlist', JSON.stringify(this.pathList));
|
|
253
|
+
this.updateCacheExpiry();
|
|
205
254
|
}
|
|
255
|
+
|
|
206
256
|
this.knowledgeByPath.clear();
|
|
207
257
|
this.labelledTerms = new Set();
|
|
258
|
+
|
|
208
259
|
for (const [key, jsonKnowledge] of this.pathList) {
|
|
209
260
|
const knowledge = JSON.parse(jsonKnowledge);
|
|
210
261
|
if ('connectivity' in knowledge) {
|
|
@@ -216,6 +267,7 @@ export default {
|
|
|
216
267
|
if (!this.labelCache.size) {
|
|
217
268
|
await this.getCachedTermLabels();
|
|
218
269
|
}
|
|
270
|
+
|
|
219
271
|
return '';
|
|
220
272
|
},
|
|
221
273
|
getSchemaVersion: async function () {
|
|
@@ -232,9 +284,11 @@ export default {
|
|
|
232
284
|
"Content-Type": "application/json"
|
|
233
285
|
}
|
|
234
286
|
});
|
|
287
|
+
|
|
235
288
|
if (!response.ok) {
|
|
236
289
|
console.error(`Cannot access ${url}`);
|
|
237
290
|
}
|
|
291
|
+
|
|
238
292
|
return await response.json();
|
|
239
293
|
} catch {
|
|
240
294
|
return null;
|
|
@@ -247,11 +301,14 @@ export default {
|
|
|
247
301
|
where entity in (?${', ?'.repeat(this.labelledTerms.size-1)})`,
|
|
248
302
|
[...this.labelledTerms.values()]
|
|
249
303
|
);
|
|
304
|
+
|
|
250
305
|
for (const termLabel of data.values) {
|
|
251
306
|
this.labelCache.set(termLabel[0], termLabel[1]);
|
|
252
307
|
}
|
|
308
|
+
|
|
253
309
|
const labelCacheObj = Object.fromEntries(this.labelCache);
|
|
254
310
|
sessionStorage.setItem('connectivity-graph-labels', JSON.stringify(labelCacheObj));
|
|
311
|
+
this.updateCacheExpiry();
|
|
255
312
|
}
|
|
256
313
|
},
|
|
257
314
|
cacheNodeLabels: function (node) {
|
|
@@ -309,7 +366,7 @@ export default {
|
|
|
309
366
|
.node-key {
|
|
310
367
|
border: 1px solid $app-primary-color;
|
|
311
368
|
padding: 4px;
|
|
312
|
-
background-color: rgba(
|
|
369
|
+
background-color: rgba(#f7faff, 0.85);
|
|
313
370
|
|
|
314
371
|
div div {
|
|
315
372
|
width: 90px;
|
|
@@ -362,6 +419,20 @@ export default {
|
|
|
362
419
|
}
|
|
363
420
|
}
|
|
364
421
|
|
|
422
|
+
:deep(.cy-graph-tooltip) {
|
|
423
|
+
padding: 4px 10px;
|
|
424
|
+
font-family: Asap;
|
|
425
|
+
font-size: 12px;
|
|
426
|
+
background: #f3ecf6 !important;
|
|
427
|
+
border: 1px solid $app-primary-color;
|
|
428
|
+
border-radius: var(--el-border-radius-base);
|
|
429
|
+
position: relative;
|
|
430
|
+
top: 0;
|
|
431
|
+
left: 0;
|
|
432
|
+
width: fit-content;
|
|
433
|
+
z-index: 1;
|
|
434
|
+
}
|
|
435
|
+
|
|
365
436
|
.visually-hidden {
|
|
366
437
|
clip: rect(0 0 0 0);
|
|
367
438
|
clip-path: inset(50%);
|
|
@@ -25,7 +25,7 @@ import cytoscape from 'cytoscape'
|
|
|
25
25
|
|
|
26
26
|
//==============================================================================
|
|
27
27
|
|
|
28
|
-
export class ConnectivityGraph
|
|
28
|
+
export class ConnectivityGraph extends EventTarget
|
|
29
29
|
{
|
|
30
30
|
cyg = null
|
|
31
31
|
nodes = []
|
|
@@ -37,8 +37,9 @@ export class ConnectivityGraph
|
|
|
37
37
|
|
|
38
38
|
constructor(labelCache, graphCanvas)
|
|
39
39
|
{
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
super()
|
|
41
|
+
this.labelCache = labelCache;
|
|
42
|
+
this.graphCanvas = graphCanvas;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
async addConnectivity(knowledge)
|
|
@@ -70,6 +71,13 @@ export class ConnectivityGraph
|
|
|
70
71
|
//================
|
|
71
72
|
{
|
|
72
73
|
this.cyg = new CytoscapeGraph(this, graphCanvas)
|
|
74
|
+
|
|
75
|
+
this.cyg.on('tap-node', (event) => {
|
|
76
|
+
const tapEvent = new CustomEvent('tap-node', {
|
|
77
|
+
detail: event.detail
|
|
78
|
+
})
|
|
79
|
+
this.dispatchEvent(tapEvent);
|
|
80
|
+
});
|
|
73
81
|
}
|
|
74
82
|
|
|
75
83
|
clearConnectivity()
|
|
@@ -140,6 +148,12 @@ export class ConnectivityGraph
|
|
|
140
148
|
}
|
|
141
149
|
return result
|
|
142
150
|
}
|
|
151
|
+
|
|
152
|
+
on(eventName, callback)
|
|
153
|
+
//=====================
|
|
154
|
+
{
|
|
155
|
+
this.addEventListener(eventName, callback)
|
|
156
|
+
}
|
|
143
157
|
}
|
|
144
158
|
|
|
145
159
|
//==============================================================================
|
|
@@ -188,13 +202,14 @@ const GRAPH_STYLE = [
|
|
|
188
202
|
|
|
189
203
|
//==============================================================================
|
|
190
204
|
|
|
191
|
-
class CytoscapeGraph
|
|
205
|
+
class CytoscapeGraph extends EventTarget
|
|
192
206
|
{
|
|
193
207
|
cy
|
|
194
208
|
tooltip
|
|
195
209
|
|
|
196
210
|
constructor(connectivityGraph, graphCanvas)
|
|
197
211
|
{
|
|
212
|
+
super()
|
|
198
213
|
this.cy = cytoscape({
|
|
199
214
|
container: graphCanvas,
|
|
200
215
|
elements: connectivityGraph.elements,
|
|
@@ -211,11 +226,12 @@ class CytoscapeGraph
|
|
|
211
226
|
}).on('mouseover', 'node', this.overNode.bind(this))
|
|
212
227
|
.on('mouseout', 'node', this.exitNode.bind(this))
|
|
213
228
|
.on('position', 'node', this.moveNode.bind(this))
|
|
229
|
+
.on('tap', 'node', this.tapNode.bind(this))
|
|
214
230
|
|
|
215
231
|
this.tooltip = document.createElement('div')
|
|
216
|
-
this.tooltip.
|
|
232
|
+
this.tooltip.className = 'cy-graph-tooltip'
|
|
217
233
|
this.tooltip.hidden = true
|
|
218
|
-
|
|
234
|
+
graphCanvas?.lastChild?.appendChild(this.tooltip)
|
|
219
235
|
}
|
|
220
236
|
|
|
221
237
|
remove()
|
|
@@ -259,6 +275,23 @@ class CytoscapeGraph
|
|
|
259
275
|
{
|
|
260
276
|
this.tooltip.hidden = true
|
|
261
277
|
}
|
|
278
|
+
|
|
279
|
+
tapNode(event)
|
|
280
|
+
//============
|
|
281
|
+
{
|
|
282
|
+
const node = event.target
|
|
283
|
+
const data = node.data()
|
|
284
|
+
const tapEvent = new CustomEvent('tap-node', {
|
|
285
|
+
detail: data
|
|
286
|
+
})
|
|
287
|
+
this.dispatchEvent(tapEvent);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
on(eventName, callback)
|
|
291
|
+
//=====================
|
|
292
|
+
{
|
|
293
|
+
this.addEventListener(eventName, callback)
|
|
294
|
+
}
|
|
262
295
|
}
|
|
263
296
|
|
|
264
297
|
//==============================================================================
|