feat: 添加debugger后端api,并修改waveformdisplay使其更加通用

This commit is contained in:
2025-07-29 15:45:45 +08:00
parent a4192659d1
commit 23d4459406
6 changed files with 697 additions and 103 deletions

View File

@@ -2,12 +2,12 @@
<div
class="w-full"
:class="{
'h-48': !analyzer.logicData.value,
'h-150': analyzer.logicData.value,
'h-48': !props.data,
'h-150': props.data,
}"
>
<v-chart
v-if="analyzer.logicData.value"
v-if="props.data"
class="w-full h-full"
:option="option"
autoresize
@@ -17,17 +17,20 @@
v-else
class="w-full h-full flex flex-col gap-6 items-center justify-center"
>
<div class="text-center">
<h3 class="text-xl font-semibold text-slate-600 mb-2">
暂无逻辑分析数据
</h3>
</div>
<template v-if="hasSlot">
<slot />
</template>
<template v-else>
<div class="text-center">
<h3 class="text-xl font-semibold text-slate-600 mb-2">暂无数据</h3>
</div>
</template>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, shallowRef } from "vue";
import { computed, shallowRef, useSlots } from "vue";
import VChart from "vue-echarts";
// Echarts
@@ -56,9 +59,8 @@ import type {
XAXisOption,
YAXisOption,
} from "echarts/types/dist/shared";
import { useRequiredInjection } from "@/utils/Common";
import { isUndefined } from "lodash";
import { useWaveformManager } from "./WaveformManager";
import type { LogicDataType } from ".";
use([
TooltipComponent,
@@ -81,7 +83,12 @@ type EChartsOption = ComposeOption<
| MarkLineComponentOption
>;
const analyzer = useRequiredInjection(useWaveformManager);
const props = defineProps<{
data?: LogicDataType;
}>();
const slots = useSlots();
const hasSlot = computed(() => !!slots.default && slots.default().length > 0);
// 添加更新选项来减少重绘
const updateOptions = shallowRef({
@@ -91,13 +98,13 @@ const updateOptions = shallowRef({
});
const option = computed((): EChartsOption => {
if (isUndefined(analyzer.logicData.value)) return {};
if (isUndefined(props.data)) return {};
// 只获取启用的通道使用y数据结构
const enabledChannels = analyzer.logicData.value.y.filter(
const enabledChannels = props.data.y.filter(
(channel) => channel.enabled,
);
const enabledChannelIndices = analyzer.logicData.value.y
const enabledChannelIndices = props.data.y
.map((channel, index) => (channel.enabled ? index : -1))
.filter((index) => index !== -1);
@@ -124,11 +131,11 @@ const option = computed((): EChartsOption => {
{
type: "category",
boundaryGap: true,
data: analyzer.logicData.value.x.map((x) => x.toFixed(3)),
data: props.data.x.map((x) => x.toFixed(3)),
axisLabel: {
formatter: (value: string) =>
analyzer.logicData.value
? `${value}${analyzer.logicData.value.xUnit}`
props.data
? `${value}${props.data.xUnit}`
: `${value}`,
},
},
@@ -157,7 +164,7 @@ const option = computed((): EChartsOption => {
const series: LineSeriesOption[] = [];
enabledChannelIndices.forEach(
(originalIndex: number, displayIndex: number) => {
const channel = analyzer.logicData.value!.y[originalIndex];
const channel = props.data!.y[originalIndex];
if (channel.type === "logic") {
// logic类型原样显示
series.push({
@@ -182,7 +189,7 @@ const option = computed((): EChartsOption => {
});
} else if (channel.type === "number") {
const values = channel.value;
const xArr = analyzer.logicData.value!.x;
const xArr = props.data!.x;
// 构造带过渡的点序列
function buildVcdLine(valArr: number[], high: number, low: number) {
const points: { x: number; y: number }[] = [];
@@ -208,7 +215,8 @@ const option = computed((): EChartsOption => {
let lastIdx = 0;
// 格式化函数
function formatValue(val: number) {
if (channel.base === "hex") return "0x" + val.toString(16).toUpperCase();
if (channel.base === "hex")
return "0x" + val.toString(16).toUpperCase();
if (channel.base === "bin") return "0b" + val.toString(2);
return val.toString();
}
@@ -314,12 +322,12 @@ const option = computed((): EChartsOption => {
},
formatter: (params: any) => {
if (Array.isArray(params) && params.length > 0) {
const timeValue = analyzer.logicData.value!.x[params[0].dataIndex];
const timeValue = props.data!.x[params[0].dataIndex];
const dataIndex = params[0].dataIndex;
let tooltip = `Time: ${timeValue.toFixed(3)}${analyzer.logicData.value!.xUnit}<br/>`;
let tooltip = `Time: ${timeValue.toFixed(3)}${props.data!.xUnit}<br/>`;
enabledChannelIndices.forEach(
(originalIndex: number, displayIndex: number) => {
const channel = analyzer.logicData.value!.y[originalIndex];
const channel = props.data!.y[originalIndex];
if (channel.type === "logic") {
const channelName = channel.name;
const originalValue = channel.value[dataIndex];

View File

@@ -1,73 +0,0 @@
import { createInjectionState } from "@vueuse/core";
import { shallowRef } from "vue";
export type LogicDataType = {
x: number[];
y: {
enabled: boolean;
type: "logic" | "number";
name: string;
color: string;
value: number[];
base: "bin" | "dec" | "hex";
}[];
xUnit: "s" | "ms" | "us" | "ns";
};
// 生成4路测试数据的函数
export function generateTestData(): LogicDataType {
// 生成时间轴数据 (0-100ns每1ns一个采样点)
const timePoints = Array.from({ length: 101 }, (_, i) => i);
return {
x: timePoints,
y: [
{
enabled: true,
type: "logic",
name: "CLK",
color: "#ff0000",
value: timePoints.map((t) => t % 2), // 时钟信号每1ns翻转
base: "bin",
},
{
enabled: true,
type: "logic",
name: "RESET",
color: "#00ff00",
value: timePoints.map((t) => (t < 10 ? 1 : 0)), // 复位信号前10ns为高电平
base: "bin",
},
{
enabled: true,
type: "number",
name: "DATA",
color: "#0000ff",
value: timePoints.map((t) => Math.floor(t / 4) % 16), // 计数器每4ns递增
base: "hex",
},
{
enabled: true,
type: "logic",
name: "ENABLE",
color: "#ff8800",
value: timePoints.map((t) => (t >= 20 && t < 80 ? 1 : 0)), // 使能信号20-80ns为高电平
base: "bin",
},
],
xUnit: "ns",
};
}
const [useProvideWaveformManager, useWaveformManager] = createInjectionState(
() => {
const logicData = shallowRef<LogicDataType>();
return {
logicData,
generateTestData,
};
},
);
export { useProvideWaveformManager, useWaveformManager };

View File

@@ -1,5 +1,61 @@
import WaveformDisplay from "./WaveformDisplay.vue";
export {
WaveformDisplay
export type LogicDataType = {
x: number[];
y: {
enabled: boolean;
type: "logic" | "number";
name: string;
color: string;
value: number[];
base: "bin" | "dec" | "hex";
}[];
xUnit: "s" | "ms" | "us" | "ns";
};
// 生成4路测试数据的函数
export function generateTestData(): LogicDataType {
// 生成时间轴数据 (0-100ns每1ns一个采样点)
const timePoints = Array.from({ length: 101 }, (_, i) => i);
return {
x: timePoints,
y: [
{
enabled: true,
type: "logic",
name: "CLK",
color: "#ff0000",
value: timePoints.map((t) => t % 2), // 时钟信号每1ns翻转
base: "bin",
},
{
enabled: true,
type: "logic",
name: "RESET",
color: "#00ff00",
value: timePoints.map((t) => (t < 10 ? 1 : 0)), // 复位信号前10ns为高电平
base: "bin",
},
{
enabled: true,
type: "number",
name: "DATA",
color: "#0000ff",
value: timePoints.map((t) => Math.floor(t / 4) % 16), // 计数器每4ns递增
base: "hex",
},
{
enabled: true,
type: "logic",
name: "ENABLE",
color: "#ff8800",
value: timePoints.map((t) => (t >= 20 && t < 80 ? 1 : 0)), // 使能信号20-80ns为高电平
base: "bin",
},
],
xUnit: "ns",
};
}
export { WaveformDisplay };