diff --git a/frontend/src/components/SvgGraph.vue b/frontend/src/components/SvgGraph.vue index 1c78bd3..b1f4cc0 100644 --- a/frontend/src/components/SvgGraph.vue +++ b/frontend/src/components/SvgGraph.vue @@ -11,10 +11,14 @@ import { import { useNow } from '@/composables/ticker'; import { GRAPH_DATA, type GraphData, GraphSide } from '@/graph/graph'; import TimeText from '@/components/TimeText.vue'; -import { getDateString } from '@/datetime'; +import { + getDateString, + getDurationString, + parseDurationString, +} from '@/datetime'; const props = defineProps<{ - duration?: number; + initial_duration?: number; utc?: boolean; left_axis?: boolean; right_axis?: boolean; @@ -56,12 +60,7 @@ onUnmounted(() => { }); const now = useNow(33); -const window_duration = computed(() => { - if (props.duration) { - return props.duration; - } - return 10 * 1000; // 10 seconds -}); +const window_duration = ref(props.initial_duration || 10 * 1000); const time_lines = [ 1, // 1ms @@ -148,6 +147,18 @@ const max_x_text = computed({ } }, }); +const duration_text = computed({ + get() { + return getDurationString(window_duration.value); + }, + set(newValue) { + const new_duration = parseDurationString(newValue); + if (!Number.isNaN(new_duration)) { + window_duration.value = Math.max(new_duration, 1); + fetch_history.value++; + } + }, +}); const x_map = (x: number) => { return ( @@ -200,13 +211,9 @@ const mouse_x = ref(null); function onMouseMove(event: MouseEvent) { if (props.cursor) { - const new_x = + mouse_x.value = event.clientX - (event.currentTarget as Element).getBoundingClientRect().left; - if (new_x == 0) { - console.log(event); - } - mouse_x.value = new_x; } } @@ -220,8 +227,6 @@ const mouse_t = computed(() => { } const t = inv_x_map(mouse_x.value); if (t < min_x.value || t > max_x.value) { - // console.log(`x ${mouse_x.value} t ${t} min ${t < min_x.value} max ${t > max_x.value}`) - // debugger; return null; } return t; @@ -237,10 +242,16 @@ const show_data_at_time = computed(() => { const should_fade = ref(false); +const max_temporal_resolution = computed(() => { + const delta_t = window_duration.value; + return Math.floor(delta_t / 1000); // Aim for a maximum of 1000 data points +}); + provide(GRAPH_DATA, { border_top: border_top, min_x: min_x, max_x: max_x, + max_temporal_resolution: max_temporal_resolution, live: live, fetch_history: fetch_history, width: () => @@ -269,6 +280,14 @@ provide(GRAPH_DATA, { :style="`height: ${controls_height}px`" >
+
+ +
10); -const min_sep = computed(() => - Math.min(props.minimum_separation || 0, maximum_minimum_separation_live), -); const graph_data = inject(GRAPH_DATA)!; const axis_data = inject(AXIS_DATA)!; +const data_min_sep = computed(() => { + return Math.max( + props.minimum_separation || 0, + toValue(graph_data.max_temporal_resolution), + ); +}); + +const live_min_sep = computed(() => + Math.min(data_min_sep.value, maximum_minimum_separation_live), +); + const { data: telemetry_data } = useTelemetry(() => props.data); const websocket = inject>(WEBSOCKET_SYMBOL)!; const value = websocket.value.listen_to_telemetry( telemetry_data, - min_sep, + live_min_sep, graph_data.live, ); @@ -95,7 +103,7 @@ watch([value], ([val]) => { x: val_t, y: item_val, } as Point; - memo.value.insert(new_item, props.minimum_separation); + memo.value.insert(new_item, data_min_sep.value); if (item_val < min.value) { min.value = item_val; } @@ -118,7 +126,7 @@ watch( const min_x = new Date(toValue(graph_data.min_x)); const max_x = new Date(toValue(graph_data.max_x)); const res = await fetch( - `/api/tlm/history/${uuid}?from=${min_x.toISOString()}&to=${max_x.toISOString()}&resolution=${props.minimum_separation || 0}`, + `/api/tlm/history/${uuid}?from=${min_x.toISOString()}&to=${max_x.toISOString()}&resolution=${data_min_sep.value}`, ); const response = (await res.json()) as TelemetryDataItem[]; for (const data_item of response) { @@ -136,9 +144,7 @@ watch( max.value = item_val; } } - memo.value.reduce_to_maximum_separation( - props.minimum_separation || 0, - ); + memo.value.reduce_to_maximum_separation(data_min_sep.value); triggerRef(memo); debounced_recompute(); recompute_bounds.value++; @@ -438,6 +444,11 @@ function onMouseExit(event: MouseEvent) {
{{ telemetry_data?.data_type }}
+
+ {{ + current_data_point?.y || 'Missing Data' + }} +