完成渲染的架构
This commit is contained in:
parent
45619460cf
commit
2a1dc56148
1
package-lock.json
generated
1
package-lock.json
generated
@ -10,6 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
|
"d3-drag": "^3.0.0",
|
||||||
"element-plus": "^2.9.1",
|
"element-plus": "^2.9.1",
|
||||||
"elkjs": "^0.9.3",
|
"elkjs": "^0.9.3",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^3.8.3",
|
"core-js": "^3.8.3",
|
||||||
"d3": "^7.9.0",
|
"d3": "^7.9.0",
|
||||||
|
"d3-drag": "^3.0.0",
|
||||||
"element-plus": "^2.9.1",
|
"element-plus": "^2.9.1",
|
||||||
"elkjs": "^0.9.3",
|
"elkjs": "^0.9.3",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
|
@ -207,3 +207,16 @@
|
|||||||
* @property {'NORTH' | 'SOUTH' | 'EAST' | 'WEST'} [elk.port.side] - 端口的位置(可选,如 "NORTH", "SOUTH", "EAST", "WEST")。
|
* @property {'NORTH' | 'SOUTH' | 'EAST' | 'WEST'} [elk.port.side] - 端口的位置(可选,如 "NORTH", "SOUTH", "EAST", "WEST")。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef BasicD3DataItem
|
||||||
|
* @property {number} x
|
||||||
|
* @property {number} y
|
||||||
|
* @property {number} width
|
||||||
|
* @property {number} height
|
||||||
|
* @property {string} [fill]
|
||||||
|
* @property {string} [text]
|
||||||
|
* @property {number} [rx]
|
||||||
|
* @property {number} [ry]
|
||||||
|
*/
|
71
src/hook/render/cell.js
Normal file
71
src/hook/render/cell.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import * as d3 from 'd3';
|
||||||
|
import { globalSetting } from '../global';
|
||||||
|
|
||||||
|
export class CellRender {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
* @param {BasicD3DataItem} cells
|
||||||
|
*/
|
||||||
|
constructor(selection, cells) {
|
||||||
|
this.parentSelection = selection;
|
||||||
|
this.data = cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const data = this.data;
|
||||||
|
|
||||||
|
let cellSelections = this.parentSelection.selectAll('g')
|
||||||
|
.data(data)
|
||||||
|
.enter()
|
||||||
|
.append(data => {
|
||||||
|
const element = data.element;
|
||||||
|
element.setAttribute('x', data.x);
|
||||||
|
element.setAttribute('y', data.y);
|
||||||
|
if (globalSetting.renderAnimation) {
|
||||||
|
element.setAttribute('stroke-opacity', 0);
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (globalSetting.renderAnimation) {
|
||||||
|
cellSelections = cellSelections
|
||||||
|
.transition()
|
||||||
|
.duration(1000)
|
||||||
|
.attr('stroke-opacity', 1);
|
||||||
|
}
|
||||||
|
cellSelections.on('end', function (data) {
|
||||||
|
const cellSelection = d3.select(this);
|
||||||
|
registerDragEvent(cellSelection, data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.selections = cellSelections;
|
||||||
|
return cellSelections;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 注册关于 器件 的拖动事件
|
||||||
|
*
|
||||||
|
* 需要提取最小拓扑子图,然后重新调整各个区域的尺寸
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
* @param {any} data
|
||||||
|
*/
|
||||||
|
export function registerDragEvent(selection, data) {
|
||||||
|
// 创建拖拽行为
|
||||||
|
const drag = d3.drag();
|
||||||
|
drag.on("drag", event => dragged(event, selection, data));
|
||||||
|
selection.call(drag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {d3.D3DragEvent} event
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
*/
|
||||||
|
function dragged(event, selection, data) {
|
||||||
|
data.x = event.x;
|
||||||
|
data.y = event.y;
|
||||||
|
selection.attr('x', event.x).attr('y', event.y);
|
||||||
|
}
|
70
src/hook/render/connection.js
Normal file
70
src/hook/render/connection.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import * as d3 from 'd3';
|
||||||
|
import { globalSetting } from '../global';
|
||||||
|
|
||||||
|
export class ConnectionRender {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
* @param {BasicD3DataItem} connections
|
||||||
|
*/
|
||||||
|
constructor(selection, connections) {
|
||||||
|
this.parentSelection = selection;
|
||||||
|
this.data = connections;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const data = this.data;
|
||||||
|
|
||||||
|
let connectionSelections = this.parentSelection.selectAll('circle')
|
||||||
|
.data(data)
|
||||||
|
.enter()
|
||||||
|
.append('circle')
|
||||||
|
.attr('cx', data => data.x)
|
||||||
|
.attr('cy', data => data.y)
|
||||||
|
.attr('width', data => data.width)
|
||||||
|
.attr('height', data => data.height)
|
||||||
|
|
||||||
|
if (globalSetting.renderAnimation) {
|
||||||
|
connectionSelections = connectionSelections
|
||||||
|
.transition()
|
||||||
|
.duration(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
connectionSelections
|
||||||
|
.attr('fill', d => d.fill)
|
||||||
|
.attr('r', d => d.r)
|
||||||
|
.on('end', function (data) {
|
||||||
|
const connectionSelection = d3.select(this);
|
||||||
|
registerDragEvent(connectionSelection, data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.selections = connectionSelections;
|
||||||
|
return connectionSelections;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 注册关于 器件 的拖动事件
|
||||||
|
*
|
||||||
|
* 需要提取最小拓扑子图,然后重新调整各个区域的尺寸
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
* @param {any} data
|
||||||
|
*/
|
||||||
|
export function registerDragEvent(selection, data) {
|
||||||
|
// 创建拖拽行为
|
||||||
|
const drag = d3.drag();
|
||||||
|
drag.on("drag", event => dragged(event, selection, data));
|
||||||
|
selection.call(drag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {d3.D3DragEvent} event
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
*/
|
||||||
|
function dragged(event, selection, data) {
|
||||||
|
data.x = event.x;
|
||||||
|
data.y = event.y;
|
||||||
|
selection.attr('x', event.x).attr('y', event.y);
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
import * as d3 from 'd3';
|
|
||||||
import ELK from 'elkjs';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 注册关于 器件 的拖动事件
|
|
||||||
*
|
|
||||||
* 需要提取最小拓扑子图,然后重新调整各个区域的尺寸
|
|
||||||
* @param {d3.Transition} renderSvg
|
|
||||||
*/
|
|
||||||
export function registerCellDragEvent(renderSvg) {
|
|
||||||
// renderSvg.call(d3.drag().on('drag', (event, g) => {
|
|
||||||
// console.log(event);
|
|
||||||
// }));
|
|
||||||
}
|
|
@ -5,6 +5,10 @@ import ELK from 'elkjs';
|
|||||||
import { Module } from './layout';
|
import { Module } from './layout';
|
||||||
import { globalLookup, globalSetting } from '../global';
|
import { globalLookup, globalSetting } from '../global';
|
||||||
import { registerCellDragEvent } from './drag';
|
import { registerCellDragEvent } from './drag';
|
||||||
|
import { PortRender } from './port';
|
||||||
|
import { InstantiationRender } from './instantiation';
|
||||||
|
import { CellRender } from './cell';
|
||||||
|
import { ConnectionRender } from './connection';
|
||||||
|
|
||||||
export class NetlistRender {
|
export class NetlistRender {
|
||||||
/**
|
/**
|
||||||
@ -82,6 +86,25 @@ export class NetlistRender {
|
|||||||
return layoutGraph;
|
return layoutGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 窗体大小发生变化时
|
||||||
|
*/
|
||||||
|
registerResizeHandler(element) {
|
||||||
|
this.resizeMonitor = new ResizeObserver(entries => {
|
||||||
|
for (const entry of entries) {
|
||||||
|
const { height, width } = entry.contentRect;
|
||||||
|
this.renderHeight = height;
|
||||||
|
this.renderWidth = width;
|
||||||
|
if (this.selection) {
|
||||||
|
this.selection
|
||||||
|
.attr('width', this.renderWidth)
|
||||||
|
.attr('height', this.renderHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.resizeMonitor.observe(element);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {ElkNode} computedLayout
|
* @param {ElkNode} computedLayout
|
||||||
@ -92,14 +115,19 @@ export class NetlistRender {
|
|||||||
const virtualHeight = computedLayout.height;
|
const virtualHeight = computedLayout.height;
|
||||||
const virtualWidth = computedLayout.width;
|
const virtualWidth = computedLayout.width;
|
||||||
|
|
||||||
|
const element = document.querySelector(container);
|
||||||
|
this.renderHeight = element.clientHeight;
|
||||||
|
this.renderWidth = element.clientWidth;
|
||||||
|
this.registerResizeHandler(element);
|
||||||
|
|
||||||
// 根据 height 进行放缩(可以通过设置进行调整)
|
// 根据 height 进行放缩(可以通过设置进行调整)
|
||||||
const ratio = this.renderHeight / virtualHeight;
|
const ratio = this.renderHeight / virtualHeight;
|
||||||
|
|
||||||
// 遍历计算布局进行创建
|
// 遍历计算布局进行创建
|
||||||
const svg = d3.select(container)
|
const svg = d3.select(container)
|
||||||
.selectAll('svg')
|
.selectAll('svg')
|
||||||
.attr('width', virtualWidth)
|
.attr('width', this.renderWidth)
|
||||||
.attr('height', virtualHeight);
|
.attr('height', this.renderHeight);
|
||||||
|
|
||||||
await this.renderLine(svg, computedLayout, ratio);
|
await this.renderLine(svg, computedLayout, ratio);
|
||||||
await this.renderEntity(svg, computedLayout, ratio);
|
await this.renderEntity(svg, computedLayout, ratio);
|
||||||
@ -123,17 +151,21 @@ export class NetlistRender {
|
|||||||
|
|
||||||
// 生成用于绘制的 d3 数据结构
|
// 生成用于绘制的 d3 数据结构
|
||||||
// 默认需要渲染成矩形的(缺失样式的器件、例化模块等等)
|
// 默认需要渲染成矩形的(缺失样式的器件、例化模块等等)
|
||||||
const squares = [];
|
const ports = [];
|
||||||
|
const instantiations = [];
|
||||||
|
|
||||||
|
const cells = [];
|
||||||
const connections = [];
|
const connections = [];
|
||||||
const svgElements = [];
|
|
||||||
const skinManager = globalLookup.skinManager;
|
const skinManager = globalLookup.skinManager;
|
||||||
|
|
||||||
|
// TODO: 把下面的逻辑融合进入 render 中
|
||||||
|
|
||||||
for (const node of computedLayout.children) {
|
for (const node of computedLayout.children) {
|
||||||
const skin = skinManager.querySkin(node.renderName);
|
const skin = skinManager.querySkin(node.renderName);
|
||||||
if (skin) {
|
if (skin) {
|
||||||
// 具有 skin 的器件
|
// 具有 skin 的器件
|
||||||
svgElements.push({
|
cells.push({
|
||||||
element: skin.meta.svgDoc.documentElement,
|
element: skin.meta.svgDoc.documentElement,
|
||||||
x: node.x,
|
x: node.x,
|
||||||
y: node.y,
|
y: node.y,
|
||||||
@ -142,8 +174,8 @@ export class NetlistRender {
|
|||||||
fill: 'var(--main-dark-color)',
|
fill: 'var(--main-dark-color)',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 没有 skin 的器件
|
if (node.renderType === 'port') {
|
||||||
squares.push({
|
ports.push({
|
||||||
x: node.x,
|
x: node.x,
|
||||||
y: node.y,
|
y: node.y,
|
||||||
width: node.width,
|
width: node.width,
|
||||||
@ -153,6 +185,19 @@ export class NetlistRender {
|
|||||||
rx: 3,
|
rx: 3,
|
||||||
ry: 3
|
ry: 3
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
// 没有 skin 的器件或者端口
|
||||||
|
instantiations.push({
|
||||||
|
x: node.x,
|
||||||
|
y: node.y,
|
||||||
|
width: node.width,
|
||||||
|
height: node.height,
|
||||||
|
fill: 'var(--main-dark-color)',
|
||||||
|
text: node.renderName,
|
||||||
|
rx: 3,
|
||||||
|
ry: 3
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果存在 port,绘制 port
|
// 如果存在 port,绘制 port
|
||||||
@ -169,114 +214,17 @@ export class NetlistRender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalSetting.renderAnimation) {
|
this.portRender = new PortRender(svg, ports);
|
||||||
svg.selectAll('rect')
|
this.portRender.render();
|
||||||
.data(squares)
|
|
||||||
.enter()
|
|
||||||
.append('rect')
|
|
||||||
.attr('x', data => data.x)
|
|
||||||
.attr('y', data => data.y)
|
|
||||||
.attr('width', data => data.width)
|
|
||||||
.attr('height', data => data.height)
|
|
||||||
.attr('fill', d => d.fill)
|
|
||||||
.transition()
|
|
||||||
.duration(1000)
|
|
||||||
.attr('stroke', 'var(--main-color)')
|
|
||||||
.attr('stroke-width', 2)
|
|
||||||
.attr('rx', d => d.rx)
|
|
||||||
.attr('ry', d => d.ry);
|
|
||||||
|
|
||||||
const renderSvg = svg.selectAll('g')
|
// this.instantiationRender = new InstantiationRender(svg, instantiations);
|
||||||
.data(svgElements)
|
// this.instantiationRender.render();
|
||||||
.enter()
|
|
||||||
.append(data => {
|
|
||||||
const element = data.element;
|
|
||||||
element.setAttribute('x', data.x);
|
|
||||||
element.setAttribute('y', data.y);
|
|
||||||
element.setAttribute('stroke-opacity', 0);
|
|
||||||
return element;
|
|
||||||
})
|
|
||||||
.transition()
|
|
||||||
.duration(1000)
|
|
||||||
.attr('stroke-opacity', 1);
|
|
||||||
|
|
||||||
registerCellDragEvent(renderSvg);
|
this.cellRender = new CellRender(svg, cells);
|
||||||
|
this.cellRender.render();
|
||||||
|
|
||||||
svg.selectAll('circle')
|
this.connectionRender = new ConnectionRender(svg, connections);
|
||||||
.data(connections)
|
this.connectionRender.render();
|
||||||
.enter()
|
|
||||||
.append('circle')
|
|
||||||
.attr('cx', data => data.x)
|
|
||||||
.attr('cy', data => data.y)
|
|
||||||
.attr('width', data => data.width)
|
|
||||||
.attr('height', data => data.height)
|
|
||||||
.transition()
|
|
||||||
.duration(1000)
|
|
||||||
.attr('fill', d => d.fill)
|
|
||||||
.attr('r', d => d.r);
|
|
||||||
|
|
||||||
svg.selectAll('text')
|
|
||||||
.data(squares)
|
|
||||||
.enter()
|
|
||||||
.append('text')
|
|
||||||
.attr('x', data => data.x + data.width / 2) // 文本的 x 坐标(居中)
|
|
||||||
.attr('y', data => data.y + 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')
|
|
||||||
.text(data => data.text); // 设置文本内容
|
|
||||||
} else {
|
|
||||||
svg.selectAll('rect')
|
|
||||||
.data(squares)
|
|
||||||
.enter()
|
|
||||||
.append('rect')
|
|
||||||
.attr('x', data => data.x)
|
|
||||||
.attr('y', data => data.y)
|
|
||||||
.attr('width', data => data.width)
|
|
||||||
.attr('height', data => data.height)
|
|
||||||
.attr('fill', d => d.fill)
|
|
||||||
.attr('stroke', 'var(--main-color)')
|
|
||||||
.attr('stroke-width', 2)
|
|
||||||
.attr('rx', d => d.rx)
|
|
||||||
.attr('ry', d => d.ry);
|
|
||||||
|
|
||||||
svg.selectAll('g')
|
|
||||||
.data(svgElements)
|
|
||||||
.enter()
|
|
||||||
.append(data => {
|
|
||||||
const element = data.element;
|
|
||||||
element.setAttribute('x', data.x);
|
|
||||||
element.setAttribute('y', data.y);
|
|
||||||
return element;
|
|
||||||
});
|
|
||||||
|
|
||||||
svg.selectAll('circle')
|
|
||||||
.data(connections)
|
|
||||||
.enter()
|
|
||||||
.append('circle')
|
|
||||||
.attr('cx', data => data.x)
|
|
||||||
.attr('cy', data => data.y)
|
|
||||||
.attr('width', data => data.width)
|
|
||||||
.attr('height', data => data.height)
|
|
||||||
.attr('fill', d => d.fill)
|
|
||||||
.attr('r', d => d.r);
|
|
||||||
|
|
||||||
svg.selectAll('text')
|
|
||||||
.data(squares)
|
|
||||||
.enter()
|
|
||||||
.append('text')
|
|
||||||
.attr('x', data => data.x + data.width / 2) // 文本的 x 坐标(居中)
|
|
||||||
.attr('y', data => data.y + data.height / 2) // 文本的 y 坐标(居中)
|
|
||||||
.attr('dominant-baseline', 'middle') // 文本垂直居中
|
|
||||||
.attr('text-anchor', 'middle') // 文本水平居中
|
|
||||||
.attr('fill', 'white') // 文本颜色
|
|
||||||
.attr('font-size', '12px')
|
|
||||||
.text(data => data.text); // 设置文本内容
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -337,4 +285,39 @@ export class NetlistRender {
|
|||||||
|
|
||||||
svg.attr('transform', `translate(${globalLookup.svgTranslateX}, ${globalLookup.svgTranslateY}) scale(${globalLookup.svgScale})`);
|
svg.attr('transform', `translate(${globalLookup.svgTranslateX}, ${globalLookup.svgTranslateY}) scale(${globalLookup.svgScale})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 渲染 module 中的 port
|
||||||
|
*/
|
||||||
|
renderPorts() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 渲染 module 中的例化模块
|
||||||
|
*/
|
||||||
|
renderInstantiations() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 渲染 module 中的基础器件
|
||||||
|
*/
|
||||||
|
renderCells() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 渲染每一个 例化模块/基础器件 的接入端口
|
||||||
|
*/
|
||||||
|
renderConnections() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 渲染连线
|
||||||
|
*/
|
||||||
|
renderWires() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
11
src/hook/render/instantiation.js
Normal file
11
src/hook/render/instantiation.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import * as d3 from 'd3';
|
||||||
|
|
||||||
|
export class InstantiationRender {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
*/
|
||||||
|
constructor(selection) {
|
||||||
|
this.selection = selection;
|
||||||
|
}
|
||||||
|
}
|
81
src/hook/render/port.js
Normal file
81
src/hook/render/port.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import * as d3 from 'd3';
|
||||||
|
import ELK from 'elkjs';
|
||||||
|
import { globalLookup, globalSetting } from '../global';
|
||||||
|
|
||||||
|
export class PortRender {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
* @param {BasicD3DataItem} ports
|
||||||
|
*/
|
||||||
|
constructor(selection, ports) {
|
||||||
|
this.parentSelection = selection;
|
||||||
|
this.data = ports;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const data = this.data;
|
||||||
|
|
||||||
|
let portSelections = this.parentSelection.selectAll('rect')
|
||||||
|
.data(data)
|
||||||
|
.enter()
|
||||||
|
.append('rect')
|
||||||
|
.attr('x', data => data.x)
|
||||||
|
.attr('y', data => data.y)
|
||||||
|
.attr('width', data => data.width)
|
||||||
|
.attr('height', data => data.height)
|
||||||
|
.attr('fill', d => d.fill);
|
||||||
|
|
||||||
|
portSelections.append("text")
|
||||||
|
.attr("x", d => d.width / 2) // 文本的 x 坐标(居中)
|
||||||
|
.attr("y", d => d.height / 2) // 文本的 y 坐标(居中)
|
||||||
|
.attr("text-anchor", "middle") // 文本水平居中
|
||||||
|
.attr("dominant-baseline", "middle") // 文本垂直居中
|
||||||
|
.text(d => d.text) // 设置文本内容
|
||||||
|
.attr("fill", "black"); // 文本颜色
|
||||||
|
|
||||||
|
if (globalSetting.renderAnimation) {
|
||||||
|
portSelections = portSelections
|
||||||
|
.transition()
|
||||||
|
.duration(1000)
|
||||||
|
}
|
||||||
|
portSelections
|
||||||
|
.attr('stroke', 'var(--main-color)')
|
||||||
|
.attr('stroke-width', 2)
|
||||||
|
.attr('rx', d => d.rx)
|
||||||
|
.attr('ry', d => d.ry)
|
||||||
|
.on('end', function (data) {
|
||||||
|
const portSelection = d3.select(this);
|
||||||
|
registerDragEvent(portSelection, data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.selections = portSelections;
|
||||||
|
return portSelections;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 注册关于 器件 的拖动事件
|
||||||
|
*
|
||||||
|
* 需要提取最小拓扑子图,然后重新调整各个区域的尺寸
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
* @param {any} data
|
||||||
|
*/
|
||||||
|
export function registerDragEvent(selection, data) {
|
||||||
|
// 创建拖拽行为
|
||||||
|
const drag = d3.drag();
|
||||||
|
drag.on("drag", event => dragged(event, selection, data));
|
||||||
|
selection.call(drag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {d3.D3DragEvent} event
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
*/
|
||||||
|
function dragged(event, selection, data) {
|
||||||
|
data.x = event.x;
|
||||||
|
data.y = event.y;
|
||||||
|
selection.attr('x', event.x).attr('y', event.y);
|
||||||
|
}
|
11
src/hook/render/wire.js
Normal file
11
src/hook/render/wire.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import * as d3 from 'd3';
|
||||||
|
|
||||||
|
export class WireRender {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {d3.Selection} selection
|
||||||
|
*/
|
||||||
|
constructor(selection) {
|
||||||
|
this.selection = selection;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user