完成线段连接

This commit is contained in:
锦恢 2024-12-24 16:25:07 +08:00
parent 45a54eb06e
commit b9b05f08fc
3 changed files with 79 additions and 20 deletions

View File

@ -20,6 +20,7 @@ export class NetlistRender {
id: 'root',
layoutOptions: {
'elk.algorithm': 'layered',
'elk.progressBar': true,
'layered.nodePlacement.strategy': 'SIDE_BASED'
},
children: [],

View File

@ -5,7 +5,8 @@
import { globalLookup } from "../global";
import { Cell, CELL_LIBS, ModuleTree } from "./yosys";
const SKIN_SCALE = 1;
export const SKIN_SCALE = 1;
export const LINE_WIDTH = 2;
export const LAYOUT_CONSTANT = {
// port
@ -116,33 +117,90 @@ export class Module {
const width = meta.width * SKIN_SCALE;
const ports = [];
for (const connectionName of cell.nameToConnection.keys()) {
const connection = cell.nameToConnection.get(connectionName);
const portSide = connection.direction === 'input' ? ELK_DIRECTION.LEFT: ELK_DIRECTION.RIGHT;
// 统计分配到左右两侧的 port
const leftSideConnections = [];
const rightSideConnections = [];
for (const conn of cell.nameToConnection.values()) {
if (conn.direction === 'input') {
leftSideConnections.push(conn);
} else {
rightSideConnections.push(conn);
}
}
// 计算左侧的
for (let i = 0; i < leftSideConnections.length; ++ i) {
const connection = leftSideConnections[i];
const yOffset = meta.getPortYOffset(connection.name) * SKIN_SCALE;
const targetY = yOffset;
// 默认采用 JUSTIFIED均分一侧的 height
// 我们绘制的 svg 的 port offset y 未必和 elk 分配得到的一样,因此需要进行修正
const layoutY = height / (leftSideConnections.length + 1) * (i + 1);
const extraOffset = LINE_WIDTH * leftSideConnections.length;
const anchorY = layoutY - targetY;
console.log(targetY, layoutY, targetY - layoutY);
let gap = (targetY - layoutY).toFixed(2);
console.log('gap', gap);
ports.push({
id: connection.id,
renderName: connectionName,
renderName: connection.name,
renderType: 'cellPort',
width: LAYOUT_CONSTANT.CELL_PORT_WIDTH,
height: LAYOUT_CONSTANT.CELL_PORT_HEIGHT,
y: yOffset,
width: 0,
height: 0,
properties: {
'port.side': portSide
'port.side': ELK_DIRECTION.LEFT,
'port.anchor': `0, ${gap}`
}
})
});
console.log(ports.at(-1).properties["port.anchor"]);
}
// 计算右侧的
for (let i = 0; i < rightSideConnections.length; ++ i) {
const connection = rightSideConnections[i];
const yOffset = meta.getPortYOffset(connection.name) * SKIN_SCALE;
const targetY = yOffset;
// 默认采用 JUSTIFIED均分一侧的 height
// 我们绘制的 svg 的 port offset y 未必和 elk 分配得到的一样,因此需要进行修正
const layoutY = height / (rightSideConnections.length + 1) * (i + 1);
const extraOffset = LINE_WIDTH * rightSideConnections.length / 2;
const anchorY = targetY - layoutY + extraOffset;
ports.push({
id: connection.id,
renderName: connection.name,
renderType: 'cellPort',
width: 0,
height: 0,
properties: {
'port.side': ELK_DIRECTION.RIGHT,
'port.anchor': `0, ${anchorY}`
}
});
}
const node = {
id: cell.id,
renderName: cell.type,
renderType: 'cell',
width,
height,
ports
ports,
layoutOptions: {
'org.eclipse.elk.portConstraints': 'FIXED_SIDE',
}
};
nodes.push(node);
} else {
// 例化模块
@ -172,11 +230,11 @@ export class Module {
width,
height,
ports,
properties: {
layoutOptions: {
// 强制固定 port 的方向
'portConstraints': 'FIXED_ORDER'
},
'org.eclipse.elk.portConstraints': 'FIXED_SIDE'
}
};
nodes.push(node);
}

View File

@ -65,8 +65,8 @@ class SkinMeta {
const parser = new DOMParser();
// 颜色替换
svgString = svgString.replace(/#279BB0/g, 'var(--main-color)');
svgString = svgString.replace(/#000000/g, 'var(--main-dark-color)');
svgString = svgString.replace(/#279BB0/g, 'var(--main-dark-color)');
svgString = svgString.replace(/#000000/g, 'var(--main-color)');
const svgDoc = parser.parseFromString(svgString, 'image/svg+xml');
const element = svgDoc.documentElement;
@ -94,7 +94,7 @@ class SkinMeta {
return 0;
}
const transform = pathElement.getAttribute('transform');
const yOffset = transform.split(' ').at(-1);
const yOffset = parseFloat(transform.split(' ').at(-1));
this.portToYOffset.set(portName, yOffset);
return yOffset;
}