add graph cursor
This commit is contained in:
@@ -21,6 +21,7 @@ const props = defineProps<{
|
||||
hide_time_ticks?: boolean;
|
||||
include_controls?: boolean;
|
||||
legend?: GraphSide;
|
||||
cursor?: boolean;
|
||||
}>();
|
||||
|
||||
const divRef = useTemplateRef<HTMLDivElement>('graph-div');
|
||||
@@ -109,15 +110,23 @@ const border_bottom = computed(() => (props.hide_time_labels ? 6 : 24));
|
||||
const max_x = now;
|
||||
const min_x = computed(() => max_x.value - window_duration.value);
|
||||
|
||||
const diff_x = computed(() => max_x.value - min_x.value);
|
||||
|
||||
const x_map = (x: number) => {
|
||||
const diff_x = max_x.value - min_x.value;
|
||||
return (
|
||||
((width.value - border_left.value - border_right.value) *
|
||||
(x - min_x.value)) /
|
||||
diff_x +
|
||||
diff_x.value +
|
||||
border_left.value
|
||||
);
|
||||
};
|
||||
const inv_x_map = (x: number) => {
|
||||
return (
|
||||
((x - border_left.value) * diff_x.value) /
|
||||
(width.value - border_left.value - border_right.value) +
|
||||
min_x.value
|
||||
);
|
||||
};
|
||||
|
||||
const telemetry_lines = ref([]);
|
||||
|
||||
@@ -132,25 +141,6 @@ const legend_x_stride = computed(() => 0);
|
||||
const legend_y_stride = computed(() => 16);
|
||||
const legend_width_output = computed(() => legend_width - 8);
|
||||
|
||||
provide<GraphData>(GRAPH_DATA, {
|
||||
border_top: border_top,
|
||||
min_x: min_x,
|
||||
max_x: now,
|
||||
width: () =>
|
||||
Math.max(width.value - border_left.value - border_right.value, 0),
|
||||
height: () =>
|
||||
Math.max(height.value - border_top.value - border_bottom.value, 0),
|
||||
x_map: x_map,
|
||||
lines: telemetry_lines,
|
||||
max_update_rate: 1000 / 10,
|
||||
legend_enabled: legend_enabled,
|
||||
legend_x: legend_x,
|
||||
legend_y: legend_y,
|
||||
legend_x_stride: legend_x_stride,
|
||||
legend_y_stride: legend_y_stride,
|
||||
legend_width: legend_width_output,
|
||||
});
|
||||
|
||||
const line_duration = computed(() => {
|
||||
const diff_x = max_x.value - min_x.value;
|
||||
return time_lines.find((duration) => diff_x / duration >= 2)!;
|
||||
@@ -168,6 +158,65 @@ const lines = computed(() => {
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
const mouse_x = ref<number | null>(null);
|
||||
|
||||
function onMouseMove(event: MouseEvent) {
|
||||
if (props.cursor) {
|
||||
const new_x =
|
||||
event.clientX -
|
||||
(event.currentTarget as Element).getBoundingClientRect().left;
|
||||
if (new_x == 0) {
|
||||
console.log(event);
|
||||
}
|
||||
mouse_x.value = new_x;
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseOut() {
|
||||
mouse_x.value = null;
|
||||
}
|
||||
|
||||
const mouse_t = computed(() => {
|
||||
if (mouse_x.value === null) {
|
||||
return null;
|
||||
}
|
||||
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;
|
||||
});
|
||||
|
||||
const show_data_at_time = computed(() => {
|
||||
if (mouse_t.value === null) {
|
||||
return max_x.value;
|
||||
} else {
|
||||
return mouse_t.value;
|
||||
}
|
||||
});
|
||||
|
||||
provide<GraphData>(GRAPH_DATA, {
|
||||
border_top: border_top,
|
||||
min_x: min_x,
|
||||
max_x: now,
|
||||
width: () =>
|
||||
Math.max(width.value - border_left.value - border_right.value, 0),
|
||||
height: () =>
|
||||
Math.max(height.value - border_top.value - border_bottom.value, 0),
|
||||
x_map: x_map,
|
||||
lines: telemetry_lines,
|
||||
max_update_rate: 1000 / 10,
|
||||
legend_enabled: legend_enabled,
|
||||
legend_x: legend_x,
|
||||
legend_y: legend_y,
|
||||
legend_x_stride: legend_x_stride,
|
||||
legend_y_stride: legend_y_stride,
|
||||
legend_width: legend_width_output,
|
||||
cursor_time: show_data_at_time,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -182,7 +231,14 @@ const lines = computed(() => {
|
||||
<span>Duration Dropdown</span>
|
||||
</div>
|
||||
</div>
|
||||
<svg ref="svg_graph" class="graph" :width="width" :height="height">
|
||||
<svg
|
||||
ref="svg_graph"
|
||||
class="graph"
|
||||
:width="width"
|
||||
:height="height"
|
||||
@mousemove="onMouseMove"
|
||||
@mouseleave="onMouseOut"
|
||||
>
|
||||
<defs>
|
||||
<clipPath id="content">
|
||||
<rect
|
||||
@@ -231,6 +287,27 @@ const lines = computed(() => {
|
||||
</template>
|
||||
</g>
|
||||
<slot></slot>
|
||||
<g class="cursor_tick" v-if="mouse_t && cursor">
|
||||
<rect
|
||||
:x="x_map(mouse_t) - 100"
|
||||
:y="height - border_bottom"
|
||||
width="200"
|
||||
height="20"
|
||||
></rect>
|
||||
<polyline
|
||||
:points="`${x_map(mouse_t)},${border_top} ${x_map(mouse_t)},${height - border_bottom}`"
|
||||
></polyline>
|
||||
<TimeText
|
||||
v-if="mouse_t"
|
||||
id="cursor_text"
|
||||
class="bottom_edge"
|
||||
:x="x_map(mouse_t)"
|
||||
:y="height - border_bottom + text_offset"
|
||||
:timestamp="mouse_t"
|
||||
:utc="props.utc"
|
||||
show_millis
|
||||
></TimeText>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
@@ -249,6 +326,16 @@ const lines = computed(() => {
|
||||
fill: variables.$time-tick;
|
||||
}
|
||||
|
||||
.cursor_tick {
|
||||
stroke: variables.$cursor-tick;
|
||||
fill: variables.$cursor-tick;
|
||||
}
|
||||
|
||||
.cursor_tick > rect {
|
||||
fill: variables.$background-color;
|
||||
opacity: 66%;
|
||||
}
|
||||
|
||||
div.full-size {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
Reference in New Issue
Block a user