diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2022-12-27 14:36:33 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2022-12-27 14:36:33 +0900 |
| commit | 9384f5399da39e53855beb8e7f8ded1aa56bf72e (patch) | |
| tree | ce5959571a981b9c4047da3c7b3fd080aa44222c /packages/frontend/src/components/MkMiniChart.vue | |
| parent | wip: retention for dashboard (diff) | |
| download | sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.tar.gz sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.tar.bz2 sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.zip | |
rename: client -> frontend
Diffstat (limited to 'packages/frontend/src/components/MkMiniChart.vue')
| -rw-r--r-- | packages/frontend/src/components/MkMiniChart.vue | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/packages/frontend/src/components/MkMiniChart.vue b/packages/frontend/src/components/MkMiniChart.vue new file mode 100644 index 0000000000..c64ce163f9 --- /dev/null +++ b/packages/frontend/src/components/MkMiniChart.vue @@ -0,0 +1,73 @@ +<template> +<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" style="overflow:visible"> + <defs> + <linearGradient :id="gradientId" x1="0" x2="0" y1="1" y2="0"> + <stop offset="0%" :stop-color="color" stop-opacity="0"></stop> + <stop offset="100%" :stop-color="color" stop-opacity="0.65"></stop> + </linearGradient> + </defs> + <polygon + :points="polygonPoints" + :style="`stroke: none; fill: url(#${ gradientId });`" + /> + <polyline + :points="polylinePoints" + fill="none" + :stroke="color" + stroke-width="2" + /> + <circle + :cx="headX" + :cy="headY" + r="3" + :fill="color" + /> +</svg> +</template> + +<script lang="ts" setup> +import { onUnmounted, watch } from 'vue'; +import { v4 as uuid } from 'uuid'; +import tinycolor from 'tinycolor2'; +import { useInterval } from '@/scripts/use-interval'; + +const props = defineProps<{ + src: number[]; +}>(); + +const viewBoxX = 50; +const viewBoxY = 50; +const gradientId = uuid(); +let polylinePoints = $ref(''); +let polygonPoints = $ref(''); +let headX = $ref<number | null>(null); +let headY = $ref<number | null>(null); +let clock = $ref<number | null>(null); +const accent = tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--accent')); +const color = accent.toRgbString(); + +function draw(): void { + const stats = props.src.slice().reverse(); + const peak = Math.max.apply(null, stats) || 1; + + const _polylinePoints = stats.map((n, i) => [ + i * (viewBoxX / (stats.length - 1)), + (1 - (n / peak)) * viewBoxY, + ]); + + polylinePoints = _polylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' '); + + polygonPoints = `0,${ viewBoxY } ${ polylinePoints } ${ viewBoxX },${ viewBoxY }`; + + headX = _polylinePoints[_polylinePoints.length - 1][0]; + headY = _polylinePoints[_polylinePoints.length - 1][1]; +} + +watch(() => props.src, draw, { immediate: true }); + +// Vueが何故かWatchを発動させない場合があるので +useInterval(draw, 1000, { + immediate: false, + afterMounted: true, +}); +</script> |