feat: 添加debugger后端api,并修改waveformdisplay使其更加通用
This commit is contained in:
@@ -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];
|
||||
|
||||
@@ -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 };
|
||||
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user