This commit is contained in:
锦恢 2024-12-31 21:13:04 +08:00
parent 64fdc7408b
commit 1b95ad73c4
4 changed files with 32 additions and 12 deletions

View File

@ -185,6 +185,8 @@ import { Module } from "./render/layout";
* @property {string[]} targets 边的目标节点列表
* @property {string} target 边的目标节点
* @property {string} targetPort 边的目标节点的port
* @property {string} [orginalSource]
* @property {string} [orginalTarget]
* @property {string} [container] 所在容器的 id 可选由布局算法生成
* @property {ElkSection[]} [sections] 具体的连线规则可选由布局算法生成
* @property {ElkLayoutOptions} [layoutOptions] 边的布局选项可选

View File

@ -232,7 +232,7 @@ export class NetlistRender {
/**
* @description 绘制实体
* @param {d3.Selection} parentSelection
* @param {ElkNode} computedLayout
* @param {import('../jsdoc').ElkNode} computedLayout
*/
async renderEntity(parentSelection, computedLayout) {
// node 可能是如下的几类
@ -560,12 +560,14 @@ export class NetlistRender {
for (const edge of connectionEdges) {
if (innerPortId2outterPortId.has(edge.source)) {
const outterId = innerPortId2outterPortId.get(edge.source);
edge.orginalSource = edge.source;
edge.source = elkNode.id;
edge.sourcePort = outterId;
}
if (innerPortId2outterPortId.has(edge.target)) {
const outterId = innerPortId2outterPortId.get(edge.target);
edge.orginalTarget = edge.target;
edge.target = elkNode.id;
edge.targetPort = outterId;
}
@ -576,6 +578,8 @@ export class NetlistRender {
elkNode.edges = [];
elkNode.layoutOptions = this.defaultLayoutOptions;
// elkNode.children.push(...portNodes);
elkNode.children.push(...cellNodes);
elkNode.children.push(...constantNodes);
elkNode.edges.push(...connectionEdges);
@ -617,7 +621,6 @@ export class NetlistRender {
const layout = s.layout;
await this.renderLine(parentSelection, layout);
const { instances } = await this.renderEntity(parentSelection, layout);
const id2selection = new Map();

View File

@ -28,27 +28,33 @@ export class InstantiationRender {
/**
* @description elknode 关于 例化模块 的数据添加为 d3 数据项目
* @param {ElkNode} node
* @param {import('../jsdoc').ElkNode} node
*/
addAsD3DataItem(node) {
const nodeModule = this.rootRender.nameToModule.get(node.renderName);
const view = nodeModule.view;
const textPadding = 5;
const portnames = [];
// 当前的例化是否为一个展开的例化
this.isExpanded = (node.children || []).length > 0;
const topPadding = this.isExpanded ? 25 : 0;
for (const port of node.ports || []) {
const isInput = port.x < LAYOUT_CONSTANT.INSTANTIATION_WIDTH;
const align = isInput ? 'left': 'end';
const portX = isInput ? port.x + textPadding : port.x - textPadding - LAYOUT_CONSTANT.INSTANCE_LEFT_MARGIN - LAYOUT_CONSTANT.INSTANCE_RIGHT_MARGIN;
const portY = this.isExpanded ? port.y - 10: port.y;
portnames.push({
name: port.renderName,
x: portX,
y: port.y,
y: portY,
align
});
}
this.data.push({
id: node.id,
type: node.renderName, // 例化模块的模块名字
@ -56,7 +62,8 @@ export class InstantiationRender {
y: node.y,
name: node.name,
width: node.width,
height: node.height,
height: node.height + topPadding,
topPadding,
text: node.renderName,
portnames,
rx: 3,
@ -83,7 +90,7 @@ export class InstantiationRender {
// 例化模块的方块
let instances = instantiationSelections.append('rect')
.attr('x', LAYOUT_CONSTANT.INSTANCE_LEFT_MARGIN)
.attr('y', LAYOUT_CONSTANT.INSTANCE_TITLE_HEIGHT)
.attr('y', d => LAYOUT_CONSTANT.INSTANCE_TITLE_HEIGHT - d.topPadding)
.attr('width', data => data.width - LAYOUT_CONSTANT.INSTANCE_LEFT_MARGIN - LAYOUT_CONSTANT.INSTANCE_RIGHT_MARGIN)
.attr('height', data => data.height - LAYOUT_CONSTANT.INSTANCE_TITLE_HEIGHT);
@ -91,7 +98,7 @@ export class InstantiationRender {
// 说明文字
let texts = instantiationSelections.append('text')
.attr('x', LAYOUT_CONSTANT.INSTANCE_LEFT_MARGIN)
.attr('y', LAYOUT_CONSTANT.INSTANCE_TITLE_HEIGHT - 8)
.attr('y', d => LAYOUT_CONSTANT.INSTANCE_TITLE_HEIGHT - 8 - d.topPadding)
.attr('dominant-baseline', 'middle')
.attr('text-anchor', 'left')
.attr('fill', 'var(--foreground)')
@ -127,7 +134,7 @@ export class InstantiationRender {
// 增加一个背景方块,防止 svg 点不到
let bgFullScreenSelections = instantiationSelections.append('rect')
.attr('x', 5 + LAYOUT_CONSTANT.INSTANCE_LEFT_MARGIN)
.attr('y', LAYOUT_CONSTANT.INSTANCE_TITLE_HEIGHT + 5)
.attr('y', d => LAYOUT_CONSTANT.INSTANCE_TITLE_HEIGHT + 5 - d.topPadding)
.attr('width', 20)
.attr('height', 20)
.attr('opacity', 0)
@ -151,7 +158,7 @@ export class InstantiationRender {
// 获取全屏图标
const element = svgResource.get('full-screen');
element.setAttribute('x', 5 + LAYOUT_CONSTANT.INSTANCE_LEFT_MARGIN);
element.setAttribute('y', LAYOUT_CONSTANT.INSTANCE_TITLE_HEIGHT + 5);
element.setAttribute('y', LAYOUT_CONSTANT.INSTANCE_TITLE_HEIGHT + 5 - data.topPadding);
element.setAttribute('width', 20);
element.setAttribute('height', 20);
element.setAttribute('class', 'pointer');

View File

@ -52,7 +52,15 @@ export class WireRender {
const targetMargin = getMarginParamter(targetPort);
beginPoint.x -= sourceMargin.rightMargin;
endPoint.x += targetMargin.leftMargin;
// 特殊情况: targetPort 为 undefined
if (targetPort === undefined) {
const port = id2port.get(edge.orginalTarget);
// TODO: 检查正确性
endPoint.x -= LAYOUT_CONSTANT.INSTANCE_RIGHT_MARGIN;
} else {
endPoint.x += targetMargin.leftMargin;
}
for (let i = 0; i < points.length; ++ i) {
// 根据点的信息创建 path