Skip to content

Commit

Permalink
VueUiDonut improve datalabels
Browse files Browse the repository at this point in the history
  • Loading branch information
graphieros committed Dec 17, 2023
1 parent 4a72ece commit 5a0603d
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 54 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "vue-data-ui",
"private": false,
"version": "1.9.27",
"version": "1.9.28",
"type": "module",
"description": "A user-empowering data visualization Vue components library",
"keywords": [
Expand Down
43 changes: 1 addition & 42 deletions src/components/vue-ui-chestnut.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup>
import { ref, computed, onMounted, nextTick } from "vue";
import { palette, opacity, shiftHue, adaptColorToBackground, makeDonut, convertColorToHex, makeXls } from "../lib";
import { calcMarkerOffsetX, calcMarkerOffsetY, calcNutArrowPath, palette, opacity, shiftHue, adaptColorToBackground, makeDonut, convertColorToHex, makeXls } from "../lib";
import pdf from "../pdf";
import img from "../img";
import mainConfig from "../default_configs.json";
Expand Down Expand Up @@ -274,33 +274,6 @@ function pickRoot(root) {
}
}
function calcMarkerOffsetX(arc, isTitle = false) {
let x = 0;
let offsetX = isTitle ? 16 : 0;
let anchor="middle";
if(arc.center.endX > arc.cx) {
x = arc.center.endX + 16 + offsetX;
anchor = "start";
} else if (arc.center.endX < arc.cx) {
x = arc.center.endX - 16 - offsetX;
anchor = "end";
} else {
x = arc.centerX + offsetX;
anchor = "middle";
}
return {x, anchor}
}
function calcMarkerOffsetY(arc) {
if (arc.center.endY > arc.cy) {
return arc.center.endY + 16;
} else if (arc.center.endY < arc.cy) {
return arc.center.endY - 32;
} else {
return arc.center.endY;
}
}
function placeLegendTopOrBottom() {
const overflowsBottom = drawableArea.value.bottom - (selectedNut.value.y1 + 180) < 0;
if(overflowsBottom) {
Expand All @@ -310,20 +283,6 @@ function placeLegendTopOrBottom() {
}
}
function calcNutArrowPath(arc) {
const start = `M${calcMarkerOffsetX(arc).x},${calcMarkerOffsetY(arc) - 4} `;
const end = ` ${arc.center.endX},${arc.center.endY}`;
let mid = "";
if (arc.center.endX > arc.cx) {
mid = `${calcMarkerOffsetX(arc).x - 12},${calcMarkerOffsetY(arc) - 4}`;
} else if(arc.center.endX < arc.cx) {
mid = `${calcMarkerOffsetX(arc).x + 12},${calcMarkerOffsetY(arc) - 4}`;
} else {
mid = `${calcMarkerOffsetX(arc).x + 12},${calcMarkerOffsetY(arc) - 4}`;
}
return `${start}${mid}${end}`;
}
function isArcBigEnough(arc) {
return arc.proportion * 100 > chestnutConfig.value.style.chart.layout.nuts.selected.labels.dataLabels.hideUnderValue;
}
Expand Down
57 changes: 46 additions & 11 deletions src/components/vue-ui-donut.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup>
import { ref, computed, nextTick } from "vue";
import { makeDonut, palette, convertColorToHex, opacity, makeXls } from '../lib';
import { calcMarkerOffsetX, calcMarkerOffsetY, calcNutArrowPath, makeDonut, palette, convertColorToHex, opacity, makeXls } from '../lib';
import pdf from "../pdf";
import img from "../img";
import mainConfig from "../default_configs.json";
Expand Down Expand Up @@ -314,7 +314,7 @@ defineExpose({

<template>
<div :ref="`donutChart`" :class="`vue-ui-donut ${donutConfig.useCssAnimation ? '' : 'vue-ui-dna'}`" :style="`font-family:${donutConfig.style.fontFamily};width:100%; text-align:center;${donutConfig.userOptions.show ? 'padding-top:36px' : ''}`" :id="`donut__${uid}`">
<div v-if="(!mutableConfig.inside || isPrinting) && donutConfig.style.chart.title.text" :style="`width:100%;background:${donutConfig.style.chart.backgroundColor}`">
<div v-if="(!mutableConfig.inside || isPrinting) && donutConfig.style.chart.title.text" :style="`width:100%;background:${donutConfig.style.chart.backgroundColor};padding-bottom:24px`">
<!-- TITLE AS DIV -->
<Title
:config="{
Expand Down Expand Up @@ -391,7 +391,7 @@ defineExpose({
:font-size="donutConfig.style.chart.title.fontSize"
:fill="donutConfig.style.chart.title.color"
:x="svg.width / 2"
:y="48"
:y="24"
text-anchor="middle"
:style="`font-weight:${donutConfig.style.chart.title.bold ? 'bold' : ''}`"
>
Expand All @@ -403,13 +403,35 @@ defineExpose({
:font-size="donutConfig.style.chart.title.subtitle.fontSize"
:fill="donutConfig.style.chart.title.subtitle.color"
:x="svg.width / 2"
:y="48 + donutConfig.style.chart.title.fontSize"
:y="24 + donutConfig.style.chart.title.fontSize"
text-anchor="middle"
:style="`font-weight:${donutConfig.style.chart.title.subtitle.bold ? 'bold' : ''}`"
>
{{ donutConfig.style.chart.title.subtitle.text }}
</text>
</g>

<!-- LABEL CONNECTOR -->
<g v-for="(arc, i) in currentDonut">
<path
v-if="isArcBigEnough(arc) && mutableConfig.dataLabels.show"
:d="calcNutArrowPath(arc, {x: svg.width / 2, y: svg.height / 2})"
:stroke="arc.color"
stroke-width="1"
stroke-linecap="round"
stroke-linejoin="round"
fill="none"
:class="!defaultConfig.useBlurOnHover || [null, undefined].includes(selectedSerie) || selectedSerie === i ? '' : 'vue-ui-donut-blur'"
/>
</g>

<path
v-for="(arc, i) in currentDonut"
:stroke="donutConfig.style.chart.backgroundColor"
:d="arc.path"
:stroke-width="defaultConfig.style.chart.layout.donut.strokeWidth"
fill="#FFFFFF"
/>
<path
v-for="(arc, i) in currentDonut"
class="vue-ui-donut-arc-path"
Expand Down Expand Up @@ -503,9 +525,22 @@ defineExpose({
<text
:data-cy="`donut-datalabel-value-${i}`"
v-if="isArcBigEnough(arc) && mutableConfig.dataLabels.show"
text-anchor="middle"
:x="calcDonutMarkerLabelPositionX(arc)"
:y="arc.center.endY - donutConfig.style.chart.layout.labels.percentage.fontSize / 2"
:text-anchor="calcMarkerOffsetX(arc, true).anchor"
:x="calcMarkerOffsetX(arc).x"
:y="calcMarkerOffsetY(arc)"
:fill="arc.color"
:font-size="donutConfig.style.chart.layout.labels.percentage.fontSize * 0.8"
font-family="Arial"
:class="!defaultConfig.useBlurOnHover || [null, undefined].includes(selectedSerie) || selectedSerie === i ? '' : 'vue-ui-donut-blur'"
>
</text>
<text
:data-cy="`donut-datalabel-value-${i}`"
v-if="isArcBigEnough(arc) && mutableConfig.dataLabels.show"
:text-anchor="calcMarkerOffsetX(arc, true, 20).anchor"
:x="calcMarkerOffsetX(arc, true, 20).x"
:y="calcMarkerOffsetY(arc)"
:fill="donutConfig.style.chart.layout.labels.percentage.color"
:font-size="donutConfig.style.chart.layout.labels.percentage.fontSize"
:style="`font-weight:${donutConfig.style.chart.layout.labels.percentage.bold ? 'bold': ''}`"
Expand All @@ -514,10 +549,10 @@ defineExpose({
</text>
<text
:data-cy="`donut-datalabel-name-${i}`"
v-if="isArcBigEnough(arc) && mutableConfig.dataLabels.show"
text-anchor="middle"
:x="calcDonutMarkerLabelPositionX(arc)"
:y="arc.center.endY + donutConfig.style.chart.layout.labels.percentage.fontSize / 2"
v-if="isArcBigEnough(arc, true, 20) && mutableConfig.dataLabels.show"
:text-anchor="calcMarkerOffsetX(arc).anchor"
:x="calcMarkerOffsetX(arc, true, 20).x"
:y="calcMarkerOffsetY(arc) + donutConfig.style.chart.layout.labels.percentage.fontSize"
:fill="donutConfig.style.chart.layout.labels.name.color"
:font-size="donutConfig.style.chart.layout.labels.name.fontSize"
:style="`font-weight:${donutConfig.style.chart.layout.labels.name.bold ? 'bold': ''}`"
Expand Down
44 changes: 44 additions & 0 deletions src/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -627,10 +627,54 @@ export function createUid() {
});
}

export function calcMarkerOffsetX(arc, isTitle = false, offset = 16) {
let x = 0;
let offsetX = isTitle ? offset : 0;
let anchor="middle";
if(arc.center.endX > arc.cx) {
x = arc.center.endX + offset + offsetX;
anchor = "start";
} else if (arc.center.endX < arc.cx) {
x = arc.center.endX - offset - offsetX;
anchor = "end";
} else {
x = arc.centerX + offsetX;
anchor = "middle";
}
return {x, anchor}
}

export function calcMarkerOffsetY(arc) {
if (arc.center.endY > arc.cy) {
return arc.center.endY + 16;
} else if (arc.center.endY < arc.cy) {
return arc.center.endY - 32;
} else {
return arc.center.endY;
}
}

export function calcNutArrowPath(arc, center=false) {
const start = `M${calcMarkerOffsetX(arc).x},${calcMarkerOffsetY(arc) - 4} `;
const end = ` ${center? center.x : arc.center.endX},${center ? center.y : arc.center.endY}`;
let mid = "";
if (arc.center.endX > arc.cx) {
mid = `${calcMarkerOffsetX(arc).x - 12},${calcMarkerOffsetY(arc) - 4}`;
} else if(arc.center.endX < arc.cx) {
mid = `${calcMarkerOffsetX(arc).x + 12},${calcMarkerOffsetY(arc) - 4}`;
} else {
mid = `${calcMarkerOffsetX(arc).x + 12},${calcMarkerOffsetY(arc) - 4}`;
}
return `${start}${mid}${end}`;
}

const lib = {
adaptColorToBackground,
addVector,
calcLinearProgression,
calcMarkerOffsetX,
calcMarkerOffsetY,
calcNutArrowPath,
calcMedian,
checkArray,
checkNaN,
Expand Down

0 comments on commit 5a0603d

Please sign in to comment.