@abi-software/flatmapvuer 0.2.4-beta-4 → 0.2.4-dynamic-1

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