From 5a7dd7f6f0845ae395f64cc0f521c0c95c72838e Mon Sep 17 00:00:00 2001 From: Kirigaya <1193466151@qq.com> Date: Wed, 25 Dec 2024 22:20:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=B8=83=E5=B1=80=E7=9A=84?= =?UTF-8?q?=E5=88=86=E7=BB=84=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/render/index.vue | 4 +++ src/hook/render/cell.js | 6 +--- src/hook/render/index.js | 26 +++++++++++---- src/hook/render/layout.js | 58 +++++++++++++++++++++------------ src/hook/render/port.js | 50 ++++++++++++++++++---------- 5 files changed, 94 insertions(+), 50 deletions(-) diff --git a/src/components/render/index.vue b/src/components/render/index.vue index 7f5d512..212e407 100644 --- a/src/components/render/index.vue +++ b/src/components/render/index.vue @@ -43,4 +43,8 @@ onMounted(async () => { cursor: grabbing; } +.port-caption { + user-select: none; +} + \ No newline at end of file diff --git a/src/hook/render/cell.js b/src/hook/render/cell.js index d6f099f..a32a0f8 100644 --- a/src/hook/render/cell.js +++ b/src/hook/render/cell.js @@ -38,7 +38,7 @@ export class CellRender { const data = this.data; const rootRender = this.rootRender; - let cellSelections = this.parentSelection.selectAll('g') + let cellSelections = this.parentSelection.selectAll('svg') .data(data) .enter() .append(data => { @@ -60,7 +60,6 @@ export class CellRender { .on('end', function (data) { const cellSelection = d3.select(this); - registerDragEvent(cellSelection, data, rootRender); }); } else { @@ -69,9 +68,6 @@ export class CellRender { .each(function (data) { const cellSelection = d3.select(this); - // 计算最小拓扑图 - const mintoGraph = undefined; - registerDragEvent(cellSelection, data, rootRender); }); } diff --git a/src/hook/render/index.js b/src/hook/render/index.js index 0acf72f..e5999ea 100644 --- a/src/hook/render/index.js +++ b/src/hook/render/index.js @@ -23,10 +23,6 @@ export class NetlistRender { */ this.elkGraph = { id: 'root', - layoutOptions: { - 'elk.progressBar': true, - 'layered.nodePlacement.strategy': 'SIDE_BASED' - }, children: [], edges: [] }; @@ -80,6 +76,13 @@ export class NetlistRender { const cellNodes = module.makeCellsElkNodes(); const [constantNodes, connectionEdges] = module.makeConnectionElkNodes(); + // debug + for (const node of portNodes) { + if (node.type === 'output') { + node.x = 400; + } + } + // 挂载到渲染图中 this.elkGraph.children.push(...portNodes); this.elkGraph.children.push(...cellNodes); @@ -97,13 +100,15 @@ export class NetlistRender { */ async createLayout() { const graph = this.elkGraph; - const start = performance.now(); const layoutGraph = await this.elk.layout(graph, { layoutOptions: { + // org.eclipse. 可以去除 'org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers': 35, - 'org.eclipse.elk.spacing.nodeNode': 35, - 'org.eclipse.elk.layered.layering.strategy': 'LONGEST_PATH' + 'elk.spacing.nodeNode': 35, + 'elk.layered.layering.strategy': 'NETWORK_SIMPLEX', + 'elk.algorithm': 'layered', + 'elk.partitioning.activate': true } }); const timecost = (performance.now() - start).toFixed(3); @@ -346,4 +351,11 @@ export class NetlistRender { // } } + + /** + * @description 初次渲染完成后,布局不一定正确,需要进行调整(output ports) + */ + adjustLayoyt() { + + } } \ No newline at end of file diff --git a/src/hook/render/layout.js b/src/hook/render/layout.js index c6f8f46..9be75ea 100644 --- a/src/hook/render/layout.js +++ b/src/hook/render/layout.js @@ -65,21 +65,36 @@ export class Module { for (const name of this.moduleTree.nameToPort.keys()) { const port = this.moduleTree.nameToPort.get(name); - const direction = port.direction === 'input' ? 'LEFT': 'RIGHT'; - - const node = { - id: port.id, - renderName: name, - renderType: 'port', - type: port.direction, - width: LAYOUT_CONSTANT.PORT_WIDTH, - height: LAYOUT_CONSTANT.PORT_HEIGHT, - layoutOptions: { - 'elk.side': direction - } - }; + if (port.direction === 'input') { + const node = { + id: port.id, + renderName: name, + renderType: 'port', + type: port.direction, + width: LAYOUT_CONSTANT.PORT_WIDTH, + height: LAYOUT_CONSTANT.PORT_HEIGHT, + layoutOptions: { + 'partitioning.partition': 1 + } + }; + + nodes.push(node); + } else { + const node = { + id: port.id, + renderName: name, + renderType: 'port', + type: port.direction, + width: LAYOUT_CONSTANT.PORT_WIDTH, + height: LAYOUT_CONSTANT.PORT_HEIGHT, + layoutOptions: { + 'partitioning.partition': 999 + } + }; + + nodes.push(node); + } - nodes.push(node); } // 非 port 的其他内部变量的节点不需要绘制,因为它们总能被表示为中间变量 @@ -165,7 +180,8 @@ export class Module { height, ports, layoutOptions: { - 'org.eclipse.elk.portConstraints': 'FIXED_POS' + 'org.eclipse.elk.portConstraints': 'FIXED_POS', + 'partitioning.partition': 10 } }; nodes.push(node); @@ -197,10 +213,11 @@ export class Module { width, height, ports, - // layoutOptions: { - // // 强制固定 port 的方向 - // 'org.eclipse.elk.portConstraints': 'FIXED_SIDE' - // } + layoutOptions: { + // 强制固定 port 的方向 + 'org.eclipse.elk.portConstraints': 'FIXED_SIDE', + 'partitioning.partition': 10 + } }; nodes.push(node); @@ -240,7 +257,8 @@ export class Module { width: LAYOUT_CONSTANT.CONSTANT_WIDTH, height: LAYOUT_CONSTANT.CONSTANT_HEIGHT, layoutOptions: { - 'elk.port.side': 'WEST' + 'elk.port.side': 'WEST', + 'partitioning.partition': 10 } }; diff --git a/src/hook/render/port.js b/src/hook/render/port.js index 17974f5..2047ce0 100644 --- a/src/hook/render/port.js +++ b/src/hook/render/port.js @@ -35,42 +35,53 @@ export class PortRender { render() { const data = this.data; - let portSelections = this.parentSelection.selectAll('rect') + let portSelections = this.parentSelection.selectAll('g.port') .data(data) .enter() - .append('rect') - .attr('x', data => data.x) - .attr('y', data => data.y) + .append('g') + .attr('class', 'port') + .attr("transform", d => `translate(${d.x}, ${d.y})`); + + let ports = portSelections.append('rect') .attr('width', data => data.width) .attr('height', data => data.height) .attr('fill', d => d.fill); + let texts = portSelections.append('text') + .attr('x', data => data.width / 2) // 文本的 x 坐标(居中) + .attr('y', data => data.height / 2) // 文本的 y 坐标(居中) + .attr('dominant-baseline', 'middle') // 文本垂直居中 + .attr('text-anchor', 'middle') // 文本水平居中 + .attr('fill', 'white') // 文本颜色 + .attr('font-size', '0') + .transition() + .duration(1000) + .attr('font-size', '12px') + .attr('class', 'port-caption') + .text(data => data.text); // 设置文本内容 - portSelections.append("text") - .attr("x", d => d.width / 2) - .attr("y", d => d.height / 2) - .text(d => d.text) - .attr('font-size', '12px'); if (globalSetting.renderAnimation) { - portSelections = portSelections - .transition() + ports.transition() .duration(1000) .attr('stroke', 'var(--main-color)') .attr('stroke-width', 2) .attr('rx', d => d.rx) - .attr('ry', d => d.ry) + .attr('ry', d => d.ry); + + portSelections .attr('class', 'grab') - .on('end', function (data) { + .each(function (data) { const portSelection = d3.select(this); registerDragEvent(portSelection, data); }); } else { - portSelections - .attr('stroke', 'var(--main-color)') + ports.attr('stroke', 'var(--main-color)') .attr('stroke-width', 2) .attr('rx', d => d.rx) - .attr('ry', d => d.ry) + .attr('ry', d => d.ry); + + portSelections .attr('class', 'grab') .each(function (data) { const portSelection = d3.select(this); @@ -84,6 +95,9 @@ export class PortRender { } } + + + /** * @description 注册关于 器件 的拖动事件 * @@ -116,10 +130,10 @@ function dragStart(event, selection, data) { * @param {d3.D3DragEvent} event * @param {d3.Selection} selection */ -function dragged(event, selection, data) { +function dragged(event, selection, data) { data.x = event.x; data.y = event.y; - selection.attr('x', event.x).attr('y', event.y); + selection.attr("transform", `translate(${event.x}, ${event.y})`); } /**