summaryrefslogtreecommitdiff
path: root/src/client/app/common/views/components/trends.chart.vue
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/app/common/views/components/trends.chart.vue')
-rw-r--r--src/client/app/common/views/components/trends.chart.vue89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/client/app/common/views/components/trends.chart.vue b/src/client/app/common/views/components/trends.chart.vue
new file mode 100644
index 0000000000..723a3947f8
--- /dev/null
+++ b/src/client/app/common/views/components/trends.chart.vue
@@ -0,0 +1,89 @@
+<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="hsl(200, 80%, 70%)"></stop>
+ <stop offset="100%" stop-color="hsl(90, 80%, 70%)"></stop>
+ </linearGradient>
+ <mask :id="maskId" x="0" y="0" :width="viewBoxX" :height="viewBoxY">
+ <polygon
+ :points="polygonPoints"
+ fill="#fff"
+ fill-opacity="0.5"/>
+ <polyline
+ :points="polylinePoints"
+ fill="none"
+ stroke="#fff"
+ stroke-width="2"/>
+ <circle
+ :cx="headX"
+ :cy="headY"
+ r="3"
+ fill="#fff"/>
+ </mask>
+ </defs>
+ <rect
+ x="-10" y="-10"
+ :width="viewBoxX + 20" :height="viewBoxY + 20"
+ :style="`stroke: none; fill: url(#${ gradientId }); mask: url(#${ maskId })`"/>
+</svg>
+</template>
+
+<script lang="ts">
+import Vue from 'vue';
+import * as uuid from 'uuid';
+
+export default Vue.extend({
+ props: {
+ src: {
+ type: Array,
+ required: true
+ }
+ },
+ data() {
+ return {
+ viewBoxX: 50,
+ viewBoxY: 30,
+ gradientId: uuid(),
+ maskId: uuid(),
+ polylinePoints: '',
+ polygonPoints: '',
+ headX: null,
+ headY: null,
+ clock: null
+ };
+ },
+ watch: {
+ src() {
+ this.draw();
+ }
+ },
+ created() {
+ this.draw();
+
+ // Vueが何故かWatchを発動させない場合があるので
+ this.clock = setInterval(this.draw, 1000);
+ },
+ beforeDestroy() {
+ clearInterval(this.clock);
+ },
+ methods: {
+ draw() {
+ const stats = this.src.slice().reverse();
+ const peak = Math.max.apply(null, stats) || 1;
+
+ const polylinePoints = stats.map((n, i) => [
+ i * (this.viewBoxX / (stats.length - 1)),
+ (1 - (n / peak)) * this.viewBoxY
+ ]);
+
+ this.polylinePoints = polylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
+
+ this.polygonPoints = `0,${ this.viewBoxY } ${ this.polylinePoints } ${ this.viewBoxX },${ this.viewBoxY }`;
+
+ this.headX = polylinePoints[polylinePoints.length - 1][0];
+ this.headY = polylinePoints[polylinePoints.length - 1][1];
+ }
+ }
+});
+</script>