initial graph

This commit is contained in:
2024-12-02 23:30:05 -08:00
parent 8e4a94f8c5
commit 3eafc20e9d
12 changed files with 367 additions and 145 deletions

View File

@@ -0,0 +1,24 @@
<script setup lang="ts">
import { provide } from 'vue'
import { AXIS_DATA, type AxisData } from '@/graph/axis'
const props = defineProps<{
y_limits?: [number, number]
}>();
provide<AxisData>(AXIS_DATA, {
min_y: -1.05,
max_y: 1.05,
});
</script>
<template>
<g>
<slot></slot>
</g>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,40 @@
<script setup lang="ts">
import { computed, provide } from 'vue'
import { useNow } from '@/composables/ticker'
import { GRAPH_DATA, type GraphData } from '@/graph/graph'
const props = defineProps<{
width: number
height: number
// min_t?: number
// max_t?: number
}>();
const svg_viewbox = computed(() => {
return `0 0 ${props.width} ${props.height}`;
})
const now = useNow(33);
const window_duration = 30 * 1000; // 30 seconds
const min_x = computed(() => now.value - window_duration);
provide<GraphData>(GRAPH_DATA, {
min_x: min_x,
max_x: now,
width: () => props.width,
height: () => props.height,
});
</script>
<template>
<svg :viewBox="svg_viewbox" :width="props.width" :height="props.height">
<slot></slot>
</svg>
</template>
<style scoped lang="scss">
svg {
border: white 1px solid;
}
</style>

View File

@@ -0,0 +1,84 @@
<script setup lang="ts">
import { useTelemetry } from '@/composables/telemetry'
import { computed, inject, shallowRef, type ShallowRef, toValue, useId, watch } from 'vue'
import { type TelemetryDataItem, WEBSOCKET_SYMBOL, type WebsocketHandle } from '@/composables/websocket'
import { GRAPH_DATA, type GraphData } from '@/graph/graph'
import { AXIS_DATA, type AxisData } from '@/graph/axis'
const props = defineProps<{
data: string
color: string
}>();
const smoothing_distance = 0.15 * 1000;
const { data, error } = useTelemetry(() => props.data);
const websocket = inject<ShallowRef<WebsocketHandle>>(WEBSOCKET_SYMBOL)!;
let value = websocket.value.listen_to_telemetry(data);
const graph_data = inject<GraphData>(GRAPH_DATA)!;
const axis_data = inject<AxisData>(AXIS_DATA)!;
let memo = shallowRef<TelemetryDataItem[]>([]);
watch([value], ([val]) => {
const min_x = toValue(graph_data.min_x);
if (val) {
const new_memo = [val].concat(memo.value);
while (new_memo.length > 2 && Date.parse(new_memo[new_memo.length - 2].timestamp) < min_x) {
new_memo.pop();
}
memo.value = new_memo;
}
});
let points = computed(() => {
let points = "";
if (memo.value.length == 0 || data.value == null) {
return "";
}
const max_x = toValue(graph_data.max_x);
const min_x = toValue(graph_data.min_x);
const diff_x = max_x - min_x;
const max_y = toValue(axis_data.max_y);
const min_y = toValue(axis_data.min_y);
const diff_y = max_y - min_y;
const width = toValue(graph_data.width);
const height = toValue(graph_data.height);
let last_x = width;
let last_t = Math.max(max_x, Date.now());
for (let data_item of memo.value) {
const t = Date.parse(data_item.timestamp);
const v = data_item.value[data.value.data_type];
const x = width * (t - min_x) / diff_x;
const y = height * (1 - (v - min_y) / diff_y);
if (last_t - t < smoothing_distance) {
points += ` ${x},${y}`;
} else {
points += ` ${last_x},${y} ${x},${y}`;
}
last_x = x;
last_t = t;
if (last_x <= 0.0) {
break;
}
}
return points;
});
console.log(useId());
</script>
<template>
<polyline fill="none" :stroke="color" stroke-width="1" :points="points"></polyline>
</template>
<style>
</style>