@tekkare/auriga 0.2.227 → 0.2.231
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/runtime/components/argMapsPortugal.vue +265 -0
- package/dist/runtime/components/argMapsPortugal.vue.d.ts +120 -0
- package/dist/runtime/components/argMapsPortugalRegions.vue +265 -0
- package/dist/runtime/components/argMapsPortugalRegions.vue.d.ts +120 -0
- package/dist/runtime/components/argSteplineChart.vue +8 -1
- package/dist/runtime/components/argSteplineChart.vue.d.ts +9 -0
- package/dist/runtime/components/maps/interfaces.d.ts +31 -0
- package/dist/runtime/components/maps/interfaces.mjs +33 -0
- package/dist/runtime/components/maps/regionsPathPt.json +82 -0
- package/dist/runtime/components/maps/regionsPathPtNuts.json +30 -0
- package/dist/runtime/components/oneRegionPt.vue +62 -0
- package/dist/runtime/components/oneRegionPt.vue.d.ts +54 -0
- package/dist/runtime/components/oneRegionPtNuts.vue +62 -0
- package/dist/runtime/components/oneRegionPtNuts.vue.d.ts +54 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="oip_table_card map_card-container"
|
|
4
|
+
:id="`container_map-${title}-${uniqueID}`"
|
|
5
|
+
>
|
|
6
|
+
<div class="p-24">
|
|
7
|
+
<slot name="customTitle" v-if="haveCustomTitle" />
|
|
8
|
+
<div v-else class="oip_subtitle">
|
|
9
|
+
{{ title ? title : "Your map title" }}
|
|
10
|
+
</div>
|
|
11
|
+
<ArgSourceContainer v-if="source !== null" @click="openSource">
|
|
12
|
+
{{ source ? source : "Your source" }}
|
|
13
|
+
</ArgSourceContainer>
|
|
14
|
+
</div>
|
|
15
|
+
<div
|
|
16
|
+
v-if="hoveredRegion !== null"
|
|
17
|
+
:id="`tooltip_map-${title}`"
|
|
18
|
+
class="tooltip_container"
|
|
19
|
+
:style="{
|
|
20
|
+
top: tooltipPosition.y + 'px',
|
|
21
|
+
left: tooltipPosition.x + 'px',
|
|
22
|
+
width: tooltipPosition.width + 'px',
|
|
23
|
+
}"
|
|
24
|
+
>
|
|
25
|
+
<div class="tooltip">
|
|
26
|
+
<p class="card_title">{{ hoveredRegion }}</p>
|
|
27
|
+
<div class="card_text">
|
|
28
|
+
<slot
|
|
29
|
+
name="Tooltip"
|
|
30
|
+
v-bind:value="{
|
|
31
|
+
name: hoveredRegion,
|
|
32
|
+
value: data.find((x) => x.name == hoveredRegion)?.value,
|
|
33
|
+
}"
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="p24">
|
|
39
|
+
<svg
|
|
40
|
+
class="map"
|
|
41
|
+
height="500"
|
|
42
|
+
:viewBox="hideIslands ? '160 0 410 800' : '0 0 570 800'"
|
|
43
|
+
preserveAspectRatio="xMidYMid meet"
|
|
44
|
+
fill="none"
|
|
45
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
46
|
+
>
|
|
47
|
+
<!-- Madeira and the Azores lie about 1000 km off the mainland: each is
|
|
48
|
+
drawn at its own scale as an inset against the west coast, the way
|
|
49
|
+
the France map places its DROM-TOM. The frames tell the reader they
|
|
50
|
+
are not to scale; `hideIslands` crops them out entirely. -->
|
|
51
|
+
<g v-if="!hideIslands" class="inset">
|
|
52
|
+
<rect x="4" y="288" width="166" height="102" rx="4" />
|
|
53
|
+
<text x="8" y="282">Azores</text>
|
|
54
|
+
<rect x="14" y="417" width="134" height="117" rx="4" />
|
|
55
|
+
<text x="18" y="411">Madeira</text>
|
|
56
|
+
</g>
|
|
57
|
+
<OneRegionPt
|
|
58
|
+
v-for="region in displayedRegions"
|
|
59
|
+
:key="region"
|
|
60
|
+
:data="{
|
|
61
|
+
color: getColor(data.find((x) => x.name == region)?.value),
|
|
62
|
+
value: data.find((x) => x.name == region)?.value,
|
|
63
|
+
}"
|
|
64
|
+
:current-region="region"
|
|
65
|
+
:title="title"
|
|
66
|
+
:hoveredRegion="hoveredRegion"
|
|
67
|
+
@hover="handleHover(region)"
|
|
68
|
+
@mouseleave="handleMouseLeave"
|
|
69
|
+
/>
|
|
70
|
+
</svg>
|
|
71
|
+
<div class="legend">
|
|
72
|
+
<div :class="reverseColors ? 'reverse_scale' : 'scale'" />
|
|
73
|
+
<div class="legend-text">
|
|
74
|
+
<template v-for="(value, index) in scale" :key="value">
|
|
75
|
+
<p v-if="index % 2 === 0">
|
|
76
|
+
{{ Math.ceil(value)?.toLocaleString("fr-FR") }}
|
|
77
|
+
</p>
|
|
78
|
+
</template>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
<slot name="Subcontent" />
|
|
83
|
+
</div>
|
|
84
|
+
</template>
|
|
85
|
+
|
|
86
|
+
<script>
|
|
87
|
+
import { computed, onMounted, ref, watch, defineComponent, nextTick } from "vue";
|
|
88
|
+
import { RegionsPt } from "./maps/interfaces";
|
|
89
|
+
import ArgSourceContainer from "./argSourceContainer.vue";
|
|
90
|
+
import OneRegionPt from "./oneRegionPt.vue";
|
|
91
|
+
export default defineComponent({
|
|
92
|
+
name: "argMapsPortugal",
|
|
93
|
+
components: { OneRegionPt, ArgSourceContainer },
|
|
94
|
+
props: {
|
|
95
|
+
data: {
|
|
96
|
+
type: Array,
|
|
97
|
+
default: null,
|
|
98
|
+
required: true
|
|
99
|
+
},
|
|
100
|
+
title: {
|
|
101
|
+
type: [String, null],
|
|
102
|
+
default: null,
|
|
103
|
+
required: false
|
|
104
|
+
},
|
|
105
|
+
source: {
|
|
106
|
+
type: [String, null],
|
|
107
|
+
default: null
|
|
108
|
+
},
|
|
109
|
+
haveCustomTitle: {
|
|
110
|
+
type: [String, null],
|
|
111
|
+
default: null,
|
|
112
|
+
required: false
|
|
113
|
+
},
|
|
114
|
+
uniqueID: {
|
|
115
|
+
type: [String, null],
|
|
116
|
+
default: null,
|
|
117
|
+
required: false
|
|
118
|
+
},
|
|
119
|
+
lang: {
|
|
120
|
+
type: String,
|
|
121
|
+
default: "en",
|
|
122
|
+
required: false
|
|
123
|
+
},
|
|
124
|
+
reverseColors: {
|
|
125
|
+
type: Boolean,
|
|
126
|
+
default: false
|
|
127
|
+
},
|
|
128
|
+
// drop Madeira and the Azores and crop to the mainland — for data that only
|
|
129
|
+
// covers continental Portugal (same idea as argMapsFrRegions' hideDromTom)
|
|
130
|
+
hideIslands: {
|
|
131
|
+
type: Boolean,
|
|
132
|
+
default: false
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
emits: ["openSource"],
|
|
136
|
+
setup(props, { emit }) {
|
|
137
|
+
const islandRegions = [RegionsPt.Azores, RegionsPt.Madeira];
|
|
138
|
+
const displayedRegions = computed(
|
|
139
|
+
() => Object.values(RegionsPt).filter(
|
|
140
|
+
(region) => !props.hideIslands || !islandRegions.includes(region)
|
|
141
|
+
)
|
|
142
|
+
);
|
|
143
|
+
const minimalValue = ref(null);
|
|
144
|
+
const maximalValue = ref(null);
|
|
145
|
+
const hoveredRegion = ref(null);
|
|
146
|
+
const tooltipPosition = ref({ x: 0, y: 0, width: 0 });
|
|
147
|
+
const scale = ref([]);
|
|
148
|
+
function getColor(value) {
|
|
149
|
+
if (!value) return "var(--lightest)";
|
|
150
|
+
if (props.reverseColors ? value <= scale.value[0] : value >= scale.value[9]) {
|
|
151
|
+
return "#3F1151";
|
|
152
|
+
} else if (props.reverseColors ? value <= scale.value[1] : value >= scale.value[8]) {
|
|
153
|
+
return "#432974";
|
|
154
|
+
} else if (props.reverseColors ? value <= scale.value[2] : value >= scale.value[7]) {
|
|
155
|
+
return "#404A85";
|
|
156
|
+
} else if (props.reverseColors ? value <= scale.value[3] : value >= scale.value[6]) {
|
|
157
|
+
return "#3F668A";
|
|
158
|
+
} else if (props.reverseColors ? value <= scale.value[4] : value >= scale.value[5]) {
|
|
159
|
+
return "#43808C";
|
|
160
|
+
} else if (props.reverseColors ? value <= scale.value[5] : value >= scale.value[4]) {
|
|
161
|
+
return "#4C9C8A";
|
|
162
|
+
} else if (props.reverseColors ? value <= scale.value[6] : value >= scale.value[3]) {
|
|
163
|
+
return "#5FB57E";
|
|
164
|
+
} else if (props.reverseColors ? value <= scale.value[7] : value >= scale.value[2]) {
|
|
165
|
+
return "#85CB68";
|
|
166
|
+
} else if (props.reverseColors ? value <= scale.value[8] : value >= scale.value[1]) {
|
|
167
|
+
return "#BDDD51";
|
|
168
|
+
} else if (props.reverseColors ? value > scale.value[8] : value >= scale.value[0]) {
|
|
169
|
+
return "#F9E855";
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function handleHover(region) {
|
|
173
|
+
hoveredRegion.value = region;
|
|
174
|
+
}
|
|
175
|
+
function handleMouseLeave() {
|
|
176
|
+
hoveredRegion.value = null;
|
|
177
|
+
}
|
|
178
|
+
function openSource() {
|
|
179
|
+
emit("openSource");
|
|
180
|
+
}
|
|
181
|
+
function setupScale() {
|
|
182
|
+
minimalValue.value = Math.floor(
|
|
183
|
+
Math.min(
|
|
184
|
+
...props.data.filter((f) => f.value !== null).map((x) => x.value)
|
|
185
|
+
)
|
|
186
|
+
);
|
|
187
|
+
maximalValue.value = Math.ceil(
|
|
188
|
+
Math.max(
|
|
189
|
+
...props.data.filter((f) => f.value !== null).map((x) => x.value)
|
|
190
|
+
)
|
|
191
|
+
);
|
|
192
|
+
const step = (maximalValue.value - minimalValue.value) / 10;
|
|
193
|
+
if (minimalValue.value !== null) {
|
|
194
|
+
scale.value = Array.from(
|
|
195
|
+
{ length: 10 },
|
|
196
|
+
(_, i) => (minimalValue.value !== null ? minimalValue.value : 0) + i * step
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
onMounted(() => {
|
|
201
|
+
setupScale();
|
|
202
|
+
});
|
|
203
|
+
watch(
|
|
204
|
+
() => props.data,
|
|
205
|
+
() => {
|
|
206
|
+
setupScale();
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
watch(
|
|
210
|
+
() => hoveredRegion.value,
|
|
211
|
+
() => {
|
|
212
|
+
if (hoveredRegion.value) {
|
|
213
|
+
const selectedRegion = document.getElementById(
|
|
214
|
+
`interactiveMap-${props.title}-${hoveredRegion.value}`
|
|
215
|
+
)?.getBoundingClientRect();
|
|
216
|
+
const containerPosition = document.getElementById(`container_map-${props.title}-${props.uniqueID}`)?.getBoundingClientRect();
|
|
217
|
+
if (!selectedRegion || !containerPosition) return;
|
|
218
|
+
tooltipPosition.value = {
|
|
219
|
+
x: selectedRegion?.x - containerPosition?.x,
|
|
220
|
+
y: selectedRegion?.top - containerPosition?.top - 60,
|
|
221
|
+
width: selectedRegion?.width
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
watch(
|
|
227
|
+
() => hoveredRegion.value,
|
|
228
|
+
async () => {
|
|
229
|
+
if (hoveredRegion.value) {
|
|
230
|
+
await nextTick();
|
|
231
|
+
const selectedRegion = document.getElementById(
|
|
232
|
+
`interactiveMap-${props.title}-${hoveredRegion.value}`
|
|
233
|
+
)?.getBoundingClientRect();
|
|
234
|
+
const containerPosition = document.getElementById(`container_map-${props.title}`)?.getBoundingClientRect();
|
|
235
|
+
const tooltipElement = document.getElementById(
|
|
236
|
+
`tooltip_map-${props.title}`
|
|
237
|
+
);
|
|
238
|
+
const tooltipHeight = tooltipElement ? tooltipElement.getBoundingClientRect().height : 60;
|
|
239
|
+
if (!selectedRegion || !containerPosition) return;
|
|
240
|
+
tooltipPosition.value = {
|
|
241
|
+
x: selectedRegion?.x - containerPosition?.x,
|
|
242
|
+
y: selectedRegion?.top - containerPosition?.top - tooltipHeight,
|
|
243
|
+
width: selectedRegion?.width
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
return {
|
|
249
|
+
getColor,
|
|
250
|
+
handleHover,
|
|
251
|
+
handleMouseLeave,
|
|
252
|
+
RegionsPt,
|
|
253
|
+
displayedRegions,
|
|
254
|
+
hoveredRegion,
|
|
255
|
+
tooltipPosition,
|
|
256
|
+
scale,
|
|
257
|
+
openSource
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
</script>
|
|
262
|
+
|
|
263
|
+
<style scoped>
|
|
264
|
+
.map{margin-top:24px;width:100%}.p24{padding:24px}.inset rect{fill:none;stroke:var(--light);stroke-width:1px;stroke-dasharray:4 3}.inset text{fill:var(--medium);font-size:13px;font-weight:600}.map path{stroke-width:2px;stroke:rgba(0,0,0,.2);max-height:400px;position:relative}.map path:hover{transition:all .2s}.map_card-container{display:flex;flex-direction:column;gap:8px;min-width:400px;position:relative;width:100%}.test{margin-bottom:200px}.tooltip_container{align-items:center;display:flex;flex-direction:column;justify-content:center;left:0;min-width:-moz-fit-content;min-width:fit-content;position:absolute;top:0;z-index:96}.tooltip{background:#fff;border:1px solid var(--light);border-radius:4px;box-shadow:var(--medium-shadow);color:var(--darkest);font-size:12px}.card_title{background-color:var(--light);border-radius:4px 4px 0 0;font-size:14px;font-weight:600;padding:2px 8px;width:calc(100% - 15px)}.card_text{color:var(--dark);font-size:12px;font-weight:400;line-height:160%;padding:8px;width:100%}.legend{display:flex;flex-direction:column;gap:8px;margin:auto;width:70%}.scale{background:linear-gradient(45deg,#3f1151,#432974,#404a85,#3f668a,#43808c,#4c9c8a,#5fb57e,#85cb68,#bddd51,#f9e855)}.reverse_scale,.scale{height:10px;transform:rotate(180deg)}.reverse_scale{background:linear-gradient(45deg,#f9e855,#bddd51,#85cb68,#5fb57e,#4c9c8a,#43808c,#3f668a,#404a85,#432974,#3f1151)}.legend-text{align-items:center;color:var(--dark);display:flex;font-size:12px;font-weight:400;justify-content:space-between;line-height:160%}.p-24{padding:0 24px}
|
|
265
|
+
</style>
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { PropType } from "vue";
|
|
2
|
+
import { RegionsPt } from "./maps/interfaces";
|
|
3
|
+
type dataRegion = {
|
|
4
|
+
name: RegionsPt;
|
|
5
|
+
value: number;
|
|
6
|
+
};
|
|
7
|
+
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
8
|
+
data: {
|
|
9
|
+
type: PropType<dataRegion[]>;
|
|
10
|
+
default: null;
|
|
11
|
+
required: true;
|
|
12
|
+
};
|
|
13
|
+
title: {
|
|
14
|
+
type: PropType<string | null>;
|
|
15
|
+
default: null;
|
|
16
|
+
required: false;
|
|
17
|
+
};
|
|
18
|
+
source: {
|
|
19
|
+
type: PropType<string | null>;
|
|
20
|
+
default: null;
|
|
21
|
+
};
|
|
22
|
+
haveCustomTitle: {
|
|
23
|
+
type: PropType<string | null>;
|
|
24
|
+
default: null;
|
|
25
|
+
required: false;
|
|
26
|
+
};
|
|
27
|
+
uniqueID: {
|
|
28
|
+
type: PropType<string | null>;
|
|
29
|
+
default: null;
|
|
30
|
+
required: false;
|
|
31
|
+
};
|
|
32
|
+
lang: {
|
|
33
|
+
type: StringConstructor;
|
|
34
|
+
default: string;
|
|
35
|
+
required: false;
|
|
36
|
+
};
|
|
37
|
+
reverseColors: {
|
|
38
|
+
type: BooleanConstructor;
|
|
39
|
+
default: boolean;
|
|
40
|
+
};
|
|
41
|
+
hideIslands: {
|
|
42
|
+
type: BooleanConstructor;
|
|
43
|
+
default: boolean;
|
|
44
|
+
};
|
|
45
|
+
}>, {
|
|
46
|
+
getColor: (value?: number) => "var(--lightest)" | "#3F1151" | "#432974" | "#404A85" | "#3F668A" | "#43808C" | "#4C9C8A" | "#5FB57E" | "#85CB68" | "#BDDD51" | "#F9E855" | undefined;
|
|
47
|
+
handleHover: (region: RegionsPt) => void;
|
|
48
|
+
handleMouseLeave: () => void;
|
|
49
|
+
RegionsPt: typeof RegionsPt;
|
|
50
|
+
displayedRegions: import("vue").ComputedRef<RegionsPt[]>;
|
|
51
|
+
hoveredRegion: import("vue").Ref<RegionsPt | null, RegionsPt | null>;
|
|
52
|
+
tooltipPosition: import("vue").Ref<{
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
width: number;
|
|
56
|
+
}, {
|
|
57
|
+
x: number;
|
|
58
|
+
y: number;
|
|
59
|
+
width: number;
|
|
60
|
+
} | {
|
|
61
|
+
x: number;
|
|
62
|
+
y: number;
|
|
63
|
+
width: number;
|
|
64
|
+
}>;
|
|
65
|
+
scale: import("vue").Ref<number[], number[]>;
|
|
66
|
+
openSource: () => void;
|
|
67
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "openSource"[], "openSource", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
68
|
+
data: {
|
|
69
|
+
type: PropType<dataRegion[]>;
|
|
70
|
+
default: null;
|
|
71
|
+
required: true;
|
|
72
|
+
};
|
|
73
|
+
title: {
|
|
74
|
+
type: PropType<string | null>;
|
|
75
|
+
default: null;
|
|
76
|
+
required: false;
|
|
77
|
+
};
|
|
78
|
+
source: {
|
|
79
|
+
type: PropType<string | null>;
|
|
80
|
+
default: null;
|
|
81
|
+
};
|
|
82
|
+
haveCustomTitle: {
|
|
83
|
+
type: PropType<string | null>;
|
|
84
|
+
default: null;
|
|
85
|
+
required: false;
|
|
86
|
+
};
|
|
87
|
+
uniqueID: {
|
|
88
|
+
type: PropType<string | null>;
|
|
89
|
+
default: null;
|
|
90
|
+
required: false;
|
|
91
|
+
};
|
|
92
|
+
lang: {
|
|
93
|
+
type: StringConstructor;
|
|
94
|
+
default: string;
|
|
95
|
+
required: false;
|
|
96
|
+
};
|
|
97
|
+
reverseColors: {
|
|
98
|
+
type: BooleanConstructor;
|
|
99
|
+
default: boolean;
|
|
100
|
+
};
|
|
101
|
+
hideIslands: {
|
|
102
|
+
type: BooleanConstructor;
|
|
103
|
+
default: boolean;
|
|
104
|
+
};
|
|
105
|
+
}>> & Readonly<{
|
|
106
|
+
onOpenSource?: ((...args: any[]) => any) | undefined;
|
|
107
|
+
}>, {
|
|
108
|
+
data: dataRegion[];
|
|
109
|
+
lang: string;
|
|
110
|
+
source: string | null;
|
|
111
|
+
title: string | null;
|
|
112
|
+
haveCustomTitle: string | null;
|
|
113
|
+
uniqueID: string | null;
|
|
114
|
+
reverseColors: boolean;
|
|
115
|
+
hideIslands: boolean;
|
|
116
|
+
}, {}, {
|
|
117
|
+
OneRegionPt: any;
|
|
118
|
+
ArgSourceContainer: any;
|
|
119
|
+
}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
120
|
+
export default _default;
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="oip_table_card map_card-container"
|
|
4
|
+
:id="`container_map-${title}-${uniqueID}`"
|
|
5
|
+
>
|
|
6
|
+
<div class="p-24">
|
|
7
|
+
<slot name="customTitle" v-if="haveCustomTitle" />
|
|
8
|
+
<div v-else class="oip_subtitle">
|
|
9
|
+
{{ title ? title : "Your map title" }}
|
|
10
|
+
</div>
|
|
11
|
+
<ArgSourceContainer v-if="source !== null" @click="openSource">
|
|
12
|
+
{{ source ? source : "Your source" }}
|
|
13
|
+
</ArgSourceContainer>
|
|
14
|
+
</div>
|
|
15
|
+
<div
|
|
16
|
+
v-if="hoveredRegion !== null"
|
|
17
|
+
:id="`tooltip_map-${title}`"
|
|
18
|
+
class="tooltip_container"
|
|
19
|
+
:style="{
|
|
20
|
+
top: tooltipPosition.y + 'px',
|
|
21
|
+
left: tooltipPosition.x + 'px',
|
|
22
|
+
width: tooltipPosition.width + 'px',
|
|
23
|
+
}"
|
|
24
|
+
>
|
|
25
|
+
<div class="tooltip">
|
|
26
|
+
<p class="card_title">{{ hoveredRegion }}</p>
|
|
27
|
+
<div class="card_text">
|
|
28
|
+
<slot
|
|
29
|
+
name="Tooltip"
|
|
30
|
+
v-bind:value="{
|
|
31
|
+
name: hoveredRegion,
|
|
32
|
+
value: data.find((x) => x.name == hoveredRegion)?.value,
|
|
33
|
+
}"
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="p24">
|
|
39
|
+
<svg
|
|
40
|
+
class="map"
|
|
41
|
+
height="500"
|
|
42
|
+
:viewBox="hideIslands ? '160 0 410 800' : '0 0 570 800'"
|
|
43
|
+
preserveAspectRatio="xMidYMid meet"
|
|
44
|
+
fill="none"
|
|
45
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
46
|
+
>
|
|
47
|
+
<!-- Madeira and the Azores lie about 1000 km off the mainland: each is
|
|
48
|
+
drawn at its own scale as an inset against the west coast, the way
|
|
49
|
+
the France map places its DROM-TOM. The frames tell the reader they
|
|
50
|
+
are not to scale; `hideIslands` crops them out entirely. -->
|
|
51
|
+
<g v-if="!hideIslands" class="inset">
|
|
52
|
+
<rect x="4" y="288" width="166" height="102" rx="4" />
|
|
53
|
+
<text x="8" y="282">Azores</text>
|
|
54
|
+
<rect x="14" y="417" width="134" height="117" rx="4" />
|
|
55
|
+
<text x="18" y="411">Madeira</text>
|
|
56
|
+
</g>
|
|
57
|
+
<OneRegionPtNuts
|
|
58
|
+
v-for="region in displayedRegions"
|
|
59
|
+
:key="region"
|
|
60
|
+
:data="{
|
|
61
|
+
color: getColor(data.find((x) => x.name == region)?.value),
|
|
62
|
+
value: data.find((x) => x.name == region)?.value,
|
|
63
|
+
}"
|
|
64
|
+
:current-region="region"
|
|
65
|
+
:title="title"
|
|
66
|
+
:hoveredRegion="hoveredRegion"
|
|
67
|
+
@hover="handleHover(region)"
|
|
68
|
+
@mouseleave="handleMouseLeave"
|
|
69
|
+
/>
|
|
70
|
+
</svg>
|
|
71
|
+
<div class="legend">
|
|
72
|
+
<div :class="reverseColors ? 'reverse_scale' : 'scale'" />
|
|
73
|
+
<div class="legend-text">
|
|
74
|
+
<template v-for="(value, index) in scale" :key="value">
|
|
75
|
+
<p v-if="index % 2 === 0">
|
|
76
|
+
{{ Math.ceil(value)?.toLocaleString("fr-FR") }}
|
|
77
|
+
</p>
|
|
78
|
+
</template>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
<slot name="Subcontent" />
|
|
83
|
+
</div>
|
|
84
|
+
</template>
|
|
85
|
+
|
|
86
|
+
<script>
|
|
87
|
+
import { computed, onMounted, ref, watch, defineComponent, nextTick } from "vue";
|
|
88
|
+
import { RegionsPtNuts } from "./maps/interfaces";
|
|
89
|
+
import ArgSourceContainer from "./argSourceContainer.vue";
|
|
90
|
+
import OneRegionPtNuts from "./oneRegionPtNuts.vue";
|
|
91
|
+
export default defineComponent({
|
|
92
|
+
name: "argMapsPortugalRegions",
|
|
93
|
+
components: { OneRegionPtNuts, ArgSourceContainer },
|
|
94
|
+
props: {
|
|
95
|
+
data: {
|
|
96
|
+
type: Array,
|
|
97
|
+
default: null,
|
|
98
|
+
required: true
|
|
99
|
+
},
|
|
100
|
+
title: {
|
|
101
|
+
type: [String, null],
|
|
102
|
+
default: null,
|
|
103
|
+
required: false
|
|
104
|
+
},
|
|
105
|
+
source: {
|
|
106
|
+
type: [String, null],
|
|
107
|
+
default: null
|
|
108
|
+
},
|
|
109
|
+
haveCustomTitle: {
|
|
110
|
+
type: [String, null],
|
|
111
|
+
default: null,
|
|
112
|
+
required: false
|
|
113
|
+
},
|
|
114
|
+
uniqueID: {
|
|
115
|
+
type: [String, null],
|
|
116
|
+
default: null,
|
|
117
|
+
required: false
|
|
118
|
+
},
|
|
119
|
+
lang: {
|
|
120
|
+
type: String,
|
|
121
|
+
default: "en",
|
|
122
|
+
required: false
|
|
123
|
+
},
|
|
124
|
+
reverseColors: {
|
|
125
|
+
type: Boolean,
|
|
126
|
+
default: false
|
|
127
|
+
},
|
|
128
|
+
// drop Madeira and the Azores and crop to the mainland — for data that only
|
|
129
|
+
// covers continental Portugal (same idea as argMapsFrRegions' hideDromTom)
|
|
130
|
+
hideIslands: {
|
|
131
|
+
type: Boolean,
|
|
132
|
+
default: false
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
emits: ["openSource"],
|
|
136
|
+
setup(props, { emit }) {
|
|
137
|
+
const islandRegions = [RegionsPtNuts.Azores, RegionsPtNuts.Madeira];
|
|
138
|
+
const displayedRegions = computed(
|
|
139
|
+
() => Object.values(RegionsPtNuts).filter(
|
|
140
|
+
(region) => !props.hideIslands || !islandRegions.includes(region)
|
|
141
|
+
)
|
|
142
|
+
);
|
|
143
|
+
const minimalValue = ref(null);
|
|
144
|
+
const maximalValue = ref(null);
|
|
145
|
+
const hoveredRegion = ref(null);
|
|
146
|
+
const tooltipPosition = ref({ x: 0, y: 0, width: 0 });
|
|
147
|
+
const scale = ref([]);
|
|
148
|
+
function getColor(value) {
|
|
149
|
+
if (!value) return "var(--lightest)";
|
|
150
|
+
if (props.reverseColors ? value <= scale.value[0] : value >= scale.value[9]) {
|
|
151
|
+
return "#3F1151";
|
|
152
|
+
} else if (props.reverseColors ? value <= scale.value[1] : value >= scale.value[8]) {
|
|
153
|
+
return "#432974";
|
|
154
|
+
} else if (props.reverseColors ? value <= scale.value[2] : value >= scale.value[7]) {
|
|
155
|
+
return "#404A85";
|
|
156
|
+
} else if (props.reverseColors ? value <= scale.value[3] : value >= scale.value[6]) {
|
|
157
|
+
return "#3F668A";
|
|
158
|
+
} else if (props.reverseColors ? value <= scale.value[4] : value >= scale.value[5]) {
|
|
159
|
+
return "#43808C";
|
|
160
|
+
} else if (props.reverseColors ? value <= scale.value[5] : value >= scale.value[4]) {
|
|
161
|
+
return "#4C9C8A";
|
|
162
|
+
} else if (props.reverseColors ? value <= scale.value[6] : value >= scale.value[3]) {
|
|
163
|
+
return "#5FB57E";
|
|
164
|
+
} else if (props.reverseColors ? value <= scale.value[7] : value >= scale.value[2]) {
|
|
165
|
+
return "#85CB68";
|
|
166
|
+
} else if (props.reverseColors ? value <= scale.value[8] : value >= scale.value[1]) {
|
|
167
|
+
return "#BDDD51";
|
|
168
|
+
} else if (props.reverseColors ? value > scale.value[8] : value >= scale.value[0]) {
|
|
169
|
+
return "#F9E855";
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function handleHover(region) {
|
|
173
|
+
hoveredRegion.value = region;
|
|
174
|
+
}
|
|
175
|
+
function handleMouseLeave() {
|
|
176
|
+
hoveredRegion.value = null;
|
|
177
|
+
}
|
|
178
|
+
function openSource() {
|
|
179
|
+
emit("openSource");
|
|
180
|
+
}
|
|
181
|
+
function setupScale() {
|
|
182
|
+
minimalValue.value = Math.floor(
|
|
183
|
+
Math.min(
|
|
184
|
+
...props.data.filter((f) => f.value !== null).map((x) => x.value)
|
|
185
|
+
)
|
|
186
|
+
);
|
|
187
|
+
maximalValue.value = Math.ceil(
|
|
188
|
+
Math.max(
|
|
189
|
+
...props.data.filter((f) => f.value !== null).map((x) => x.value)
|
|
190
|
+
)
|
|
191
|
+
);
|
|
192
|
+
const step = (maximalValue.value - minimalValue.value) / 10;
|
|
193
|
+
if (minimalValue.value !== null) {
|
|
194
|
+
scale.value = Array.from(
|
|
195
|
+
{ length: 10 },
|
|
196
|
+
(_, i) => (minimalValue.value !== null ? minimalValue.value : 0) + i * step
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
onMounted(() => {
|
|
201
|
+
setupScale();
|
|
202
|
+
});
|
|
203
|
+
watch(
|
|
204
|
+
() => props.data,
|
|
205
|
+
() => {
|
|
206
|
+
setupScale();
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
watch(
|
|
210
|
+
() => hoveredRegion.value,
|
|
211
|
+
() => {
|
|
212
|
+
if (hoveredRegion.value) {
|
|
213
|
+
const selectedRegion = document.getElementById(
|
|
214
|
+
`interactiveMap-${props.title}-${hoveredRegion.value}`
|
|
215
|
+
)?.getBoundingClientRect();
|
|
216
|
+
const containerPosition = document.getElementById(`container_map-${props.title}-${props.uniqueID}`)?.getBoundingClientRect();
|
|
217
|
+
if (!selectedRegion || !containerPosition) return;
|
|
218
|
+
tooltipPosition.value = {
|
|
219
|
+
x: selectedRegion?.x - containerPosition?.x,
|
|
220
|
+
y: selectedRegion?.top - containerPosition?.top - 60,
|
|
221
|
+
width: selectedRegion?.width
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
watch(
|
|
227
|
+
() => hoveredRegion.value,
|
|
228
|
+
async () => {
|
|
229
|
+
if (hoveredRegion.value) {
|
|
230
|
+
await nextTick();
|
|
231
|
+
const selectedRegion = document.getElementById(
|
|
232
|
+
`interactiveMap-${props.title}-${hoveredRegion.value}`
|
|
233
|
+
)?.getBoundingClientRect();
|
|
234
|
+
const containerPosition = document.getElementById(`container_map-${props.title}`)?.getBoundingClientRect();
|
|
235
|
+
const tooltipElement = document.getElementById(
|
|
236
|
+
`tooltip_map-${props.title}`
|
|
237
|
+
);
|
|
238
|
+
const tooltipHeight = tooltipElement ? tooltipElement.getBoundingClientRect().height : 60;
|
|
239
|
+
if (!selectedRegion || !containerPosition) return;
|
|
240
|
+
tooltipPosition.value = {
|
|
241
|
+
x: selectedRegion?.x - containerPosition?.x,
|
|
242
|
+
y: selectedRegion?.top - containerPosition?.top - tooltipHeight,
|
|
243
|
+
width: selectedRegion?.width
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
return {
|
|
249
|
+
getColor,
|
|
250
|
+
handleHover,
|
|
251
|
+
handleMouseLeave,
|
|
252
|
+
RegionsPtNuts,
|
|
253
|
+
displayedRegions,
|
|
254
|
+
hoveredRegion,
|
|
255
|
+
tooltipPosition,
|
|
256
|
+
scale,
|
|
257
|
+
openSource
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
</script>
|
|
262
|
+
|
|
263
|
+
<style scoped>
|
|
264
|
+
.map{margin-top:24px;width:100%}.p24{padding:24px}.inset rect{fill:none;stroke:var(--light);stroke-width:1px;stroke-dasharray:4 3}.inset text{fill:var(--medium);font-size:13px;font-weight:600}.map path{stroke-width:2px;stroke:rgba(0,0,0,.2);max-height:400px;position:relative}.map path:hover{transition:all .2s}.map_card-container{display:flex;flex-direction:column;gap:8px;min-width:400px;position:relative;width:100%}.test{margin-bottom:200px}.tooltip_container{align-items:center;display:flex;flex-direction:column;justify-content:center;left:0;min-width:-moz-fit-content;min-width:fit-content;position:absolute;top:0;z-index:96}.tooltip{background:#fff;border:1px solid var(--light);border-radius:4px;box-shadow:var(--medium-shadow);color:var(--darkest);font-size:12px}.card_title{background-color:var(--light);border-radius:4px 4px 0 0;font-size:14px;font-weight:600;padding:2px 8px;width:calc(100% - 15px)}.card_text{color:var(--dark);font-size:12px;font-weight:400;line-height:160%;padding:8px;width:100%}.legend{display:flex;flex-direction:column;gap:8px;margin:auto;width:70%}.scale{background:linear-gradient(45deg,#3f1151,#432974,#404a85,#3f668a,#43808c,#4c9c8a,#5fb57e,#85cb68,#bddd51,#f9e855)}.reverse_scale,.scale{height:10px;transform:rotate(180deg)}.reverse_scale{background:linear-gradient(45deg,#f9e855,#bddd51,#85cb68,#5fb57e,#4c9c8a,#43808c,#3f668a,#404a85,#432974,#3f1151)}.legend-text{align-items:center;color:var(--dark);display:flex;font-size:12px;font-weight:400;justify-content:space-between;line-height:160%}.p-24{padding:0 24px}
|
|
265
|
+
</style>
|