完成布局的分组优化
This commit is contained in:
parent
2f1d16c303
commit
5a7dd7f6f0
@ -43,4 +43,8 @@ onMounted(async () => {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.port-caption {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
</style>
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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() {
|
||||
|
||||
}
|
||||
}
|
@ -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';
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
}
|
||||
};
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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 注册关于 器件 的拖动事件
|
||||
*
|
||||
@ -119,7 +133,7 @@ function dragStart(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})`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user