@abi-software/map-utilities 0.0.0-beta.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/src/App.vue ADDED
@@ -0,0 +1,506 @@
1
+ <script setup>
2
+ import { ref, provide, onMounted, watch } from "vue";
3
+
4
+ import flatmapTreeData from "../static/FlatmapTreeData.json";
5
+ import scaffoldTreeData from "../static/ScaffoldTreeData.json";
6
+
7
+ /**
8
+ * DrawToolbar
9
+ */
10
+ const flatmapToolbarOptions = [
11
+ "Edit",
12
+ "Delete",
13
+ "Point",
14
+ "LineString",
15
+ "Polygon",
16
+ "Connection",
17
+ ];
18
+ const scaffoldToolbarOptions = ["Edit", "Point", "LineString"];
19
+ const activeDrawTool = ref(undefined);
20
+ const activeDrawMode = ref(undefined);
21
+ const hoverVisibilities = [
22
+ { value: false, refs: "toolbarPopover", ref: "editPopover" },
23
+ { value: false, refs: "toolbarPopover", ref: "deletePopover" },
24
+ { value: false, refs: "toolbarPopover", ref: "pointPopover" },
25
+ { value: false, refs: "toolbarPopover", ref: "lineStringPopover" },
26
+ { value: false, refs: "toolbarPopover", ref: "polygonPopover" },
27
+ { value: false, refs: "toolbarPopover", ref: "connectionPopover" },
28
+ ];
29
+ const isFlatmap = ref(true);
30
+ const appRef = ref(null);
31
+ const newlyDrawnEntry = ref({});
32
+ const connectionEntry = ref({});
33
+ const drawnType = ref("All tools");
34
+ const drawnTypes = [
35
+ { value: "All tools", label: "All tools" },
36
+ { value: "Point", label: "Point" },
37
+ { value: "LineString", label: "LineString" },
38
+ { value: "Polygon", label: "Polygon" },
39
+ { value: "None", label: "None" },
40
+ ];
41
+
42
+ onMounted(() => {
43
+ console.log("🚀 ~ onMounted ~ appRef:", appRef.value);
44
+ });
45
+
46
+ watch(drawnType, () => {
47
+ finaliseNewDrawn();
48
+ });
49
+
50
+ function toolbarEvent(type, name) {
51
+ console.log("🚀 ~ toolbarEvent ~ type, name:", type, name);
52
+ connectionEntry.value = {};
53
+ if (type === "mode") {
54
+ activeDrawMode.value = name;
55
+ } else if (type === "tool") {
56
+ activeDrawTool.value = name;
57
+ }
58
+ }
59
+ function startNewDrawn(type) {
60
+ activeDrawTool.value = type;
61
+ newlyDrawnEntry.value = {};
62
+ connectionEntry.value = {};
63
+ }
64
+ function finishNewDrawn() {
65
+ newlyDrawnEntry.value = {
66
+ id: 1,
67
+ value: "newly drawn entry",
68
+ };
69
+ }
70
+ function addConnection() {
71
+ connectionEntry.value = {
72
+ " 1026": {
73
+ id: 1026,
74
+ label: "body proper",
75
+ models: "UBERON:0013702",
76
+ },
77
+ " 4958": {
78
+ id: 4958,
79
+ label: "liver",
80
+ models: "UBERON:0002107",
81
+ },
82
+ };
83
+ }
84
+ function removeConnection() {
85
+ connectionEntry.value = {};
86
+ }
87
+ function featureTooltip(value) {
88
+ console.log("🚀 ~ featureTooltip ~ value:", value);
89
+ }
90
+ function finaliseNewDrawn() {
91
+ activeDrawTool.value = undefined;
92
+ newlyDrawnEntry.value = {};
93
+ connectionEntry.value = {};
94
+ }
95
+ /**
96
+ * HelpModeDialog
97
+ */
98
+ const helpMode = ref(false);
99
+ const helpModeActiveItem = ref(0);
100
+ const helpModeLastItem = ref(false);
101
+ const useHelpModeDialog = ref(false);
102
+
103
+ function showHelpModeDialog() {
104
+ helpMode.value = true;
105
+ useHelpModeDialog.value = true;
106
+ }
107
+ function onHelpModeShowNext() {
108
+ helpModeActiveItem.value += 1;
109
+ console.log(
110
+ "🚀 ~ onHelpModeShowNext ~ helpModeActiveItem:",
111
+ helpModeActiveItem.value
112
+ );
113
+ }
114
+ function onFinishHelpMode() {
115
+ helpMode.value = false;
116
+ // reset help mode to default values
117
+ helpModeActiveItem.value = 0;
118
+ helpModeLastItem.value = false;
119
+ }
120
+ /**
121
+ * Tooltip
122
+ */
123
+ const tooltipDisplay = ref(false);
124
+ const tooltipEntry = ref({});
125
+ const featuresAlert = ref(undefined);
126
+ const annotationDisplay = ref(false);
127
+ const annotationEntry = ref({});
128
+
129
+ provide(/* key */ "getFeaturesAlert", /* value */ () => featuresAlert.value);
130
+ provide(/* key */ "$annotator", /* value */ undefined);
131
+ provide(/* key */ "userApiKey", /* value */ undefined);
132
+
133
+ function addTooltipEntry() {
134
+ tooltipDisplay.value = true;
135
+ tooltipEntry.value = {
136
+ destinations: [null],
137
+ origins: [null],
138
+ components: ["pudendal nerve"],
139
+ destinationsWithDatasets: [
140
+ { id: "UBERON:0004917", name: "urethral sphincter" },
141
+ ],
142
+ originsWithDatasets: [
143
+ { id: "UBERON:0022278", name: "nucleus of pudendal nerve" },
144
+ ],
145
+ componentsWithDatasets: [{ id: "UBERON:0011390", name: "pudendal nerve" }],
146
+ title:
147
+ "Nucleus of the pudendal nerve to urethral sphincter via pudendal nerve",
148
+ featureId: ["ilxtr:sparc-nlp/mmset1/1"],
149
+ hyperlinks: [
150
+ {
151
+ url: "https://pubmed.ncbi.nlm.nih.gov/?term=%2F%2Fdoi.org%2F10.1155%252F2012%252F816274",
152
+ id: "pubmed",
153
+ },
154
+ ],
155
+ provenanceTaxonomy: ["NCBITaxon:9606"],
156
+ provenanceTaxonomyLabel: ["Homo sapiens"],
157
+ };
158
+ }
159
+ function removeTooltipEntry() {
160
+ tooltipDisplay.value = false;
161
+ tooltipEntry.value = {};
162
+ }
163
+ function addAnnotationEntry() {
164
+ tooltipDisplay.value = true;
165
+ annotationDisplay.value = true;
166
+ annotationEntry.value = {
167
+ id: "digestive_8-1",
168
+ featureId: 4958,
169
+ label: "liver",
170
+ models: "UBERON:0002107",
171
+ type: "feature",
172
+ mapUUID: "b650201e-f27a-54a1-84fc-6ec2e7cf4c15",
173
+ resourceId:
174
+ "https://mapcore-demo.org/devel/flatmap/v4/flatmap/b650201e-f27a-54a1-84fc-6ec2e7cf4c15",
175
+ };
176
+ }
177
+ function removeAnnotationEntry() {
178
+ tooltipDisplay.value = false;
179
+ annotationDisplay.value = false;
180
+ annotationEntry.value = {};
181
+ }
182
+ function commitAnnotationEvent(value) {
183
+ console.log("🚀 ~ commitAnnotationEvent ~ value:", value);
184
+ }
185
+ /**
186
+ * TreeControls
187
+ */
188
+ const isReady = ref(true);
189
+ const mapType = ref("flatmap");
190
+ const flatmapTreeDataEntry = flatmapTreeData;
191
+ const scaffoldTreeDataEntry = scaffoldTreeData[0].children;
192
+ const treeDataEntry = ref(flatmapTreeDataEntry);
193
+
194
+ function switchTreeEntry(value) {
195
+ isReady.value = false;
196
+ if (value === "flatmap") {
197
+ mapType.value = "flatmap";
198
+ treeDataEntry.value = flatmapTreeDataEntry;
199
+ } else if (value === "scaffold") {
200
+ mapType.value = "scaffold";
201
+ treeDataEntry.value = scaffoldTreeDataEntry;
202
+ }
203
+ isReady.value = true;
204
+ }
205
+ function setColourField(treeData, nodeData, activeColour) {
206
+ treeData
207
+ .filter((data) => {
208
+ // Filtering if single node is provided and it does not have children field
209
+ if (nodeData && !data.children) {
210
+ return data.id === nodeData.id;
211
+ } else {
212
+ return true;
213
+ }
214
+ })
215
+ .map((data) => {
216
+ if (data.children) {
217
+ // Using recursive to process nested data if children field exists
218
+ setColourField(data.children, nodeData, activeColour);
219
+ } else {
220
+ // Active colour used for current display
221
+ data["activeColour"] = activeColour;
222
+ }
223
+ });
224
+ }
225
+ function setColour(nodeData, value) {
226
+ if (nodeData && nodeData.isPrimitives) {
227
+ const activeColour = value ? value : nodeData.defaultColour;
228
+ setColourField(treeDataEntry.value, nodeData, activeColour)
229
+ }
230
+ }
231
+ function checkAll(value) {
232
+ console.log("🚀 ~ checkAll ~ value:", value);
233
+ }
234
+ function checkChanged(value) {
235
+ console.log("🚀 ~ checkChanged ~ value:", value);
236
+ }
237
+ function changeActive(value) {
238
+ console.log("🚀 ~ changeActive ~ value:", value);
239
+ }
240
+ function changeHover(value) {
241
+ console.log("🚀 ~ changeHover ~ value:", value);
242
+ }
243
+ </script>
244
+
245
+ <template>
246
+ <div ref="appRef">
247
+ <div class="maplibregl-canvas"></div>
248
+ <el-row>
249
+ <el-col>
250
+ <h3>DrawToolbar</h3>
251
+ </el-col>
252
+ <el-col>
253
+ <el-switch
254
+ v-model="isFlatmap"
255
+ active-text="Flatmap"
256
+ inactive-text="Scaffold"
257
+ />
258
+ </el-col>
259
+ </el-row>
260
+ <el-row v-show="isFlatmap">
261
+ <el-col>
262
+ <el-select
263
+ v-model="drawnType"
264
+ placeholder="Select"
265
+ style="width: 120px"
266
+ >
267
+ <el-option
268
+ v-for="item in drawnTypes"
269
+ :key="item.value"
270
+ :label="item.label"
271
+ :value="item.value"
272
+ />
273
+ </el-select>
274
+ </el-col>
275
+ <el-col>
276
+ <el-button
277
+ v-show="
278
+ (!activeDrawTool || activeDrawTool === 'Point') &&
279
+ (drawnType === 'All tools' ||
280
+ drawnType === 'Point' ||
281
+ drawnType === 'None')
282
+ "
283
+ @click="startNewDrawn('Point')"
284
+ size="small"
285
+ >
286
+ Draw New Point
287
+ </el-button>
288
+ <el-button
289
+ v-show="
290
+ (!activeDrawTool || activeDrawTool === 'LineString') &&
291
+ (drawnType === 'All tools' ||
292
+ drawnType === 'LineString' ||
293
+ drawnType === 'None')
294
+ "
295
+ @click="startNewDrawn('LineString')"
296
+ size="small"
297
+ >
298
+ Draw New LineString
299
+ </el-button>
300
+ <el-button
301
+ v-show="
302
+ (!activeDrawTool || activeDrawTool === 'Polygon') &&
303
+ (drawnType === 'All tools' ||
304
+ drawnType === 'Polygon' ||
305
+ drawnType === 'None')
306
+ "
307
+ @click="startNewDrawn('Polygon')"
308
+ size="small"
309
+ >
310
+ Draw New Polygon
311
+ </el-button>
312
+ <el-button v-show="activeDrawTool" @click="finishNewDrawn" size="small">
313
+ Finish New Drawn
314
+ </el-button>
315
+ <el-button
316
+ v-show="Object.keys(newlyDrawnEntry).length > 0"
317
+ @click="finaliseNewDrawn"
318
+ size="small"
319
+ >
320
+ Finalise New Drawn
321
+ </el-button>
322
+ </el-col>
323
+ <el-col>
324
+ <el-button
325
+ v-show="
326
+ !Object.keys(connectionEntry).length > 0 &&
327
+ (!activeDrawTool || activeDrawTool === 'LineString') &&
328
+ (drawnType === 'All tools' ||
329
+ drawnType === 'LineString' ||
330
+ drawnType === 'None')
331
+ "
332
+ @click="addConnection"
333
+ size="small"
334
+ >
335
+ Add Connection
336
+ </el-button>
337
+ <el-button
338
+ v-show="Object.keys(connectionEntry).length > 0"
339
+ @click="removeConnection"
340
+ size="small"
341
+ >
342
+ Remove Connection
343
+ </el-button>
344
+ </el-col>
345
+ </el-row>
346
+ <el-row>
347
+ <el-col>
348
+ <h3>HelpModeDialog</h3>
349
+ <span v-show="helpMode && useHelpModeDialog"
350
+ >Current item: {{ helpModeActiveItem }}</span
351
+ >
352
+ </el-col>
353
+ <el-col>
354
+ <el-button @click="showHelpModeDialog" size="small">
355
+ Show HelpMode Dialog
356
+ </el-button>
357
+ <el-button
358
+ v-show="helpMode && useHelpModeDialog"
359
+ @click="onHelpModeShowNext"
360
+ size="small"
361
+ >
362
+ Show Next
363
+ </el-button>
364
+ <el-button
365
+ v-show="helpMode && useHelpModeDialog"
366
+ @click="onFinishHelpMode"
367
+ size="small"
368
+ >
369
+ Hide HelpMode Dialog
370
+ </el-button>
371
+ </el-col>
372
+ </el-row>
373
+ <el-row>
374
+ <el-col>
375
+ <h3>Tooltip</h3>
376
+ </el-col>
377
+ <el-col>
378
+ <el-button
379
+ v-show="!annotationDisplay"
380
+ @click="addTooltipEntry"
381
+ size="small"
382
+ >
383
+ Add Tooltip Entry
384
+ </el-button>
385
+ <el-button
386
+ v-show="Object.keys(tooltipEntry).length > 0"
387
+ @click="removeTooltipEntry"
388
+ size="small"
389
+ >
390
+ Remove Tooltip Entry
391
+ </el-button>
392
+ <el-button
393
+ v-show="!Object.keys(tooltipEntry).length > 0"
394
+ @click="addAnnotationEntry"
395
+ size="small"
396
+ >
397
+ Add Annotation Entry
398
+ </el-button>
399
+ <el-button
400
+ v-show="Object.keys(annotationEntry).length > 0"
401
+ @click="removeAnnotationEntry"
402
+ size="small"
403
+ >
404
+ Remove Annotation Entry
405
+ </el-button>
406
+ </el-col>
407
+ </el-row>
408
+ <el-row>
409
+ <el-col>
410
+ <h3>TreeControls - {{ mapType }}</h3>
411
+ </el-col>
412
+ <el-col>
413
+ <el-button @click="switchTreeEntry('flatmap')" size="small">
414
+ Add Flatmap Tree Entry
415
+ </el-button>
416
+ <el-button @click="switchTreeEntry('scaffold')" size="small">
417
+ Add Scaffold Tree Entry
418
+ </el-button>
419
+ </el-col>
420
+ </el-row>
421
+
422
+ <DrawToolbar
423
+ v-show="isFlatmap"
424
+ :mapCanvas="{
425
+ containerHTML: appRef,
426
+ class: '.maplibregl-canvas',
427
+ }"
428
+ :toolbarOptions="flatmapToolbarOptions"
429
+ :drawnType="drawnType"
430
+ :activeDrawTool="activeDrawTool"
431
+ :activeDrawMode="activeDrawMode"
432
+ :newlyDrawnEntry="newlyDrawnEntry"
433
+ :connectionEntry="connectionEntry"
434
+ :hoverVisibilities="hoverVisibilities"
435
+ @clickToolbar="toolbarEvent"
436
+ @featureTooltip="featureTooltip"
437
+ @confirmDrawn="finaliseNewDrawn"
438
+ @cancelDrawn="finaliseNewDrawn"
439
+ ref="toolbarPopover"
440
+ />
441
+ <DrawToolbar
442
+ v-show="!isFlatmap"
443
+ :toolbarOptions="scaffoldToolbarOptions"
444
+ :activeDrawTool="activeDrawTool"
445
+ :activeDrawMode="activeDrawMode"
446
+ :hoverVisibilities="hoverVisibilities"
447
+ @clickToolbar="toolbarEvent"
448
+ ref="toolbarPopover"
449
+ />
450
+ <HelpModeDialog
451
+ v-show="helpMode && useHelpModeDialog"
452
+ class="help-mode-dialog"
453
+ :lastItem="helpModeLastItem"
454
+ @show-next="onHelpModeShowNext"
455
+ @finish-help-mode="onFinishHelpMode"
456
+ />
457
+ <Tooltip
458
+ v-show="tooltipDisplay"
459
+ class="tooltip"
460
+ :tooltipEntry="tooltipEntry"
461
+ :annotationDisplay="annotationDisplay"
462
+ :annotationEntry="annotationEntry"
463
+ @annotation="commitAnnotationEvent"
464
+ />
465
+ <TreeControls
466
+ v-show="mapType === 'flatmap'"
467
+ mapType="flatmap"
468
+ title="Systems"
469
+ :treeData="treeDataEntry"
470
+ active=""
471
+ hover=""
472
+ @checkAll="checkAll"
473
+ @checkChanged="checkChanged"
474
+ @changeActive="changeActive"
475
+ @changeHover="changeHover"
476
+ />
477
+ <TreeControls
478
+ v-show="mapType === 'scaffold'"
479
+ mapType="scaffold"
480
+ title="Regions"
481
+ :isReady="isReady"
482
+ :treeData="treeDataEntry"
483
+ :active="[]"
484
+ :hover="[]"
485
+ :showColourPicker="true"
486
+ @setColour="setColour"
487
+ @checkChanged="checkChanged"
488
+ />
489
+ </div>
490
+ </template>
491
+
492
+ <style scoped>
493
+ .options-container {
494
+ text-align: center;
495
+ }
496
+ .help-mode-dialog {
497
+ position: absolute;
498
+ top: 50%;
499
+ }
500
+ .tooltip {
501
+ width: 400px;
502
+ position: absolute;
503
+ top: calc(50% - 100px);
504
+ left: calc(50% - 200px);
505
+ }
506
+ </style>
@@ -0,0 +1,43 @@
1
+ // Primary colors
2
+ $purple: #8300BF;
3
+ $darkBlue: #24245B;
4
+ $grey: #303133;
5
+
6
+ // Secondary colors
7
+ $lightPurple: #BC00FC;
8
+ $blue: #0026FF;
9
+
10
+ // Status colors
11
+ $success: #5e9f69;
12
+ $warning: #FF8400;
13
+ $danger: #b51d09;
14
+
15
+ // Text colors
16
+ $neutralGrey: #616161;
17
+ $mediumGrey: #606266;
18
+ $lightGrey: #909399;
19
+
20
+ // Line colors
21
+ $lineColor1: #DCDFE6;
22
+ $lineColor2: #E4E7ED;
23
+
24
+ // Background colors
25
+ $background: #F5F7FA;
26
+ $cochlear: #FFFFFF;
27
+
28
+ //Search box colors
29
+ $darkGrey: #606266;
30
+
31
+ $app-primary-color: $purple !default;
32
+ $app-secondary-color: $darkBlue !default;
33
+ $text-color: $grey !default;
34
+ $input-text: $grey !default;
35
+
36
+ $system-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif !important;
37
+ $font-family: 'Asap', sans-serif;
38
+
39
+ // Viewport Sizes
40
+ $viewport-sm: 20rem;
41
+ $viewport-md: 47rem;
42
+ $viewport-lg: 64rem;
43
+ $viewport-xlg: 120rem;
@@ -0,0 +1,5 @@
1
+ @import '_variables';
2
+
3
+ @import url('https://fonts.googleapis.com/css?family=Asap:400,400i,500,600,700&display=swap');
4
+
5
+ $--color-primary: $app-primary-color !default;
@@ -0,0 +1,118 @@
1
+ <template>
2
+ <div class="dialog-container">
3
+ <el-row>
4
+ <el-col>
5
+ <el-row v-if="inDrawing">
6
+ <span class="dialog-title">Finalise drawing</span>
7
+ <el-button-group>
8
+ <el-button
9
+ type="primary"
10
+ plain
11
+ @click="$emit('confirmDrawn', true)"
12
+ >
13
+ Confirm
14
+ </el-button>
15
+ <el-button type="primary" plain @click="$emit('cancelDrawn', true)">
16
+ Cancel
17
+ </el-button>
18
+ </el-button-group>
19
+ </el-row>
20
+ <el-row v-else>
21
+ <span class="dialog-title">Visualise connection</span>
22
+ <el-button
23
+ type="primary"
24
+ plain
25
+ @click="$emit('dialogDisplay', false)"
26
+ >
27
+ Close
28
+ </el-button>
29
+ </el-row>
30
+ </el-col>
31
+ </el-row>
32
+ <el-row v-if="connectionExist">
33
+ <el-col>
34
+ <b><span>Related Features</span></b>
35
+ <el-row v-for="(value, key) in connectionEntry" :key="key">
36
+ <el-card :shadow="shadowDisplay(key)" @click="handleTooltip(key)">
37
+ <span>{{ capitalise(value.label) }}</span>
38
+ </el-card>
39
+ </el-row>
40
+ </el-col>
41
+ </el-row>
42
+ </div>
43
+ </template>
44
+
45
+ <script>
46
+ const capitalise = function (str) {
47
+ if (str) return str.charAt(0).toUpperCase() + str.slice(1);
48
+ return "";
49
+ };
50
+
51
+ export default {
52
+ name: "ConnectionDialog",
53
+ props: {
54
+ connectionEntry: {
55
+ type: Object,
56
+ default: {},
57
+ },
58
+ inDrawing: {
59
+ type: Boolean,
60
+ default: false,
61
+ },
62
+ connectionExist: {
63
+ type: Boolean,
64
+ default: false,
65
+ },
66
+ },
67
+ data: function () {
68
+ return {
69
+ tooltipId: undefined,
70
+ };
71
+ },
72
+ methods: {
73
+ shadowDisplay: function (value) {
74
+ return this.tooltipId === value ? "always" : "hover";
75
+ },
76
+ capitalise: function (label) {
77
+ return capitalise(label);
78
+ },
79
+ handleTooltip: function (value) {
80
+ this.tooltipId = this.tooltipId === value ? undefined : value;
81
+ this.$emit("featureTooltip", this.tooltipId);
82
+ },
83
+ },
84
+ };
85
+ </script>
86
+
87
+ <style lang="scss" scoped>
88
+ .dialog-container {
89
+ width: 200px;
90
+ height: fit-content;
91
+ text-align: justify;
92
+ border-radius: 4px;
93
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
94
+ pointer-events: auto;
95
+ background: #fff;
96
+ border: 1px solid $app-primary-color;
97
+ display: flex;
98
+ flex-direction: column;
99
+ padding: 0.8em;
100
+ }
101
+
102
+ .dialog-title {
103
+ font-size: 18px;
104
+ font-weight: bold;
105
+ color: rgb(131, 0, 191);
106
+ }
107
+
108
+ .el-button {
109
+ margin: 5px 0px;
110
+ }
111
+
112
+ :deep(.el-card) {
113
+ width: 100%;
114
+ --el-card-padding: 8px;
115
+ border: 0;
116
+ cursor: pointer;
117
+ }
118
+ </style>