add: DDS virtual component
This commit is contained in:
parent
6a786c1519
commit
91838ff632
|
@ -12,6 +12,7 @@
|
||||||
"@types/lodash": "^4.17.16",
|
"@types/lodash": "^4.17.16",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"log-symbols": "^7.0.0",
|
"log-symbols": "^7.0.0",
|
||||||
|
"mathjs": "^14.4.0",
|
||||||
"pinia": "^3.0.1",
|
"pinia": "^3.0.1",
|
||||||
"tinypool": "^1.0.2",
|
"tinypool": "^1.0.2",
|
||||||
"ts-log": "^2.2.7",
|
"ts-log": "^2.2.7",
|
||||||
|
@ -474,6 +475,15 @@
|
||||||
"@babel/core": "^7.0.0-0"
|
"@babel/core": "^7.0.0-0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/runtime": {
|
||||||
|
"version": "7.27.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz",
|
||||||
|
"integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/template": {
|
"node_modules/@babel/template": {
|
||||||
"version": "7.27.0",
|
"version": "7.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
|
||||||
|
@ -2130,6 +2140,19 @@
|
||||||
],
|
],
|
||||||
"license": "CC-BY-4.0"
|
"license": "CC-BY-4.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/complex.js": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-qtx7HRhPGSCBtGiST4/WGHuW+zeaND/6Ld+db6PbrulIB1i2Ev/2UPiqcmpQNPSyfBKraC0EOvOKCB5dGZKt3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/rawify"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/convert-source-map": {
|
"node_modules/convert-source-map": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||||
|
@ -2231,6 +2254,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/decimal.js": {
|
||||||
|
"version": "10.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz",
|
||||||
|
"integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/default-browser": {
|
"node_modules/default-browser": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
|
||||||
|
@ -2378,6 +2407,12 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/escape-latex": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/estree-walker": {
|
"node_modules/estree-walker": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
|
@ -2667,6 +2702,12 @@
|
||||||
"node": ">=16"
|
"node": ">=16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/javascript-natural-sort": {
|
||||||
|
"version": "0.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
|
||||||
|
"integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/jiti": {
|
"node_modules/jiti": {
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
|
||||||
|
@ -3020,6 +3061,42 @@
|
||||||
"@jridgewell/sourcemap-codec": "^1.5.0"
|
"@jridgewell/sourcemap-codec": "^1.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mathjs": {
|
||||||
|
"version": "14.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mathjs/-/mathjs-14.4.0.tgz",
|
||||||
|
"integrity": "sha512-CpoYDhNENefjIG9wU9epr+0pBHzlaySfpWcblZdAf5qXik/j/U8eSmx/oNbmXO0F5PyfwPGVD/wK4VWsTho1SA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.26.10",
|
||||||
|
"complex.js": "^2.2.5",
|
||||||
|
"decimal.js": "^10.4.3",
|
||||||
|
"escape-latex": "^1.2.0",
|
||||||
|
"fraction.js": "^5.2.1",
|
||||||
|
"javascript-natural-sort": "^0.7.1",
|
||||||
|
"seedrandom": "^3.0.5",
|
||||||
|
"tiny-emitter": "^2.1.0",
|
||||||
|
"typed-function": "^4.2.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"mathjs": "bin/cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mathjs/node_modules/fraction.js": {
|
||||||
|
"version": "5.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.2.2.tgz",
|
||||||
|
"integrity": "sha512-uXBDv5knpYmv/2gLzWQ5mBHGBRk9wcKTeWu6GLTUEQfjCxO09uM/mHDrojlL+Q1mVGIIFo149Gba7od1XPgSzQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/rawify"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/memorystream": {
|
"node_modules/memorystream": {
|
||||||
"version": "0.3.1",
|
"version": "0.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
|
||||||
|
@ -3429,6 +3506,12 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/seedrandom": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||||
|
@ -3563,6 +3646,12 @@
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tiny-emitter": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/tinyglobby": {
|
"node_modules/tinyglobby": {
|
||||||
"version": "0.2.13",
|
"version": "0.2.13",
|
||||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
|
||||||
|
@ -3611,6 +3700,15 @@
|
||||||
"integrity": "sha512-HjX/7HxQe2bXkbp8pHTjy4Ir9eHIDnDDsLDphhGqy6I9iZ/vD4QXWEIlrVRZsEX+kS2jIiiF/mnl0nKnPTiYFw==",
|
"integrity": "sha512-HjX/7HxQe2bXkbp8pHTjy4Ir9eHIDnDDsLDphhGqy6I9iZ/vD4QXWEIlrVRZsEX+kS2jIiiF/mnl0nKnPTiYFw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/typed-function": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.7.3",
|
"version": "5.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
"@types/lodash": "^4.17.16",
|
"@types/lodash": "^4.17.16",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"log-symbols": "^7.0.0",
|
"log-symbols": "^7.0.0",
|
||||||
|
"mathjs": "^14.4.0",
|
||||||
"pinia": "^3.0.1",
|
"pinia": "^3.0.1",
|
||||||
"tinypool": "^1.0.2",
|
"tinypool": "^1.0.2",
|
||||||
"ts-log": "^2.2.7",
|
"ts-log": "^2.2.7",
|
||||||
|
|
|
@ -115,16 +115,40 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 虚拟外设列表 (虚拟外设选项卡) -->
|
||||||
<!-- 虚拟外设列表 (虚拟外设选项卡) -->
|
|
||||||
<div v-if="activeTab === 'virtual'" class="px-6 py-4 overflow-auto flex-1">
|
<div v-if="activeTab === 'virtual'" class="px-6 py-4 overflow-auto flex-1">
|
||||||
<div class="py-16 text-center">
|
<div v-if="filteredVirtualDevices.length > 0" class="grid grid-cols-2 gap-4">
|
||||||
|
<div v-for="(device, index) in filteredVirtualDevices" :key="index"
|
||||||
|
class="card bg-base-200 hover:bg-base-300 transition-all duration-300 hover:shadow-md cursor-pointer"
|
||||||
|
@click="addComponent(device)">
|
||||||
|
<div class="card-body p-3 items-center text-center">
|
||||||
|
<div class="bg-base-100 rounded-lg w-full h-[90px] flex items-center justify-center overflow-hidden p-2">
|
||||||
|
<!-- 直接使用组件作为预览 -->
|
||||||
|
<component
|
||||||
|
v-if="componentModules[device.type]"
|
||||||
|
:is="componentModules[device.type].default"
|
||||||
|
class="component-preview"
|
||||||
|
:size="getPreviewSize(device.type)"
|
||||||
|
/>
|
||||||
|
<!-- 加载中状态 -->
|
||||||
|
<span v-else class="text-xs text-gray-400">加载中...</span>
|
||||||
|
</div>
|
||||||
|
<h3 class="card-title text-sm mt-2">{{ device.name }}</h3>
|
||||||
|
<p class="text-xs opacity-70">{{ device.type }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 无搜索结果 -->
|
||||||
|
<div v-else class="py-16 text-center">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="mx-auto text-base-300 mb-3">
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="mx-auto text-base-300 mb-3">
|
||||||
<circle cx="12" cy="12" r="10"></circle>
|
<circle cx="11" cy="11" r="8"></circle>
|
||||||
<line x1="12" y1="8" x2="12" y2="16"></line>
|
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||||
<line x1="8" y1="12" x2="16" y2="12"></line>
|
<line x1="8" y1="11" x2="14" y2="11"></line>
|
||||||
</svg>
|
</svg>
|
||||||
<p class="text-base-content opacity-70">虚拟外设功能即将推出</p>
|
<p class="text-base-content opacity-70">没有找到匹配的虚拟外设</p>
|
||||||
|
<button class="btn btn-sm btn-ghost mt-3" @click="searchQuery = ''">
|
||||||
|
清除搜索
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -182,6 +206,11 @@ const availableComponents = [
|
||||||
{ type: 'PG2L100H_FBG676', name: 'PG2L100H FBG676芯片' }
|
{ type: 'PG2L100H_FBG676', name: 'PG2L100H FBG676芯片' }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// --- 可用虚拟外设列表 ---
|
||||||
|
const availableVirtualDevices = [
|
||||||
|
{ type: 'DDS', name: '信号发生器' }
|
||||||
|
];
|
||||||
|
|
||||||
// --- 可用模板列表 ---
|
// --- 可用模板列表 ---
|
||||||
const availableTemplates = ref([
|
const availableTemplates = ref([
|
||||||
{
|
{
|
||||||
|
@ -226,6 +255,7 @@ async function loadComponentModule(type: string) {
|
||||||
|
|
||||||
// 预加载组件模块
|
// 预加载组件模块
|
||||||
async function preloadComponentModules() {
|
async function preloadComponentModules() {
|
||||||
|
// 加载基础组件
|
||||||
for (const component of availableComponents) {
|
for (const component of availableComponents) {
|
||||||
try {
|
try {
|
||||||
await loadComponentModule(component.type);
|
await loadComponentModule(component.type);
|
||||||
|
@ -233,6 +263,15 @@ async function preloadComponentModules() {
|
||||||
console.error(`Failed to preload component ${component.type}:`, error);
|
console.error(`Failed to preload component ${component.type}:`, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载虚拟外设组件
|
||||||
|
for (const device of availableVirtualDevices) {
|
||||||
|
try {
|
||||||
|
await loadComponentModule(device.type);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to preload virtual device ${device.type}:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取组件预览时适合的尺寸
|
// 获取组件预览时适合的尺寸
|
||||||
|
@ -250,7 +289,8 @@ function getPreviewSize(componentType: string): number {
|
||||||
'SD': 0.6, // SD卡插槽适中
|
'SD': 0.6, // SD卡插槽适中
|
||||||
'SFP': 0.4, // SFP光纤模块较大
|
'SFP': 0.4, // SFP光纤模块较大
|
||||||
'SMA': 0.7, // SMA连接器可以适中
|
'SMA': 0.7, // SMA连接器可以适中
|
||||||
'MotherBoard': 0.13 // 主板最大,需要最小尺寸
|
'MotherBoard': 0.13, // 主板最大,需要最小尺寸
|
||||||
|
'DDS': 0.3 // 信号发生器较大,需要较小尺寸
|
||||||
};
|
};
|
||||||
|
|
||||||
// 返回对应尺寸,如果没有特定配置则返回默认值0.5
|
// 返回对应尺寸,如果没有特定配置则返回默认值0.5
|
||||||
|
@ -350,6 +390,18 @@ const filteredTemplates = computed(() => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 过滤后的虚拟外设列表 (用于菜单)
|
||||||
|
const filteredVirtualDevices = computed(() => {
|
||||||
|
if (!searchQuery.value || activeTab.value !== 'virtual') {
|
||||||
|
return availableVirtualDevices;
|
||||||
|
}
|
||||||
|
const query = searchQuery.value.toLowerCase();
|
||||||
|
return availableVirtualDevices.filter(device =>
|
||||||
|
device.name.toLowerCase().includes(query) ||
|
||||||
|
device.type.toLowerCase().includes(query)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// 生命周期钩子
|
// 生命周期钩子
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 预加载组件模块
|
// 预加载组件模块
|
||||||
|
|
|
@ -114,9 +114,7 @@
|
||||||
'alert-info'}`">
|
'alert-info'}`">
|
||||||
<span>{{ notificationMessage }}</span>
|
<span>{{ notificationMessage }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> <!-- 加载指示器 -->
|
||||||
|
|
||||||
<!-- 加载指示器 -->
|
|
||||||
<div v-if="isLoading" class="absolute inset-0 bg-black bg-opacity-30 flex items-center justify-center z-50">
|
<div v-if="isLoading" class="absolute inset-0 bg-black bg-opacity-30 flex items-center justify-center z-50">
|
||||||
<div class="loading loading-spinner loading-lg text-primary"></div>
|
<div class="loading loading-spinner loading-lg text-primary"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1002,10 +1000,26 @@ function setDiagramData(data: DiagramData) {
|
||||||
emit('diagram-updated', data);
|
emit('diagram-updated', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 无加载动画的数据更新方法
|
||||||
|
function updateDiagramDataDirectly(data: DiagramData) {
|
||||||
|
// 检查组件是否仍然挂载
|
||||||
|
if (!document.body.contains(canvasContainer.value)) {
|
||||||
|
return; // 如果组件已经卸载,不执行后续操作
|
||||||
|
}
|
||||||
|
|
||||||
|
diagramData.value = data;
|
||||||
|
saveDiagramData(data);
|
||||||
|
|
||||||
|
// 发出diagram-updated事件
|
||||||
|
emit('diagram-updated', data);
|
||||||
|
}
|
||||||
|
|
||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
defineExpose({
|
defineExpose({
|
||||||
// 基本数据操作
|
// 基本数据操作
|
||||||
getDiagramData: () => diagramData.value, setDiagramData: (data: DiagramData) => {
|
getDiagramData: () => diagramData.value,
|
||||||
|
updateDiagramDataDirectly,
|
||||||
|
setDiagramData: (data: DiagramData) => {
|
||||||
// 检查组件是否仍然挂载
|
// 检查组件是否仍然挂载
|
||||||
if (!document.body.contains(canvasContainer.value)) {
|
if (!document.body.contains(canvasContainer.value)) {
|
||||||
return; // 如果组件已经卸载,不执行后续操作
|
return; // 如果组件已经卸载,不执行后续操作
|
||||||
|
|
|
@ -11,6 +11,14 @@
|
||||||
@updateDirectProp="(componentId, propName, value) => $emit('updateDirectProp', componentId, propName, value)"
|
@updateDirectProp="(componentId, propName, value) => $emit('updateDirectProp', componentId, propName, value)"
|
||||||
/>
|
/>
|
||||||
</CollapsibleSection>
|
</CollapsibleSection>
|
||||||
|
|
||||||
|
<!-- 信号发生器(DDS)特殊属性编辑器 -->
|
||||||
|
<div v-if="isDDSComponent">
|
||||||
|
<DDSPropertyEditor
|
||||||
|
v-model="ddsProperties"
|
||||||
|
@update:modelValue="updateDDSProperties"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 如果选中的组件有pins属性,则显示引脚配置区域 -->
|
<!-- 如果选中的组件有pins属性,则显示引脚配置区域 -->
|
||||||
<CollapsibleSection
|
<CollapsibleSection
|
||||||
|
@ -73,6 +81,7 @@ import { type DiagramPart } from '@/components/diagramManager';
|
||||||
import { type PropertyConfig } from '@/components/equipments/componentConfig';
|
import { type PropertyConfig } from '@/components/equipments/componentConfig';
|
||||||
import CollapsibleSection from './CollapsibleSection.vue';
|
import CollapsibleSection from './CollapsibleSection.vue';
|
||||||
import PropertyEditor from './PropertyEditor.vue';
|
import PropertyEditor from './PropertyEditor.vue';
|
||||||
|
import DDSPropertyEditor from './equipments/DDSPropertyEditor.vue';
|
||||||
import { ref, computed, watch } from 'vue';
|
import { ref, computed, watch } from 'vue';
|
||||||
|
|
||||||
// 定义Pin接口
|
// 定义Pin接口
|
||||||
|
@ -94,6 +103,14 @@ const propertySectionExpanded = ref(true);
|
||||||
const pinsSectionExpanded = ref(false);
|
const pinsSectionExpanded = ref(false);
|
||||||
const wireSectionExpanded = ref(false);
|
const wireSectionExpanded = ref(false);
|
||||||
|
|
||||||
|
// DDS特殊属性
|
||||||
|
const ddsProperties = ref({
|
||||||
|
frequency: 1000,
|
||||||
|
phase: 0,
|
||||||
|
waveform: 'sine',
|
||||||
|
customWaveformPoints: []
|
||||||
|
});
|
||||||
|
|
||||||
// 本地维护一个pins数组副本
|
// 本地维护一个pins数组副本
|
||||||
const componentPins = ref<Pin[]>([]);
|
const componentPins = ref<Pin[]>([]);
|
||||||
|
|
||||||
|
@ -106,6 +123,18 @@ watch(() => props.componentData?.attrs?.pins, (newPins) => {
|
||||||
}
|
}
|
||||||
}, { deep: true, immediate: true });
|
}, { deep: true, immediate: true });
|
||||||
|
|
||||||
|
// 监听DDS组件数据变化,更新特殊属性
|
||||||
|
watch(() => props.componentData?.attrs, (newAttrs) => {
|
||||||
|
if (newAttrs && isDDSComponent.value) {
|
||||||
|
ddsProperties.value = {
|
||||||
|
frequency: newAttrs.frequency || 1000,
|
||||||
|
phase: newAttrs.phase || 0,
|
||||||
|
waveform: newAttrs.waveform || 'sine',
|
||||||
|
customWaveformPoints: newAttrs.customWaveformPoints || []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, { deep: true, immediate: true });
|
||||||
|
|
||||||
// 计算属性:检查组件是否有pins属性
|
// 计算属性:检查组件是否有pins属性
|
||||||
const hasPinsProperty = computed(() => {
|
const hasPinsProperty = computed(() => {
|
||||||
if (!props.componentData || !props.componentData.attrs) {
|
if (!props.componentData || !props.componentData.attrs) {
|
||||||
|
@ -121,6 +150,11 @@ const hasPinsProperty = computed(() => {
|
||||||
return 'pins' in props.componentData.attrs;
|
return 'pins' in props.componentData.attrs;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 计算属性:检查组件是否为DDS组件
|
||||||
|
const isDDSComponent = computed(() => {
|
||||||
|
return props.componentData?.type === 'DDS';
|
||||||
|
});
|
||||||
|
|
||||||
// 定义事件
|
// 定义事件
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'updateProp', componentId: string, propName: string, value: any): void;
|
(e: 'updateProp', componentId: string, propName: string, value: any): void;
|
||||||
|
@ -133,6 +167,30 @@ function updatePins() {
|
||||||
emit('updateProp', props.componentData.id, 'pins', componentPins.value);
|
emit('updateProp', props.componentData.id, 'pins', componentPins.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监听DDS组件数据变化,更新特殊属性
|
||||||
|
watch(() => props.componentData?.attrs, (newAttrs) => {
|
||||||
|
if (newAttrs && isDDSComponent.value) {
|
||||||
|
ddsProperties.value = {
|
||||||
|
frequency: newAttrs.frequency || 1000,
|
||||||
|
phase: newAttrs.phase || 0,
|
||||||
|
waveform: newAttrs.waveform || 'sine',
|
||||||
|
customWaveformPoints: newAttrs.customWaveformPoints || []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, { deep: true, immediate: true });
|
||||||
|
|
||||||
|
// 更新DDS属性
|
||||||
|
function updateDDSProperties(newProperties: any) {
|
||||||
|
ddsProperties.value = newProperties;
|
||||||
|
if (props.componentData && props.componentData.id) {
|
||||||
|
// 将各个属性单独更新,而不是作为一个整体
|
||||||
|
emit('updateProp', props.componentData.id, 'frequency', newProperties.frequency);
|
||||||
|
emit('updateProp', props.componentData.id, 'phase', newProperties.phase);
|
||||||
|
emit('updateProp', props.componentData.id, 'waveform', newProperties.waveform);
|
||||||
|
emit('updateProp', props.componentData.id, 'customWaveformPoints', newProperties.customWaveformPoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
@ -0,0 +1,339 @@
|
||||||
|
<template>
|
||||||
|
<div class="dds-component" :style="{ width: width + 'px', height: height + 'px', position: 'relative' }">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
:width="width"
|
||||||
|
:height="height"
|
||||||
|
viewBox="0 0 300 200"
|
||||||
|
class="dds-device"
|
||||||
|
> <!-- 信号发生器外壳,扩大屏幕部分 -->
|
||||||
|
<rect width="300" height="180" rx="10" ry="10" fill="#2a323c" stroke="#444" stroke-width="2" />
|
||||||
|
|
||||||
|
<!-- 信号发生器显示屏,扩大屏幕 -->
|
||||||
|
<rect x="20" y="20" width="260" height="140" rx="5" ry="5" fill="#1a1f25" stroke="#555" stroke-width="1" />
|
||||||
|
|
||||||
|
<!-- 波形显示 -->
|
||||||
|
<path :d="currentWaveformPath" stroke="lime" stroke-width="2" fill="none" />
|
||||||
|
|
||||||
|
<!-- 信息显示区域 -->
|
||||||
|
<text x="30" y="40" fill="#0f0" font-size="14">{{ displayFrequency }}</text>
|
||||||
|
<text x="200" y="40" fill="#0f0" font-size="14">φ: {{ phase }}°</text>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<!-- 输出引脚 -->
|
||||||
|
<div
|
||||||
|
v-for="pin in pins"
|
||||||
|
:key="pin.pinId"
|
||||||
|
:style="{
|
||||||
|
position: 'absolute',
|
||||||
|
left: `${pin.x * props.size}px`,
|
||||||
|
top: `${pin.y * props.size}px`,
|
||||||
|
transform: 'translate(-50%, -50%)'
|
||||||
|
}"
|
||||||
|
:data-pin-wrapper="`${pin.pinId}`"
|
||||||
|
:data-pin-x="`${pin.x * props.size}`"
|
||||||
|
:data-pin-y="`${pin.y * props.size}`"
|
||||||
|
>
|
||||||
|
<Pin
|
||||||
|
:ref="el => { if(el) pinRefs[pin.pinId] = el }"
|
||||||
|
:label="pin.pinId"
|
||||||
|
:constraint="pin.constraint"
|
||||||
|
:pinId="pin.pinId"
|
||||||
|
@pin-click="$emit('pin-click', $event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, watch, onMounted } from 'vue';
|
||||||
|
import Pin from './Pin.vue';
|
||||||
|
|
||||||
|
// 存储Pin引用
|
||||||
|
const pinRefs = ref<Record<string, any>>({});
|
||||||
|
|
||||||
|
// DDS属性
|
||||||
|
interface DDSProps {
|
||||||
|
size?: number;
|
||||||
|
pins?: {
|
||||||
|
pinId: string;
|
||||||
|
constraint: string;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}[];
|
||||||
|
frequency?: number;
|
||||||
|
phase?: number;
|
||||||
|
timebase?: number; // 添加时基属性
|
||||||
|
waveform?: string;
|
||||||
|
savedWaveforms?: string[];
|
||||||
|
customWaveformPoints?: number[][];
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<DDSProps>(), {
|
||||||
|
size: 1,
|
||||||
|
pins: () => [
|
||||||
|
{ pinId: 'OUT', constraint: '', x: 300, y: 90 }, // 调整输出引脚位置
|
||||||
|
],
|
||||||
|
frequency: 1000,
|
||||||
|
phase: 0,
|
||||||
|
timebase: 1, // 默认时基为1
|
||||||
|
waveform: 'sine',
|
||||||
|
savedWaveforms: () => ['sine', 'square', 'triangle', 'sawtooth'],
|
||||||
|
customWaveformPoints: () => []
|
||||||
|
});
|
||||||
|
|
||||||
|
// 组件尺寸
|
||||||
|
const width = computed(() => 300 * props.size);
|
||||||
|
const height = computed(() => 180 * props.size); // 减小整体高度
|
||||||
|
|
||||||
|
// 波形状态
|
||||||
|
const frequency = ref(props.frequency);
|
||||||
|
const phase = ref(props.phase);
|
||||||
|
const timebase = ref(props.timebase || 1); // 添加时基参数,默认为1
|
||||||
|
const currentWaveformIndex = ref(0);
|
||||||
|
const waveformNames = ['正弦波', '方波', '三角波', '锯齿波'];
|
||||||
|
const waveforms = ['sine', 'square', 'triangle', 'sawtooth'];
|
||||||
|
|
||||||
|
// 波形函数集合
|
||||||
|
interface WaveformFunction {
|
||||||
|
(x: number, width: number, height: number, phaseRad: number): number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WaveformFunctions {
|
||||||
|
[key: string]: WaveformFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
const waveformFunctions: WaveformFunctions = {
|
||||||
|
// 正弦波函数: sin(2π*x + φ)
|
||||||
|
sine: (x: number, width: number, height: number, phaseRad: number): number => {
|
||||||
|
return height/2 * Math.sin(2 * Math.PI * (x / width) * 2 + phaseRad);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 方波函数: 周期性的高低电平
|
||||||
|
square: (x: number, width: number, height: number, phaseRad: number): number => {
|
||||||
|
const normX = (x / width + phaseRad / (2 * Math.PI)) % 1;
|
||||||
|
return normX < 0.5 ? height/4 : -height/4;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 三角波函数: 线性上升和下降
|
||||||
|
triangle: (x: number, width: number, height: number, phaseRad: number): number => {
|
||||||
|
const normX = (x / width + phaseRad / (2 * Math.PI)) % 1;
|
||||||
|
return height/2 - height * Math.abs(2 * normX - 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 锯齿波函数: 线性上升,瞬间下降
|
||||||
|
sawtooth: (x: number, width: number, height: number, phaseRad: number): number => {
|
||||||
|
const normX = (x / width + phaseRad / (2 * Math.PI)) % 1;
|
||||||
|
return height/2 - height/2 * (2 * normX);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 计算当前显示频率
|
||||||
|
const displayFrequency = computed(() => {
|
||||||
|
if (frequency.value >= 1000000) {
|
||||||
|
return `${(frequency.value / 1000000).toFixed(2)} MHz`;
|
||||||
|
} else if (frequency.value >= 1000) {
|
||||||
|
return `${(frequency.value / 1000).toFixed(2)} kHz`;
|
||||||
|
} else {
|
||||||
|
return `${frequency.value.toFixed(2)} Hz`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 格式化时基显示
|
||||||
|
function formatTimebase(tb: number): string {
|
||||||
|
if (tb < 0.1) {
|
||||||
|
return `${(tb * 1000).toFixed(0)} ms/div`;
|
||||||
|
} else if (tb < 1) {
|
||||||
|
return `${(tb * 1000).toFixed(0)} ms/div`;
|
||||||
|
} else {
|
||||||
|
return `${tb.toFixed(1)} s/div`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算当前显示时基
|
||||||
|
const displayTimebase = computed(() => formatTimebase(timebase.value));
|
||||||
|
|
||||||
|
// 生成波形路径
|
||||||
|
const currentWaveformPath = computed(() => {
|
||||||
|
const width = 240;
|
||||||
|
const height = 100; // 更大的波形显示高度,因为我们增加了屏幕高度
|
||||||
|
const xOffset = 30;
|
||||||
|
const yOffset = 50; // 上移位置以适应新布局
|
||||||
|
const currentWaveform = waveforms[currentWaveformIndex.value];
|
||||||
|
const phaseRadians = phase.value * Math.PI / 180;
|
||||||
|
|
||||||
|
// 时基和频率共同影响周期数量
|
||||||
|
// 频率因素 - 频率越高,一个屏幕内显示的周期越多
|
||||||
|
// 使用对数缩放可以更好地表示广泛范围的频率变化
|
||||||
|
const freqLog = Math.log10(frequency.value) - 2; // 从100Hz开始作为基准
|
||||||
|
const frequencyFactor = Math.max(0.1, Math.min(10, freqLog)); // 限制在合理范围内
|
||||||
|
|
||||||
|
// 时基影响周期数量 - 时基越小,显示的周期越多
|
||||||
|
const timebaseFactor = 1 / timebase.value;
|
||||||
|
|
||||||
|
// 组合因素
|
||||||
|
const scaleFactor = timebaseFactor * frequencyFactor;
|
||||||
|
|
||||||
|
let path = `M${xOffset},${yOffset + height/2}`;
|
||||||
|
|
||||||
|
// 使用波形函数生成路径
|
||||||
|
const waveFunction = waveformFunctions[currentWaveform];
|
||||||
|
|
||||||
|
// 生成路径点
|
||||||
|
for (let x = 0; x <= width; x++) {
|
||||||
|
// 应用组合缩放因素 - 影响x轴的缩放
|
||||||
|
const scaledX = x * scaleFactor;
|
||||||
|
const y = waveFunction(scaledX, width, height, phaseRadians);
|
||||||
|
path += ` L${x + xOffset},${yOffset + height/2 - y}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 波形操作函数
|
||||||
|
function selectWaveform(index: number) {
|
||||||
|
currentWaveformIndex.value = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
function increaseFrequency() {
|
||||||
|
if (frequency.value < 10) {
|
||||||
|
frequency.value += 0.1;
|
||||||
|
} else if (frequency.value < 100) {
|
||||||
|
frequency.value += 1;
|
||||||
|
} else if (frequency.value < 1000) {
|
||||||
|
frequency.value += 10;
|
||||||
|
} else if (frequency.value < 10000) {
|
||||||
|
frequency.value += 100;
|
||||||
|
} else if (frequency.value < 100000) {
|
||||||
|
frequency.value += 1000;
|
||||||
|
} else {
|
||||||
|
frequency.value += 10000;
|
||||||
|
}
|
||||||
|
frequency.value = Math.min(frequency.value, 10000000); // 最大10MHz
|
||||||
|
}
|
||||||
|
|
||||||
|
function decreaseFrequency() {
|
||||||
|
if (frequency.value <= 10) {
|
||||||
|
frequency.value -= 0.1;
|
||||||
|
} else if (frequency.value <= 100) {
|
||||||
|
frequency.value -= 1;
|
||||||
|
} else if (frequency.value <= 1000) {
|
||||||
|
frequency.value -= 10;
|
||||||
|
} else if (frequency.value <= 10000) {
|
||||||
|
frequency.value -= 100;
|
||||||
|
} else if (frequency.value <= 100000) {
|
||||||
|
frequency.value -= 1000;
|
||||||
|
} else {
|
||||||
|
frequency.value -= 10000;
|
||||||
|
}
|
||||||
|
frequency.value = Math.max(frequency.value, 0.1); // 最小0.1Hz
|
||||||
|
frequency.value = parseFloat(frequency.value.toFixed(1)); // 修复浮点数精度问题
|
||||||
|
}
|
||||||
|
|
||||||
|
function increasePhase() {
|
||||||
|
phase.value += 15;
|
||||||
|
if (phase.value >= 360) {
|
||||||
|
phase.value -= 360;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function decreasePhase() {
|
||||||
|
phase.value -= 15;
|
||||||
|
if (phase.value < 0) {
|
||||||
|
phase.value += 360;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听props变化
|
||||||
|
watch(
|
||||||
|
() => props.frequency,
|
||||||
|
(newValue) => {
|
||||||
|
if (newValue !== undefined && newValue !== frequency.value) {
|
||||||
|
frequency.value = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.phase,
|
||||||
|
(newValue) => {
|
||||||
|
if (newValue !== undefined && newValue !== phase.value) {
|
||||||
|
phase.value = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.timebase,
|
||||||
|
(newValue) => {
|
||||||
|
if (newValue !== undefined && newValue !== timebase.value) {
|
||||||
|
timebase.value = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.waveform,
|
||||||
|
(newValue) => {
|
||||||
|
if (newValue !== undefined) {
|
||||||
|
const index = waveforms.indexOf(newValue);
|
||||||
|
if (index !== -1) {
|
||||||
|
currentWaveformIndex.value = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始化波形类型
|
||||||
|
if (props.waveform) {
|
||||||
|
const index = waveforms.indexOf(props.waveform);
|
||||||
|
if (index !== -1) {
|
||||||
|
currentWaveformIndex.value = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化时基
|
||||||
|
if (props.timebase !== undefined) {
|
||||||
|
timebase.value = props.timebase;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 暴露属性和方法
|
||||||
|
defineExpose({
|
||||||
|
frequency,
|
||||||
|
phase,
|
||||||
|
timebase,
|
||||||
|
currentWaveformIndex,
|
||||||
|
selectWaveform,
|
||||||
|
increaseFrequency,
|
||||||
|
decreaseFrequency,
|
||||||
|
increasePhase,
|
||||||
|
decreasePhase
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dds-component {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- 导出默认属性函数供外部使用 -->
|
||||||
|
<script lang="ts">
|
||||||
|
export function getDefaultProps() {
|
||||||
|
return {
|
||||||
|
size: 1,
|
||||||
|
pins: [
|
||||||
|
{ pinId: 'OUT', constraint: '', x: 300, y: 90 }, // 调整输出引脚位置
|
||||||
|
],
|
||||||
|
frequency: 1000,
|
||||||
|
phase: 0,
|
||||||
|
timebase: 1, // 添加默认时基
|
||||||
|
waveform: 'sine',
|
||||||
|
savedWaveforms: ['sine', 'square', 'triangle', 'sawtooth'],
|
||||||
|
customWaveformPoints: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
File diff suppressed because it is too large
Load Diff
|
@ -213,13 +213,12 @@ async function handleAddComponent(componentData: { type: string; name: string; p
|
||||||
index: 0
|
index: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('添加新组件:', newComponent);
|
console.log('添加新组件:', newComponent);
|
||||||
|
|
||||||
// 通过画布实例添加组件
|
// 通过画布实例添加组件
|
||||||
if (canvasInstance && canvasInstance.getDiagramData && canvasInstance.setDiagramData) {
|
if (canvasInstance && canvasInstance.getDiagramData && canvasInstance.updateDiagramDataDirectly) {
|
||||||
const currentData = canvasInstance.getDiagramData();
|
const currentData = canvasInstance.getDiagramData();
|
||||||
currentData.parts.push(newComponent);
|
currentData.parts.push(newComponent);
|
||||||
canvasInstance.setDiagramData(currentData);
|
canvasInstance.updateDiagramDataDirectly(currentData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,10 +226,9 @@ async function handleAddComponent(componentData: { type: string; name: string; p
|
||||||
async function handleAddTemplate(templateData: { id: string; name: string; template: any }) {
|
async function handleAddTemplate(templateData: { id: string; name: string; template: any }) {
|
||||||
console.log('添加模板:', templateData);
|
console.log('添加模板:', templateData);
|
||||||
console.log('=== 模板组件数量:', templateData.template?.parts?.length || 0);
|
console.log('=== 模板组件数量:', templateData.template?.parts?.length || 0);
|
||||||
|
// 获取画布实例
|
||||||
// 获取画布实例
|
|
||||||
const canvasInstance = diagramCanvas.value as any;
|
const canvasInstance = diagramCanvas.value as any;
|
||||||
if (!canvasInstance || !canvasInstance.getDiagramData || !canvasInstance.setDiagramData) {
|
if (!canvasInstance || !canvasInstance.getDiagramData || !canvasInstance.updateDiagramDataDirectly) {
|
||||||
console.error('没有可用的画布实例添加模板');
|
console.error('没有可用的画布实例添加模板');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -337,9 +335,8 @@ async function handleAddTemplate(templateData: { id: string; name: string; templ
|
||||||
// 添加到当前连接列表
|
// 添加到当前连接列表
|
||||||
currentData.connections.push(...newConnections);
|
currentData.connections.push(...newConnections);
|
||||||
}
|
}
|
||||||
|
// 更新图表数据
|
||||||
// 更新图表数据
|
canvasInstance.updateDiagramDataDirectly(currentData);
|
||||||
canvasInstance.setDiagramData(currentData);
|
|
||||||
console.log('=== 更新图表数据完成,新组件数量:', currentData.parts.length);
|
console.log('=== 更新图表数据完成,新组件数量:', currentData.parts.length);
|
||||||
|
|
||||||
// 显示成功消息
|
// 显示成功消息
|
||||||
|
@ -459,7 +456,7 @@ function handleComponentDelete(componentId: string) {
|
||||||
// 更新组件属性的方法
|
// 更新组件属性的方法
|
||||||
function updateComponentProp(componentId: string, propName: string, value: any) {
|
function updateComponentProp(componentId: string, propName: string, value: any) {
|
||||||
const canvasInstance = diagramCanvas.value as any;
|
const canvasInstance = diagramCanvas.value as any;
|
||||||
if (!canvasInstance || !canvasInstance.getDiagramData || !canvasInstance.setDiagramData) {
|
if (!canvasInstance || !canvasInstance.getDiagramData || !canvasInstance.updateDiagramDataDirectly) {
|
||||||
console.error('没有可用的画布实例进行属性更新');
|
console.error('没有可用的画布实例进行属性更新');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -484,7 +481,7 @@ function updateComponentProp(componentId: string, propName: string, value: any)
|
||||||
part.attrs[propName] = value;
|
part.attrs[propName] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvasInstance.setDiagramData(currentData);
|
canvasInstance.updateDiagramDataDirectly(currentData);
|
||||||
console.log(`更新组件${componentId}的属性${propName}为:`, value, typeof value);
|
console.log(`更新组件${componentId}的属性${propName}为:`, value, typeof value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -492,7 +489,7 @@ function updateComponentProp(componentId: string, propName: string, value: any)
|
||||||
// 更新组件的直接属性
|
// 更新组件的直接属性
|
||||||
function updateComponentDirectProp(componentId: string, propName: string, value: any) {
|
function updateComponentDirectProp(componentId: string, propName: string, value: any) {
|
||||||
const canvasInstance = diagramCanvas.value as any;
|
const canvasInstance = diagramCanvas.value as any;
|
||||||
if (!canvasInstance || !canvasInstance.getDiagramData || !canvasInstance.setDiagramData) {
|
if (!canvasInstance || !canvasInstance.getDiagramData || !canvasInstance.updateDiagramDataDirectly) {
|
||||||
console.error('没有可用的画布实例进行属性更新');
|
console.error('没有可用的画布实例进行属性更新');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -504,7 +501,7 @@ function updateComponentDirectProp(componentId: string, propName: string, value:
|
||||||
// @ts-ignore: 动态属性赋值
|
// @ts-ignore: 动态属性赋值
|
||||||
part[propName] = value;
|
part[propName] = value;
|
||||||
|
|
||||||
canvasInstance.setDiagramData(currentData);
|
canvasInstance.updateDiagramDataDirectly(currentData);
|
||||||
console.log(`更新组件${componentId}的直接属性${propName}为:`, value, typeof value);
|
console.log(`更新组件${componentId}的直接属性${propName}为:`, value, typeof value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue