实现动态增加线宽
This commit is contained in:
parent
7a6ed915d0
commit
0b8e986990
@ -15,7 +15,7 @@
|
||||
|
||||
<script>
|
||||
window.readNetFile = async () => {
|
||||
const inputVcdFile = 'full_adder.json';
|
||||
const inputVcdFile = 'IF_ID.json';
|
||||
const skin = 'dide.skin';
|
||||
const r1 = await fetch(inputVcdFile);
|
||||
const r2 = await fetch(skin);
|
||||
@ -23,7 +23,7 @@
|
||||
const skinBinary = await r2.arrayBuffer();
|
||||
return [ netJson, skinBinary ];
|
||||
}
|
||||
window.moduleName = 'full_adder';
|
||||
window.moduleName = 'IF_ID';
|
||||
// window.avoidWasm = 'avoid.wasm';
|
||||
</script>
|
||||
</head>
|
||||
|
@ -75,6 +75,7 @@
|
||||
{{ t('bold-multi-width-wire') }}
|
||||
</span>
|
||||
<el-switch
|
||||
@change="onBoldMultiWidthWireChange"
|
||||
v-model="globalSetting.boldMultiWidthWire"
|
||||
active-text="ON"
|
||||
inactive-text="OFF"
|
||||
@ -166,12 +167,13 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { globalSetting } from '@/hook/global';
|
||||
import { globalLookup, globalSetting } from '@/hook/global';
|
||||
import { reactive, defineComponent, watch, ref, onMounted } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { languageSetting } from './language';
|
||||
import { crossDotStyle, onConnectStyleChange } from './cross-dot-style';
|
||||
import { colorManager, onCellColorChange, onGeneralColorChange, predefinedColors } from './color';
|
||||
import { LINE_WIDTH } from '@/hook/render/layout';
|
||||
|
||||
defineComponent({ name: "dide-setting" });
|
||||
const { t, locale } = useI18n();
|
||||
@ -199,7 +201,6 @@ function onlanguagechange(code) {
|
||||
}
|
||||
|
||||
function onRenderArrowChange() {
|
||||
const rootStyles = getComputedStyle(document.documentElement);
|
||||
if (globalSetting.renderArrow) {
|
||||
document.documentElement.style.setProperty(`--line-arrow-opacity`, '1');
|
||||
} else {
|
||||
@ -207,6 +208,26 @@ function onRenderArrowChange() {
|
||||
}
|
||||
}
|
||||
|
||||
function onBoldMultiWidthWireChange() {
|
||||
const netlist = globalLookup.netlistRender;
|
||||
const renderView = netlist.renderView;
|
||||
const stack = [renderView];
|
||||
while (stack.length > 0) {
|
||||
const view = stack.pop();
|
||||
view.wireRender.lineSelections
|
||||
.attr('stroke-width', d => {
|
||||
console.log('enter');
|
||||
|
||||
const incrementWidth = globalSetting.boldMultiWidthWire ? 2 : 0;
|
||||
return d.width > 1 ? LINE_WIDTH + incrementWidth: LINE_WIDTH;
|
||||
});
|
||||
for (const id of view.id2children.keys()) {
|
||||
const subView = view.getChild(id);
|
||||
stack.push(subView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
colorManager.initColor();
|
||||
});
|
||||
|
@ -15,6 +15,7 @@ import { dotConnect } from './yosys';
|
||||
import { CrossDotRender } from './cross-dot';
|
||||
import { RangeTreeMap } from '../algorithm/range-tree';
|
||||
import { ConstantRender } from './constant';
|
||||
import { RenderViewNode } from './render-view';
|
||||
|
||||
export class NetlistRender {
|
||||
/**
|
||||
@ -209,15 +210,16 @@ export class NetlistRender {
|
||||
// 底层模块
|
||||
const topModule = this.nameToModule.get(this.topModuleName);
|
||||
|
||||
// 生成连接
|
||||
await this.renderLine(g, computedLayout, topModule);
|
||||
|
||||
// 生成实体
|
||||
await this.renderEntity(g, computedLayout, topModule);
|
||||
|
||||
// svg 挂载为全局注册的 selection
|
||||
this.selection = svg;
|
||||
this.g = g;
|
||||
|
||||
this.renderView = new RenderViewNode(g);
|
||||
|
||||
// 生成连接
|
||||
await this.renderLine(this.renderView, computedLayout, topModule);
|
||||
|
||||
// 生成实体
|
||||
await this.renderEntity(this.renderView, computedLayout, topModule);
|
||||
|
||||
// 注册平移和缩放
|
||||
this.registerRenderTransform(g);
|
||||
@ -235,10 +237,10 @@ export class NetlistRender {
|
||||
|
||||
/**
|
||||
* @description 绘制实体
|
||||
* @param {d3.Selection} parentSelection
|
||||
* @param {RenderViewNode} view
|
||||
* @param {import('../jsdoc').ElkNode} computedLayout
|
||||
*/
|
||||
async renderEntity(parentSelection, computedLayout) {
|
||||
async renderEntity(view, computedLayout) {
|
||||
// node 可能是如下的几类
|
||||
// - module 的 port
|
||||
// - 器件(基础器件 & 例化模块)
|
||||
@ -246,11 +248,11 @@ export class NetlistRender {
|
||||
const skinManager = globalLookup.skinManager;
|
||||
|
||||
// 创建各个主要实体的 render
|
||||
this.cellRender = new CellRender(parentSelection, this);
|
||||
this.portRender = new PortRender(parentSelection, this);
|
||||
this.instantiationRender = new InstantiationRender(parentSelection, this);
|
||||
this.connectionRender = new ConnectionRender(parentSelection, this);
|
||||
this.constantRender = new ConstantRender(parentSelection, this);
|
||||
view.cellRender = new CellRender(view.g, this);
|
||||
view.portRender = new PortRender(view.g, this);
|
||||
view.instantiationRender = new InstantiationRender(view.g, this);
|
||||
view.connectionRender = new ConnectionRender(view.g, this);
|
||||
view.constantRender = new ConstantRender(view.g, this);
|
||||
|
||||
for (const node of computedLayout.children) {
|
||||
// 只计算形体的,因为 连接点 非常小,几乎不影响布局
|
||||
@ -260,42 +262,40 @@ export class NetlistRender {
|
||||
if (skin) {
|
||||
// 具有 skin 的器件
|
||||
const element = skin.meta.svgDoc.documentElement.cloneNode(true);
|
||||
this.cellRender.addAsD3DataItem(node, element);
|
||||
view.cellRender.addAsD3DataItem(node, element);
|
||||
} else {
|
||||
if (node.renderType === 'port') {
|
||||
this.portRender.addAsD3DataItem(node);
|
||||
view.portRender.addAsD3DataItem(node);
|
||||
} else if (node.renderType === 'instance') {
|
||||
// 没有 skin 的器件或者端口
|
||||
this.instantiationRender.addAsD3DataItem(node);
|
||||
view.instantiationRender.addAsD3DataItem(node);
|
||||
} else if (node.renderType === 'constant') {
|
||||
this.constantRender.addAsD3DataItem(node);
|
||||
view.constantRender.addAsD3DataItem(node);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果存在 port,绘制 port
|
||||
for (const cellPort of node.ports || []) {
|
||||
this.connectionRender.addAsD3DataItem(cellPort, node);
|
||||
view.connectionRender.addAsD3DataItem(cellPort, node);
|
||||
}
|
||||
}
|
||||
|
||||
const ports = this.portRender.render();
|
||||
const instances = this.instantiationRender.render();
|
||||
const cells = this.cellRender.render();
|
||||
const connections = this.connectionRender.render();
|
||||
const constants = this.constantRender.render();
|
||||
|
||||
return { ports, instances, cells, connections };
|
||||
view.portRender.render();
|
||||
view.instantiationRender.render();
|
||||
view.cellRender.render();
|
||||
view.connectionRender.render();
|
||||
view.constantRender.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 绘制连线和交叉点
|
||||
* @param {d3.Selection} parentSelection
|
||||
* @param {RenderViewNode} view
|
||||
* @param {ElkNode} computedLayout
|
||||
* @param {Module} module
|
||||
*/
|
||||
async renderLine(parentSelection, computedLayout, module) {
|
||||
this.wireRender = new WireRender(parentSelection, this);
|
||||
this.crossDotRender = new CrossDotRender(parentSelection, this);
|
||||
async renderLine(view, computedLayout, module) {
|
||||
view.wireRender = new WireRender(view.g, this);
|
||||
view.crossDotRender = new CrossDotRender(view.g, this);
|
||||
|
||||
// 建立关于 port 的索引
|
||||
const id2port = new Map();
|
||||
@ -316,7 +316,7 @@ export class NetlistRender {
|
||||
points.push(point);
|
||||
}
|
||||
points.push(section.endPoint);
|
||||
this.wireRender.addAsD3DataItems(points, edge, id2port, width);
|
||||
view.wireRender.addAsD3DataItems(points, edge, id2port, width);
|
||||
|
||||
// 加入 range tree 中
|
||||
for (let i = 0; i < points.length - 1; ++ i) {
|
||||
@ -337,14 +337,14 @@ export class NetlistRender {
|
||||
for (const point of section.bendPoints || []) {
|
||||
const degree = rangeTree.getDegree(point);
|
||||
if (degree >= 3) {
|
||||
this.crossDotRender.addAsD3DataItem(point.x, point.y);
|
||||
view.crossDotRender.addAsD3DataItem(point.x, point.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.wireRender.render();
|
||||
this.crossDotRender.render();
|
||||
view.wireRender.render();
|
||||
view.crossDotRender.render();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -614,34 +614,31 @@ export class NetlistRender {
|
||||
this.zoom.translateBy(this.selection, deltaX, deltaY);
|
||||
|
||||
const svg = this.selection;
|
||||
const g = this.g;
|
||||
const g = this.renderView.g;
|
||||
|
||||
g.selectAll('*').remove();
|
||||
this.renderView.id2children.clear();
|
||||
|
||||
// 开始递归地进行渲染
|
||||
const renderStack = [
|
||||
{
|
||||
parentSelection: g,
|
||||
view: this.renderView,
|
||||
layout: computedLayout
|
||||
}
|
||||
];
|
||||
|
||||
while (renderStack.length > 0) {
|
||||
const s = renderStack.pop();
|
||||
const parentSelection = s.parentSelection;
|
||||
const view = s.view;
|
||||
const layout = s.layout;
|
||||
|
||||
const layoutName = layout.renderName || this.topModuleName;
|
||||
const module = this.nameToModule.get(layoutName);
|
||||
|
||||
await this.renderLine(parentSelection, layout, module);
|
||||
const { instances } = await this.renderEntity(parentSelection, layout, module);
|
||||
await this.renderLine(view, layout, module);
|
||||
await this.renderEntity(view, layout, module);
|
||||
|
||||
const id2selection = new Map();
|
||||
instances.each(function(data) {
|
||||
const selection = d3.select(this);
|
||||
id2selection.set(data.id, selection);
|
||||
});
|
||||
const id2selection = view.instantiationRender.id2selection;
|
||||
|
||||
// 将需要渲染子图的部分扔进渲染器
|
||||
for (const node of layout.children || []) {
|
||||
@ -649,8 +646,10 @@ export class NetlistRender {
|
||||
|
||||
if (subChildren.length > 0) {
|
||||
const selection = id2selection.get(node.id);
|
||||
const subView = new RenderViewNode(selection);
|
||||
view.setChild(node.id, subView);
|
||||
renderStack.push({
|
||||
parentSelection: selection,
|
||||
view: subView,
|
||||
layout: node
|
||||
});
|
||||
}
|
||||
@ -702,37 +701,41 @@ export class NetlistRender {
|
||||
this.zoom.translateBy(this.selection, deltaX, deltaY);
|
||||
|
||||
const svg = this.selection;
|
||||
const g = this.g;
|
||||
const g = this.renderView.g;
|
||||
|
||||
g.selectAll('*').remove();
|
||||
this.renderView.id2children.clear();
|
||||
|
||||
// 开始递归地进行渲染
|
||||
const renderStack = [
|
||||
{
|
||||
parentSelection: g,
|
||||
view: this.renderView,
|
||||
layout: computedLayout
|
||||
}
|
||||
];
|
||||
|
||||
while (renderStack.length > 0) {
|
||||
const s = renderStack.pop();
|
||||
const parentSelection = s.parentSelection;
|
||||
const view = s.view;
|
||||
const layout = s.layout;
|
||||
await this.renderLine(parentSelection, layout);
|
||||
const { instances } = await this.renderEntity(parentSelection, layout);
|
||||
const id2selection = new Map();
|
||||
instances.each(function(data) {
|
||||
const selection = d3.select(this);
|
||||
id2selection.set(data.id, selection);
|
||||
});
|
||||
|
||||
const layoutName = layout.renderName || this.topModuleName;
|
||||
const module = this.nameToModule.get(layoutName);
|
||||
|
||||
await this.renderLine(view, layout, module);
|
||||
await this.renderEntity(view, layout, module);
|
||||
|
||||
const id2selection = view.instantiationRender.id2selection;
|
||||
|
||||
// 将需要渲染子图的部分扔进渲染器
|
||||
for (const node of layout.children || []) {
|
||||
const subChildren = node.children || [];
|
||||
if (subChildren.length > 0) {
|
||||
const selection = id2selection.get(node.id);
|
||||
const subView = new RenderViewNode(selection);
|
||||
view.id2children.set(node.id, subView);
|
||||
renderStack.push({
|
||||
parentSelection: selection,
|
||||
view: subView,
|
||||
layout: node
|
||||
});
|
||||
}
|
||||
|
@ -235,6 +235,15 @@ export class InstantiationRender {
|
||||
});
|
||||
|
||||
this.selections = instantiationSelections;
|
||||
|
||||
const id2selection = new Map();
|
||||
instantiationSelections.each(function(data) {
|
||||
const selection = d3.select(this);
|
||||
id2selection.set(data.id, selection);
|
||||
});
|
||||
|
||||
this.id2selection = id2selection;
|
||||
|
||||
return instantiationSelections;
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,6 @@ export class WireRender {
|
||||
.attr("fill", "none")
|
||||
.attr('stroke', 'var(--wire-color)')
|
||||
|
||||
this.lineSelections = lineSelections;
|
||||
const arrows = new Map();
|
||||
|
||||
let arrowSelections = this.selection.selectAll('svg.line-arrow')
|
||||
@ -196,21 +195,23 @@ export class WireRender {
|
||||
});
|
||||
|
||||
|
||||
if (globalSetting.renderAnimation) {
|
||||
lineSelections = lineSelections
|
||||
.transition()
|
||||
.duration(1000);
|
||||
}
|
||||
// if (globalSetting.renderAnimation) {
|
||||
// lineSelections = lineSelections
|
||||
// .transition()
|
||||
// .duration(1000);
|
||||
// }
|
||||
|
||||
lineSelections
|
||||
.attr('stroke-width', d => {
|
||||
const incrementWidth = globalSetting.boldMultiWidthWire ? 1 : 0;
|
||||
const incrementWidth = globalSetting.boldMultiWidthWire ? 2 : 0;
|
||||
return d.width > 1 ? LINE_WIDTH + incrementWidth: LINE_WIDTH;
|
||||
})
|
||||
.each(function (data) {
|
||||
const selection = d3.select(this);
|
||||
// const manager = _this.createDataManager(selection, data);
|
||||
});
|
||||
|
||||
this.lineSelections = lineSelections;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user