Skip to content

Commit

Permalink
VueUiXy layout improvements for bar types only edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
graphieros committed Mar 8, 2024
1 parent 8684ebc commit 6618c43
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 40 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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": "2.0.11",
"version": "2.0.12",
"type": "module",
"description": "A user-empowering data visualization Vue components library",
"keywords": [
Expand Down
78 changes: 62 additions & 16 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,34 @@ import { getVueDataUiConfig } from "vue-data-ui";
const dataset = ref([
{
name: "Series 1",
series: [200, 100, 125, 230, 120, 100, 90, 50, 12, 25, 100, 154, 155],
type: "line",
name: "Serie 1",
series: [200],
type: "bar",
dataLabels: true
},
{
name: "Some long name",
series: [100],
type: "bar",
dataLabels: true
},
{
name: "Some even longer name",
series: [150],
type: "bar",
},
{
name: "Weird serie name",
series: [90],
type: "bar",
},
{
name: "Another weird long name",
series: [120],
type: "bar",
},
]);
const dataset2 = ref([
{
name: "Series 1",
Expand Down Expand Up @@ -2342,13 +2365,30 @@ const donutConfig = ref({
const xyConfig = ref({
chart: {
tooltip: {
customFormat: ({ seriesIndex, datapoint, series, bars, lines, plots, config }) => {
console.log({seriesIndex, datapoint, series, bars, lines, plots, config});
return 'TEST'
}
}
}
labels: {
fontSize: 30
},
// tooltip: {
// customFormat: ({ seriesIndex, datapoint, series, bars, lines, plots, config }) => {
// console.log({seriesIndex, datapoint, series, bars, lines, plots, config});
// return 'TEST'
// }
// }
},
bar: {
labels: {
show: false,
},
serieName: {
show: true,
offsetY: -6,
useAbbreviation: true,
abbreviationSize: 4,
useSerieColor: true,
color: "#FF0000",
bold: true
}
},
})
const waffleConfig = ref({
Expand Down Expand Up @@ -2747,7 +2787,7 @@ function selectHistoDatapoint({ datapoint, index }) {
</template>
</Box>

<Box open @copy="copyConfig(PROD_CONFIG.vue_ui_donut_evolution)">
<Box @copy="copyConfig(PROD_CONFIG.vue_ui_donut_evolution)">
<template #title>
<BaseIcon name="chartDonutEvolution"/>
VueUiDonutEvolution
Expand Down Expand Up @@ -3006,7 +3046,7 @@ function selectHistoDatapoint({ datapoint, index }) {
</template>
</Box>

<Box @copy="copyConfig(PROD_CONFIG.vue_ui_xy)">
<Box open @copy="copyConfig(PROD_CONFIG.vue_ui_xy)">
<template #title>
<BaseIcon name="chartLine" />
VueUiXy
Expand All @@ -3027,9 +3067,11 @@ function selectHistoDatapoint({ datapoint, index }) {
@selectLegend="selectLegendXY"
@selectX="selectX"
>
<template #svg="{ svg }">
<circle :cx="svg.width / 2" :cy="svg.height / 2" :r="30" fill="#FF000033"/>
</template>
</XyTest>
<XyTest
:config="xyConfig"
:dataset="dataset"
>
</XyTest>
</template>
<template #prod>
Expand All @@ -3044,6 +3086,10 @@ function selectHistoDatapoint({ datapoint, index }) {
<circle :cx="svg.width / 2" :cy="svg.height / 2" :r="30" fill="#FF000033"/>
</template>
</VueUiXy>
<VueUiXy
:config="xyConfig"
:dataset="dataset"
/>
</template>
<template #config>
{{ PROD_CONFIG.vue_ui_xy }}
Expand Down Expand Up @@ -3193,7 +3239,7 @@ function selectHistoDatapoint({ datapoint, index }) {
</template>
</Box>

<Box open @copy="copyConfig(PROD_CONFIG.vue_ui_onion)">
<Box @copy="copyConfig(PROD_CONFIG.vue_ui_onion)">
<template #title>
<BaseIcon name="chartOnion" />
VueUiOnion
Expand Down
46 changes: 29 additions & 17 deletions src/components/vue-ui-xy.vue
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,12 @@
</g>

<!-- X LABELS BAR -->
<g v-if="chartConfig.bar.labels.show && mutableConfig.dataLabels.show">
<g v-if="(chartConfig.bar.labels.show || chartConfig.bar.serieName.show) && mutableConfig.dataLabels.show">
<g v-for="(serie, i) in barSet" :key="`xLabel_bar_${i}`" :class="`xLabel_bar_${i}`">
<g v-for="(plot, j) in serie.plots" :key="`xLabel_bar_${i}_${j}`">
<text
:data-cy="`xy-bar-label-x-${i}-${j}`"
v-if="!Object.hasOwn(serie, 'dataLabels') || serie.dataLabels === true"
v-if="(!Object.hasOwn(serie, 'dataLabels') || serie.dataLabels === true) && chartConfig.bar.labels.show"
:x="plot.x + calcRectWidth() * 1.1"
:y="plot.y + (plot.value > 0 ? chartConfig.bar.labels.offsetY : - chartConfig.bar.labels.offsetY * 3)"
text-anchor="middle"
Expand All @@ -314,6 +314,17 @@
>
{{ canShowValue(plot.value) ? dataLabel({p:chartConfig.chart.labels.prefix, v: plot.value, s: chartConfig.chart.labels.suffix, r: chartConfig.bar.labels.rounding}) : '' }}
</text>
<text
v-if="chartConfig.bar.serieName.show"
:x="plot.x + calcRectWidth() * 1.1"
:y="plot.y + (plot.value > 0 ? chartConfig.bar.serieName.offsetY : - chartConfig.bar.serieName.offsetY * 3)"
text-anchor="middle"
:font-size="chartConfig.chart.labels.fontSize"
:fill="chartConfig.bar.serieName.useSerieColor ? serie.color : chartConfig.bar.serieName.color"
:font-weight="chartConfig.bar.serieName.bold ? 'bold' : 'normal'"
>
{{ chartConfig.bar.serieName.useAbbreviation ? abbreviate({ source: serie.name, length: chartConfig.bar.serieName.abbreviationSize}) : serie.name }}
</text>
</g>
</g>
</g>
Expand Down Expand Up @@ -593,14 +604,14 @@
</svg>

<!-- SLICER -->
<div v-if="chartConfig.chart.zoom.show" class="vue-ui-xy-range-slider-wrapper" data-html2canvas-ignore style="position:relative">
<div v-if="chartConfig.chart.zoom.show && maxX > 6" class="vue-ui-xy-range-slider-wrapper" data-html2canvas-ignore style="position:relative">
<div class="vue-ui-xy-range-slider-label-left" data-cy-zoom-legend>
{{ chartConfig.chart.grid.labels.xAxisLabels.values[slicer.start] }}
</div>
<div class="vue-ui-xy-range-slider">
<div class="vue-ui-xy-slider-track" :id="`vue-ui-slider-track_${uniqueId}`"></div>
<input data-cy="xy-range-start" :id="`start_${uniqueId}`" type="range" :style="`border:none !important;accent-color:${chartConfig.chart.zoom.color}`" :min="0" :max="maxX" v-model="slicer.start">
<input :id="`end_${uniqueId}`" type="range" :style="`border:none !important;accent-color:${chartConfig.chart.zoom.color}`" :min="0" :max="maxX" v-model="slicer.end">
<div class="vue-ui-xy-slider-track" :id="`vue-ui-slider-track_${sliderId}`"></div>
<input data-cy="xy-range-start" :id="`start_${sliderId}`" type="range" :style="`border:none !important;accent-color:${chartConfig.chart.zoom.color}`" :min="0" :max="maxX" v-model="slicer.start">
<input :id="`end_${sliderId}`" type="range" :style="`border:none !important;accent-color:${chartConfig.chart.zoom.color}`" :min="0" :max="maxX" v-model="slicer.end">

</div>
<div class="vue-ui-xy-range-slider-label-right" data-cy-zoom-legend>
Expand Down Expand Up @@ -683,6 +694,7 @@ import pdf from '../pdf';
import img from "../img";
import { useMouse } from '../useMouse';
import {
abbreviate,
adaptColorToBackground,
calcLinearProgression,
calculateNiceScale,
Expand Down Expand Up @@ -712,7 +724,7 @@ import Shape from "../atoms/Shape.vue";
import BaseIcon from '../atoms/BaseIcon.vue';
import TableSparkline from "./vue-ui-table-sparkline.vue";
const uid = createUid();
const sliderId = createUid();
export default {
name: "vue-ui-xy",
Expand Down Expand Up @@ -740,7 +752,6 @@ export default {
TableSparkline
},
data(){
const uniqueId = uid;
const maxX = Math.max(...this.dataset.map(datapoint => datapoint.series.length));
const slicer = {
start: 0,
Expand Down Expand Up @@ -783,13 +794,14 @@ export default {
selectedSerieIndex: null,
selectedRowIndex: null,
segregatedSeries: [],
uniqueId,
uniqueId: createUid(),
step: 0,
slicer,
__to__: null,
maxX,
showSparklineTable: true,
segregateStep: 0
segregateStep: 0,
sliderId
}
},
computed: {
Expand Down Expand Up @@ -837,6 +849,7 @@ export default {
series: datapoint.series.map(d => {
return this.isSafeValue(d) ? d : null
}).slice(this.slicer.start, this.slicer.end),
color: this.convertColorToHex(datapoint.color ? datapoint.color : this.palette[i]),
id: `uniqueId_${i}`
}
});
Expand All @@ -847,7 +860,6 @@ export default {
...datapoint,
series: datapoint.series.map(plot => plot + this.relativeZero),
absoluteValues: datapoint.series,
color: this.convertColorToHex(datapoint.color ? datapoint.color : this.palette[i]),
}
}).filter(s => !this.segregatedSeries.includes(s.id));
},
Expand Down Expand Up @@ -893,7 +905,6 @@ export default {
...datapoint,
series: datapoint.series.map(plot => plot + this.relativeZero),
absoluteValues: datapoint.series,
color: this.convertColorToHex(datapoint.color ? datapoint.color : this.palette[i]),
}
})
},
Expand All @@ -907,7 +918,7 @@ export default {
y: this.drawingArea.bottom - (this.drawingArea.height * this.ratioToMax(plot)),
value: datapoint.absoluteValues[j],
}
})
}),
}
})
},
Expand Down Expand Up @@ -1225,11 +1236,11 @@ export default {
if (this.chartConfig.chart.zoom.show) {
const vm = this;
const sliderOne = document.getElementById(`start_${this.uniqueId}`);
const sliderTwo = document.getElementById(`end_${this.uniqueId}`);
const sliderOne = document.getElementById(`start_${this.sliderId}`);
const sliderTwo = document.getElementById(`end_${this.sliderId}`);
let minGap = 0;
const sliderTrack = document.getElementById(`vue-ui-slider-track_${this.uniqueId}`);
const sliderTrack = document.getElementById(`vue-ui-slider-track_${this.sliderId}`);
sliderOne.addEventListener("input", slideOne);
sliderTwo.addEventListener("input", slideTwo);
Expand Down Expand Up @@ -1287,6 +1298,7 @@ export default {
}
},
methods: {
abbreviate,
calculateNiceScale,
checkNaN,
createSmoothPath,
Expand Down Expand Up @@ -1328,7 +1340,7 @@ export default {
start: 0,
end: Math.max(...this.dataset.map(datapoint => datapoint.series.length))
}
const sliderTrack = document.getElementById(`vue-ui-slider-track_${this.uniqueId}`);
const sliderTrack = document.getElementById(`vue-ui-slider-track_${this.sliderId}`);
sliderTrack.style.background = `linear-gradient(to right, #dadae5 0% , #858585 100% , #858585 0%, #dadae5 100%)`;
},
createCanvasArea(plots) {
Expand Down
9 changes: 9 additions & 0 deletions src/default_configs.json
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,15 @@
"offsetY": -6,
"rounding": 0,
"color": "#2D353C"
},
"serieName": {
"show": false,
"offsetY": -6,
"useAbbreviation": true,
"abbreviationSize": 3,
"useSerieColor": true,
"color": "#2D353C",
"bold": false
}
},
"line": {
Expand Down
31 changes: 27 additions & 4 deletions src/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ export function findArcMidpoint(pathElement) {
export function calcNutArrowPath(arc, center = false, yOffsetTop = 16, yOffsetBottom = 16, toCenter = false, hideStart = false, arcSize = 0) {
const { x, y } = findArcMidpoint(arc.path)

const { x:endX, y:endY } = offsetFromCenterPoint({
const { x: endX, y: endY } = offsetFromCenterPoint({
initX: x,
initY: y,
offset: arcSize,
Expand Down Expand Up @@ -735,7 +735,7 @@ export function sumByAttribute(arr, attr) {
export function makePath(plots, closed = true) {
let path = "";
plots.forEach(plot => {
path += `${plot.x},${plot.y } `
path += `${plot.x},${plot.y} `
})
return `M${path}${closed ? 'Z' : ''}`;
}
Expand Down Expand Up @@ -925,11 +925,34 @@ export function interpolateColorHex(minColor, maxColor, minValue, maxValue, valu
* @property {boolean=} space - space between elements
* @type {DataLabel}
*/
export function dataLabel({p = '', v, s = '', r = 0, space = false}) {
return `${p ?? ''}${space ? ' ': ''}${[undefined, null].includes(v) ? '-' : Number(Number(v).toFixed(r).toLocaleString())}${space ? ' ' : ''}${s ?? ''}`
export function dataLabel({ p = '', v, s = '', r = 0, space = false }) {
return `${p ?? ''}${space ? ' ' : ''}${[undefined, null].includes(v) ? '-' : Number(Number(v).toFixed(r).toLocaleString())}${space ? ' ' : ''}${s ?? ''}`
}

export function abbreviate({ source, length = 3 }) {
if (!source && source !== 0) {
return ''
}
source = String(source);
const sourceSplit = source.length > 1 ? source.split(' ') : [source];
if(sourceSplit.length === 1 && sourceSplit[0].length === 1) {
return String(source).toUpperCase()
}
if (sourceSplit.length === 1) {
return source.slice(0, length).toUpperCase()
} else {
const result = [];
sourceSplit.forEach((chunk, i) => {
if (i < length) {
result.push(chunk.slice(0, 1))
}
})
return result.join().replaceAll(',', '').toUpperCase();
}
}

const lib = {
abbreviate,
adaptColorToBackground,
addVector,
calcLinearProgression,
Expand Down
Loading

0 comments on commit 6618c43

Please sign in to comment.