Skip to content

Commit ae7bbe1

Browse files
committed
Extended prefix & suffix dataLabels config options for most charts
1 parent 584154a commit ae7bbe1

17 files changed

+254
-72
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vue-data-ui",
33
"private": false,
4-
"version": "1.9.88",
4+
"version": "1.9.89",
55
"type": "module",
66
"description": "A user-empowering data visualization Vue components library",
77
"keywords": [

src/App.vue

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ const config = ref({
174174
},
175175
},
176176
},
177+
labels: {
178+
prefix: "$",
179+
suffix: "£"
180+
},
177181
legend: {
178182
useDiv: true,
179183
},
@@ -818,12 +822,18 @@ const radarDataset = ref({
818822
categories: [
819823
{
820824
name: "category 1",
825+
prefix: "a",
826+
suffix: "b"
821827
},
822828
{
823829
name: "category 2",
830+
prefix: "c",
831+
suffix: "d"
824832
},
825833
{
826834
name: "category 3",
835+
prefix: "e",
836+
suffix: "f"
827837
},
828838
],
829839
series: [
@@ -2261,6 +2271,8 @@ const sparklineConfig = ref({
22612271
color: "#CCCCCC",
22622272
roundingValue: 0,
22632273
valueType: "latest",
2274+
prefix: "$",
2275+
suffix: "£"
22642276
},
22652277
title: {
22662278
show: true,
@@ -2382,6 +2394,8 @@ const heatmapConfig = ref({
23822394
},
23832395
},
23842396
dataLabels: {
2397+
prefix: "$",
2398+
suffix: "£",
23852399
yAxis: {
23862400
fontSize: 24,
23872401
},
@@ -3103,7 +3117,9 @@ const thermoConfig = ref({
31033117
fontSize: 14,
31043118
rounding: 1,
31053119
bold: true,
3106-
color: "#FAFAFA"
3120+
color: "#FAFAFA",
3121+
prefix: "$",
3122+
suffix: "£"
31073123
}
31083124
},
31093125
title: {
@@ -3452,6 +3468,14 @@ const histoDataset = ref([
34523468
const ringsConfig = ref({
34533469
style: {
34543470
chart: {
3471+
layout: {
3472+
labels: {
3473+
dataLabels: {
3474+
prefix: "$",
3475+
suffix: "£"
3476+
}
3477+
}
3478+
},
34553479
title: {
34563480
text: "Title",
34573481
subtitle: {
@@ -4612,6 +4636,14 @@ const moodRadarConfig = ref({
46124636
:config="{
46134637
style: {
46144638
chart: {
4639+
layout: {
4640+
labels: {
4641+
dataLabels: {
4642+
prefix: '$',
4643+
suffix: '£'
4644+
}
4645+
}
4646+
},
46154647
title: {
46164648
text: 'Title',
46174649
subtitle: {
@@ -4868,7 +4900,7 @@ const moodRadarConfig = ref({
48684900
<WaffleTest
48694901
ref="waffletest"
48704902
:dataset="donutDataset"
4871-
:config="{useBlurOnHover: true, style:{chart:{title:{text:'Title',subtitle:{text:'Subtitle'}}}}}"
4903+
:config="{useBlurOnHover: true, style:{chart:{layout:{labels:{dataLabels:{prefix: '$', suffix: '£'}}},title:{text:'Title',subtitle:{text:'Subtitle'}}}}}"
48724904
@selectLegend="selectLegendWaffle"
48734905
>
48744906
<template #svg="{ svg }">

src/components/vue-ui-donut.vue

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
<script setup>
22
import { ref, computed, nextTick } from "vue";
3-
import { calcMarkerOffsetX, calcMarkerOffsetY, calcNutArrowPath, makeDonut, palette, convertColorToHex, opacity, createUid, createCsvContent, downloadCsv } from '../lib';
3+
import {
4+
calcMarkerOffsetX,
5+
calcMarkerOffsetY,
6+
calcNutArrowPath,
7+
convertColorToHex,
8+
createCsvContent,
9+
createUid,
10+
dataLabel,
11+
downloadCsv,
12+
makeDonut,
13+
opacity,
14+
palette,
15+
} from '../lib';
416
import pdf from "../pdf";
517
import img from "../img";
618
import mainConfig from "../default_configs.json";
@@ -180,7 +192,7 @@ function useTooltip(arc, i, showTooltip = true) {
180192
html += `<div data-cy="donut-tooltip-name" style="width:100%;text-align:center;border-bottom:1px solid #ccc;padding-bottom:6px;margin-bottom:3px;">${arc.name}</div>`;
181193
html += `<div style="display:flex;flex-direction:row;gap:6px;align-items:center;"><svg viewBox="0 0 12 12" height="14" width="14"><circle data-cy="donut-tooltip-marker" cx="6" cy="6" r="6" stroke="none" fill="${arc.color}"/></svg>`;
182194
if(donutConfig.value.style.chart.tooltip.showValue) {
183-
html += `<b data-cy="donut-tooltip-value">${arc.value.toFixed(donutConfig.value.style.chart.tooltip.roundingValue)}</b>`;
195+
html += `<b data-cy="donut-tooltip-value">${ dataLabel({p: donutConfig.value.style.chart.layout.labels.dataLabels.prefix, v: arc.value, s: donutConfig.value.style.chart.layout.labels.dataLabels.suffix, r: donutConfig.value.style.chart.tooltip.roundingValue})}</b>`;
184196
}
185197
if(donutConfig.value.style.chart.tooltip.showPercentage) {
186198
if(!donutConfig.value.style.chart.tooltip.showValue) {
@@ -256,18 +268,18 @@ function generateCsv() {
256268
257269
const dataTable = computed(() => {
258270
const head = [
259-
` <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18 16v2a1 1 0 0 1 -1 1h-11l6 -7l-6 -7h11a1 1 0 0 1 1 1v2" /></svg>`,
260-
Number(total.value.toFixed(donutConfig.value.table.td.roundingValue)).toLocaleString(),
271+
` <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18 16v2a1 1 0 0 1 -1 1h-11l6 -7l-6 -7h11a1 1 0 0 1 1 1v2" /></svg>`, dataLabel({p: donutConfig.value.style.chart.layout.labels.dataLabels.prefix, v: total.value, s: donutConfig.value.style.chart.layout.labels.dataLabels.suffix, r: donutConfig.value.table.td.roundingValue}),
261272
'100%'
262273
];
263274
264275
const body = table.value.head.map((h,i) => {
276+
const label = dataLabel({p: donutConfig.value.style.chart.layout.labels.dataLabels.prefix, v: table.value.body[i], s: donutConfig.value.style.chart.layout.labels.dataLabels.suffix, r: donutConfig.value.table.td.roundingValue});
265277
return [
266278
{
267279
color: h.color,
268280
name: h.name
269281
},
270-
table.value.body[i].toFixed(donutConfig.value.table.td.roundingValue),
282+
label,
271283
isNaN(table.value.body[i] / total.value) ? "-" : (table.value.body[i] / total.value * 100).toFixed(donutConfig.value.table.td.roundingPercentage) + '%'
272284
]
273285
});
@@ -481,7 +493,7 @@ defineExpose({
481493
:font-size="donutConfig.style.chart.layout.labels.hollow.total.value.fontSize"
482494
:style="`font-weight:${donutConfig.style.chart.layout.labels.hollow.total.value.bold ? 'bold': ''}`"
483495
>
484-
{{ donutConfig.style.chart.layout.labels.hollow.total.value.prefix }} {{ Number(total.toFixed(donutConfig.style.chart.layout.labels.hollow.total.value.rounding)).toLocaleString() }} {{ donutConfig.style.chart.layout.labels.hollow.total.value.suffix }}
496+
{{ dataLabel({p: donutConfig.style.chart.layout.labels.hollow.total.value.prefix, v: total, s: donutConfig.style.chart.layout.labels.hollow.total.value.suffix}) }}
485497
</text>
486498

487499
<text
@@ -533,7 +545,7 @@ defineExpose({
533545
:font-size="donutConfig.style.chart.layout.labels.percentage.fontSize"
534546
:style="`font-weight:${donutConfig.style.chart.layout.labels.percentage.bold ? 'bold': ''}`"
535547
>
536-
{{ displayArcPercentage(arc, currentDonut) }}
548+
{{ displayArcPercentage(arc, currentDonut) }} {{ donutConfig.style.chart.layout.labels.value.show ? `(${dataLabel({p: donutConfig.style.chart.layout.labels.dataLabels.prefix, v: arc.value, s: donutConfig.style.chart.layout.labels.dataLabels.suffix, rounding: donutConfig.style.chart.layout.labels.value.rounding})})` : '' }}
537549
</text>
538550
<text
539551
:data-cy="`donut-datalabel-name-${i}`"
@@ -567,7 +579,7 @@ defineExpose({
567579
>
568580
<template #item="{legend, index}">
569581
<div @click="segregate(index)" :style="`opacity:${segregated.includes(index) ? 0.5 : 1}`">
570-
{{ legend.name }} : {{ Number(legend.value.toFixed(donutConfig.style.chart.legend.roundingValue)).toLocaleString() }}
582+
{{ legend.name }} : {{ dataLabel({p: donutConfig.style.chart.layout.labels.dataLabels.prefix, v: legend.value, s: donutConfig.style.chart.layout.labels.dataLabels.suffix, r: donutConfig.style.chart.legend.roundingValue}) }}
571583
<span v-if="!segregated.includes(index)">
572584
({{ isNaN(legend.value / total) ? '-' : (legend.value / total * 100).toFixed(donutConfig.style.chart.legend.roundingPercentage)}}%)
573585
</span>
@@ -592,7 +604,7 @@ defineExpose({
592604
>
593605
<template #item="{legend, index}">
594606
<div @click="segregate(index)" :style="`opacity:${segregated.includes(index) ? 0.5 : 1}`">
595-
{{ legend.name }} : {{ Number(legend.value.toFixed(donutConfig.style.chart.legend.roundingValue)).toLocaleString() }}
607+
{{ legend.name }} : {{ dataLabel({p: donutConfig.style.chart.layout.labels.dataLabels.prefix, v: legend.value, s: donutConfig.style.chart.layout.labels.dataLabels.suffix, r: donutConfig.style.chart.legend.roundingValue}) }}
596608
<span v-if="!segregated.includes(index)">
597609
({{ isNaN(legend.value / total) ? '-' : (legend.value / total * 100).toFixed(donutConfig.style.chart.legend.roundingPercentage)}}%)
598610
</span>

src/components/vue-ui-heatmap.vue

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
<script setup>
22
import { ref, computed, nextTick, onMounted } from "vue";
3-
import { opacity, createUid, createCsvContent, downloadCsv, interpolateColorHex, adaptColorToBackground } from "../lib";
3+
import {
4+
adaptColorToBackground,
5+
createCsvContent,
6+
createUid,
7+
dataLabel,
8+
downloadCsv,
9+
interpolateColorHex,
10+
opacity,
11+
} from "../lib";
412
import mainConfig from "../default_configs.json";
513
import pdf from "../pdf";
614
import img from "../img";
@@ -166,7 +174,7 @@ function useTooltip(datapoint) {
166174
let html = "";
167175
168176
html += `<div data-cy="heatmap-tootlip-name">${yAxisName} ${xAxisName ? `${xAxisName}` : ''}</div>`;
169-
html += `<div data-cy="heatmap-tooltip-value" style="margin-top:6px;padding-top:6px;border-top:1px solid #e1e5e8;font-weight:bold;display:flex;flex-direction:row;gap:12px;align-items:center;justify-content:center"><span style="color:${interpolateColorHex(heatmapConfig.value.style.layout.cells.colors.cold, heatmapConfig.value.style.layout.cells.colors.hot, minValue.value, maxValue.value, value)}">⬤</span><span>${isNaN(value) ? "-" : Number(value.toFixed(heatmapConfig.value.style.tooltip.roundingValue)).toLocaleString()}</span></div>`
177+
html += `<div data-cy="heatmap-tooltip-value" style="margin-top:6px;padding-top:6px;border-top:1px solid #e1e5e8;font-weight:bold;display:flex;flex-direction:row;gap:12px;align-items:center;justify-content:center"><span style="color:${interpolateColorHex(heatmapConfig.value.style.layout.cells.colors.cold, heatmapConfig.value.style.layout.cells.colors.hot, minValue.value, maxValue.value, value)}">⬤</span><span>${isNaN(value) ? "-" : dataLabel({p:heatmapConfig.value.style.layout.dataLabels.prefix, v: value, s: heatmapConfig.value.style.layout.dataLabels.suffix, r:heatmapConfig.value.style.tooltip.roundingValue })}</span></div>`
170178
tooltipContent.value = `<div style="font-size:${heatmapConfig.value.style.tooltip.fontSize}px">${html}</div>`;
171179
}
172180
@@ -518,7 +526,7 @@ defineExpose({
518526
</td>
519527
<td class="vue-ui-data-table__tbody__td" v-for="(trData, j) in dataset" :data-cell="dataset[j].name" :style="`outline:${heatmapConfig.table.td.outline}`">
520528
<div style="display: flex; align-items:center; gap: 5px; justify-content:flex-end; width:100%; padding-right:3px;">
521-
{{ isNaN(trData.values[i]) ? '-' : Number(trData.values[i].toFixed(heatmapConfig.table.td.roundingValue)).toLocaleString() }}
529+
{{ isNaN(trData.values[i]) ? '-' : dataLabel({p:heatmapConfig.style.layout.dataLabels.prefix, v:trData.values[i], s: heatmapConfig.style.layout.dataLabels.suffix, r: heatmapConfig.table.td.roundingValue}) }}
522530
</div>
523531
</td>
524532
</tr>

src/components/vue-ui-onion.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
<script setup>
22
import { ref, computed, nextTick } from "vue";
3-
import { convertColorToHex, palette, opacity, createUid, createCsvContent, downloadCsv } from "../lib.js";
3+
import {
4+
convertColorToHex,
5+
palette,
6+
opacity,
7+
createUid,
8+
createCsvContent,
9+
downloadCsv
10+
} from "../lib.js";
411
import pdf from "../pdf";
512
import img from "../img";
613
import mainConfig from "../default_configs.json";

src/components/vue-ui-radar.vue

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
<script setup>
22
import { ref, computed, nextTick } from "vue";
3-
import { palette, createPolygonPath, shiftHue, opacity, convertColorToHex, makePath, createUid, createCsvContent, downloadCsv } from "../lib";
3+
import {
4+
convertColorToHex,
5+
createCsvContent,
6+
createPolygonPath,
7+
createUid,
8+
dataLabel,
9+
downloadCsv,
10+
makePath,
11+
opacity,
12+
palette,
13+
shiftHue,
14+
} from "../lib";
415
import pdf from "../pdf";
516
import img from "../img";
617
import mainConfig from "../default_configs.json";
@@ -115,6 +126,8 @@ const datasetCopy = computed(() => {
115126
name: c.name,
116127
categoryId: `radar_category_${uid.value}_${i}`,
117128
color: convertColorToHex(c.color) || palette[i] || palette[i % palette.length],
129+
prefix: c.prefix ?? '',
130+
suffix: c.suffix ?? ''
118131
}
119132
});
120133
});
@@ -252,8 +265,8 @@ const dataTable = computed(() => {
252265
return [
253266
ds.name,
254267
ds.target,
255-
...ds.values.map(v => {
256-
return `${![null, undefined].includes(v) ? v.toFixed(radarConfig.value.table.td.roundingPercentage) : '-'} (${isNaN(v / ds.target) ? '' : (v / ds.target * 100).toFixed(radarConfig.value.table.td.roundingPercentage)}%)`
268+
...ds.values.map((v, i) => {
269+
return `${dataLabel({p: datasetCopy.value[i].prefix, v, s: datasetCopy.value[i].suffix, r:radarConfig.value.table.td.roundingValue})} (${isNaN(v / ds.target) ? '' : (v / ds.target * 100).toFixed(radarConfig.value.table.td.roundingPercentage)}%)`
257270
})
258271
]
259272
});
@@ -290,7 +303,7 @@ function useTooltip(apex, i) {
290303
value: apex.values[k] / apex.target * 100,
291304
color: datasetCopy.value[k].color,
292305
suffix: '%)',
293-
prefix: `${apex.values[k].toFixed(radarConfig.value.style.chart.tooltip.roundingValue)} (`,
306+
prefix: `${dataLabel({p: datasetCopy.value[k].prefix ?? '',v:apex.values[k],s:datasetCopy.value[k].suffix ?? '', r:radarConfig.value.style.chart.tooltip.roundingValue})} (`,
294307
rounding: radarConfig.value.style.chart.tooltip.roundingPercentage
295308
})
296309
}

src/components/vue-ui-rings.vue

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<script setup>
22
import { computed, ref, nextTick } from "vue";
33
import {
4-
palette,
54
convertColorToHex,
6-
opacity,
5+
createCsvContent,
76
createUid,
7+
dataLabel,
8+
downloadCsv,
9+
opacity,
10+
palette,
811
shiftHue,
9-
createCsvContent,
10-
downloadCsv
1112
} from "../lib";
1213
import pdf from "../pdf";
1314
import img from "../img";
@@ -195,9 +196,7 @@ function useTooltip(index) {
195196
196197
html += `<div style="display:flex;flex-direction:row;gap:6px;align-items:center;"><svg viewBox="0 0 12 12" height="14" width="14"><circle data-cy="waffle-tooltip-marker" cx="6" cy="6" r="6" stroke="none" fill="${selected.color}" /></svg>`;
197198
if (ringsConfig.value.style.chart.tooltip.showValue) {
198-
html += `<b data-cy="waffle-tooltip-value">${selected.value.toFixed(
199-
ringsConfig.value.style.chart.tooltip.roundingValue
200-
)}</b>`;
199+
html += `<b data-cy="waffle-tooltip-value">${dataLabel({p:ringsConfig.value.style.chart.layout.labels.dataLabels.prefix, v: selected.value, s:ringsConfig.value.style.chart.layout.labels.dataLabels.suffix, r:ringsConfig.value.style.chart.tooltip.roundingValue})}</b>`;
201200
}
202201
if (ringsConfig.value.style.chart.tooltip.showPercentage) {
203202
if (!ringsConfig.value.style.chart.tooltip.showValue) {
@@ -270,7 +269,7 @@ const table = computed(() => {
270269
const dataTable = computed(() => {
271270
const head = [
272271
` <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M18 16v2a1 1 0 0 1 -1 1h-11l6 -7l-6 -7h11a1 1 0 0 1 1 1v2" /></svg>`,
273-
Number(grandTotal.value.toFixed(ringsConfig.value.table.td.roundingValue)).toLocaleString(),
272+
dataLabel({p: ringsConfig.value.style.chart.layout.labels.dataLabels.prefix, v: grandTotal.value, s: ringsConfig.value.style.chart.layout.labels.dataLabels.suffix, r: ringsConfig.value.table.td.roundingValue}),
274273
'100%'
275274
];
276275
@@ -280,7 +279,7 @@ const dataTable = computed(() => {
280279
color: h.color,
281280
name: h.name
282281
},
283-
table.value.body[i].toFixed(ringsConfig.value.table.td.roundingValue),
282+
dataLabel({p: ringsConfig.value.style.chart.layout.labels.dataLabels.prefix, v: table.value.body[i], s: ringsConfig.value.style.chart.layout.labels.dataLabels.suffix, r:ringsConfig.value.table.td.roundingValue}),
284283
isNaN(table.value.body[i] / grandTotal.value) ? "-" : (table.value.body[i] / grandTotal.value * 100).toFixed(ringsConfig.value.table.td.roundingPercentage) + '%'
285284
]
286285
});
@@ -499,7 +498,7 @@ defineExpose({
499498
>
500499
<template #item="{legend}">
501500
<div @click="segregate(legend.uid)" :style="`opacity:${segregated.includes(legend.uid) ? 0.5 : 1}`">
502-
{{ legend.name }} : {{ Number(legend.value.toFixed(ringsConfig.style.chart.legend.roundingValue)).toLocaleString() }}
501+
{{ legend.name }} : {{ dataLabel({p:ringsConfig.style.chart.layout.labels.dataLabels.prefix, v: legend.value, s: ringsConfig.style.chart.layout.labels.dataLabels.suffix, r:ringsConfig.style.chart.legend.roundingValue}) }}
503502
<span v-if="!segregated.includes(legend.uid)">
504503
({{ isNaN(legend.value / grandTotal) ? '-' : (legend.value / grandTotal * 100).toFixed(ringsConfig.style.chart.legend.roundingPercentage)}}%)
505504
</span>

src/components/vue-ui-sparkline.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<script setup>
22
import { ref, computed } from "vue";
33
import {
4+
createSmoothPath,
45
createUid,
5-
shiftHue,
6+
dataLabel as dl,
67
opacity,
7-
createSmoothPath,
8+
shiftHue,
89
} from "../lib";
910
import mainConfig from "../default_configs.json";
1011
import { useNestedProp } from "../useNestedProp";
@@ -271,7 +272,7 @@ const isBar = computed(() => {
271272
:font-weight="sparklineConfig.style.dataLabel.bold ? 'bold' : 'normal'"
272273
:fill="sparklineConfig.style.dataLabel.color"
273274
>
274-
{{ selectedPlot ? (Number(selectedPlot.absoluteValue.toFixed(sparklineConfig.style.dataLabel.roundingValue))).toLocaleString() : (Number(dataLabel.toFixed(sparklineConfig.style.dataLabel.roundingValue))).toLocaleString() }}
275+
{{ selectedPlot ? dl({p: sparklineConfig.style.dataLabel.prefix, v: selectedPlot.absoluteValue, s: sparklineConfig.style.dataLabel.suffix, r: sparklineConfig.style.dataLabel.roundingValue }) : dl({p: sparklineConfig.style.dataLabel.prefix, v: dataLabel, s: sparklineConfig.style.dataLabel.suffix, r: sparklineConfig.style.dataLabel.roundingValue }) }}
275276
</text>
276277

277278
<!-- MOUSE TRAP -->

src/components/vue-ui-thermometer.cy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ describe('<VueUiThermometer />', () => {
3030
cy.get(`[data-cy="thermometer-datalabel"]`).then(($label) => {
3131
cy.wrap($label)
3232
.should('exist')
33-
.contains(Number(fixture.dataset.value.toFixed(fixture.config.style.chart.label.rounding)).toLocaleString());
33+
.contains(30.8);
3434

3535
cy.wrap($label)
3636
.invoke('attr', 'fill')

0 commit comments

Comments
 (0)