refactor: 修改逻辑分析仪,使其直接使用manager进行管理
This commit is contained in:
parent
9f25391540
commit
ef76f3e9c7
|
@ -1,5 +1,4 @@
|
||||||
import { createInjectionState } from "@vueuse/core";
|
import { createInjectionState } from "@vueuse/core";
|
||||||
import { generateTestLogicData, type LogicDataType } from ".";
|
|
||||||
import { shallowRef, reactive, ref, computed } from "vue";
|
import { shallowRef, reactive, ref, computed } from "vue";
|
||||||
import {
|
import {
|
||||||
CaptureConfig,
|
CaptureConfig,
|
||||||
|
@ -12,12 +11,18 @@ import {
|
||||||
import { AuthManager } from "@/utils/AuthManager";
|
import { AuthManager } from "@/utils/AuthManager";
|
||||||
import { useAlertStore } from "@/components/Alert";
|
import { useAlertStore } from "@/components/Alert";
|
||||||
|
|
||||||
|
export type LogicDataType = {
|
||||||
|
x: number[];
|
||||||
|
y: number[][]; // 8 channels of digital data (0 or 1)
|
||||||
|
xUnit: "s" | "ms" | "us" | "ns";
|
||||||
|
};
|
||||||
|
|
||||||
// 通道接口定义
|
// 通道接口定义
|
||||||
export interface Channel {
|
export type Channel = {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
label: string;
|
label: string;
|
||||||
color: string;
|
color: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 全局模式选项
|
// 全局模式选项
|
||||||
const globalModes = [
|
const globalModes = [
|
||||||
|
@ -101,6 +106,16 @@ const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
|
||||||
() => channels.filter((channel) => channel.enabled).length,
|
() => channels.filter((channel) => channel.enabled).length,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 添加计算属性:获取通道名称数组
|
||||||
|
const channelNames = computed(() =>
|
||||||
|
channels.map(channel => channel.label)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 添加计算属性:获取启用通道的名称数组
|
||||||
|
const enabledChannelNames = computed(() =>
|
||||||
|
channels.filter(channel => channel.enabled).map(channel => channel.label)
|
||||||
|
);
|
||||||
|
|
||||||
const enableAllChannels = () => {
|
const enableAllChannels = () => {
|
||||||
channels.forEach((channel) => {
|
channels.forEach((channel) => {
|
||||||
channel.enabled = true;
|
channel.enabled = true;
|
||||||
|
@ -195,6 +210,85 @@ const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
|
||||||
alert?.info("配置已重置", 2000);
|
alert?.info("配置已重置", 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 添加设置逻辑数据的方法
|
||||||
|
const setLogicData = (data: LogicDataType) => {
|
||||||
|
logicData.value = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加生成测试数据的方法
|
||||||
|
const generateTestData = () => {
|
||||||
|
const sampleRate = 10000; // 10kHz sampling
|
||||||
|
const duration = 1;
|
||||||
|
const points = Math.floor(sampleRate * duration);
|
||||||
|
|
||||||
|
const x = Array.from({ length: points }, (_, i) => (i / sampleRate) * 1000); // time in ms
|
||||||
|
|
||||||
|
// Generate 8 channels with different digital patterns
|
||||||
|
const y = [
|
||||||
|
// Channel 0: Clock signal 100Hz
|
||||||
|
Array.from(
|
||||||
|
{ length: points },
|
||||||
|
(_, i) => Math.floor((100 * i) / sampleRate) % 2,
|
||||||
|
),
|
||||||
|
// Channel 1: Clock/2 signal 50Hz
|
||||||
|
Array.from(
|
||||||
|
{ length: points },
|
||||||
|
(_, i) => Math.floor((50 * i) / sampleRate) % 2,
|
||||||
|
),
|
||||||
|
// Channel 2: Clock/4 signal 25Hz
|
||||||
|
Array.from(
|
||||||
|
{ length: points },
|
||||||
|
(_, i) => Math.floor((25 * i) / sampleRate) % 2,
|
||||||
|
),
|
||||||
|
// Channel 3: Clock/8 signal 12.5Hz
|
||||||
|
Array.from(
|
||||||
|
{ length: points },
|
||||||
|
(_, i) => Math.floor((12.5 * i) / sampleRate) % 2,
|
||||||
|
),
|
||||||
|
// Channel 4: Data signal (pseudo-random pattern)
|
||||||
|
Array.from(
|
||||||
|
{ length: points },
|
||||||
|
(_, i) => Math.abs( Math.floor(Math.sin(i * 0.01) * 10) % 2 ),
|
||||||
|
),
|
||||||
|
// Channel 5: Enable signal (periodic pulse)
|
||||||
|
Array.from(
|
||||||
|
{ length: points },
|
||||||
|
(_, i) => (Math.floor(i / 50) % 10) < 3 ? 1 : 0,
|
||||||
|
),
|
||||||
|
// Channel 6: Reset signal (occasional pulse)
|
||||||
|
Array.from(
|
||||||
|
{ length: points },
|
||||||
|
(_, i) => (Math.floor(i / 200) % 20) === 0 ? 1 : 0,
|
||||||
|
),
|
||||||
|
// Channel 7: Status signal (slow changing)
|
||||||
|
Array.from(
|
||||||
|
{ length: points },
|
||||||
|
(_, i) => Math.floor(i / 1000) % 2,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
// 同时更新通道标签为更有意义的名称
|
||||||
|
const testChannelNames = [
|
||||||
|
"CLK",
|
||||||
|
"CLK/2",
|
||||||
|
"CLK/4",
|
||||||
|
"CLK/8",
|
||||||
|
"PWM",
|
||||||
|
"ENABLE",
|
||||||
|
"RESET",
|
||||||
|
"STATUS"
|
||||||
|
];
|
||||||
|
|
||||||
|
channels.forEach((channel, index) => {
|
||||||
|
channel.label = testChannelNames[index];
|
||||||
|
});
|
||||||
|
|
||||||
|
// 设置逻辑数据
|
||||||
|
setLogicData({ x, y, xUnit: "ms" });
|
||||||
|
|
||||||
|
alert?.success("测试数据生成成功", 2000);
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// 原有的逻辑数据
|
// 原有的逻辑数据
|
||||||
logicData,
|
logicData,
|
||||||
|
@ -205,6 +299,8 @@ const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
|
||||||
channels,
|
channels,
|
||||||
signalConfigs,
|
signalConfigs,
|
||||||
enabledChannelCount,
|
enabledChannelCount,
|
||||||
|
channelNames,
|
||||||
|
enabledChannelNames,
|
||||||
|
|
||||||
// 选项数据
|
// 选项数据
|
||||||
globalModes,
|
globalModes,
|
||||||
|
@ -217,6 +313,8 @@ const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
|
||||||
setGlobalMode,
|
setGlobalMode,
|
||||||
applyConfiguration,
|
applyConfiguration,
|
||||||
resetConfiguration,
|
resetConfiguration,
|
||||||
|
setLogicData,
|
||||||
|
generateTestData,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="group relative px-8 py-3 bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700 text-white font-medium rounded-lg shadow-lg hover:shadow-xl transform hover:scale-105 transition-all duration-200 ease-in-out focus:outline-none focus:ring-4 focus:ring-blue-300 active:scale-95"
|
class="group relative px-8 py-3 bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700 text-white font-medium rounded-lg shadow-lg hover:shadow-xl transform hover:scale-105 transition-all duration-200 ease-in-out focus:outline-none focus:ring-4 focus:ring-blue-300 active:scale-95"
|
||||||
@click="handleGenerateTestData"
|
@click="analyzer.generateTestData"
|
||||||
>
|
>
|
||||||
<span class="flex items-center gap-2">
|
<span class="flex items-center gap-2">
|
||||||
<RefreshCcw
|
<RefreshCcw
|
||||||
|
@ -45,7 +45,6 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, shallowRef } from "vue";
|
import { computed, shallowRef } from "vue";
|
||||||
import VChart from "vue-echarts";
|
import VChart from "vue-echarts";
|
||||||
import { generateTestLogicData } from "./index";
|
|
||||||
import { RefreshCcw } from "lucide-vue-next";
|
import { RefreshCcw } from "lucide-vue-next";
|
||||||
|
|
||||||
// Echarts
|
// Echarts
|
||||||
|
@ -145,8 +144,8 @@ const option = computed((): EChartsOption => {
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
formatter: (value: number) => {
|
formatter: (value: number) => {
|
||||||
const channelIndex = Math.round(value / channelSpacing);
|
const channelIndex = Math.round(value / channelSpacing);
|
||||||
return channelIndex < channelCount && analyzer.logicData.value
|
return channelIndex < channelCount
|
||||||
? analyzer.logicData.value.channelNames[channelIndex]
|
? analyzer.channelNames.value[channelIndex]
|
||||||
: "";
|
: "";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -157,9 +156,7 @@ const option = computed((): EChartsOption => {
|
||||||
// 创建系列数据,每个通道有不同的Y偏移
|
// 创建系列数据,每个通道有不同的Y偏移
|
||||||
const series: LineSeriesOption[] = analyzer.logicData.value.y.map(
|
const series: LineSeriesOption[] = analyzer.logicData.value.y.map(
|
||||||
(channelData: number[], index: number) => ({
|
(channelData: number[], index: number) => ({
|
||||||
name:
|
name: analyzer.channelNames.value[index],
|
||||||
analyzer.logicData.value?.channelNames?.[index] ??
|
|
||||||
`Channel ${index + 1}`,
|
|
||||||
type: "line",
|
type: "line",
|
||||||
data: channelData.map(
|
data: channelData.map(
|
||||||
(value: number) => value + index * channelSpacing + 0.2,
|
(value: number) => value + index * channelSpacing + 0.2,
|
||||||
|
@ -205,7 +202,7 @@ const option = computed((): EChartsOption => {
|
||||||
|
|
||||||
// 显示所有通道在当前时间点的原始数值(0或1)
|
// 显示所有通道在当前时间点的原始数值(0或1)
|
||||||
if (analyzer.logicData.value) {
|
if (analyzer.logicData.value) {
|
||||||
analyzer.logicData.value.channelNames.forEach(
|
analyzer.channelNames.value.forEach(
|
||||||
(channelName: string, index: number) => {
|
(channelName: string, index: number) => {
|
||||||
const originalValue =
|
const originalValue =
|
||||||
analyzer.logicData.value!.y[index][dataIndex];
|
analyzer.logicData.value!.y[index][dataIndex];
|
||||||
|
@ -247,7 +244,4 @@ const option = computed((): EChartsOption => {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleGenerateTestData() {
|
|
||||||
analyzer.logicData.value = generateTestLogicData();
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,79 +1,5 @@
|
||||||
import { exp } from "mathjs";
|
|
||||||
import LogicalWaveFormDisplay from "./LogicalWaveFormDisplay.vue";
|
import LogicalWaveFormDisplay from "./LogicalWaveFormDisplay.vue";
|
||||||
|
|
||||||
type LogicDataType = {
|
export { LogicalWaveFormDisplay };
|
||||||
x: number[];
|
|
||||||
y: number[][]; // 8 channels of digital data (0 or 1)
|
|
||||||
xUnit: "s" | "ms" | "us" | "ns";
|
|
||||||
channelNames: string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Test data generator for 8-channel digital signals
|
|
||||||
function generateTestLogicData(): LogicDataType {
|
|
||||||
const sampleRate = 10000; // 10kHz sampling
|
|
||||||
const duration = 1;
|
|
||||||
const points = Math.floor(sampleRate * duration);
|
|
||||||
|
|
||||||
const x = Array.from({ length: points }, (_, i) => (i / sampleRate) * 1000); // time in ms
|
|
||||||
|
|
||||||
// Generate 8 channels with different digital patterns
|
|
||||||
const y = [
|
|
||||||
// Channel 0: Clock signal 100Hz
|
|
||||||
Array.from(
|
|
||||||
{ length: points },
|
|
||||||
(_, i) => Math.floor((100 * i) / sampleRate) % 2,
|
|
||||||
),
|
|
||||||
// Channel 1: Clock/2 signal 50Hz
|
|
||||||
Array.from(
|
|
||||||
{ length: points },
|
|
||||||
(_, i) => Math.floor((50 * i) / sampleRate) % 2,
|
|
||||||
),
|
|
||||||
// Channel 2: Clock/4 signal 25Hz
|
|
||||||
Array.from(
|
|
||||||
{ length: points },
|
|
||||||
(_, i) => Math.floor((25 * i) / sampleRate) % 2,
|
|
||||||
),
|
|
||||||
// Channel 3: Clock/8 signal 12.5Hz
|
|
||||||
Array.from(
|
|
||||||
{ length: points },
|
|
||||||
(_, i) => Math.floor((12.5 * i) / sampleRate) % 2,
|
|
||||||
),
|
|
||||||
// Channel 4: Data signal (pseudo-random pattern)
|
|
||||||
Array.from(
|
|
||||||
{ length: points },
|
|
||||||
(_, i) => Math.abs( Math.floor(Math.sin(i * 0.01) * 10) % 2 ),
|
|
||||||
),
|
|
||||||
// Channel 5: Enable signal (periodic pulse)
|
|
||||||
Array.from(
|
|
||||||
{ length: points },
|
|
||||||
(_, i) => (Math.floor(i / 50) % 10) < 3 ? 1 : 0,
|
|
||||||
),
|
|
||||||
// Channel 6: Reset signal (occasional pulse)
|
|
||||||
Array.from(
|
|
||||||
{ length: points },
|
|
||||||
(_, i) => (Math.floor(i / 200) % 20) === 0 ? 1 : 0,
|
|
||||||
),
|
|
||||||
// Channel 7: Status signal (slow changing)
|
|
||||||
Array.from(
|
|
||||||
{ length: points },
|
|
||||||
(_, i) => Math.floor(i / 1000) % 2,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
const channelNames = [
|
|
||||||
"CLK",
|
|
||||||
"CLK/2",
|
|
||||||
"CLK/4",
|
|
||||||
"CLK/8",
|
|
||||||
"PWM",
|
|
||||||
"ENABLE",
|
|
||||||
"RESET",
|
|
||||||
"STATUS"
|
|
||||||
];
|
|
||||||
|
|
||||||
return { x, y, xUnit: "ms", channelNames };
|
|
||||||
}
|
|
||||||
|
|
||||||
export { LogicalWaveFormDisplay, generateTestLogicData, type LogicDataType };
|
|
||||||
export { default as TriggerSettings } from './TriggerSettings.vue'
|
export { default as TriggerSettings } from './TriggerSettings.vue'
|
||||||
export { useProvideLogicAnalyzer , useLogicAnalyzerState } from './LogicAnalyzerManager.ts'
|
export { useProvideLogicAnalyzer , useLogicAnalyzerState } from './LogicAnalyzerManager.ts'
|
Loading…
Reference in New Issue