Skip to content

Commit 177330f

Browse files
committed
VueUiSparkline add smooth line option
1 parent 042880a commit 177330f

File tree

8 files changed

+90
-87
lines changed

8 files changed

+90
-87
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.0",
4+
"version": "1.9.1",
55
"type": "module",
66
"description": "A user-empowering data visualization Vue components library",
77
"keywords": [

src/App.vue

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2287,6 +2287,7 @@ const sparklineConfig = ref({
22872287
line: {
22882288
color: "#3366cc",
22892289
strokeWidth: 3,
2290+
smooth: true
22902291
},
22912292
zeroLine: {
22922293
color: "#505050",
@@ -2330,71 +2331,71 @@ const sparklineConfig = ref({
23302331
const sparklineDataset = ref([
23312332
{
23322333
period: "period1",
2333-
value: -21.66,
2334+
value: 0,
23342335
},
23352336
{
23362337
period: "period2",
2337-
value: -13,
2338+
value: -1,
23382339
},
23392340
{
23402341
period: "period3",
2341-
value: -8,
2342+
value: 2,
23422343
},
23432344
{
23442345
period: "period4",
2345-
value: -5,
2346+
value: 3,
23462347
},
23472348
{
23482349
period: "period5",
2349-
value: -3,
2350+
value: -4,
23502351
},
23512352
{
23522353
period: "period6",
2353-
value: -2,
2354+
value: 5,
23542355
},
23552356
{
23562357
period: "period6",
2357-
value: -1,
2358+
value: -6,
23582359
},
23592360
{
23602361
period: "period8",
2361-
value: -1,
2362+
value: 7,
23622363
},
23632364
{
23642365
period: "period9",
2365-
value: 0,
2366+
value: -8,
23662367
},
23672368
{
23682369
period: "period10",
2369-
value: 1,
2370+
value: 9,
23702371
},
23712372
{
23722373
period: "period11",
2373-
value: 1,
2374+
value: -10,
23742375
},
23752376
{
23762377
period: "period12",
2377-
value: 2,
2378+
value: 11,
23782379
},
23792380
{
23802381
period: "period13",
2381-
value: 3,
2382+
value: -12,
23822383
},
23832384
{
23842385
period: "period14",
2385-
value: 5,
2386+
value: 13,
23862387
},
23872388
{
23882389
period: "period15",
2389-
value: 8,
2390+
value: -14,
23902391
},
23912392
{
23922393
period: "period16",
2393-
value: 13,
2394+
value: 15,
23942395
},
23952396
{
23962397
period: "period17",
2397-
value: 21,
2398+
value: -16,
23982399
},
23992400
]);
24002401
@@ -3531,6 +3532,19 @@ const showLocalTest = ref(false);
35313532
<button @click="printRelation">PRINT RELATION CIRCLE</button>
35323533
<button @click="printThermo">PRINT THERMO</button>
35333534

3535+
<div style="max-width: 1000px; margin: 0 auto; margin-bottom: 48px">
3536+
<VueUiSparkline
3537+
v-if="!showLocalTest"
3538+
:config="sparklineConfig"
3539+
:dataset="sparklineDataset"
3540+
/>
3541+
<SparklineTest
3542+
v-if="showLocalTest"
3543+
:config="sparklineConfig"
3544+
:dataset="sparklineDataset"
3545+
/>
3546+
</div>
3547+
35343548
<div style="max-width: 1000px; margin: 0 auto">
35353549
<VueUiXy
35363550
ref="xytest"
@@ -3852,18 +3866,7 @@ const showLocalTest = ref(false);
38523866
:dataset="heatmapDataset"
38533867
/>
38543868
</div>
3855-
<div style="max-width: 1000px; margin: 0 auto; margin-bottom: 48px">
3856-
<VueUiSparkline
3857-
v-if="!showLocalTest"
3858-
:config="sparklineConfig"
3859-
:dataset="sparklineDataset"
3860-
/>
3861-
<SparklineTest
3862-
v-if="showLocalTest"
3863-
:config="sparklineConfig"
3864-
:dataset="sparklineDataset"
3865-
/>
3866-
</div>
3869+
38673870
<div style="max-width: 1000px; margin: 0 auto; margin-bottom: 48px">
38683871
<XyTest ref="xytest" :config="config" :dataset="barset" v-if="showLocalTest" />
38693872
<VueUiXy ref="xytest" :config="config" :dataset="barset" v-if="!showLocalTest" />

src/components/vue-ui-sparkline.vue

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
treeShake,
55
shiftHue,
66
opacity,
7-
convertConfigColors
7+
convertConfigColors,
8+
createSmoothPath
89
} from "../lib";
910
import mainConfig from "../default_configs.json";
1011
@@ -154,14 +155,22 @@ const dataLabel = computed(() => {
154155
<!-- AREA -->
155156
<g v-if="sparklineConfig.style.area.show">
156157
<path
158+
v-if="sparklineConfig.style.line.smooth"
159+
:d="`M ${mutableDataset[0].x},${drawingArea.bottom} ${createSmoothPath(mutableDataset)} L ${mutableDataset.at(-1).x},${drawingArea.bottom} Z`"
160+
:fill="sparklineConfig.style.area.useGradient ? `url(#sparkline_gradient_${uid})` : `${sparklineConfig.style.area.color}${opacity[sparklineConfig.style.area.opacity]}`"
161+
/>
162+
<path
163+
v-else
157164
:d="`M${area}Z`"
158165
:fill="sparklineConfig.style.area.useGradient ? `url(#sparkline_gradient_${uid})` : `${sparklineConfig.style.area.color}${opacity[sparklineConfig.style.area.opacity]}`"
159166
/>
160167
</g>
161168

169+
<path v-if="sparklineConfig.style.line.smooth" :d="`M ${createSmoothPath(mutableDataset)}`" :stroke="sparklineConfig.style.line.color" fill="none" :stroke-width="sparklineConfig.style.line.strokeWidth" stroke-linecap="round"/>
170+
162171
<g v-for="(plot, i) in mutableDataset">
163172
<line
164-
v-if="i < mutableDataset.length - 1"
173+
v-if="i < mutableDataset.length - 1 && !sparklineConfig.style.line.smooth"
165174
:x1="plot.x"
166175
:x2="mutableDataset[i + 1].x"
167176
:y1="plot.y"

src/components/vue-ui-xy.vue

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@
300300
<text
301301
v-if="!Object.hasOwn(serie, 'dataLabels') || serie.dataLabels === true"
302302
:x="plot.x + calcRectWidth() * 1.1"
303-
:y="plot.y + chartConfig.bar.labels.offsetY"
303+
:y="plot.y + (plot.value > 0 ? chartConfig.bar.labels.offsetY : - chartConfig.bar.labels.offsetY * 3)"
304304
text-anchor="middle"
305305
:font-size="chartConfig.chart.labels.fontSize"
306306
:fill="chartConfig.bar.labels.color"
@@ -360,7 +360,7 @@
360360
<text
361361
v-if="!Object.hasOwn(serie, 'dataLabels') || serie.dataLabels === true"
362362
:x="plot.x"
363-
:y="plot.y + chartConfig.line.labels.offsetY"
363+
:y="plot.y + (plot.value > 0 ? chartConfig.line.labels.offsetY : - chartConfig.line.labels.offsetY * 3)"
364364
text-anchor="middle"
365365
:font-size="chartConfig.chart.labels.fontSize"
366366
:fill="chartConfig.line.labels.color"
@@ -598,13 +598,11 @@ import {
598598
convertConfigColors,
599599
makeXls,
600600
adaptColorToBackground,
601-
calcLinearProgression
601+
calcLinearProgression,
602+
createSmoothPath
602603
} from '../lib';
603604
import mainConfig from "../default_configs.json";
604605
605-
// TOD0:
606-
// . add emit on click (emit all data at given index, maybe choose which to emit if multiseries; so it could dynamically feed another chart)
607-
608606
export default {
609607
name: "vue-ui-xy",
610608
props: {
@@ -688,18 +686,6 @@ export default {
688686
return val;
689687
}
690688
},
691-
// chartConfig() {
692-
// if(!Object.keys(this.config || {}).length) {
693-
// return this.defaultConfig
694-
// }
695-
696-
// const reconcilied = this.treeShake({
697-
// defaultConfig: this.defaultConfig,
698-
// userConfig: this.config
699-
// });
700-
701-
// return this.convertConfigColors(reconcilied);
702-
// },
703689
relativeZero() {
704690
if(this.min >= 0) return 0;
705691
return Math.abs(this.min);
@@ -1064,6 +1050,7 @@ export default {
10641050
},
10651051
methods: {
10661052
checkNaN,
1053+
createSmoothPath,
10671054
isSafeValue,
10681055
treeShake,
10691056
shiftHue,
@@ -1083,40 +1070,6 @@ export default {
10831070
});
10841071
return [ start.x, start.y, ...path, end.x, end.y].toString();
10851072
},
1086-
createSmoothPath(points) {
1087-
const smoothing = 0.2;
1088-
function line(pointA, pointB) {
1089-
const lengthX = pointB.x - pointA.x;
1090-
const lengthY = pointB.y - pointA.y;
1091-
return {
1092-
length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
1093-
angle: Math.atan2(lengthY, lengthX)
1094-
};
1095-
}
1096-
function controlPoint(current, previous, next, reverse) {
1097-
const p = previous || current;
1098-
const n = next || current;
1099-
const o = line(p, n);
1100-
1101-
const angle = o.angle + (reverse ? Math.PI : 0);
1102-
const length = o.length * smoothing;
1103-
1104-
const x = current.x + Math.cos(angle) * length;
1105-
const y = current.y + Math.sin(angle) * length;
1106-
return { x, y };
1107-
}
1108-
function bezierCommand(point, i, a) {
1109-
const cps = controlPoint(a[i - 1], a[i - 2], point);
1110-
const cpe = controlPoint(point, a[i - 1], a[i + 1], true);
1111-
return `C ${cps.x},${cps.y} ${cpe.x},${cpe.y} ${point.x},${point.y}`;
1112-
}
1113-
const d = points.reduce((acc, point, i, a) => i === 0
1114-
? `${point.x},${point.y} `
1115-
: `${acc} ${bezierCommand(point, i, a)} `
1116-
, '');
1117-
1118-
return d;
1119-
},
11201073
/////////////////////////////// CANVAS /////////////////////////////////
11211074
createCanvasArea(plots) {
11221075
const start = { x: plots[0].x, y: this.zero };

src/default_configs.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,8 @@
14641464
"fontFamily": "inherit",
14651465
"line": {
14661466
"color":"#3366cc",
1467-
"strokeWidth": 3
1467+
"strokeWidth": 3,
1468+
"smooth": false
14681469
},
14691470
"zeroLine": {
14701471
"color": "#2D353C",

src/lib.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,12 +583,48 @@ export function calcMedian(arr) {
583583
return arr.length % 2 !== 0 ? nums[mid] : (nums[mid-1] + nums[mid]) / 2;
584584
}
585585

586+
export function createSmoothPath(points) {
587+
const smoothing = 0.2;
588+
function line(pointA, pointB) {
589+
const lengthX = pointB.x - pointA.x;
590+
const lengthY = pointB.y - pointA.y;
591+
return {
592+
length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
593+
angle: Math.atan2(lengthY, lengthX)
594+
};
595+
}
596+
function controlPoint(current, previous, next, reverse) {
597+
const p = previous || current;
598+
const n = next || current;
599+
const o = line(p, n);
600+
601+
const angle = o.angle + (reverse ? Math.PI : 0);
602+
const length = o.length * smoothing;
603+
604+
const x = current.x + Math.cos(angle) * length;
605+
const y = current.y + Math.sin(angle) * length;
606+
return { x, y };
607+
}
608+
function bezierCommand(point, i, a) {
609+
const cps = controlPoint(a[i - 1], a[i - 2], point);
610+
const cpe = controlPoint(point, a[i - 1], a[i + 1], true);
611+
return `C ${cps.x},${cps.y} ${cpe.x},${cpe.y} ${point.x},${point.y}`;
612+
}
613+
const d = points.reduce((acc, point, i, a) => i === 0
614+
? `${point.x},${point.y} `
615+
: `${acc} ${bezierCommand(point, i, a)} `
616+
, '');
617+
618+
return d;
619+
}
620+
586621
const lib = {
587622
addVector,
588623
checkNaN,
589624
calcMedian,
590625
convertColorToHex,
591626
createPolygonPath,
627+
createSmoothPath,
592628
createStar,
593629
degreesToRadians,
594630
giftWrap,

types/vue-data-ui.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,7 @@ declare module 'vue-data-ui' {
22152215
line?: {
22162216
color?: string;
22172217
strokeWidth?: number;
2218+
smooth?: boolean;
22182219
};
22192220
zeroLine?: {
22202221
color?: string;

0 commit comments

Comments
 (0)