Skip to content

Commit 62bc51b

Browse files
committed
Improvement - VueUiDonutEvolution - Use VueUiDonut in zoom dialog instead of fixed chart covering rect
1 parent 1e71ff3 commit 62bc51b

File tree

3 files changed

+63
-147
lines changed

3 files changed

+63
-147
lines changed

src/atoms/BaseDraggableDialog.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ onUnmounted(() => {
183183
184184
<template>
185185
<Teleport to="body">
186-
<div v-if="isOpen" class="modal vue-ui-draggable-dialog" :style="modalStyle" @click.stop>
186+
<div v-if="isOpen" data-cy="draggable-dialog" class="modal vue-ui-draggable-dialog" :style="modalStyle" @click.stop>
187187
<div class="modal-header" :style="{
188188
backgroundColor: headerBg,
189189
color: headerColor
@@ -213,7 +213,7 @@ onUnmounted(() => {
213213
<span class="modal-title">
214214
<slot name="title"/>
215215
</span>
216-
<button class="close" @click="close">
216+
<button data-cy="draggable-dialog-close" class="close" @click="close">
217217
<BaseIcon name="close" :stroke="headerColor"/>
218218
</button>
219219
</div>

src/components/vue-ui-donut-evolution.cy.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,9 @@ describe('<VueUiDonutEvolution />', () => {
4141

4242
cy.log('shows zoomed donut on trap click');
4343
cy.get('[data-cy-trap]').eq(0).click();
44-
cy.get('[data-cy-zoom]').should('be.visible');
45-
cy.get('[data-cy-zoom-donut]').should('be.visible');
46-
cy.get('[data-cy-close]').should('be.visible').click({ force: true});
47-
cy.get('[data-cy-zoom]').should('not.exist');
44+
cy.get('[data-cy="draggable-dialog"]').should('be.visible');
45+
cy.get('[data-cy="draggable-dialog-close"]').should('be.visible').click({ force: true});
46+
cy.get('[data-cy="draggable-dialog"]').should('not.exist');
4847

4948
cy.log('segregates series when selecting legend items');
5049
cy.get('[data-cy="legend-item"]').eq(0).click().then(() => {

src/components/vue-ui-donut-evolution.vue

Lines changed: 58 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
createCsvContent,
1414
createUid,
1515
dataLabel,
16+
deepEmptyObjectToNull,
1617
downloadCsv,
1718
error,
1819
getMissingDatasetAttributes,
@@ -41,6 +42,8 @@ import PackageVersion from "../atoms/PackageVersion.vue";
4142
import PenAndPaper from "../atoms/PenAndPaper.vue";
4243
import { useUserOptionState } from "../useUserOptionState";
4344
import { useChartAccessibility } from "../useChartAccessibility";
45+
import BaseDraggableDialog from "../atoms/BaseDraggableDialog.vue";
46+
import VueUiDonut from "./vue-ui-donut.vue";
4447
4548
const { vue_ui_donut_evolution: DEFAULT_CONFIG } = useConfig();
4649
@@ -422,36 +425,29 @@ function displayArcPercentage(arc, stepBreakdown) {
422425
}
423426
424427
function leave() {
425-
if (isFixed.value) return;
426428
hoveredIndex.value = null;
427429
hoveredDatapoint.value = null;
428430
}
429431
430432
function enter(datapoint) {
431-
if (isFixed.value) return;
432433
hoveredIndex.value = datapoint.index;
433434
hoveredDatapoint.value = datapoint;
434435
}
435436
436437
const fixedDatapointIndex = ref(null);
437438
438439
function fixDatapoint(datapoint, index) {
439-
if(!datapoint.subtotal) return;
440+
if(!datapoint.subtotal || !FINAL_CONFIG.value.style.chart.dialog.show) return;
440441
hoveredDatapoint.value = null;
441442
hoveredIndex.value = null;
442443
isFixed.value = true;
443444
fixedDatapoint.value = datapoint;
445+
createDonutDatasetForDialog(datapoint);
444446
if(![null, undefined].includes(index)) {
445447
fixedDatapointIndex.value = index;
446448
}
447449
}
448450
449-
function unfixDatapoint() {
450-
fixedDatapoint.value = null;
451-
isFixed.value = false;
452-
fixedDatapointIndex.value = null;
453-
}
454-
455451
const legendSet = computed(() => {
456452
return convertedDataset.value
457453
.map((serie, i) => {
@@ -582,8 +578,27 @@ function toggleAnnotator() {
582578
function isArcBigEnoughHover(arc) {
583579
return arc.proportion * 100 > FINAL_CONFIG.value.style.chart.donuts.hover.hideLabelsUnderValue;
584580
}
585-
function isArcBigEnoughZoom(arc) {
586-
return arc.proportion * 100 > FINAL_CONFIG.value.style.chart.donuts.zoom.hideLabelsUnderValue;
581+
582+
const donutDataset = ref([]);
583+
const donutConfig = ref({});
584+
const dialog = ref(null);
585+
586+
function createDonutDatasetForDialog(ds) {
587+
donutDataset.value = ds.donut.map(ds => {
588+
return {
589+
name: ds.name,
590+
values: [ds.value],
591+
color: ds.color
592+
}
593+
});
594+
595+
donutConfig.value = deepEmptyObjectToNull({
596+
...FINAL_CONFIG.value.style.chart.dialog.donutChart,
597+
responsive: true,
598+
theme: FINAL_CONFIG.value.theme,
599+
});
600+
601+
dialog.value && dialog.value.open();
587602
}
588603
589604
defineExpose({
@@ -692,7 +707,7 @@ defineExpose({
692707
:class="{ 'vue-data-ui-fullscreen--on': isFullscreen, 'vue-data-ui-fulscreen--off': !isFullscreen }"
693708
data-cy="donut-evolution-svg"
694709
:viewBox="`0 0 ${svg.absoluteWidth} ${svg.absoluteHeight}`"
695-
:style="`max-width:100%; overflow: visible; background:transparent;color:${FINAL_CONFIG.style.chart.color}`"
710+
:style="`max-width:100%; overflow: visible; background:transparent;color:${FINAL_CONFIG.style.chart.color};`"
696711
>
697712
<PackageVersion />
698713
@@ -764,7 +779,7 @@ defineExpose({
764779
</g>
765780
766781
<!-- Y LABELS -->
767-
<g v-if="FINAL_CONFIG.style.chart.layout.grid.yAxis.dataLabels.show" :class="{'donut-opacity': true, 'donut-behind': hoveredIndex !== null || isFixed}">
782+
<g v-if="FINAL_CONFIG.style.chart.layout.grid.yAxis.dataLabels.show" :class="{'donut-opacity': true, 'donut-behind': hoveredIndex !== null}">
768783
<g v-for="(yLabel, i) in yLabels">
769784
<line
770785
data-cy="axis-y-tick"
@@ -803,7 +818,7 @@ defineExpose({
803818
</g>
804819
805820
<!-- X LABELS -->
806-
<g v-if="FINAL_CONFIG.style.chart.layout.grid.xAxis.dataLabels.show" :class="{'donut-opacity': true, 'donut-behind': isFixed}">
821+
<g v-if="FINAL_CONFIG.style.chart.layout.grid.xAxis.dataLabels.show" :class="{'donut-opacity': true,}">
807822
<g v-for="(_, i) in (slicer.end - slicer.start)">
808823
<text
809824
data-cy="axis-x-label"
@@ -822,7 +837,7 @@ defineExpose({
822837
<!-- DATAPOINTS -->
823838
<g v-for="(datapoint, i ) in drawableDataset">
824839
<line
825-
:class="{'donut-opacity': true, 'donut-behind': hoveredIndex !== null || isFixed}"
840+
:class="{'donut-opacity': true, 'donut-behind': hoveredIndex !== null}"
826841
v-if="FINAL_CONFIG.style.chart.layout.line.show && i < drawableDataset.length - 1 && ![datapoint.subtotal, drawableDataset[i + 1].subtotal].includes(null)"
827842
:x1="datapoint.x"
828843
:y1="datapoint.y"
@@ -844,7 +859,7 @@ defineExpose({
844859
</g>
845860
</g>
846861
847-
<g v-for="(datapoint, i ) in drawableDataset" :data-cy="`donut-wrapper-${i}`" :class="{'donut-opacity': true, 'donut-behind': (i !== hoveredIndex && hoveredIndex !== null) || isFixed}">
862+
<g v-for="(datapoint, i ) in drawableDataset" :data-cy="`donut-wrapper-${i}`" :class="{'donut-opacity': true, 'donut-behind': (i !== hoveredIndex && hoveredIndex !== null)}">
848863
<g v-if="datapoint.subtotal">
849864
<g v-if="hoveredIndex !== null && hoveredIndex === i">
850865
<g v-for="arc in datapoint.donutHover">
@@ -886,7 +901,7 @@ defineExpose({
886901
</g>
887902
</g>
888903
</g>
889-
<g v-for="(datapoint, i ) in drawableDataset" :class="{'donut-opacity': true, 'donut-behind': (i !== hoveredIndex && hoveredIndex !== null) || isFixed}">
904+
<g v-for="(datapoint, i ) in drawableDataset" :class="{'donut-opacity': true, 'donut-behind': (i !== hoveredIndex && hoveredIndex !== null)}">
890905
<g v-if="datapoint.subtotal !== null">
891906
<circle
892907
v-if="datapoint.subtotal === 0"
@@ -918,7 +933,7 @@ defineExpose({
918933
</g>
919934
920935
<!-- DATALABELS -->
921-
<g v-for="(datapoint, i ) in drawableDataset" :class="{'donut-opacity': true, 'donut-behind': (i !== hoveredIndex && hoveredIndex !== null) || isFixed}">
936+
<g v-for="(datapoint, i ) in drawableDataset" :class="{'donut-opacity': true, 'donut-behind': (i !== hoveredIndex && hoveredIndex !== null) || (isFixed && i !== fixedDatapoint.index)}">
922937
<text
923938
v-if="datapoint.subtotal !== null && FINAL_CONFIG.style.chart.layout.dataLabels.show"
924939
text-anchor="middle"
@@ -936,12 +951,14 @@ defineExpose({
936951
<rect
937952
v-for="(datapoint, i) in drawableDataset"
938953
:x="padding.left + (i * slit)"
939-
:y="svg.absoluteHeight - padding.bottom - 10"
954+
:y="padding.top"
940955
:width="slit"
941-
:height="10"
942-
:fill="hoveredIndex === datapoint.index ? `url(#hover_${uid})` : 'transparent'"
943-
@click="fixDatapoint(datapoint, i)"
944-
:class="{'donut-hover': hoveredIndex === datapoint.index && datapoint.subtotal}"
956+
:height="svg.height"
957+
:fill="[hoveredIndex, fixedDatapointIndex].includes(datapoint.index) ? `url(#hover_${uid})` : 'transparent'"
958+
:class="{'donut-hover': datapoint.subtotal && [hoveredIndex, fixedDatapointIndex].includes(datapoint.index)}"
959+
:style="{
960+
pointerEvents: 'none'
961+
}"
945962
/>
946963
<rect
947964
v-for="(datapoint, i) in drawableDataset"
@@ -957,124 +974,6 @@ defineExpose({
957974
@click="fixDatapoint(datapoint, i)"
958975
:class="{'donut-hover': hoveredIndex === datapoint.index && datapoint.subtotal}"
959976
/>
960-
961-
<!-- DIALOG -->
962-
<g v-if="isFixed" data-cy-zoom class="vue-ui-donut-evolution-dialog">
963-
<rect
964-
:rx="4"
965-
:x="padding.left"
966-
:y="padding.top"
967-
:width="svg.width"
968-
:height="svg.height"
969-
:fill="FINAL_CONFIG.style.chart.backgroundColor"
970-
style="filter:drop-shadow(0 12px 12px rgba(0,0,0,0.3))"
971-
/>
972-
<line
973-
data-dom-to-png-ignore
974-
:x1="svg.absoluteWidth - padding.right - 15"
975-
:y1="padding.top + 5"
976-
:x2="svg.absoluteWidth - padding.right - 4"
977-
:y2="padding.top + 15.5"
978-
stroke-linecap="round"
979-
:stroke="FINAL_CONFIG.style.chart.color"
980-
stroke-width="1.5"
981-
/>
982-
<line
983-
data-dom-to-png-ignore
984-
:x1="svg.absoluteWidth - padding.right - 15"
985-
:y2="padding.top + 5"
986-
:x2="svg.absoluteWidth - padding.right - 4"
987-
:y1="padding.top + 15.5"
988-
stroke-linecap="round"
989-
:stroke="FINAL_CONFIG.style.chart.color"
990-
stroke-width="1.5"
991-
/>
992-
<circle
993-
data-cy-close
994-
@click="unfixDatapoint"
995-
@keypress.enter="unfixDatapoint"
996-
:cx="svg.absoluteWidth - padding.right - svg.width / 40"
997-
:cy="padding.top + svg.height / 30"
998-
:r="svg.height / 12"
999-
fill="transparent"
1000-
style="cursor:pointer"
1001-
tabindex="0"
1002-
/>
1003-
1004-
<g v-for="arc in fixedDatapoint.donutFocus">
1005-
<path
1006-
v-if="isArcBigEnoughZoom(arc)"
1007-
data-cy-zoom-donut
1008-
:d="calcNutArrowPath(arc, {x: svg.centerX, y: svg.centerY}, 12, 12, false, false, 15)"
1009-
:stroke="arc.color"
1010-
stroke-width="1"
1011-
stroke-linecap="round"
1012-
stroke-linejoin="round"
1013-
fill="none"
1014-
class="vue-ui-donut-evolution-focus"
1015-
/>
1016-
</g>
1017-
<circle
1018-
:cx="padding.left + svg.width / 2"
1019-
:cy="padding.top + svg.height / 2"
1020-
:r="svg.height / 7"
1021-
:fill="FINAL_CONFIG.style.chart.backgroundColor"
1022-
/>
1023-
<path
1024-
v-for="(arc, k) in fixedDatapoint.donutFocus"
1025-
:d="arc.arcSlice"
1026-
:fill="`${arc.color}`"
1027-
:stroke-width="1"
1028-
:stroke="FINAL_CONFIG.style.chart.backgroundColor"
1029-
class="vue-ui-donut-evolution-focus"
1030-
/>
1031-
<g v-for="(arc, i) in fixedDatapoint.donutFocus" class="vue-ui-donut-evolution-focus">
1032-
<text
1033-
v-if="isArcBigEnoughZoom(arc)"
1034-
:data-cy="`donut-datalabel-value-${i}`"
1035-
:text-anchor="calcMarkerOffsetX(arc, true, 20).anchor"
1036-
:x="calcMarkerOffsetX(arc, true, 10).x"
1037-
:y="calcMarkerOffsetY(arc)"
1038-
:fill="FINAL_CONFIG.style.chart.layout.grid.yAxis.dataLabels.color"
1039-
:font-size="10"
1040-
:font-weight="'bold'"
1041-
>
1042-
{{ arc.name}}: {{ displayArcPercentage(arc, fixedDatapoint.donutFocus) }} ({{ arc.value === null ? '-' : labellizeValue(arc.value, arc, i) }})
1043-
</text>
1044-
</g>
1045-
<circle
1046-
:cx="padding.left + (svg.width / 2)"
1047-
:cy="padding.top + (svg.height / 2)"
1048-
:r="svg.height / 3.8"
1049-
:fill="`url(#focus_${uid})`"
1050-
/>
1051-
<circle
1052-
:cx="padding.left + (svg.width / 2)"
1053-
:cy="padding.top + (svg.height / 2)"
1054-
:r="svg.height / 7.7"
1055-
:fill="FINAL_CONFIG.style.chart.backgroundColor"
1056-
/>
1057-
<text
1058-
text-anchor="middle"
1059-
:x="padding.left + svg.width / 2"
1060-
:y="padding.top + (svg.height / 2) + 14 / 3"
1061-
:font-size="14"
1062-
:font-weight="'bold'"
1063-
:fill="FINAL_CONFIG.style.chart.layout.dataLabels.color"
1064-
class="vue-ui-donut-evolution-focus"
1065-
>
1066-
{{ labellizeValue(fixedDatapoint.subtotal, fixedDatapoint, null) }}
1067-
</text>
1068-
<text
1069-
v-if="FINAL_CONFIG.style.chart.layout.grid.xAxis.dataLabels.values[fixedDatapoint.index]"
1070-
:x="padding.left + 6"
1071-
:y="padding.top + FINAL_CONFIG.style.chart.layout.grid.xAxis.dataLabels.fontSize * 2"
1072-
:font-size="FINAL_CONFIG.style.chart.layout.grid.xAxis.dataLabels.fontSize * 1.6"
1073-
:fill="FINAL_CONFIG.style.chart.layout.dataLabels.color"
1074-
>
1075-
{{ FINAL_CONFIG.style.chart.layout.grid.xAxis.dataLabels.values[Number(fixedDatapoint.index) + Number(slicer.start)] }}
1076-
</text>
1077-
</g>
1078977
<slot name="svg" :svg="svg"/>
1079978
</svg>
1080979
@@ -1209,6 +1108,24 @@ defineExpose({
12091108
</DataTable>
12101109
</template>
12111110
</Accordion>
1111+
1112+
<BaseDraggableDialog
1113+
v-if="FINAL_CONFIG.style.chart.dialog.show"
1114+
ref="dialog"
1115+
@close="fixedDatapoint = null; isFixed = false"
1116+
:backgroundColor="FINAL_CONFIG.style.chart.dialog.backgroundColor"
1117+
:color="FINAL_CONFIG.style.chart.dialog.color"
1118+
:headerBg="FINAL_CONFIG.style.chart.dialog.header.backgroundColor"
1119+
:headerColor="FINAL_CONFIG.style.chart.dialog.header.color">
1120+
<template #title>
1121+
{{ FINAL_CONFIG.style.chart.layout.grid.xAxis.dataLabels.values[Number(fixedDatapoint.index) + Number(slicer.start)] }}
1122+
</template>
1123+
<VueUiDonut
1124+
v-if="fixedDatapoint"
1125+
:config="donutConfig"
1126+
:dataset="donutDataset"
1127+
/>
1128+
</BaseDraggableDialog>
12121129
</div>
12131130
</template>
12141131

0 commit comments

Comments
 (0)