diff --git a/frontend/src/components/SvgGraph.vue b/frontend/src/components/SvgGraph.vue index 7155d3c..ab67068 100644 --- a/frontend/src/components/SvgGraph.vue +++ b/frontend/src/components/SvgGraph.vue @@ -7,6 +7,7 @@ import TimeText from '@/components/TimeText.vue'; const props = defineProps<{ width: number; height: number; + duration?: number; border_left_right?: number; border_top_bottom?: number; utc?: boolean; @@ -21,7 +22,12 @@ const height = computed(() => { }); const now = useNow(33); -const window_duration = 10 * 1000; // 10 seconds +const window_duration = computed(() => { + if (props.duration) { + return props.duration; + } + return 10 * 1000; // 10 seconds +}); const time_lines = [ 1, // 1ms @@ -58,7 +64,7 @@ const border_left_right = computed(() => props.border_left_right || 0); const border_top_bottom = computed(() => props.border_top_bottom || 0); const max_x = now; -const min_x = computed(() => max_x.value - window_duration); +const min_x = computed(() => max_x.value - window_duration.value); const x_map = (x: number) => { const diff_x = max_x.value - min_x.value; @@ -79,10 +85,10 @@ provide(GRAPH_DATA, { height: () => height.value - 2 * border_top_bottom.value, x_map: x_map, lines: telemetry_lines, - max_update_rate: 1000 / 10 + max_update_rate: 1000 / 10, }); -const duration = computed(() => { +const line_duration = computed(() => { const diff_x = max_x.value - min_x.value; return time_lines.find((duration) => diff_x / duration >= 2)!; }); @@ -90,11 +96,11 @@ const duration = computed(() => { const lines = computed(() => { const result = []; for ( - let i = Math.ceil(max_x.value / duration.value); - i >= Math.ceil(min_x.value / duration.value) - 5; + let i = Math.ceil(max_x.value / line_duration.value); + i >= Math.ceil(min_x.value / line_duration.value) - 5; i-- ) { - const x = i * duration.value; + const x = i * line_duration.value; result.push(x); } return result; @@ -140,7 +146,7 @@ const lines = computed(() => { :y="height - border_top_bottom + text_offset" :timestamp="tick" :utc="props.utc" - :show_millis="duration < 1000" + :show_millis="line_duration < 1000" > diff --git a/frontend/src/components/TelemetryLine.vue b/frontend/src/components/TelemetryLine.vue index 6c2aba0..3960785 100644 --- a/frontend/src/components/TelemetryLine.vue +++ b/frontend/src/components/TelemetryLine.vue @@ -12,7 +12,6 @@ import { watch, } from 'vue'; import { - type TelemetryDataItem, WEBSOCKET_SYMBOL, type WebsocketHandle, } from '@/composables/websocket'; @@ -23,16 +22,20 @@ import type { Point } from '@/graph/line'; const props = defineProps<{ data: string; + minimum_separation?: number; class?: string; }>(); -const smoothing_distance = 0.15 * 1000; +const smoothing_distance_x = 5; const text_offset = computed(() => 10); const { data } = useTelemetry(() => props.data); const websocket = inject>(WEBSOCKET_SYMBOL)!; -const value = websocket.value.listen_to_telemetry(data); +const value = websocket.value.listen_to_telemetry( + data, + props.minimum_separation, +); const graph_data = inject(GRAPH_DATA)!; const axis_data = inject(AXIS_DATA)!; @@ -46,7 +49,10 @@ function trigger_recompute() { recompute_points.value = Date.now(); } function debounced_recompute() { - if (recompute_points.value + toValue(graph_data.max_update_rate) < Date.now()) { + if ( + recompute_points.value + toValue(graph_data.max_update_rate) < + Date.now() + ) { trigger_recompute(); } } @@ -72,10 +78,12 @@ watch([value], ([val]) => { if (val_t >= min_x) { // TODO: Insert this in the right spot in memo const item_val = val.value[data.value!.data_type] as number; - const new_memo = [{ - x: val_t, - y: item_val, - }].concat(memo.value); + const new_memo = [ + { + x: val_t, + y: item_val, + }, + ].concat(memo.value); if (item_val < min.value) { min.value = item_val; } @@ -100,10 +108,7 @@ watch([graph_data.min_x, graph_data.max_x], ([min_x, max_x]) => { } } if (max_x) { - while ( - new_memo.length > 2 && - new_memo[1].x > toValue(max_x) - ) { + while (new_memo.length > 2 && new_memo[1].x > toValue(max_x)) { new_memo.shift(); memo_changed = true; } @@ -137,7 +142,7 @@ watch( watch( [max, axis_data.axis_update_watch], ([max_val]) => { - trigger_recompute() + trigger_recompute(); axis_data.max_y_callback(max_val); }, { @@ -145,7 +150,7 @@ watch( }, ); -const points = ref(""); +const points = ref(''); const old_max = ref(0); @@ -153,42 +158,38 @@ const group_transform = computed(() => { const new_max = toValue(graph_data.max_x); const offset = graph_data.x_map(old_max.value) - graph_data.x_map(new_max); return `translate(${offset} 0)`; -}) +}); -watch( - [recompute_points], - () => { - let new_points = ''; - if (memo.value.length == 0 || data.value == null) { - return ''; - } - - const future_number = toValue(graph_data.max_x) + 99999999; - - let last_x = graph_data.x_map(future_number); - old_max.value = toValue(graph_data.max_x); - let last_t = future_number + smoothing_distance; - - for (const data_item of memo.value) { - const t = data_item.x; - const v = data_item.y; - const x = graph_data.x_map(t); - const y = axis_data.y_map(v); - - if (last_t - t < smoothing_distance) { - new_points += ` ${x},${y}`; - } else { - new_points += ` ${last_x},${y} ${x},${y}`; - } - last_x = x; - last_t = t; - if (last_x <= 0.0) { - break; - } - } - points.value = new_points; +watch([recompute_points], () => { + let new_points = ''; + if (memo.value.length == 0 || data.value == null) { + return ''; } -) + + const future_number = + toValue(graph_data.max_x) + toValue(graph_data.max_update_rate); + + let last_x = graph_data.x_map(future_number) + smoothing_distance_x; + old_max.value = toValue(graph_data.max_x); + + for (const data_item of memo.value) { + const t = data_item.x; + const v = data_item.y; + const x = graph_data.x_map(t); + const y = axis_data.y_map(v); + + if (last_x - x < smoothing_distance_x) { + new_points += ` ${x},${y}`; + } else { + new_points += ` ${last_x},${y} ${x},${y}`; + } + last_x = x; + if (last_x <= 0.0) { + break; + } + } + points.value = new_points; +}); const current_value = computed(() => { const val = value.value; @@ -201,9 +202,7 @@ const current_value = computed(() => {