@abi-software/map-utilities 1.1.3-beta.0 → 1.1.3-beta.10
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 +5904 -5541
- package/dist/map-utilities.umd.cjs +37 -32
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/App.vue +37 -0
- package/src/components/ConnectivityGraph/ConnectivityGraph.vue +441 -44
- package/src/components/ConnectivityGraph/graph.js +123 -23
- package/src/components/TreeControls/TreeControls.vue +38 -1
- package/src/components.d.ts +5 -0
|
@@ -25,9 +25,9 @@ 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 = []
|
|
32
32
|
edges = []
|
|
33
33
|
axons = []
|
|
@@ -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)
|
|
@@ -69,15 +70,56 @@ export class ConnectivityGraph
|
|
|
69
70
|
showConnectivity(graphCanvas)
|
|
70
71
|
//================
|
|
71
72
|
{
|
|
72
|
-
this.
|
|
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()
|
|
76
84
|
//=================
|
|
77
85
|
{
|
|
78
|
-
if (this.cy) {
|
|
79
|
-
this.cy.remove()
|
|
80
|
-
this.cy = null
|
|
86
|
+
if (this.cyg?.cy) {
|
|
87
|
+
this.cyg.cy.remove()
|
|
88
|
+
this.cyg.cy = null
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
reset()
|
|
93
|
+
//=====
|
|
94
|
+
{
|
|
95
|
+
if (this.cyg?.cy) {
|
|
96
|
+
this.cyg.cy.reset()
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
zoom(val)
|
|
101
|
+
//=======
|
|
102
|
+
{
|
|
103
|
+
if (this.cyg?.cy) {
|
|
104
|
+
const currentZoom = this.cyg.cy.zoom()
|
|
105
|
+
const width = this.cyg.cy.width()
|
|
106
|
+
const height = this.cyg.cy.height()
|
|
107
|
+
const positionToRender = {
|
|
108
|
+
x: width/2,
|
|
109
|
+
y: height/2,
|
|
110
|
+
}
|
|
111
|
+
this.cyg.cy.zoom({
|
|
112
|
+
level: currentZoom + val,
|
|
113
|
+
renderedPosition: positionToRender,
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
enableZoom(option)
|
|
119
|
+
//================
|
|
120
|
+
{
|
|
121
|
+
if (this.cyg?.cy) {
|
|
122
|
+
this.cyg.cy.userZoomingEnabled(option)
|
|
81
123
|
}
|
|
82
124
|
}
|
|
83
125
|
|
|
@@ -124,6 +166,12 @@ export class ConnectivityGraph
|
|
|
124
166
|
}
|
|
125
167
|
return result
|
|
126
168
|
}
|
|
169
|
+
|
|
170
|
+
on(eventName, callback)
|
|
171
|
+
//=====================
|
|
172
|
+
{
|
|
173
|
+
this.addEventListener(eventName, callback)
|
|
174
|
+
}
|
|
127
175
|
}
|
|
128
176
|
|
|
129
177
|
//==============================================================================
|
|
@@ -132,54 +180,81 @@ const GRAPH_STYLE = [
|
|
|
132
180
|
{
|
|
133
181
|
'selector': 'node',
|
|
134
182
|
'style': {
|
|
135
|
-
'label':
|
|
136
|
-
'background-color': '#80F0F0',
|
|
183
|
+
'label': function(ele) { return trimLabel(ele.data('label')) },
|
|
184
|
+
// 'background-color': '#80F0F0',
|
|
185
|
+
'background-color': 'transparent',
|
|
186
|
+
'background-opacity': '0',
|
|
137
187
|
'text-valign': 'center',
|
|
138
188
|
'text-wrap': 'wrap',
|
|
189
|
+
'width': '80px',
|
|
190
|
+
'height': '80px',
|
|
139
191
|
'text-max-width': '80px',
|
|
140
|
-
'font-size': '6px'
|
|
192
|
+
'font-size': '6px',
|
|
193
|
+
'shape': 'round-rectangle',
|
|
194
|
+
'border-width': 1,
|
|
195
|
+
'border-style': 'solid',
|
|
196
|
+
'border-color': 'gray',
|
|
141
197
|
}
|
|
142
198
|
},
|
|
143
199
|
{
|
|
144
200
|
'selector': 'node[axon]',
|
|
145
201
|
'style': {
|
|
146
|
-
'background-color': 'green'
|
|
202
|
+
// 'background-color': 'green',
|
|
203
|
+
'shape': 'round-diamond',
|
|
147
204
|
}
|
|
148
205
|
},
|
|
149
206
|
{
|
|
150
207
|
'selector': 'node[dendrite]',
|
|
151
208
|
'style': {
|
|
152
|
-
'background-color': 'red'
|
|
209
|
+
// 'background-color': 'red',
|
|
210
|
+
'shape': 'ellipse',
|
|
153
211
|
}
|
|
154
212
|
},
|
|
155
213
|
{
|
|
156
214
|
'selector': 'node[both-a-d]',
|
|
157
215
|
'style': {
|
|
158
|
-
'background-color': 'gray'
|
|
216
|
+
// 'background-color': 'gray',
|
|
217
|
+
'shape': 'round-rectangle',
|
|
159
218
|
}
|
|
160
219
|
},
|
|
161
220
|
{
|
|
162
221
|
'selector': 'edge',
|
|
163
222
|
'style': {
|
|
164
|
-
'width':
|
|
165
|
-
'line-color': '
|
|
166
|
-
'target-arrow-color': '
|
|
223
|
+
'width': 1,
|
|
224
|
+
'line-color': 'dimgray',
|
|
225
|
+
'target-arrow-color': 'dimgray',
|
|
167
226
|
'target-arrow-shape': 'triangle',
|
|
168
227
|
'curve-style': 'bezier'
|
|
169
228
|
}
|
|
170
229
|
}
|
|
171
230
|
]
|
|
172
231
|
|
|
232
|
+
function trimLabel(label) {
|
|
233
|
+
const labels = label.split('\n')
|
|
234
|
+
const half = labels.length/2
|
|
235
|
+
const trimLabels = labels.slice(half)
|
|
236
|
+
return trimLabels.join('\n')
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function capitalizeLabels(input) {
|
|
240
|
+
return input.split('\n').map(label => {
|
|
241
|
+
if (label && label[0] >= 'a' && label[0] <= 'z') {
|
|
242
|
+
return label.charAt(0).toUpperCase() + label.slice(1)
|
|
243
|
+
}
|
|
244
|
+
return label
|
|
245
|
+
}).join('\n')
|
|
246
|
+
}
|
|
247
|
+
|
|
173
248
|
//==============================================================================
|
|
174
249
|
|
|
175
|
-
class CytoscapeGraph
|
|
250
|
+
class CytoscapeGraph extends EventTarget
|
|
176
251
|
{
|
|
177
252
|
cy
|
|
178
253
|
tooltip
|
|
179
254
|
|
|
180
255
|
constructor(connectivityGraph, graphCanvas)
|
|
181
256
|
{
|
|
182
|
-
|
|
257
|
+
super()
|
|
183
258
|
this.cy = cytoscape({
|
|
184
259
|
container: graphCanvas,
|
|
185
260
|
elements: connectivityGraph.elements,
|
|
@@ -189,15 +264,19 @@ class CytoscapeGraph
|
|
|
189
264
|
roots: connectivityGraph.roots
|
|
190
265
|
},
|
|
191
266
|
directed: true,
|
|
192
|
-
style: GRAPH_STYLE
|
|
267
|
+
style: GRAPH_STYLE,
|
|
268
|
+
minZoom: 0.5,
|
|
269
|
+
maxZoom: 10,
|
|
270
|
+
wheelSensitivity: 0.4,
|
|
193
271
|
}).on('mouseover', 'node', this.overNode.bind(this))
|
|
194
272
|
.on('mouseout', 'node', this.exitNode.bind(this))
|
|
195
273
|
.on('position', 'node', this.moveNode.bind(this))
|
|
274
|
+
.on('tap', this.tapNode.bind(this))
|
|
196
275
|
|
|
197
276
|
this.tooltip = document.createElement('div')
|
|
198
|
-
this.tooltip.
|
|
277
|
+
this.tooltip.className = 'cy-graph-tooltip'
|
|
199
278
|
this.tooltip.hidden = true
|
|
200
|
-
|
|
279
|
+
graphCanvas?.lastChild?.appendChild(this.tooltip)
|
|
201
280
|
}
|
|
202
281
|
|
|
203
282
|
remove()
|
|
@@ -220,10 +299,14 @@ class CytoscapeGraph
|
|
|
220
299
|
//==============
|
|
221
300
|
{
|
|
222
301
|
const node = event.target
|
|
223
|
-
|
|
302
|
+
const label = capitalizeLabels(node.data().label)
|
|
303
|
+
|
|
304
|
+
this.tooltip.innerText = label
|
|
224
305
|
this.tooltip.style.left = `${event.renderedPosition.x}px`
|
|
225
306
|
this.tooltip.style.top = `${event.renderedPosition.y}px`
|
|
307
|
+
this.tooltip.style.maxWidth = '240px'
|
|
226
308
|
this.tooltip.hidden = false
|
|
309
|
+
|
|
227
310
|
this.checkRightBoundary(event.renderedPosition.x)
|
|
228
311
|
}
|
|
229
312
|
|
|
@@ -241,6 +324,23 @@ class CytoscapeGraph
|
|
|
241
324
|
{
|
|
242
325
|
this.tooltip.hidden = true
|
|
243
326
|
}
|
|
327
|
+
|
|
328
|
+
tapNode(event)
|
|
329
|
+
//============
|
|
330
|
+
{
|
|
331
|
+
const node = event.target
|
|
332
|
+
const data = node.data()
|
|
333
|
+
const tapEvent = new CustomEvent('tap-node', {
|
|
334
|
+
detail: data
|
|
335
|
+
})
|
|
336
|
+
this.dispatchEvent(tapEvent);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
on(eventName, callback)
|
|
340
|
+
//=====================
|
|
341
|
+
{
|
|
342
|
+
this.addEventListener(eventName, callback)
|
|
343
|
+
}
|
|
244
344
|
}
|
|
245
345
|
|
|
246
346
|
//==============================================================================
|
|
@@ -6,12 +6,21 @@
|
|
|
6
6
|
{{ title }}
|
|
7
7
|
</div>
|
|
8
8
|
</el-col>
|
|
9
|
+
<el-col v-if="enableFilter" :span="12">
|
|
10
|
+
<div>
|
|
11
|
+
<el-input
|
|
12
|
+
class="tree-filter-input"
|
|
13
|
+
v-model="filterText"
|
|
14
|
+
placeholder="Filter keyword"
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
17
|
+
</el-col>
|
|
9
18
|
</el-row>
|
|
10
19
|
<div class="tree-container" ref="treeContainer">
|
|
11
20
|
<div :class="['tree-tooltip', tooltipAtBottom ? 'bottom' : '']" >
|
|
12
21
|
<el-popover
|
|
13
22
|
ref="tooltip"
|
|
14
|
-
:visible="tooltipVisible"
|
|
23
|
+
:visible="tooltipVisible && tooltipLabel !== ''"
|
|
15
24
|
placement="top"
|
|
16
25
|
:show-arrow="false"
|
|
17
26
|
:teleported="false"
|
|
@@ -38,6 +47,7 @@
|
|
|
38
47
|
:default-expanded-keys="expandedKeys"
|
|
39
48
|
@check="checkChanged"
|
|
40
49
|
:indent="8"
|
|
50
|
+
:filter-node-method="filterNode"
|
|
41
51
|
:class="[mapType === 'flatmap' ? 'hide_grandchildren_checkbox': '']"
|
|
42
52
|
>
|
|
43
53
|
<template #default="{ node, data }">
|
|
@@ -138,10 +148,15 @@ export default {
|
|
|
138
148
|
type: [String, Array],
|
|
139
149
|
required: true,
|
|
140
150
|
},
|
|
151
|
+
enableFilter: {
|
|
152
|
+
type: Boolean,
|
|
153
|
+
default: true,
|
|
154
|
+
}
|
|
141
155
|
},
|
|
142
156
|
data: function () {
|
|
143
157
|
return {
|
|
144
158
|
defaultExpandedKeys: ["All"],
|
|
159
|
+
filterText: "",
|
|
145
160
|
myPopperClass: "hide-scaffold-colour-popup",
|
|
146
161
|
tooltipVisible: false,
|
|
147
162
|
tooltipLabel: "",
|
|
@@ -178,8 +193,17 @@ export default {
|
|
|
178
193
|
else this.myPopperClass = "hide-scaffold-colour-popup";
|
|
179
194
|
},
|
|
180
195
|
},
|
|
196
|
+
filterText: {
|
|
197
|
+
handler: function (value) {
|
|
198
|
+
if (this.$refs.regionTree) this.$refs.regionTree.filter(value);
|
|
199
|
+
},
|
|
200
|
+
},
|
|
181
201
|
},
|
|
182
202
|
methods: {
|
|
203
|
+
filterNode: function(value, data) {
|
|
204
|
+
if (!value) return true;
|
|
205
|
+
return data.label ? data.label.toLowerCase().includes(value.toLowerCase()) : false;
|
|
206
|
+
},
|
|
183
207
|
setColour: function (nodeData, value) {
|
|
184
208
|
this.$emit("setColour", nodeData, value);
|
|
185
209
|
},
|
|
@@ -250,6 +274,9 @@ export default {
|
|
|
250
274
|
unmounted: function () {
|
|
251
275
|
this.sortedPrimitiveGroups = undefined;
|
|
252
276
|
},
|
|
277
|
+
mounted: function() {
|
|
278
|
+
if (this.$refs.regionTree) this.$refs.regionTree.filter(this.filterText);
|
|
279
|
+
}
|
|
253
280
|
};
|
|
254
281
|
</script>
|
|
255
282
|
|
|
@@ -265,6 +292,7 @@ export default {
|
|
|
265
292
|
}
|
|
266
293
|
|
|
267
294
|
.selections-container {
|
|
295
|
+
width: 260px;
|
|
268
296
|
padding-top: 5px;
|
|
269
297
|
}
|
|
270
298
|
|
|
@@ -278,6 +306,15 @@ export default {
|
|
|
278
306
|
margin-left: 8px;
|
|
279
307
|
}
|
|
280
308
|
|
|
309
|
+
:deep(.tree-filter-input) {
|
|
310
|
+
.el-input__inner {
|
|
311
|
+
height: 20px;
|
|
312
|
+
}
|
|
313
|
+
.el-input__wrapper.is-focus{
|
|
314
|
+
box-shadow: 0 0 0 1px $app-primary-color;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
281
318
|
.tree-container {
|
|
282
319
|
width: 260px;
|
|
283
320
|
border: 1px solid rgb(144, 147, 153);
|
package/src/components.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ declare module 'vue' {
|
|
|
18
18
|
ElCol: typeof import('element-plus/es')['ElCol']
|
|
19
19
|
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
|
20
20
|
ElIcon: typeof import('element-plus/es')['ElIcon']
|
|
21
|
+
ElIconAim: typeof import('@element-plus/icons-vue')['Aim']
|
|
21
22
|
ElIconArrowDown: typeof import('@element-plus/icons-vue')['ArrowDown']
|
|
22
23
|
ElIconArrowUp: typeof import('@element-plus/icons-vue')['ArrowUp']
|
|
23
24
|
ElIconClose: typeof import('@element-plus/icons-vue')['Close']
|
|
@@ -25,7 +26,11 @@ declare module 'vue' {
|
|
|
25
26
|
ElIconDelete: typeof import('@element-plus/icons-vue')['Delete']
|
|
26
27
|
ElIconEdit: typeof import('@element-plus/icons-vue')['Edit']
|
|
27
28
|
ElIconFinished: typeof import('@element-plus/icons-vue')['Finished']
|
|
29
|
+
ElIconLock: typeof import('@element-plus/icons-vue')['Lock']
|
|
30
|
+
ElIconUnlock: typeof import('@element-plus/icons-vue')['Unlock']
|
|
28
31
|
ElIconWarning: typeof import('@element-plus/icons-vue')['Warning']
|
|
32
|
+
ElIconZoomIn: typeof import('@element-plus/icons-vue')['ZoomIn']
|
|
33
|
+
ElIconZoomOut: typeof import('@element-plus/icons-vue')['ZoomOut']
|
|
29
34
|
ElInput: typeof import('element-plus/es')['ElInput']
|
|
30
35
|
ElMain: typeof import('element-plus/es')['ElMain']
|
|
31
36
|
ElOption: typeof import('element-plus/es')['ElOption']
|