@abi-software/flatmapvuer 0.2.4 → 0.2.5-alpha.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.
@@ -1,1282 +1,1282 @@
1
- <template>
2
- <div
3
- class="flatmap-container"
4
- v-loading="loading"
5
- element-loading-text="Loading..."
6
- element-loading-spinner="el-icon-loading"
7
- element-loading-background="rgba(0, 0, 0, 0.3)"
8
- >
9
- <map-svg-sprite-color />
10
- <div style="height:100%;width:100%;position:relative;overflow-y:none">
11
- <div style="height:100%;width:100%;" ref="display"></div>
12
- <el-popover
13
- :content="warningMessage"
14
- placement="right"
15
- v-if="displayWarning"
16
- :appendToBody="false"
17
- trigger="manual"
18
- popper-class="warning-popper flatmap-popper right-popper"
19
- v-model="hoverVisibilities[6].value"
20
- ref="warningPopover"
21
- ></el-popover>
22
- <i
23
- class="el-icon-warning warning-icon"
24
- v-if="displayWarning"
25
- @mouseover="showToolitip(6)"
26
- @mouseout="hideToolitip(6)"
27
- v-popover:warningPopover
28
- >
29
- <span class="warning-text">Beta</span>
30
- </i>
31
- <div class="bottom-right-control">
32
- <el-popover
33
- content="Zoom in"
34
- placement="left"
35
- :appendToBody="false"
36
- trigger="manual"
37
- popper-class="flatmap-popper left-popper"
38
- v-model="hoverVisibilities[0].value"
39
- >
40
- <map-svg-icon
41
- icon="zoomIn"
42
- class="icon-button zoomIn"
43
- slot="reference"
44
- @click.native="zoomIn()"
45
- @mouseover.native="showToolitip(0)"
46
- @mouseout.native="hideToolitip(0)"
47
- />
48
- </el-popover>
49
- <el-popover
50
- content="Zoom out"
51
- placement="top-end"
52
- :appendToBody="false"
53
- trigger="manual"
54
- popper-class="flatmap-popper popper-zoomout"
55
- v-model="hoverVisibilities[1].value"
56
- >
57
- <map-svg-icon
58
- icon="zoomOut"
59
- class="icon-button zoomOut"
60
- slot="reference"
61
- @click.native="zoomOut()"
62
- @mouseover.native="showToolitip(1)"
63
- @mouseout.native="hideToolitip(1)"
64
- />
65
- </el-popover>
66
- <el-popover
67
- content="Reset"
68
- placement="top"
69
- :appendToBody="false"
70
- trigger="manual"
71
- popper-class="flatmap-popper"
72
- v-model="hoverVisibilities[2].value"
73
- >
74
- <div>
75
- Fit to
76
- <br>
77
- window
78
- </div>
79
- <map-svg-icon
80
- slot="reference"
81
- icon="fitWindow"
82
- class="icon-button fitWindow"
83
- @click.native="resetView()"
84
- @mouseover.native="showToolitip(2)"
85
- @mouseout.native="hideToolitip(2)"
86
- />
87
- </el-popover>
88
- </div>
89
- <el-popover
90
- content="Change pathway visibility"
91
- placement="right"
92
- :appendToBody="false"
93
- trigger="manual"
94
- popper-class="flatmap-popper right-popper"
95
- v-model="hoverVisibilities[4].value"
96
- ref="checkBoxPopover"
97
- />
98
- <div class="pathway-location" :class="{ open: drawerOpen, close: !drawerOpen }">
99
- <div
100
- class="pathway-container"
101
- v-if="pathways.length > 0 && pathControls"
102
- v-popover:checkBoxPopover
103
- >
104
- <el-popover
105
- content="Find these markers for data"
106
- placement="right"
107
- :appendToBody="false"
108
- trigger="manual"
109
- popper-class="flatmap-popper popper-bump-right right-popper"
110
- v-model="hoverVisibilities[5].value"
111
- ref="markerPopover"
112
- ></el-popover>
113
- <div
114
- v-show="hoverVisibilities[5].value"
115
- class="flatmap-marker-help"
116
- v-html="flatmapMarker"
117
- v-popover:markerPopover
118
- ></div>
119
- <el-row>
120
- <el-col :span="12">
121
- <div class="pathways-display-text">Pathways</div>
122
- </el-col>
123
- <el-col :span="12">
124
- <el-checkbox
125
- class="all-checkbox"
126
- :indeterminate="isIndeterminate"
127
- v-model="checkAll"
128
- @change="handleCheckAllChange"
129
- >Display all</el-checkbox>
130
- </el-col>
131
- </el-row>
132
- <el-checkbox-group
133
- v-model="checkedItems"
134
- size="small"
135
- class="checkbox-group"
136
- @change="handleCheckedItemsChange"
137
- >
138
- <div class="checkbox-group-inner">
139
- <el-row v-for="item in pathways" :key="item.type" :label="item.type">
140
- <div class="checkbox-container">
141
- <el-checkbox
142
- class="my-checkbox"
143
- :label="item.type"
144
- @change="visibilityToggle()"
145
- :checked="true"
146
- >
147
- <div class="path-visual" :class="item.type"></div>
148
- {{item.label}}
149
- </el-checkbox>
150
- </div>
151
- </el-row>
152
- </div>
153
- </el-checkbox-group>
154
- </div>
155
- <div
156
- @click="toggleDrawer"
157
- class="drawer-button"
158
- :class="{ open: drawerOpen, close: !drawerOpen }"
159
- >
160
- <i class="el-icon-arrow-left"></i>
161
- </div>
162
- </div>
163
- <el-popover
164
- ref="backgroundPopover"
165
- placement="top-start"
166
- width="175"
167
- :appendToBody="false"
168
- trigger="click"
169
- popper-class="background-popper"
170
- >
171
- <el-row class="backgroundText">Organs display</el-row>
172
- <el-row class="backgroundControl">
173
- <el-radio-group v-model="colourRadio" class="flatmap-radio" @change="setColour">
174
- <el-radio :label="true">Colour</el-radio>
175
- <el-radio :label="false">Greyscale</el-radio>
176
- </el-radio-group>
177
- </el-row>
178
- <el-row class="backgroundSpacer"></el-row>
179
- <el-row class="backgroundText">Outlines display</el-row>
180
- <el-row class="backgroundControl">
181
- <el-radio-group v-model="outlinesRadio" class="flatmap-radio" @change="setOutlines">
182
- <el-radio :label="true">Show</el-radio>
183
- <el-radio :label="false">Hide</el-radio>
184
- </el-radio-group>
185
- </el-row>
186
- <el-row class="backgroundSpacer"></el-row>
187
- <el-row class="backgroundText">Change background</el-row>
188
- <el-row class="backgroundControl">
189
- <div
190
- v-for="item in availableBackground"
191
- :key="item"
192
- :class="['backgroundChoice', item, item == currentBackground ? 'active' :'']"
193
- @click="backgroundChangeCallback(item)"
194
- />
195
- </el-row>
196
- </el-popover>
197
- <el-popover
198
- content="Change background color"
199
- placement="right"
200
- v-model="hoverVisibilities[3].value"
201
- :appendToBody="false"
202
- trigger="manual"
203
- popper-class="flatmap-popper right-popper"
204
- >
205
- <map-svg-icon
206
- v-popover:backgroundPopover
207
- icon="changeBckgd"
208
- class="icon-button background-colour"
209
- :class="{ open: drawerOpen, close: !drawerOpen }"
210
- slot="reference"
211
- @mouseover.native="showToolitip(3)"
212
- @mouseout.native="hideToolitip(3)"
213
- />
214
- </el-popover>
215
- <Tooltip
216
- ref="tooltip"
217
- class="tooltip"
218
- :content="tooltipContent"
219
- :flatmapAPI="flatmapAPI"
220
- @resource-selected="resourceSelected"
221
- />
222
- </div>
223
- </div>
224
- </template>
225
-
226
- <script>
227
- /* eslint-disable no-alert, no-console */
228
- import Vue from "vue";
229
- import Tooltip from "./Tooltip";
230
- import { MapSvgIcon, MapSvgSpriteColor } from "@abi-software/svg-sprite";
231
- import {
232
- Checkbox,
233
- CheckboxGroup,
234
- Col,
235
- Loading,
236
- Radio,
237
- RadioGroup,
238
- Row
239
- } from "element-ui";
240
- import lang from "element-ui/lib/locale/lang/en";
241
- import locale from "element-ui/lib/locale";
242
- import flatmapMarker from "../icons/flatmap-marker";
243
- locale.use(lang);
244
- Vue.use(Checkbox);
245
- Vue.use(CheckboxGroup);
246
- Vue.use(Col);
247
- Vue.use(Loading.directive);
248
- Vue.use(Radio);
249
- Vue.use(RadioGroup);
250
- Vue.use(Row);
251
- const ResizeSensor = require("css-element-queries/src/ResizeSensor");
252
-
253
- const mapResize = map => {
254
- return () => {
255
- if (map) map.resize();
256
- };
257
- };
258
-
259
- export default {
260
- name: "FlatmapVuer",
261
- components: {
262
- MapSvgIcon,
263
- MapSvgSpriteColor,
264
- Tooltip
265
- },
266
- beforeCreate: function() {
267
- this.mapManager = undefined;
268
- this.mapImp = undefined;
269
- },
270
- methods: {
271
- backgroundChangeCallback: function(colour) {
272
- this.currentBackground = colour;
273
- if (this.mapImp) {
274
- this.mapImp.setBackgroundColour(this.currentBackground, 1);
275
- }
276
- },
277
- toggleDrawer: function() {
278
- this.drawerOpen = !this.drawerOpen;
279
- },
280
- /**
281
- * Function to toggle colour/greyscale of organs.
282
- */
283
- setColour: function(flag) {
284
- this.colourRadio = flag;
285
- if (this.mapImp) {
286
- this.mapImp.setColour({ colour: flag, outline: this.outlinesRadio });
287
- }
288
- },
289
- /**
290
- * Function to toggle outlines f organs.
291
- */
292
- setOutlines: function(flag) {
293
- this.outlineRadio = flag;
294
- if (this.mapImp) {
295
- this.mapImp.setColour({ colour: this.colourRadio, outline: flag });
296
- }
297
- },
298
- /**
299
- * Function to toggle paths to default.
300
- * Also called when the associated button is pressed.
301
- */
302
- resetView: function() {
303
- if (this.mapImp) {
304
- this.mapImp.resetMap();
305
- this.checkedItems = this.mapImp.pathTypes().map(item => item.type);
306
- this.isIndeterminate = false;
307
- this.checkAll = true;
308
- }
309
- },
310
- /**
311
- * Function to zoom in.
312
- * Also called when the associated button is pressed.
313
- */
314
- zoomIn: function() {
315
- if (this.mapImp) {
316
- this.mapImp.zoomIn();
317
- }
318
- },
319
- /**
320
- * Function to zoom out.
321
- * Also called when the associated button is pressed.
322
- */
323
- zoomOut: function() {
324
- if (this.mapImp) {
325
- this.mapImp.zoomOut();
326
- }
327
- },
328
- visibilityToggle: function() {
329
- if (this.mapImp) {
330
- this.mapImp.showPaths(this.checkedItems);
331
- }
332
- },
333
- handleCheckedItemsChange: function(value) {
334
- let checkedCount = value.length;
335
- this.checkAll = checkedCount === this.pathways.length;
336
- this.isIndeterminate =
337
- checkedCount > 0 && checkedCount < this.pathways.length;
338
- },
339
- handleCheckAllChange(val) {
340
- this.checkedItems = val ? this.pathways.map(a => a.type) : [];
341
- this.isIndeterminate = false;
342
- if (this.mapImp) {
343
- this.mapImp.showPaths(this.checkedItems);
344
- }
345
- },
346
- enablePanZoomEvents: function(flag) {
347
- this.mapImp.enablePanZoomEvents(flag);
348
- },
349
- eventCallback: function() {
350
- return (eventType, data, ...args) => {
351
- if (eventType !== "pan-zoom") {
352
- const label = data.label;
353
- const resource = [data.models];
354
- const taxonomy = this.entry;
355
- const payload = {
356
- dataset: data.dataset,
357
- taxonomy: taxonomy,
358
- resource: resource,
359
- label: label,
360
- feature: data,
361
- userData: args,
362
- eventType: eventType
363
- };
364
- // Disable the nueron pop up for now.
365
- if (data && data.type !== "marker")
366
- this.checkAndCreatePopups(data);
367
- this.$emit("resource-selected", payload);
368
- } else {
369
- this.$emit("pan-zoom-callback", data);
370
- }
371
- };
372
- },
373
- // checkNeuronClicked shows a neuron path pop up if a path was recently clicked
374
- checkAndCreatePopups: function(data) {
375
- if (
376
- data.eventType == "click" &&
377
- this.createTooltipFromNeuronCuration(data)
378
- ) {
379
- this.mapImp.showPopup(
380
- this.mapImp.modelFeatureIds(data.resource[0])[0],
381
- this.$refs.tooltip.$el,
382
- { className: "flatmap-tooltip-dialog" }
383
- );
384
- this.popUpCssHack();
385
- }
386
- },
387
- popUpCssHack: function() {
388
- // Below is a hack to remove flatmap tooltips while popup is open
389
- let ftooltip = document.querySelector(".flatmap-tooltip-popup");
390
- if (ftooltip) ftooltip.style.display = "none";
391
- document.querySelector(".mapboxgl-popup-close-button").style.display =
392
- "block";
393
- this.$refs.tooltip.$el.style.display = "flex";
394
- document.querySelector(".mapboxgl-popup-close-button").onclick = () => {
395
- document.querySelector(".flatmap-tooltip-popup").style.display =
396
- "block";
397
- };
398
- },
399
- resourceSelected: function(action) {
400
- this.$emit("resource-selected", action);
401
- },
402
- createTooltipFromNeuronCuration: function(data) {
403
- const feature = data.resource[0];
404
- let content = {
405
- title: undefined,
406
- components: undefined,
407
- start: undefined,
408
- distribution: undefined,
409
- actions: []
410
- };
411
-
412
- let foundAnnotations = false;
413
- this.tooltipVisible = false;
414
-
415
- // neural data check
416
- if (feature) {
417
- if (feature.includes("ilxtr:neuron")) {
418
- foundAnnotations = true;
419
- this.tooltipVisible = true;
420
- this.tooltipContent = content;
421
- this.tooltipContent.uberon = feature;
422
- this.tooltipContent.title = data.label;
423
- this.tooltipContent.featureId = feature;
424
- this.tooltipContent.actions.push({
425
- title: "Search for dataset",
426
- label: "Neuron Datasets",
427
- resource: feature.split(":")[1],
428
- type: "Neuron Search",
429
- nervePath: true
430
- });
431
- }
432
- }
433
- // annotated with datset check
434
- if (data.dataset) {
435
- foundAnnotations = true;
436
- this.tooltipVisible = true;
437
- this.tooltipContent = content;
438
- this.tooltipContent.uberon = feature;
439
- this.tooltipContent.title = data.label;
440
- this.tooltipContent.actions.push({
441
- title: "View dataset",
442
- resource: data.dataset,
443
- type: "URL",
444
- nervePath: false
445
- });
446
- }
447
-
448
- if (foundAnnotations) {
449
- return true;
450
- } else {
451
- return false;
452
- }
453
- },
454
- // Keeping this as an API
455
- showPopup: function(featureId, node, options) {
456
- let myOptions = options;
457
- if (this.mapImp) {
458
- if (myOptions) {
459
- if (!myOptions.className) myOptions.className = "flatmapvuer-popover";
460
- } else {
461
- myOptions = { className: "flatmapvuer-popover" };
462
- }
463
- this.mapImp.showPopup(featureId, node, myOptions);
464
- }
465
- },
466
- showMarkerPopup: function(featureId, node, options) {
467
- if (this.mapImp) {
468
- this.mapImp.showMarkerPopup(featureId, node, options);
469
- }
470
- },
471
- setHelpMode: function(helpMode) {
472
- if (helpMode) {
473
- this.inHelp = true;
474
- this.hoverVisibilities.forEach(item => {
475
- item.value = true;
476
- });
477
- this.openFlatmapHelpPopup();
478
- } else {
479
- this.inHelp = false;
480
- this.hoverVisibilities.forEach(item => {
481
- item.value = false;
482
- });
483
- this.closeFlatmapHelpPopup();
484
- }
485
- },
486
- showToolitip: function(tooltipNumber) {
487
- if (!this.inHelp) {
488
- this.tooltipWait = setTimeout(() => {
489
- this.hoverVisibilities[tooltipNumber].value = true;
490
- }, 500);
491
- }
492
- },
493
- hideToolitip: function(tooltipNumber) {
494
- if (!this.inHelp) {
495
- this.hoverVisibilities[tooltipNumber].value = false;
496
- clearTimeout(this.tooltipWait);
497
- }
498
- },
499
- openFlatmapHelpPopup: function() {
500
- if (this.mapImp) {
501
- let heartId = this.mapImp.featureIdsForModel("UBERON:0000948")[0];
502
- const elm = "Click for more information";
503
- this.mapImp.showPopup(heartId, elm, {
504
- anchor: "top",
505
- className: "flatmap-popup-popper"
506
- });
507
- }
508
- },
509
- closeFlatmapHelpPopup: function() {
510
- this.$el
511
- .querySelectorAll(".mapboxgl-popup-close-button")
512
- .forEach(item => {
513
- item.click();
514
- });
515
- },
516
- getLabels: function() {
517
- let labels = [];
518
- if (this.mapImp) {
519
- let annotations = this.mapImp.annotations;
520
- for (let value of annotations.values()) {
521
- if (value.label) labels.push(value.label);
522
- }
523
- return Array.from(new Set(labels));
524
- }
525
- },
526
- getState: function() {
527
- if (this.mapImp) {
528
- let state = {
529
- entry: this.entry,
530
- viewport: this.mapImp.getState()
531
- };
532
- return state;
533
- }
534
- return undefined;
535
- },
536
- setState: function(state) {
537
- if (state) {
538
- if (this.mapImp && state.entry) {
539
- if (this.entry == state.entry)
540
- if (state.viewport) {
541
- this.mapImp.setState(state.viewport);
542
- }
543
- } else {
544
- this.createFlatmap(state);
545
- }
546
- }
547
- },
548
- createFlatmap: function(state) {
549
- if (!this.mapImp && !this.loading) {
550
- this.loading = true;
551
- let minimap = false;
552
- if (this.displayMinimap) {
553
- minimap = { position: "top-right" };
554
- }
555
- let entry = this.entry;
556
- if (state && state.entry) entry = state.entry;
557
- let promise1 = this.mapManager.loadMap(
558
- entry,
559
- this.$refs.display,
560
- this.eventCallback(),
561
- {
562
- //fullscreenControl: false,
563
- //annotatable: false,
564
- //debug: true,
565
- featureInfo: this.featureInfo,
566
- "min-zoom": this.minZoom,
567
- pathControls: false,
568
- searchable: this.searchable,
569
- tooltips: this.tooltips,
570
- minimap: minimap
571
- }
572
- );
573
- promise1.then(returnedObject => {
574
- this.mapImp = returnedObject;
575
- this.sensor = new ResizeSensor(
576
- this.$refs.display,
577
- mapResize(this.mapImp)
578
- );
579
- this.mapImp.setBackgroundOpacity(1);
580
- this.backgroundChangeCallback(this.currentBackground);
581
- this.pathways = this.mapImp.pathTypes();
582
- this.$emit("ready", this);
583
- this.loading = false;
584
- if (this._viewportToBeSet)
585
- this.mapImp.setState(this._viewportToBeSet);
586
- else if (state && state.viewport)
587
- this.mapImp.setState(state.viewport);
588
- });
589
- } else if (state) {
590
- if (this.entry == state.entry) this._viewportToBeSet = state.viewport;
591
- }
592
- },
593
- showMinimap: function(flag) {
594
- if (this.mapImp)
595
- this.mapImp.showMinimap(flag);
596
- },
597
- showPathwaysDrawer: function(flag) {
598
- this.drawerOpen = flag;
599
- },
600
- /**
601
- * Function to display features with annotation matching the provided term.
602
- */
603
- searchAndShowResult: function(term) {
604
- if (this.mapImp) {
605
- if (term === undefined || term === "") {
606
- this.mapImp.clearSearchResults();
607
- } else {
608
- let searchResults = this.mapImp.search(term);
609
- if (searchResults && searchResults.__featureIds.length > 0)
610
- this.mapImp.showSearchResults(searchResults);
611
- else this.mapImp.clearSearchResults();
612
- }
613
- }
614
- }
615
- },
616
- props: {
617
- entry: String,
618
- featureInfo: {
619
- type: Boolean,
620
- default: false
621
- },
622
- minZoom: {
623
- type: Number,
624
- default: 4
625
- },
626
- pathControls: {
627
- type: Boolean,
628
- default: true
629
- },
630
- searchable: {
631
- type: Boolean,
632
- default: false
633
- },
634
- tooltips: {
635
- type: Boolean,
636
- default: true
637
- },
638
- helpMode: {
639
- type: Boolean,
640
- default: false
641
- },
642
- renderAtMounted: {
643
- type: Boolean,
644
- default: true
645
- },
646
- displayWarning: {
647
- type: Boolean,
648
- default: true
649
- },
650
- displayMinimap: {
651
- type: Boolean,
652
- default: false
653
- },
654
- warningMessage: {
655
- type: String,
656
- default: "Beta feature - This map is based on the connectivity of a rat. New connectivity and species specificity will be added as the SPARC program progress."
657
- },
658
- /**
659
- * State containing state of the flatmap.
660
- */
661
- state: {
662
- type: Object,
663
- default: undefined
664
- },
665
- /**
666
- * Specify the endpoint of the flatmap server.
667
- */
668
- flatmapAPI: {
669
- type: String,
670
- default: "https://mapcore-demo.org/flatmaps/"
671
- }
672
- },
673
- data: function() {
674
- return {
675
- checkedItems: [],
676
- pathways: [],
677
- isIndeterminate: false,
678
- checkAll: true,
679
- hoverVisibilities: [
680
- { value: false },
681
- { value: false },
682
- { value: false },
683
- { value: false },
684
- { value: false },
685
- { value: false },
686
- { value: false }
687
- ],
688
- inHelp: false,
689
- currentBackground: "white",
690
- availableBackground: ["white", "lightskyblue", "black"],
691
- loading: false,
692
- flatmapMarker: flatmapMarker,
693
- drawerOpen: true,
694
- tooltipContent: {},
695
- colourRadio: true,
696
- outlinesRadio: true
697
- };
698
- },
699
- watch: {
700
- entry: function() {
701
- if (!this.state) this.createFlatmap();
702
- },
703
- helpMode: function(val) {
704
- this.setHelpMode(val);
705
- },
706
- state: {
707
- handler: function(state) {
708
- this.setState(state);
709
- },
710
- immediate: true,
711
- deep: true
712
- }
713
- },
714
- mounted: function() {
715
- const flatmap = require("@abi-software/flatmap-viewer");
716
- this.mapManager = new flatmap.MapManager(this.flatmapAPI);
717
- if (this.renderAtMounted) this.createFlatmap();
718
- }
719
- };
720
- </script>
721
-
722
- <!-- Add "scoped" attribute to limit CSS to this component only -->
723
- <style scoped lang="scss">
724
- @import "~element-ui/packages/theme-chalk/src/button";
725
- @import "~element-ui/packages/theme-chalk/src/checkbox";
726
- @import "~element-ui/packages/theme-chalk/src/checkbox-group";
727
- @import "~element-ui/packages/theme-chalk/src/loading";
728
- @import "~element-ui/packages/theme-chalk/src/row";
729
-
730
- .warning-icon {
731
- position: absolute;
732
- top: 90px;
733
- left: 37px;
734
- text-align: left;
735
- font-size: 25px;
736
- color: $warning;
737
-
738
- &:hover {
739
- cursor: pointer;
740
- }
741
- }
742
-
743
- .warning-text {
744
- font-size: 15px;
745
- vertical-align: 5px;
746
- }
747
-
748
- .path-visual {
749
- margin: 3px 0;
750
- height: 3px;
751
- width: 25px;
752
- margin-right: 5px;
753
- display: inline-block;
754
- &.cns {
755
- background: #9b1fc1;
756
- }
757
- &.lcn {
758
- background: #f19e38;
759
- }
760
- &.para-pre {
761
- background: #3f8f4a;
762
- }
763
- &.para-post {
764
- background: repeating-linear-gradient(
765
- 90deg,
766
- #3f8f4a,
767
- #3f8f4a 6px,
768
- transparent 0,
769
- transparent 9px
770
- );
771
- }
772
- &.sensory {
773
- background: #2a62f6;
774
- }
775
- &.somatic {
776
- background: #98561d;
777
- }
778
- &.symp-pre {
779
- background: #ea3423;
780
- }
781
- &.symp-post {
782
- background: repeating-linear-gradient(
783
- 90deg,
784
- #ea3423,
785
- #ea3423 6px,
786
- transparent 0,
787
- transparent 9px
788
- );
789
- }
790
- }
791
-
792
- .flatmap-container {
793
- height: 100%;
794
- width: 100%;
795
- }
796
-
797
- .pathway-location {
798
- position: absolute;
799
- bottom: 0px;
800
- transition: all 1s ease;
801
- &.open {
802
- left: 0px;
803
- }
804
- &.close {
805
- left: -298px;
806
- }
807
- }
808
-
809
- .pathway-container {
810
- float: left;
811
- padding-left: 16px;
812
- padding-right: 18px;
813
- max-height: calc(100% - 184px);
814
- text-align: left;
815
- overflow: auto;
816
- border: 1px solid rgb(220, 223, 230);
817
- padding-top: 7px;
818
- padding-bottom: 16px;
819
- background: #ffffff;
820
- }
821
-
822
- .pathways-display-text {
823
- width: 59px;
824
- height: 20px;
825
- color: rgb(48, 49, 51);
826
- font-size: 14px;
827
- font-weight: normal;
828
- line-height: 20px;
829
- margin-left: 8px;
830
- }
831
-
832
- .all-checkbox {
833
- float: right;
834
- }
835
-
836
- .checkbox-container {
837
- display: flex;
838
- cursor: pointer;
839
- }
840
-
841
- .checkbox-group {
842
- width: 260px;
843
- border: 1px solid rgb(144, 147, 153);
844
- border-radius: 4px;
845
- background: #ffffff;
846
- }
847
-
848
- .my-checkbox {
849
- background-color: #fff;
850
- width: 100%;
851
- }
852
-
853
- .checkbox-group-inner {
854
- padding: 18px;
855
- }
856
-
857
- .flatmap-marker-help {
858
- display: inline-block;
859
- }
860
-
861
- ::v-deep .popper-bump-right {
862
- left: 30px;
863
- }
864
-
865
- ::v-deep .el-checkbox__label {
866
- padding-left: 5px;
867
- color: $app-primary-color;
868
- font-size: 12px;
869
- font-weight: 500;
870
- letter-spacing: 0px;
871
- line-height: 14px;
872
- }
873
-
874
- ::v-deep .el-checkbox__input {
875
- &.is-indeterminate,
876
- &.is-checked {
877
- .el-checkbox__inner {
878
- background-color: $app-primary-color;
879
- border-color: $app-primary-color;
880
- }
881
- }
882
- }
883
-
884
- ::v-deep .el-checkbox__label {
885
- color: $app-primary-color !important;
886
- }
887
-
888
- .el-dropdown-link {
889
- cursor: pointer;
890
- color: #409eff;
891
- }
892
- .el-icon-arrow-down {
893
- font-size: 12px;
894
- }
895
- .demonstration {
896
- display: block;
897
- color: #8492a6;
898
- font-size: 14px;
899
- margin-bottom: 20px;
900
- }
901
-
902
- .tooltip {
903
- display: none;
904
- }
905
-
906
- ::v-deep .mapboxgl-popup {
907
- max-width: 300px !important;
908
- }
909
-
910
- ::v-deep .flatmap-tooltip-popup {
911
- &.mapboxgl-popup-anchor-bottom {
912
- .mapboxgl-popup-content {
913
- margin-bottom: 12px;
914
- &::after,
915
- &::before {
916
- top: 100%;
917
- border-width: 12px;
918
- }
919
- /* this border color controlls the color of the triangle (what looks like the fill of the triangle) */
920
- &::after {
921
- margin-top: -1px;
922
- border-color: rgb(255, 255, 255) transparent transparent transparent;
923
- }
924
- /* this border color controlls the outside, thin border */
925
- &::before {
926
- margin: 0 auto;
927
- border-color: $app-primary-color transparent transparent transparent;
928
- }
929
- }
930
- }
931
- &.mapboxgl-popup-anchor-top {
932
- .mapboxgl-popup-content {
933
- margin-top: 18px;
934
- &::after,
935
- &::before {
936
- top: calc(-100% + 6px);
937
- border-width: 12px;
938
- }
939
- /* this border color controlls the color of the triangle (what looks like the fill of the triangle) */
940
- &::after {
941
- margin-top: 1px;
942
- border-color: transparent transparent rgb(255, 255, 255) transparent;
943
- }
944
- &::before {
945
- margin: 0 auto;
946
- border-color: transparent transparent $app-primary-color transparent;
947
- }
948
- }
949
- }
950
- .mapboxgl-popup-content {
951
- border-radius: 4px;
952
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
953
- pointer-events: none;
954
- display: none;
955
- background: #fff;
956
- border: 1px solid $app-primary-color;
957
- padding-left: 6px;
958
- padding-right: 6px;
959
- display: flex;
960
- justify-content: center;
961
- align-items: center;
962
- &::after,
963
- &::before {
964
- content: "";
965
- display: block;
966
- position: absolute;
967
- width: 0;
968
- height: 0;
969
- border-style: solid;
970
- flex-shrink: 0;
971
- }
972
- }
973
- .mapboxgl-popup-tip {
974
- display: none;
975
- }
976
- }
977
-
978
- ::v-deep .mapboxgl-popup {
979
- &.flatmap-marker-popup {
980
- box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
981
- pointer-events: auto;
982
- background: #fff;
983
- }
984
- }
985
-
986
- /* Fix for chrome bug where under triangle pops up above one on top of it */
987
- .selector:not(*:root),
988
- ::v-deep.flatmap-tooltip-popup {
989
- .mapboxgl-popup-content::after {
990
- top: 99.9%;
991
- }
992
- }
993
-
994
- ::v-deep .flatmap-tooltip-dialog {
995
- .mapboxgl-popup-tip {
996
- display: none;
997
- }
998
- }
999
-
1000
- ::v-deep .flatmap-marker-popup {
1001
- .mapboxgl-popup-content {
1002
- padding: 0px;
1003
- }
1004
- }
1005
-
1006
- ::v-deep .flatmapvuer-popover {
1007
- .mapboxgl-popup-close-button {
1008
- position: absolute;
1009
- right: 0.5em;
1010
- top: 0;
1011
- border: 0;
1012
- border-radius: 0 3px 0 0;
1013
- cursor: pointer;
1014
- background-color: transparent;
1015
- font-size: 2.5em;
1016
- color: grey;
1017
- top: 0.95em;
1018
- }
1019
- }
1020
-
1021
- .zoomOut {
1022
- padding-left: 8px;
1023
- }
1024
-
1025
- .fitWindow {
1026
- padding-left: 8px;
1027
- }
1028
-
1029
- .background-colour {
1030
- bottom: 16px;
1031
- position: absolute;
1032
- transition: all 1s ease;
1033
- }
1034
- .background-colour.open {
1035
- left: 322px;
1036
- }
1037
- .background-colour.close {
1038
- left: 24px;
1039
- }
1040
-
1041
- ::v-deep .background-popper {
1042
- padding: 5px 12px;
1043
- background-color: #ffffff;
1044
- border: 1px solid $app-primary-color;
1045
- box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.06);
1046
- height: 200px;
1047
- width: 175px;
1048
- min-width: 175px;
1049
- &.el-popper[x-placement^="top"] {
1050
- .popper__arrow {
1051
- border-top-color: $app-primary-color !important;
1052
- &::after {
1053
- border-top-color: #fff !important;
1054
- }
1055
- }
1056
- }
1057
- }
1058
-
1059
- .backgroundText {
1060
- color: rgb(48, 49, 51);
1061
- font-size: 14px;
1062
- font-weight: normal;
1063
- line-height: 20px;
1064
- }
1065
-
1066
- .backgroundControl {
1067
- display: flex;
1068
- margin-top: 16px;
1069
- }
1070
-
1071
- .backgroundChoice {
1072
- width: 20px;
1073
- height: 20px;
1074
- border: 1px solid rgb(144, 147, 153);
1075
- margin-left: 20px;
1076
- &.active {
1077
- border: 2px solid $app-primary-color;
1078
- }
1079
- &:hover {
1080
- cursor: pointer;
1081
- }
1082
- &.white {
1083
- background-color: white;
1084
- margin-left: 10px;
1085
- }
1086
- &.black {
1087
- background-color: black;
1088
- }
1089
- &.lightskyblue {
1090
- background-color: white;
1091
- }
1092
- }
1093
-
1094
- .togglePaths {
1095
- top: 201px;
1096
- right: 20px;
1097
- position: absolute;
1098
- }
1099
-
1100
- .icon-button {
1101
- height: 24px !important;
1102
- width: 24px !important;
1103
- color: $app-primary-color;
1104
- &:hover {
1105
- cursor: pointer;
1106
- }
1107
- }
1108
-
1109
- ::v-deep .flatmap-popper {
1110
- padding: 6px 4px;
1111
- font-size: 12px;
1112
- color: rgb(48, 49, 51);
1113
- background-color: #f3ecf6;
1114
- border: 1px solid $app-primary-color;
1115
- white-space: nowrap;
1116
- min-width: unset;
1117
- &.warning-popper {
1118
- min-width: 150px;
1119
- max-width: 400px;
1120
- word-break: keep-all;
1121
- white-space: unset;
1122
- }
1123
- &.left-popper {
1124
- .popper__arrow {
1125
- border-left-color: $app-primary-color !important;
1126
- &::after {
1127
- border-left-color: #f3ecf6 !important;
1128
- }
1129
- }
1130
- }
1131
- &.right-popper {
1132
- .popper__arrow {
1133
- border-right-color: $app-primary-color !important;
1134
- &:after {
1135
- border-right-color: #f3ecf6 !important;
1136
- }
1137
- }
1138
- }
1139
- &.el-popper[x-placement^="top"] {
1140
- .popper__arrow {
1141
- border-top-color: $app-primary-color !important;
1142
- &:after {
1143
- border-top-color: #f3ecf6 !important;
1144
- }
1145
- }
1146
- }
1147
- }
1148
-
1149
- ::v-deep .el-loading-spinner {
1150
- i,
1151
- .el-loading-text {
1152
- color: $app-primary-color;
1153
- }
1154
- }
1155
-
1156
- ::v-deep .flatmap-popup-popper {
1157
- .mapboxgl-popup-tip {
1158
- border-bottom-color: $app-primary-color;
1159
- }
1160
- .mapboxgl-popup-content {
1161
- padding: 6px 4px;
1162
- font-size: 12px;
1163
- color: rgb(48, 49, 51);
1164
- background-color: #f3ecf6;
1165
- border: 1px solid $app-primary-color;
1166
- white-space: nowrap;
1167
- min-width: unset;
1168
- .mapboxgl-popup-close-button {
1169
- display: none;
1170
- }
1171
- }
1172
- }
1173
-
1174
- ::v-deep .flatmap-popper {
1175
-
1176
- }
1177
-
1178
- ::v-deep .popper-zoomout {
1179
- padding-right: 13px !important;
1180
- left: -21px !important;
1181
- }
1182
-
1183
- ::v-deep .popper-zoomout {
1184
- .popper__arrow {
1185
- left: 53px !important;
1186
- }
1187
- }
1188
-
1189
- ::v-deep .mapboxgl-popup-content {
1190
- padding: 0px;
1191
- }
1192
-
1193
- .bottom-right-control {
1194
- position: absolute;
1195
- right: 16px;
1196
- bottom: 16px;
1197
- }
1198
-
1199
- ::v-deep .my-drawer {
1200
- background: rgba(0, 0, 0, 0);
1201
- box-shadow: none;
1202
- }
1203
-
1204
- .drawer {
1205
- ::v-deep .el-drawer:focus {
1206
- outline: none;
1207
- }
1208
- }
1209
-
1210
- .open-drawer,
1211
- .drawer-button {
1212
- z-index: 8;
1213
- width: 20px;
1214
- height: 40px;
1215
- border: solid 1px #e4e7ed;
1216
- text-align: center;
1217
- vertical-align: middle;
1218
- cursor: pointer;
1219
- pointer-events: auto;
1220
- }
1221
-
1222
- .open-drawer {
1223
- position: absolute;
1224
- left: 0px;
1225
- background-color: #f7faff;
1226
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
1227
- }
1228
-
1229
- .drawer-button {
1230
- float: left;
1231
- margin-top: calc(50% - 36px);
1232
- border-left: 0;
1233
- background-color: #ffffff;
1234
- i {
1235
- margin-top: 12px;
1236
- color: $app-primary-color;
1237
- transition-delay: 0.9s;
1238
- }
1239
- &.open {
1240
- i {
1241
- transform: rotate(0deg) scaleY(2.5);
1242
- }
1243
- }
1244
- &.close {
1245
- i {
1246
- transform: rotate(180deg) scaleY(2.5);
1247
- }
1248
- }
1249
- }
1250
-
1251
- ::v-deep .mapboxgl-canvas-container {
1252
- canvas {
1253
- outline: none;
1254
- }
1255
- }
1256
-
1257
- .backgroundSpacer {
1258
- border-bottom: 1px solid #e4e7ed;
1259
- margin-bottom: 10px;
1260
- }
1261
-
1262
- .flatmap-radio {
1263
- ::v-deep label {
1264
- margin-right: 20px;
1265
- &:last-child {
1266
- margin-right: 0px;
1267
- }
1268
- }
1269
- .el-radio__input {
1270
- &.is-checked {
1271
- & + .el-radio__label {
1272
- color: $app-primary-color;
1273
- }
1274
- .el-radio__inner {
1275
- border-color: $app-primary-color;
1276
- background: $app-primary-color;
1277
- }
1278
- }
1279
- }
1280
- }
1281
- </style>
1282
-
1
+ <template>
2
+ <div
3
+ class="flatmap-container"
4
+ v-loading="loading"
5
+ element-loading-text="Loading..."
6
+ element-loading-spinner="el-icon-loading"
7
+ element-loading-background="rgba(0, 0, 0, 0.3)"
8
+ >
9
+ <map-svg-sprite-color />
10
+ <div style="height:100%;width:100%;position:relative;overflow-y:none">
11
+ <div style="height:100%;width:100%;" ref="display"></div>
12
+ <el-popover
13
+ :content="warningMessage"
14
+ placement="right"
15
+ v-if="displayWarning"
16
+ :appendToBody="false"
17
+ trigger="manual"
18
+ popper-class="warning-popper flatmap-popper right-popper"
19
+ v-model="hoverVisibilities[6].value"
20
+ ref="warningPopover"
21
+ ></el-popover>
22
+ <i
23
+ class="el-icon-warning warning-icon"
24
+ v-if="displayWarning"
25
+ @mouseover="showToolitip(6)"
26
+ @mouseout="hideToolitip(6)"
27
+ v-popover:warningPopover
28
+ >
29
+ <span class="warning-text">Beta</span>
30
+ </i>
31
+ <div class="bottom-right-control">
32
+ <el-popover
33
+ content="Zoom in"
34
+ placement="left"
35
+ :appendToBody="false"
36
+ trigger="manual"
37
+ popper-class="flatmap-popper left-popper"
38
+ v-model="hoverVisibilities[0].value"
39
+ >
40
+ <map-svg-icon
41
+ icon="zoomIn"
42
+ class="icon-button zoomIn"
43
+ slot="reference"
44
+ @click.native="zoomIn()"
45
+ @mouseover.native="showToolitip(0)"
46
+ @mouseout.native="hideToolitip(0)"
47
+ />
48
+ </el-popover>
49
+ <el-popover
50
+ content="Zoom out"
51
+ placement="top-end"
52
+ :appendToBody="false"
53
+ trigger="manual"
54
+ popper-class="flatmap-popper popper-zoomout"
55
+ v-model="hoverVisibilities[1].value"
56
+ >
57
+ <map-svg-icon
58
+ icon="zoomOut"
59
+ class="icon-button zoomOut"
60
+ slot="reference"
61
+ @click.native="zoomOut()"
62
+ @mouseover.native="showToolitip(1)"
63
+ @mouseout.native="hideToolitip(1)"
64
+ />
65
+ </el-popover>
66
+ <el-popover
67
+ content="Reset"
68
+ placement="top"
69
+ :appendToBody="false"
70
+ trigger="manual"
71
+ popper-class="flatmap-popper"
72
+ v-model="hoverVisibilities[2].value"
73
+ >
74
+ <div>
75
+ Fit to
76
+ <br>
77
+ window
78
+ </div>
79
+ <map-svg-icon
80
+ slot="reference"
81
+ icon="fitWindow"
82
+ class="icon-button fitWindow"
83
+ @click.native="resetView()"
84
+ @mouseover.native="showToolitip(2)"
85
+ @mouseout.native="hideToolitip(2)"
86
+ />
87
+ </el-popover>
88
+ </div>
89
+ <el-popover
90
+ content="Change pathway visibility"
91
+ placement="right"
92
+ :appendToBody="false"
93
+ trigger="manual"
94
+ popper-class="flatmap-popper right-popper"
95
+ v-model="hoverVisibilities[4].value"
96
+ ref="checkBoxPopover"
97
+ />
98
+ <div class="pathway-location" :class="{ open: drawerOpen, close: !drawerOpen }">
99
+ <div
100
+ class="pathway-container"
101
+ v-if="pathways.length > 0 && pathControls"
102
+ v-popover:checkBoxPopover
103
+ >
104
+ <el-popover
105
+ content="Find these markers for data"
106
+ placement="right"
107
+ :appendToBody="false"
108
+ trigger="manual"
109
+ popper-class="flatmap-popper popper-bump-right right-popper"
110
+ v-model="hoverVisibilities[5].value"
111
+ ref="markerPopover"
112
+ ></el-popover>
113
+ <div
114
+ v-show="hoverVisibilities[5].value"
115
+ class="flatmap-marker-help"
116
+ v-html="flatmapMarker"
117
+ v-popover:markerPopover
118
+ ></div>
119
+ <el-row>
120
+ <el-col :span="12">
121
+ <div class="pathways-display-text">Pathways</div>
122
+ </el-col>
123
+ <el-col :span="12">
124
+ <el-checkbox
125
+ class="all-checkbox"
126
+ :indeterminate="isIndeterminate"
127
+ v-model="checkAll"
128
+ @change="handleCheckAllChange"
129
+ >Display all</el-checkbox>
130
+ </el-col>
131
+ </el-row>
132
+ <el-checkbox-group
133
+ v-model="checkedItems"
134
+ size="small"
135
+ class="checkbox-group"
136
+ @change="handleCheckedItemsChange"
137
+ >
138
+ <div class="checkbox-group-inner">
139
+ <el-row v-for="item in pathways" :key="item.type" :label="item.type">
140
+ <div class="checkbox-container">
141
+ <el-checkbox
142
+ class="my-checkbox"
143
+ :label="item.type"
144
+ @change="visibilityToggle()"
145
+ :checked="true"
146
+ >
147
+ <div class="path-visual" :class="item.type"></div>
148
+ {{item.label}}
149
+ </el-checkbox>
150
+ </div>
151
+ </el-row>
152
+ </div>
153
+ </el-checkbox-group>
154
+ </div>
155
+ <div
156
+ @click="toggleDrawer"
157
+ class="drawer-button"
158
+ :class="{ open: drawerOpen, close: !drawerOpen }"
159
+ >
160
+ <i class="el-icon-arrow-left"></i>
161
+ </div>
162
+ </div>
163
+ <el-popover
164
+ ref="backgroundPopover"
165
+ placement="top-start"
166
+ width="175"
167
+ :appendToBody="false"
168
+ trigger="click"
169
+ popper-class="background-popper"
170
+ >
171
+ <el-row class="backgroundText">Organs display</el-row>
172
+ <el-row class="backgroundControl">
173
+ <el-radio-group v-model="colourRadio" class="flatmap-radio" @change="setColour">
174
+ <el-radio :label="true">Colour</el-radio>
175
+ <el-radio :label="false">Greyscale</el-radio>
176
+ </el-radio-group>
177
+ </el-row>
178
+ <el-row class="backgroundSpacer"></el-row>
179
+ <el-row class="backgroundText">Outlines display</el-row>
180
+ <el-row class="backgroundControl">
181
+ <el-radio-group v-model="outlinesRadio" class="flatmap-radio" @change="setOutlines">
182
+ <el-radio :label="true">Show</el-radio>
183
+ <el-radio :label="false">Hide</el-radio>
184
+ </el-radio-group>
185
+ </el-row>
186
+ <el-row class="backgroundSpacer"></el-row>
187
+ <el-row class="backgroundText">Change background</el-row>
188
+ <el-row class="backgroundControl">
189
+ <div
190
+ v-for="item in availableBackground"
191
+ :key="item"
192
+ :class="['backgroundChoice', item, item == currentBackground ? 'active' :'']"
193
+ @click="backgroundChangeCallback(item)"
194
+ />
195
+ </el-row>
196
+ </el-popover>
197
+ <el-popover
198
+ content="Change background color"
199
+ placement="right"
200
+ v-model="hoverVisibilities[3].value"
201
+ :appendToBody="false"
202
+ trigger="manual"
203
+ popper-class="flatmap-popper right-popper"
204
+ >
205
+ <map-svg-icon
206
+ v-popover:backgroundPopover
207
+ icon="changeBckgd"
208
+ class="icon-button background-colour"
209
+ :class="{ open: drawerOpen, close: !drawerOpen }"
210
+ slot="reference"
211
+ @mouseover.native="showToolitip(3)"
212
+ @mouseout.native="hideToolitip(3)"
213
+ />
214
+ </el-popover>
215
+ <Tooltip
216
+ ref="tooltip"
217
+ class="tooltip"
218
+ :content="tooltipContent"
219
+ :flatmapAPI="flatmapAPI"
220
+ @resource-selected="resourceSelected"
221
+ />
222
+ </div>
223
+ </div>
224
+ </template>
225
+
226
+ <script>
227
+ /* eslint-disable no-alert, no-console */
228
+ import Vue from "vue";
229
+ import Tooltip from "./Tooltip";
230
+ import { MapSvgIcon, MapSvgSpriteColor } from "@abi-software/svg-sprite";
231
+ import {
232
+ Checkbox,
233
+ CheckboxGroup,
234
+ Col,
235
+ Loading,
236
+ Radio,
237
+ RadioGroup,
238
+ Row
239
+ } from "element-ui";
240
+ import lang from "element-ui/lib/locale/lang/en";
241
+ import locale from "element-ui/lib/locale";
242
+ import flatmapMarker from "../icons/flatmap-marker";
243
+ locale.use(lang);
244
+ Vue.use(Checkbox);
245
+ Vue.use(CheckboxGroup);
246
+ Vue.use(Col);
247
+ Vue.use(Loading.directive);
248
+ Vue.use(Radio);
249
+ Vue.use(RadioGroup);
250
+ Vue.use(Row);
251
+ const ResizeSensor = require("css-element-queries/src/ResizeSensor");
252
+
253
+ const mapResize = map => {
254
+ return () => {
255
+ if (map) map.resize();
256
+ };
257
+ };
258
+
259
+ export default {
260
+ name: "FlatmapVuer",
261
+ components: {
262
+ MapSvgIcon,
263
+ MapSvgSpriteColor,
264
+ Tooltip
265
+ },
266
+ beforeCreate: function() {
267
+ this.mapManager = undefined;
268
+ this.mapImp = undefined;
269
+ },
270
+ methods: {
271
+ backgroundChangeCallback: function(colour) {
272
+ this.currentBackground = colour;
273
+ if (this.mapImp) {
274
+ this.mapImp.setBackgroundColour(this.currentBackground, 1);
275
+ }
276
+ },
277
+ toggleDrawer: function() {
278
+ this.drawerOpen = !this.drawerOpen;
279
+ },
280
+ /**
281
+ * Function to toggle colour/greyscale of organs.
282
+ */
283
+ setColour: function(flag) {
284
+ this.colourRadio = flag;
285
+ if (this.mapImp) {
286
+ this.mapImp.setColour({ colour: flag, outline: this.outlinesRadio });
287
+ }
288
+ },
289
+ /**
290
+ * Function to toggle outlines f organs.
291
+ */
292
+ setOutlines: function(flag) {
293
+ this.outlineRadio = flag;
294
+ if (this.mapImp) {
295
+ this.mapImp.setColour({ colour: this.colourRadio, outline: flag });
296
+ }
297
+ },
298
+ /**
299
+ * Function to toggle paths to default.
300
+ * Also called when the associated button is pressed.
301
+ */
302
+ resetView: function() {
303
+ if (this.mapImp) {
304
+ this.mapImp.resetMap();
305
+ this.checkedItems = this.mapImp.pathTypes().map(item => item.type);
306
+ this.isIndeterminate = false;
307
+ this.checkAll = true;
308
+ }
309
+ },
310
+ /**
311
+ * Function to zoom in.
312
+ * Also called when the associated button is pressed.
313
+ */
314
+ zoomIn: function() {
315
+ if (this.mapImp) {
316
+ this.mapImp.zoomIn();
317
+ }
318
+ },
319
+ /**
320
+ * Function to zoom out.
321
+ * Also called when the associated button is pressed.
322
+ */
323
+ zoomOut: function() {
324
+ if (this.mapImp) {
325
+ this.mapImp.zoomOut();
326
+ }
327
+ },
328
+ visibilityToggle: function() {
329
+ if (this.mapImp) {
330
+ this.mapImp.showPaths(this.checkedItems);
331
+ }
332
+ },
333
+ handleCheckedItemsChange: function(value) {
334
+ let checkedCount = value.length;
335
+ this.checkAll = checkedCount === this.pathways.length;
336
+ this.isIndeterminate =
337
+ checkedCount > 0 && checkedCount < this.pathways.length;
338
+ },
339
+ handleCheckAllChange(val) {
340
+ this.checkedItems = val ? this.pathways.map(a => a.type) : [];
341
+ this.isIndeterminate = false;
342
+ if (this.mapImp) {
343
+ this.mapImp.showPaths(this.checkedItems);
344
+ }
345
+ },
346
+ enablePanZoomEvents: function(flag) {
347
+ this.mapImp.enablePanZoomEvents(flag);
348
+ },
349
+ eventCallback: function() {
350
+ return (eventType, data, ...args) => {
351
+ if (eventType !== "pan-zoom") {
352
+ const label = data.label;
353
+ const resource = [data.models];
354
+ const taxonomy = this.entry;
355
+ const payload = {
356
+ dataset: data.dataset,
357
+ taxonomy: taxonomy,
358
+ resource: resource,
359
+ label: label,
360
+ feature: data,
361
+ userData: args,
362
+ eventType: eventType
363
+ };
364
+ // Disable the nueron pop up for now.
365
+ if (data && data.type !== "marker")
366
+ this.checkAndCreatePopups(data);
367
+ this.$emit("resource-selected", payload);
368
+ } else {
369
+ this.$emit("pan-zoom-callback", data);
370
+ }
371
+ };
372
+ },
373
+ // checkNeuronClicked shows a neuron path pop up if a path was recently clicked
374
+ checkAndCreatePopups: function(data) {
375
+ if (
376
+ data.eventType == "click" &&
377
+ this.createTooltipFromNeuronCuration(data)
378
+ ) {
379
+ this.mapImp.showPopup(
380
+ this.mapImp.modelFeatureIds(data.resource[0])[0],
381
+ this.$refs.tooltip.$el,
382
+ { className: "flatmap-tooltip-dialog" }
383
+ );
384
+ this.popUpCssHack();
385
+ }
386
+ },
387
+ popUpCssHack: function() {
388
+ // Below is a hack to remove flatmap tooltips while popup is open
389
+ let ftooltip = document.querySelector(".flatmap-tooltip-popup");
390
+ if (ftooltip) ftooltip.style.display = "none";
391
+ document.querySelector(".mapboxgl-popup-close-button").style.display =
392
+ "block";
393
+ this.$refs.tooltip.$el.style.display = "flex";
394
+ document.querySelector(".mapboxgl-popup-close-button").onclick = () => {
395
+ document.querySelector(".flatmap-tooltip-popup").style.display =
396
+ "block";
397
+ };
398
+ },
399
+ resourceSelected: function(action) {
400
+ this.$emit("resource-selected", action);
401
+ },
402
+ createTooltipFromNeuronCuration: function(data) {
403
+ const feature = data.resource[0];
404
+ let content = {
405
+ title: undefined,
406
+ components: undefined,
407
+ start: undefined,
408
+ distribution: undefined,
409
+ actions: []
410
+ };
411
+
412
+ let foundAnnotations = false;
413
+ this.tooltipVisible = false;
414
+
415
+ // neural data check
416
+ if (feature) {
417
+ if (feature.includes("ilxtr:neuron")) {
418
+ foundAnnotations = true;
419
+ this.tooltipVisible = true;
420
+ this.tooltipContent = content;
421
+ this.tooltipContent.uberon = feature;
422
+ this.tooltipContent.title = data.label;
423
+ this.tooltipContent.featureId = feature;
424
+ this.tooltipContent.actions.push({
425
+ title: "Search for dataset",
426
+ label: "Neuron Datasets",
427
+ resource: feature.split(":")[1],
428
+ type: "Neuron Search",
429
+ nervePath: true
430
+ });
431
+ }
432
+ }
433
+ // annotated with datset check
434
+ if (data.dataset) {
435
+ foundAnnotations = true;
436
+ this.tooltipVisible = true;
437
+ this.tooltipContent = content;
438
+ this.tooltipContent.uberon = feature;
439
+ this.tooltipContent.title = data.label;
440
+ this.tooltipContent.actions.push({
441
+ title: "View dataset",
442
+ resource: data.dataset,
443
+ type: "URL",
444
+ nervePath: false
445
+ });
446
+ }
447
+
448
+ if (foundAnnotations) {
449
+ return true;
450
+ } else {
451
+ return false;
452
+ }
453
+ },
454
+ // Keeping this as an API
455
+ showPopup: function(featureId, node, options) {
456
+ let myOptions = options;
457
+ if (this.mapImp) {
458
+ if (myOptions) {
459
+ if (!myOptions.className) myOptions.className = "flatmapvuer-popover";
460
+ } else {
461
+ myOptions = { className: "flatmapvuer-popover" };
462
+ }
463
+ this.mapImp.showPopup(featureId, node, myOptions);
464
+ }
465
+ },
466
+ showMarkerPopup: function(featureId, node, options) {
467
+ if (this.mapImp) {
468
+ this.mapImp.showMarkerPopup(featureId, node, options);
469
+ }
470
+ },
471
+ setHelpMode: function(helpMode) {
472
+ if (helpMode) {
473
+ this.inHelp = true;
474
+ this.hoverVisibilities.forEach(item => {
475
+ item.value = true;
476
+ });
477
+ this.openFlatmapHelpPopup();
478
+ } else {
479
+ this.inHelp = false;
480
+ this.hoverVisibilities.forEach(item => {
481
+ item.value = false;
482
+ });
483
+ this.closeFlatmapHelpPopup();
484
+ }
485
+ },
486
+ showToolitip: function(tooltipNumber) {
487
+ if (!this.inHelp) {
488
+ this.tooltipWait = setTimeout(() => {
489
+ this.hoverVisibilities[tooltipNumber].value = true;
490
+ }, 500);
491
+ }
492
+ },
493
+ hideToolitip: function(tooltipNumber) {
494
+ if (!this.inHelp) {
495
+ this.hoverVisibilities[tooltipNumber].value = false;
496
+ clearTimeout(this.tooltipWait);
497
+ }
498
+ },
499
+ openFlatmapHelpPopup: function() {
500
+ if (this.mapImp) {
501
+ let heartId = this.mapImp.featureIdsForModel("UBERON:0000948")[0];
502
+ const elm = "Click for more information";
503
+ this.mapImp.showPopup(heartId, elm, {
504
+ anchor: "top",
505
+ className: "flatmap-popup-popper"
506
+ });
507
+ }
508
+ },
509
+ closeFlatmapHelpPopup: function() {
510
+ this.$el
511
+ .querySelectorAll(".mapboxgl-popup-close-button")
512
+ .forEach(item => {
513
+ item.click();
514
+ });
515
+ },
516
+ getLabels: function() {
517
+ let labels = [];
518
+ if (this.mapImp) {
519
+ let annotations = this.mapImp.annotations;
520
+ for (let value of annotations.values()) {
521
+ if (value.label) labels.push(value.label);
522
+ }
523
+ return Array.from(new Set(labels));
524
+ }
525
+ },
526
+ getState: function() {
527
+ if (this.mapImp) {
528
+ let state = {
529
+ entry: this.entry,
530
+ viewport: this.mapImp.getState()
531
+ };
532
+ return state;
533
+ }
534
+ return undefined;
535
+ },
536
+ setState: function(state) {
537
+ if (state) {
538
+ if (this.mapImp && state.entry) {
539
+ if (this.entry == state.entry)
540
+ if (state.viewport) {
541
+ this.mapImp.setState(state.viewport);
542
+ }
543
+ } else {
544
+ this.createFlatmap(state);
545
+ }
546
+ }
547
+ },
548
+ createFlatmap: function(state) {
549
+ if (!this.mapImp && !this.loading) {
550
+ this.loading = true;
551
+ let minimap = false;
552
+ if (this.displayMinimap) {
553
+ minimap = { position: "top-right" };
554
+ }
555
+ let entry = this.entry;
556
+ if (state && state.entry) entry = state.entry;
557
+ let promise1 = this.mapManager.loadMap(
558
+ entry,
559
+ this.$refs.display,
560
+ this.eventCallback(),
561
+ {
562
+ //fullscreenControl: false,
563
+ //annotatable: false,
564
+ //debug: true,
565
+ featureInfo: this.featureInfo,
566
+ "min-zoom": this.minZoom,
567
+ pathControls: false,
568
+ searchable: this.searchable,
569
+ tooltips: this.tooltips,
570
+ minimap: minimap
571
+ }
572
+ );
573
+ promise1.then(returnedObject => {
574
+ this.mapImp = returnedObject;
575
+ this.sensor = new ResizeSensor(
576
+ this.$refs.display,
577
+ mapResize(this.mapImp)
578
+ );
579
+ this.mapImp.setBackgroundOpacity(1);
580
+ this.backgroundChangeCallback(this.currentBackground);
581
+ this.pathways = this.mapImp.pathTypes();
582
+ this.$emit("ready", this);
583
+ this.loading = false;
584
+ if (this._viewportToBeSet)
585
+ this.mapImp.setState(this._viewportToBeSet);
586
+ else if (state && state.viewport)
587
+ this.mapImp.setState(state.viewport);
588
+ });
589
+ } else if (state) {
590
+ if (this.entry == state.entry) this._viewportToBeSet = state.viewport;
591
+ }
592
+ },
593
+ showMinimap: function(flag) {
594
+ if (this.mapImp)
595
+ this.mapImp.showMinimap(flag);
596
+ },
597
+ showPathwaysDrawer: function(flag) {
598
+ this.drawerOpen = flag;
599
+ },
600
+ /**
601
+ * Function to display features with annotation matching the provided term.
602
+ */
603
+ searchAndShowResult: function(term) {
604
+ if (this.mapImp) {
605
+ if (term === undefined || term === "") {
606
+ this.mapImp.clearSearchResults();
607
+ } else {
608
+ let searchResults = this.mapImp.search(term);
609
+ if (searchResults && searchResults.__featureIds.length > 0)
610
+ this.mapImp.showSearchResults(searchResults);
611
+ else this.mapImp.clearSearchResults();
612
+ }
613
+ }
614
+ }
615
+ },
616
+ props: {
617
+ entry: String,
618
+ featureInfo: {
619
+ type: Boolean,
620
+ default: false
621
+ },
622
+ minZoom: {
623
+ type: Number,
624
+ default: 4
625
+ },
626
+ pathControls: {
627
+ type: Boolean,
628
+ default: true
629
+ },
630
+ searchable: {
631
+ type: Boolean,
632
+ default: false
633
+ },
634
+ tooltips: {
635
+ type: Boolean,
636
+ default: true
637
+ },
638
+ helpMode: {
639
+ type: Boolean,
640
+ default: false
641
+ },
642
+ renderAtMounted: {
643
+ type: Boolean,
644
+ default: true
645
+ },
646
+ displayWarning: {
647
+ type: Boolean,
648
+ default: true
649
+ },
650
+ displayMinimap: {
651
+ type: Boolean,
652
+ default: false
653
+ },
654
+ warningMessage: {
655
+ type: String,
656
+ default: "Beta feature - This map is based on the connectivity of a rat. New connectivity and species specificity will be added as the SPARC program progress."
657
+ },
658
+ /**
659
+ * State containing state of the flatmap.
660
+ */
661
+ state: {
662
+ type: Object,
663
+ default: undefined
664
+ },
665
+ /**
666
+ * Specify the endpoint of the flatmap server.
667
+ */
668
+ flatmapAPI: {
669
+ type: String,
670
+ default: "https://mapcore-demo.org/flatmaps/"
671
+ }
672
+ },
673
+ data: function() {
674
+ return {
675
+ checkedItems: [],
676
+ pathways: [],
677
+ isIndeterminate: false,
678
+ checkAll: true,
679
+ hoverVisibilities: [
680
+ { value: false },
681
+ { value: false },
682
+ { value: false },
683
+ { value: false },
684
+ { value: false },
685
+ { value: false },
686
+ { value: false }
687
+ ],
688
+ inHelp: false,
689
+ currentBackground: "white",
690
+ availableBackground: ["white", "lightskyblue", "black"],
691
+ loading: false,
692
+ flatmapMarker: flatmapMarker,
693
+ drawerOpen: true,
694
+ tooltipContent: {},
695
+ colourRadio: true,
696
+ outlinesRadio: true
697
+ };
698
+ },
699
+ watch: {
700
+ entry: function() {
701
+ if (!this.state) this.createFlatmap();
702
+ },
703
+ helpMode: function(val) {
704
+ this.setHelpMode(val);
705
+ },
706
+ state: {
707
+ handler: function(state) {
708
+ this.setState(state);
709
+ },
710
+ immediate: true,
711
+ deep: true
712
+ }
713
+ },
714
+ mounted: function() {
715
+ const flatmap = require("@abi-software/flatmap-viewer");
716
+ this.mapManager = new flatmap.MapManager(this.flatmapAPI);
717
+ if (this.renderAtMounted) this.createFlatmap();
718
+ }
719
+ };
720
+ </script>
721
+
722
+ <!-- Add "scoped" attribute to limit CSS to this component only -->
723
+ <style scoped lang="scss">
724
+ @import "~element-ui/packages/theme-chalk/src/button";
725
+ @import "~element-ui/packages/theme-chalk/src/checkbox";
726
+ @import "~element-ui/packages/theme-chalk/src/checkbox-group";
727
+ @import "~element-ui/packages/theme-chalk/src/loading";
728
+ @import "~element-ui/packages/theme-chalk/src/row";
729
+
730
+ .warning-icon {
731
+ position: absolute;
732
+ top: 90px;
733
+ left: 37px;
734
+ text-align: left;
735
+ font-size: 25px;
736
+ color: $warning;
737
+
738
+ &:hover {
739
+ cursor: pointer;
740
+ }
741
+ }
742
+
743
+ .warning-text {
744
+ font-size: 15px;
745
+ vertical-align: 5px;
746
+ }
747
+
748
+ .path-visual {
749
+ margin: 3px 0;
750
+ height: 3px;
751
+ width: 25px;
752
+ margin-right: 5px;
753
+ display: inline-block;
754
+ &.cns {
755
+ background: #9b1fc1;
756
+ }
757
+ &.lcn {
758
+ background: #f19e38;
759
+ }
760
+ &.para-pre {
761
+ background: #3f8f4a;
762
+ }
763
+ &.para-post {
764
+ background: repeating-linear-gradient(
765
+ 90deg,
766
+ #3f8f4a,
767
+ #3f8f4a 6px,
768
+ transparent 0,
769
+ transparent 9px
770
+ );
771
+ }
772
+ &.sensory {
773
+ background: #2a62f6;
774
+ }
775
+ &.somatic {
776
+ background: #98561d;
777
+ }
778
+ &.symp-pre {
779
+ background: #ea3423;
780
+ }
781
+ &.symp-post {
782
+ background: repeating-linear-gradient(
783
+ 90deg,
784
+ #ea3423,
785
+ #ea3423 6px,
786
+ transparent 0,
787
+ transparent 9px
788
+ );
789
+ }
790
+ }
791
+
792
+ .flatmap-container {
793
+ height: 100%;
794
+ width: 100%;
795
+ }
796
+
797
+ .pathway-location {
798
+ position: absolute;
799
+ bottom: 0px;
800
+ transition: all 1s ease;
801
+ &.open {
802
+ left: 0px;
803
+ }
804
+ &.close {
805
+ left: -298px;
806
+ }
807
+ }
808
+
809
+ .pathway-container {
810
+ float: left;
811
+ padding-left: 16px;
812
+ padding-right: 18px;
813
+ max-height: calc(100% - 184px);
814
+ text-align: left;
815
+ overflow: auto;
816
+ border: 1px solid rgb(220, 223, 230);
817
+ padding-top: 7px;
818
+ padding-bottom: 16px;
819
+ background: #ffffff;
820
+ }
821
+
822
+ .pathways-display-text {
823
+ width: 59px;
824
+ height: 20px;
825
+ color: rgb(48, 49, 51);
826
+ font-size: 14px;
827
+ font-weight: normal;
828
+ line-height: 20px;
829
+ margin-left: 8px;
830
+ }
831
+
832
+ .all-checkbox {
833
+ float: right;
834
+ }
835
+
836
+ .checkbox-container {
837
+ display: flex;
838
+ cursor: pointer;
839
+ }
840
+
841
+ .checkbox-group {
842
+ width: 260px;
843
+ border: 1px solid rgb(144, 147, 153);
844
+ border-radius: 4px;
845
+ background: #ffffff;
846
+ }
847
+
848
+ .my-checkbox {
849
+ background-color: #fff;
850
+ width: 100%;
851
+ }
852
+
853
+ .checkbox-group-inner {
854
+ padding: 18px;
855
+ }
856
+
857
+ .flatmap-marker-help {
858
+ display: inline-block;
859
+ }
860
+
861
+ ::v-deep .popper-bump-right {
862
+ left: 30px;
863
+ }
864
+
865
+ ::v-deep .el-checkbox__label {
866
+ padding-left: 5px;
867
+ color: $app-primary-color;
868
+ font-size: 12px;
869
+ font-weight: 500;
870
+ letter-spacing: 0px;
871
+ line-height: 14px;
872
+ }
873
+
874
+ ::v-deep .el-checkbox__input {
875
+ &.is-indeterminate,
876
+ &.is-checked {
877
+ .el-checkbox__inner {
878
+ background-color: $app-primary-color;
879
+ border-color: $app-primary-color;
880
+ }
881
+ }
882
+ }
883
+
884
+ ::v-deep .el-checkbox__label {
885
+ color: $app-primary-color !important;
886
+ }
887
+
888
+ .el-dropdown-link {
889
+ cursor: pointer;
890
+ color: #409eff;
891
+ }
892
+ .el-icon-arrow-down {
893
+ font-size: 12px;
894
+ }
895
+ .demonstration {
896
+ display: block;
897
+ color: #8492a6;
898
+ font-size: 14px;
899
+ margin-bottom: 20px;
900
+ }
901
+
902
+ .tooltip {
903
+ display: none;
904
+ }
905
+
906
+ ::v-deep .mapboxgl-popup {
907
+ max-width: 300px !important;
908
+ }
909
+
910
+ ::v-deep .flatmap-tooltip-popup {
911
+ &.mapboxgl-popup-anchor-bottom {
912
+ .mapboxgl-popup-content {
913
+ margin-bottom: 12px;
914
+ &::after,
915
+ &::before {
916
+ top: 100%;
917
+ border-width: 12px;
918
+ }
919
+ /* this border color controlls the color of the triangle (what looks like the fill of the triangle) */
920
+ &::after {
921
+ margin-top: -1px;
922
+ border-color: rgb(255, 255, 255) transparent transparent transparent;
923
+ }
924
+ /* this border color controlls the outside, thin border */
925
+ &::before {
926
+ margin: 0 auto;
927
+ border-color: $app-primary-color transparent transparent transparent;
928
+ }
929
+ }
930
+ }
931
+ &.mapboxgl-popup-anchor-top {
932
+ .mapboxgl-popup-content {
933
+ margin-top: 18px;
934
+ &::after,
935
+ &::before {
936
+ top: calc(-100% + 6px);
937
+ border-width: 12px;
938
+ }
939
+ /* this border color controlls the color of the triangle (what looks like the fill of the triangle) */
940
+ &::after {
941
+ margin-top: 1px;
942
+ border-color: transparent transparent rgb(255, 255, 255) transparent;
943
+ }
944
+ &::before {
945
+ margin: 0 auto;
946
+ border-color: transparent transparent $app-primary-color transparent;
947
+ }
948
+ }
949
+ }
950
+ .mapboxgl-popup-content {
951
+ border-radius: 4px;
952
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
953
+ pointer-events: none;
954
+ display: none;
955
+ background: #fff;
956
+ border: 1px solid $app-primary-color;
957
+ padding-left: 6px;
958
+ padding-right: 6px;
959
+ display: flex;
960
+ justify-content: center;
961
+ align-items: center;
962
+ &::after,
963
+ &::before {
964
+ content: "";
965
+ display: block;
966
+ position: absolute;
967
+ width: 0;
968
+ height: 0;
969
+ border-style: solid;
970
+ flex-shrink: 0;
971
+ }
972
+ }
973
+ .mapboxgl-popup-tip {
974
+ display: none;
975
+ }
976
+ }
977
+
978
+ ::v-deep .mapboxgl-popup {
979
+ &.flatmap-marker-popup {
980
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
981
+ pointer-events: auto;
982
+ background: #fff;
983
+ }
984
+ }
985
+
986
+ /* Fix for chrome bug where under triangle pops up above one on top of it */
987
+ .selector:not(*:root),
988
+ ::v-deep.flatmap-tooltip-popup {
989
+ .mapboxgl-popup-content::after {
990
+ top: 99.9%;
991
+ }
992
+ }
993
+
994
+ ::v-deep .flatmap-tooltip-dialog {
995
+ .mapboxgl-popup-tip {
996
+ display: none;
997
+ }
998
+ }
999
+
1000
+ ::v-deep .flatmap-marker-popup {
1001
+ .mapboxgl-popup-content {
1002
+ padding: 0px;
1003
+ }
1004
+ }
1005
+
1006
+ ::v-deep .flatmapvuer-popover {
1007
+ .mapboxgl-popup-close-button {
1008
+ position: absolute;
1009
+ right: 0.5em;
1010
+ top: 0;
1011
+ border: 0;
1012
+ border-radius: 0 3px 0 0;
1013
+ cursor: pointer;
1014
+ background-color: transparent;
1015
+ font-size: 2.5em;
1016
+ color: grey;
1017
+ top: 0.95em;
1018
+ }
1019
+ }
1020
+
1021
+ .zoomOut {
1022
+ padding-left: 8px;
1023
+ }
1024
+
1025
+ .fitWindow {
1026
+ padding-left: 8px;
1027
+ }
1028
+
1029
+ .background-colour {
1030
+ bottom: 16px;
1031
+ position: absolute;
1032
+ transition: all 1s ease;
1033
+ }
1034
+ .background-colour.open {
1035
+ left: 322px;
1036
+ }
1037
+ .background-colour.close {
1038
+ left: 24px;
1039
+ }
1040
+
1041
+ ::v-deep .background-popper {
1042
+ padding: 5px 12px;
1043
+ background-color: #ffffff;
1044
+ border: 1px solid $app-primary-color;
1045
+ box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.06);
1046
+ height: 200px;
1047
+ width: 175px;
1048
+ min-width: 175px;
1049
+ &.el-popper[x-placement^="top"] {
1050
+ .popper__arrow {
1051
+ border-top-color: $app-primary-color !important;
1052
+ &::after {
1053
+ border-top-color: #fff !important;
1054
+ }
1055
+ }
1056
+ }
1057
+ }
1058
+
1059
+ .backgroundText {
1060
+ color: rgb(48, 49, 51);
1061
+ font-size: 14px;
1062
+ font-weight: normal;
1063
+ line-height: 20px;
1064
+ }
1065
+
1066
+ .backgroundControl {
1067
+ display: flex;
1068
+ margin-top: 16px;
1069
+ }
1070
+
1071
+ .backgroundChoice {
1072
+ width: 20px;
1073
+ height: 20px;
1074
+ border: 1px solid rgb(144, 147, 153);
1075
+ margin-left: 20px;
1076
+ &.active {
1077
+ border: 2px solid $app-primary-color;
1078
+ }
1079
+ &:hover {
1080
+ cursor: pointer;
1081
+ }
1082
+ &.white {
1083
+ background-color: white;
1084
+ margin-left: 10px;
1085
+ }
1086
+ &.black {
1087
+ background-color: black;
1088
+ }
1089
+ &.lightskyblue {
1090
+ background-color: white;
1091
+ }
1092
+ }
1093
+
1094
+ .togglePaths {
1095
+ top: 201px;
1096
+ right: 20px;
1097
+ position: absolute;
1098
+ }
1099
+
1100
+ .icon-button {
1101
+ height: 24px !important;
1102
+ width: 24px !important;
1103
+ color: $app-primary-color;
1104
+ &:hover {
1105
+ cursor: pointer;
1106
+ }
1107
+ }
1108
+
1109
+ ::v-deep .flatmap-popper {
1110
+ padding: 6px 4px;
1111
+ font-size: 12px;
1112
+ color: rgb(48, 49, 51);
1113
+ background-color: #f3ecf6;
1114
+ border: 1px solid $app-primary-color;
1115
+ white-space: nowrap;
1116
+ min-width: unset;
1117
+ &.warning-popper {
1118
+ min-width: 150px;
1119
+ max-width: 400px;
1120
+ word-break: keep-all;
1121
+ white-space: unset;
1122
+ }
1123
+ &.left-popper {
1124
+ .popper__arrow {
1125
+ border-left-color: $app-primary-color !important;
1126
+ &::after {
1127
+ border-left-color: #f3ecf6 !important;
1128
+ }
1129
+ }
1130
+ }
1131
+ &.right-popper {
1132
+ .popper__arrow {
1133
+ border-right-color: $app-primary-color !important;
1134
+ &:after {
1135
+ border-right-color: #f3ecf6 !important;
1136
+ }
1137
+ }
1138
+ }
1139
+ &.el-popper[x-placement^="top"] {
1140
+ .popper__arrow {
1141
+ border-top-color: $app-primary-color !important;
1142
+ &:after {
1143
+ border-top-color: #f3ecf6 !important;
1144
+ }
1145
+ }
1146
+ }
1147
+ }
1148
+
1149
+ ::v-deep .el-loading-spinner {
1150
+ i,
1151
+ .el-loading-text {
1152
+ color: $app-primary-color;
1153
+ }
1154
+ }
1155
+
1156
+ ::v-deep .flatmap-popup-popper {
1157
+ .mapboxgl-popup-tip {
1158
+ border-bottom-color: $app-primary-color;
1159
+ }
1160
+ .mapboxgl-popup-content {
1161
+ padding: 6px 4px;
1162
+ font-size: 12px;
1163
+ color: rgb(48, 49, 51);
1164
+ background-color: #f3ecf6;
1165
+ border: 1px solid $app-primary-color;
1166
+ white-space: nowrap;
1167
+ min-width: unset;
1168
+ .mapboxgl-popup-close-button {
1169
+ display: none;
1170
+ }
1171
+ }
1172
+ }
1173
+
1174
+ ::v-deep .flatmap-popper {
1175
+
1176
+ }
1177
+
1178
+ ::v-deep .popper-zoomout {
1179
+ padding-right: 13px !important;
1180
+ left: -21px !important;
1181
+ }
1182
+
1183
+ ::v-deep .popper-zoomout {
1184
+ .popper__arrow {
1185
+ left: 53px !important;
1186
+ }
1187
+ }
1188
+
1189
+ ::v-deep .mapboxgl-popup-content {
1190
+ padding: 0px;
1191
+ }
1192
+
1193
+ .bottom-right-control {
1194
+ position: absolute;
1195
+ right: 16px;
1196
+ bottom: 16px;
1197
+ }
1198
+
1199
+ ::v-deep .my-drawer {
1200
+ background: rgba(0, 0, 0, 0);
1201
+ box-shadow: none;
1202
+ }
1203
+
1204
+ .drawer {
1205
+ ::v-deep .el-drawer:focus {
1206
+ outline: none;
1207
+ }
1208
+ }
1209
+
1210
+ .open-drawer,
1211
+ .drawer-button {
1212
+ z-index: 8;
1213
+ width: 20px;
1214
+ height: 40px;
1215
+ border: solid 1px #e4e7ed;
1216
+ text-align: center;
1217
+ vertical-align: middle;
1218
+ cursor: pointer;
1219
+ pointer-events: auto;
1220
+ }
1221
+
1222
+ .open-drawer {
1223
+ position: absolute;
1224
+ left: 0px;
1225
+ background-color: #f7faff;
1226
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
1227
+ }
1228
+
1229
+ .drawer-button {
1230
+ float: left;
1231
+ margin-top: calc(50% - 36px);
1232
+ border-left: 0;
1233
+ background-color: #ffffff;
1234
+ i {
1235
+ margin-top: 12px;
1236
+ color: $app-primary-color;
1237
+ transition-delay: 0.9s;
1238
+ }
1239
+ &.open {
1240
+ i {
1241
+ transform: rotate(0deg) scaleY(2.5);
1242
+ }
1243
+ }
1244
+ &.close {
1245
+ i {
1246
+ transform: rotate(180deg) scaleY(2.5);
1247
+ }
1248
+ }
1249
+ }
1250
+
1251
+ ::v-deep .mapboxgl-canvas-container {
1252
+ canvas {
1253
+ outline: none;
1254
+ }
1255
+ }
1256
+
1257
+ .backgroundSpacer {
1258
+ border-bottom: 1px solid #e4e7ed;
1259
+ margin-bottom: 10px;
1260
+ }
1261
+
1262
+ .flatmap-radio {
1263
+ ::v-deep label {
1264
+ margin-right: 20px;
1265
+ &:last-child {
1266
+ margin-right: 0px;
1267
+ }
1268
+ }
1269
+ .el-radio__input {
1270
+ &.is-checked {
1271
+ & + .el-radio__label {
1272
+ color: $app-primary-color;
1273
+ }
1274
+ .el-radio__inner {
1275
+ border-color: $app-primary-color;
1276
+ background: $app-primary-color;
1277
+ }
1278
+ }
1279
+ }
1280
+ }
1281
+ </style>
1282
+