Files
weather-station/client/src/components/Seismic.vue
2026-06-27 13:47:38 -04:00

69 lines
2.1 KiB
Vue

<script setup lang="ts">
import Loading from '@/components/Loading.vue';
import {ref, onMounted, onUnmounted} from 'vue';
import {api} from '../services/api';
import MetricRow from './MetricRow.vue';
const d = ref<any>(null);
const history = ref<number[]>([]);
const W = 320, H = 60, MAX_PTS = 120;
let interval: ReturnType<typeof setInterval>;
function toPath(pts: number[]) {
if (!pts.length) return '';
const mid = H / 2, amp = H / 2 - 4;
const max = Math.max(Math.max(...pts), 1.0); // 1.0 = min scale floor
// Fixed px per point — path grows left→right, never stretches
const segW = W / (MAX_PTS - 1);
const subPts: { x: number; y: number }[] = [];
pts.forEach((v, i) => {
const norm = (v / max) * amp;
const baseX = i * segW;
const s = segW / 4;
subPts.push({ x: baseX, y: mid - norm * 0.5 });
subPts.push({ x: baseX + s, y: mid - norm });
subPts.push({ x: baseX + s * 2, y: mid + norm });
subPts.push({ x: baseX + s * 3, y: mid });
});
return subPts.map((p, i) =>
`${i === 0 ? 'M' : 'L'} ${p.x.toFixed(1)} ${p.y.toFixed(1)}`
).join(' ');
}
async function poll() {
d.value = await api.current('seismic_magnitude');
history.value.push(d.value.seismic_magnitude ?? 0);
if(history.value.length > MAX_PTS) history.value.shift();
}
onMounted(async () => { await poll(); interval = setInterval(poll, 1000); });
onUnmounted(() => clearInterval(interval));
</script>
<style scoped lang="scss">
svg { width: 100%; height: 60px; overflow: visible; }
</style>
<template>
<div class="card">
<div class="card-title">🫨 Seismic</div>
<div v-if="!d" class="p-2">
<div class="w-100 pos-rel br-2 overflow-hidden" style="height: 80px">
<Loading />
</div>
</div>
<template v-else>
<MetricRow label="Magnitude" :value="d.seismic_magnitude?.toFixed(1)" metric-key="seismic_magnitude" :data="d" />
<svg :viewBox="`0 0 ${W} ${H}`" preserveAspectRatio="none">
<line :x1="0" :y1="H/2" :x2="W" :y2="H/2" stroke="var(--border)" stroke-width="1" />
<path :d="toPath(history)" fill="none" stroke="var(--accent)" stroke-width="1.5" />
</svg>
</template>
</div>
</template>