@abi-software/flatmapvuer 0.3.3 → 0.3.5

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