refactor: 修改逻辑分析仪,使其直接使用manager进行管理
This commit is contained in:
		@@ -1,5 +1,4 @@
 | 
			
		||||
import { createInjectionState } from "@vueuse/core";
 | 
			
		||||
import { generateTestLogicData, type LogicDataType } from ".";
 | 
			
		||||
import { shallowRef, reactive, ref, computed } from "vue";
 | 
			
		||||
import {
 | 
			
		||||
  CaptureConfig,
 | 
			
		||||
@@ -12,12 +11,18 @@ import {
 | 
			
		||||
import { AuthManager } from "@/utils/AuthManager";
 | 
			
		||||
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;
 | 
			
		||||
  label: string;
 | 
			
		||||
  color: string;
 | 
			
		||||
}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// 全局模式选项
 | 
			
		||||
const globalModes = [
 | 
			
		||||
@@ -101,6 +106,16 @@ const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
 | 
			
		||||
      () => 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 = () => {
 | 
			
		||||
      channels.forEach((channel) => {
 | 
			
		||||
        channel.enabled = true;
 | 
			
		||||
@@ -195,6 +210,85 @@ const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
 | 
			
		||||
      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 {
 | 
			
		||||
      // 原有的逻辑数据
 | 
			
		||||
      logicData,
 | 
			
		||||
@@ -205,6 +299,8 @@ const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
 | 
			
		||||
      channels,
 | 
			
		||||
      signalConfigs,
 | 
			
		||||
      enabledChannelCount,
 | 
			
		||||
      channelNames,
 | 
			
		||||
      enabledChannelNames,
 | 
			
		||||
 | 
			
		||||
      // 选项数据
 | 
			
		||||
      globalModes,
 | 
			
		||||
@@ -217,6 +313,8 @@ const [useProvideLogicAnalyzer, useLogicAnalyzerState] = createInjectionState(
 | 
			
		||||
      setGlobalMode,
 | 
			
		||||
      applyConfiguration,
 | 
			
		||||
      resetConfiguration,
 | 
			
		||||
      setLogicData,
 | 
			
		||||
      generateTestData,
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
 | 
			
		||||
      <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"
 | 
			
		||||
        @click="handleGenerateTestData"
 | 
			
		||||
        @click="analyzer.generateTestData"
 | 
			
		||||
      >
 | 
			
		||||
        <span class="flex items-center gap-2">
 | 
			
		||||
          <RefreshCcw
 | 
			
		||||
@@ -45,7 +45,6 @@
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { computed, shallowRef } from "vue";
 | 
			
		||||
import VChart from "vue-echarts";
 | 
			
		||||
import { generateTestLogicData } from "./index";
 | 
			
		||||
import { RefreshCcw } from "lucide-vue-next";
 | 
			
		||||
 | 
			
		||||
// Echarts
 | 
			
		||||
@@ -145,8 +144,8 @@ const option = computed((): EChartsOption => {
 | 
			
		||||
      axisLabel: {
 | 
			
		||||
        formatter: (value: number) => {
 | 
			
		||||
          const channelIndex = Math.round(value / channelSpacing);
 | 
			
		||||
          return channelIndex < channelCount && analyzer.logicData.value
 | 
			
		||||
            ? analyzer.logicData.value.channelNames[channelIndex]
 | 
			
		||||
          return channelIndex < channelCount
 | 
			
		||||
            ? analyzer.channelNames.value[channelIndex]
 | 
			
		||||
            : "";
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
@@ -157,9 +156,7 @@ const option = computed((): EChartsOption => {
 | 
			
		||||
  // 创建系列数据,每个通道有不同的Y偏移
 | 
			
		||||
  const series: LineSeriesOption[] = analyzer.logicData.value.y.map(
 | 
			
		||||
    (channelData: number[], index: number) => ({
 | 
			
		||||
      name:
 | 
			
		||||
        analyzer.logicData.value?.channelNames?.[index] ??
 | 
			
		||||
        `Channel ${index + 1}`,
 | 
			
		||||
      name: analyzer.channelNames.value[index],
 | 
			
		||||
      type: "line",
 | 
			
		||||
      data: channelData.map(
 | 
			
		||||
        (value: number) => value + index * channelSpacing + 0.2,
 | 
			
		||||
@@ -205,7 +202,7 @@ const option = computed((): EChartsOption => {
 | 
			
		||||
 | 
			
		||||
          // 显示所有通道在当前时间点的原始数值(0或1)
 | 
			
		||||
          if (analyzer.logicData.value) {
 | 
			
		||||
            analyzer.logicData.value.channelNames.forEach(
 | 
			
		||||
            analyzer.channelNames.value.forEach(
 | 
			
		||||
              (channelName: string, index: number) => {
 | 
			
		||||
                const originalValue =
 | 
			
		||||
                  analyzer.logicData.value!.y[index][dataIndex];
 | 
			
		||||
@@ -247,7 +244,4 @@ const option = computed((): EChartsOption => {
 | 
			
		||||
  };
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function handleGenerateTestData() {
 | 
			
		||||
  analyzer.logicData.value = generateTestLogicData();
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,79 +1,5 @@
 | 
			
		||||
import { exp } from "mathjs";
 | 
			
		||||
import LogicalWaveFormDisplay from "./LogicalWaveFormDisplay.vue";
 | 
			
		||||
 | 
			
		||||
type LogicDataType = {
 | 
			
		||||
  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 { LogicalWaveFormDisplay };
 | 
			
		||||
export { default as TriggerSettings } from './TriggerSettings.vue'
 | 
			
		||||
export { useProvideLogicAnalyzer , useLogicAnalyzerState } from './LogicAnalyzerManager.ts'
 | 
			
		||||
		Reference in New Issue
	
	Block a user