egirlskey/packages/frontend/src/widgets/server-metric/net.vue
2022-12-27 18:29:39 +09:00

140 lines
3.4 KiB
Vue

<template>
<div class="oxxrhrto">
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`">
<polygon
:points="inPolygonPoints"
fill="#94a029"
fill-opacity="0.5"
/>
<polyline
:points="inPolylinePoints"
fill="none"
stroke="#94a029"
stroke-width="1"
/>
<circle
:cx="inHeadX"
:cy="inHeadY"
r="1.5"
fill="#94a029"
/>
<text x="1" y="5">NET rx <tspan>{{ bytes(inRecent) }}</tspan></text>
</svg>
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`">
<polygon
:points="outPolygonPoints"
fill="#ff9156"
fill-opacity="0.5"
/>
<polyline
:points="outPolylinePoints"
fill="none"
stroke="#ff9156"
stroke-width="1"
/>
<circle
:cx="outHeadX"
:cy="outHeadY"
r="1.5"
fill="#ff9156"
/>
<text x="1" y="5">NET tx <tspan>{{ bytes(outRecent) }}</tspan></text>
</svg>
</div>
</template>
<script lang="ts" setup>
import { onMounted, onBeforeUnmount } from 'vue';
import bytes from '@/filters/bytes';
const props = defineProps<{
connection: any,
meta: any
}>();
let viewBoxX: number = $ref(50);
let viewBoxY: number = $ref(30);
let stats: any[] = $ref([]);
let inPolylinePoints: string = $ref('');
let outPolylinePoints: string = $ref('');
let inPolygonPoints: string = $ref('');
let outPolygonPoints: string = $ref('');
let inHeadX: any = $ref(null);
let inHeadY: any = $ref(null);
let outHeadX: any = $ref(null);
let outHeadY: any = $ref(null);
let inRecent: number = $ref(0);
let outRecent: number = $ref(0);
onMounted(() => {
props.connection.on('stats', onStats);
props.connection.on('statsLog', onStatsLog);
props.connection.send('requestLog', {
id: Math.random().toString().substr(2, 8),
});
});
onBeforeUnmount(() => {
props.connection.off('stats', onStats);
props.connection.off('statsLog', onStatsLog);
});
function onStats(connStats) {
stats.push(connStats);
if (stats.length > 50) stats.shift();
const inPeak = Math.max(1024 * 64, Math.max(...stats.map(s => s.net.rx)));
const outPeak = Math.max(1024 * 64, Math.max(...stats.map(s => s.net.tx)));
let inPolylinePointsStats = stats.map((s, i) => [viewBoxX - ((stats.length - 1) - i), (1 - (s.net.rx / inPeak)) * viewBoxY]);
let outPolylinePointsStats = stats.map((s, i) => [viewBoxX - ((stats.length - 1) - i), (1 - (s.net.tx / outPeak)) * viewBoxY]);
inPolylinePoints = inPolylinePointsStats.map(xy => `${xy[0]},${xy[1]}`).join(' ');
outPolylinePoints = outPolylinePointsStats.map(xy => `${xy[0]},${xy[1]}`).join(' ');
inPolygonPoints = `${viewBoxX - (stats.length - 1)},${viewBoxY} ${inPolylinePoints} ${viewBoxX},${viewBoxY}`;
outPolygonPoints = `${viewBoxX - (stats.length - 1)},${viewBoxY} ${outPolylinePoints} ${viewBoxX},${viewBoxY}`;
inHeadX = inPolylinePointsStats[inPolylinePointsStats.length - 1][0];
inHeadY = inPolylinePointsStats[inPolylinePointsStats.length - 1][1];
outHeadX = outPolylinePointsStats[outPolylinePointsStats.length - 1][0];
outHeadY = outPolylinePointsStats[outPolylinePointsStats.length - 1][1];
inRecent = connStats.net.rx;
outRecent = connStats.net.tx;
}
function onStatsLog(statsLog) {
for (const revStats of [...statsLog].reverse()) {
onStats(revStats);
}
}
</script>
<style lang="scss" scoped>
.oxxrhrto {
display: flex;
> svg {
display: block;
padding: 10px;
width: 50%;
&:first-child {
padding-right: 5px;
}
&:last-child {
padding-left: 5px;
}
> text {
font-size: 4.5px;
fill: currentColor;
> tspan {
opacity: 0.5;
}
}
}
}
</style>