| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- <!-- eslint-disable @intlify/vue-i18n/no-raw-text -->
- <template>
- <div>
- <q-card style="height: 100%">
- <q-card-section class="row justify-between">
- <div class="column">
- <span class="text-bold text-description q-mb-sm">
- {{ props.title }}
- </span>
- <span>{{ props.subtitle }}</span>
- </div>
- <q-btn
- icon="mdi-tray-arrow-down"
- dense
- flat
- class="q-my-auto"
- @click="downloadImage"
- />
- </q-card-section>
- <q-separator inset />
- <q-card-section>
- <div style="display: flex; flex-direction: column">
- <div @mouseover="hideInfoBox">
- <svg
- ref="ref_mapa"
- xmlns="http://www.w3.org/2000/svg"
- class="mapa-svg-estados"
- viewBox="120 50 500 500"
- @click="mapclick"
- >
- <g id="mapa-svg-area">
- <MapaEstado
- v-for="item in items"
- ref="child"
- :key="item.uf"
- :item="item"
- :show-circle-info="showCircleInfo"
- :class="item.classObject"
- :style="item.color ? `fill: ${item.color}` : ''"
- @state-selected-event="onStateSelectedEvent"
- @state-mouse-over-event="onStateMouseOverEvent"
- />
- </g>
- </svg>
- </div>
- <div class="bg-background--2 q-pa-md" style="border-radius: 0.5rem">
- <div
- v-if="selected"
- style="display: flex; flex-direction: column; gap: 0.5rem"
- >
- <span>
- <b> Estado:</b> {{ dadosEstado.name }} -
- {{ dadosEstado.uf.toUpperCase() }}
- </span>
- <span><b>Participantes:</b> {{ dadosEstado.pessoas || 0 }}</span>
- </div>
- <div
- v-else
- style="display: flex; flex-direction: column; gap: 0.5rem"
- >
- <span>
- <b>Selecione um estado</b>
- </span>
- </div>
- </div>
- </div>
- </q-card-section>
- </q-card>
- </div>
- </template>
- <script setup>
- import { computed, onMounted, ref } from "vue";
- import MapaEstado from "../MapaEstado.vue";
- import { DadosBrasil } from "./DadosBrasil";
- import { base64ToJPEG } from "src/helpers/convertBase64Image";
- const selected = ref(null);
- const showCircleInfo = ref(false);
- const infoBoxActive = ref(false);
- const infoBoxPosX = ref(0);
- const infoBoxPosY = ref(0);
- const infoBoxData = ref("");
- const child = ref(null);
- const items = ref(DadosBrasil);
- const ref_mapa = ref(null);
- const props = defineProps({
- data: {
- type: Array,
- required: true,
- },
- title: {
- type: String,
- required: false,
- default: "PARTICIPANTES POR ESTADO - BRASIL",
- },
- subtitle: {
- type: String,
- required: false,
- default: "Número de participantes do evento por estado brasileiro",
- },
- });
- const mapclick = (event) => {
- // console.log("mapa-brasil: mapclick");
- if (event.target.tagName == "svg") {
- resetSelectionAction();
- infoBoxActive.value = false;
- }
- };
- const onStateSelectedEvent = (args) => {
- // console.log("mapa-brasil: onStateSelectedEvent: ", args);
- selected.value = args.src.item.uf;
- resetSelectionAction();
- args.enable();
- };
- const onStateMouseOverEvent = (args) => {
- // console.log("mapa-brasil: onStateMouseOverEvent: ", args);
- setInfoBoxPosition({ x: args.event.pageX, y: args.event.pageY });
- setInfoBoxData([
- args.src.item.name,
- args.src.item.regional,
- args.src.item.altText,
- ]);
- infoBoxActive.value = true;
- };
- const resetSelectionAction = () => {
- // console.log("mapa-brasil: resetSelectionAction", child.value);
- for (let index = 0; index < child.value.length; index++) {
- child.value[index].resetAction();
- }
- };
- const setInfoBoxPosition = (args) => {
- infoBoxPosX.value = args.x + 30;
- infoBoxPosY.value = args.y;
- };
- const setInfoBoxData = (args) => {
- infoBoxData.value = args.filter(function (a) {
- return a !== "" ? a : null;
- });
- };
- const hideInfoBox = (args) => {
- if (
- ["DIV", "SVG"].indexOf(args.target.tagName.toString().toUpperCase()) > -1
- ) {
- infoBoxActive.value = false;
- }
- };
- onMounted(() => {
- const dataOrganizada = [...props.data].sort(
- (a, b) => a?.total_pessoas_por_estado - b?.total_pessoas_por_estado
- );
- const maiorNumero =
- dataOrganizada[dataOrganizada.length - 1]?.total_pessoas_por_estado;
- const faixa = maiorNumero / 5;
- const colors = ["#f6a0a1", "#f27e7f", "#ee585a", "#EB3537", "#c31315"];
- items.value.forEach((item) => {
- const estado = dataOrganizada.find((e) => e.estado === item.uf);
- if (estado) {
- const indexFaixa = Math.ceil(estado?.total_pessoas_por_estado / faixa);
- item.color = colors[indexFaixa - 1];
- item.pessoas = estado.total_pessoas_por_estado;
- } else {
- item.color = "#494949";
- item.pessoas = 0;
- }
- });
- });
- const dadosEstado = computed(() => {
- const estado = items.value.find((item) => item.uf === selected.value);
- return estado;
- });
- const downloadImage = () => {
- const svgString = new XMLSerializer().serializeToString(ref_mapa.value);
- const base64String = btoa(svgString);
- base64ToJPEG(base64String, props.title);
- };
- </script>
- <style lang="scss">
- svg text {
- fill: var(--default-stroke);
- font-family: monospace;
- }
- .mapa-svg-estados {
- fill: var(--default-fill);
- -webkit-transition: 0.8s ease;
- -moz-transition: 0.8s ease;
- -ms-transition: 0.8s ease;
- -o-transition: 0.8s ease;
- transition: 0.8s ease;
- stroke-dasharray: 180%;
- stroke-dashoffset: -120%;
- stroke-width: 1px;
- stroke: var(--default-stroke);
- text {
- fill: var(--default-stroke);
- stroke: none !important;
- }
- }
- .mapa-svg-estados:hover {
- cursor: pointer;
- fill: #8d1012 !important;
- }
- .mapa-svg-estados-active {
- cursor: pointer;
- stroke: #ffffff;
- fill: #ffc712 !important;
- stroke-dashoffset: 0%;
- transition: 0.8s ease;
- -webkit-transition: 0.8s ease;
- -moz-transition: 0.8s ease;
- -ms-transition: 0.8s ease;
- -o-transition: 0.8s ease;
- text {
- fill: #ffffff;
- stroke: none !important;
- }
- }
- </style>
|