利用d3.js力导布局绘制资源拓扑图实例教程(3)

效果如下:

ok 已经基本实现啦,那就这样啦,等后台同学实现一下接口就可以上线啦,日均UV两位数的产品要啥自行车,有的看就不错了(手动二哈)。

当然不行了,有这么一个都市传说,中台产品的好用与否与离职率高低成相关关系。本来需要打开资源拓扑图就是一件很🤢的事了,再看到这么一款体验极差的产品,感觉分分钟就要离职了。为了给我司年交易额两万亿的长远目标添砖加瓦,我们来看看有啥需要改进的地方。

至少字给我居中吧

注意到我们的字都是左下角定位到节点中心的,这是因为我们使用的是 svg 的 text 元素,默认情况下给 text 元素设置的 x 和 y 代表了 text 元素 baseLine 的起始位置。当然我们可以通过直接设置 dx 与 dy 设置一个偏移量来完成居中的问题,但考虑到 svg 元素相比普通的 html 元素毕竟还是有所限制,并不方便将来的扩展啥的,所以我们索性把所有的圆点与文字都换成 html 元素。

...

const nodeElements = html.append('div') 
 .selectAll('div')
 .data(nodes.filter(node => node.isAppNode))
 .enter().append('div')
 // css modules
 .attr('class', styles.NodeItem)
 .html((node: INode) => {
 return `<p>${node.id}</p>`;
 });

const labelElements = html.append('div') 
 .selectAll('div')
 .data(nodes.filter(node => !node.isAppNode))
 .enter().append('div')
 // css modules
 .attr('class', styles.LabelItem)
 .html(node => `
 <p>${node.label}</p>
 <p>Avada Kedavra!</p>
 `);

...

const render = () => { 
 nodeElements
 .attr('style', (node) => {
 return `transform: translate3d(calc(${node.x}px - 50%), calc(${node.y}px - 50%), 0);`;
 });

 labelElements
 .attr('style', (node) => {
 return `transform: translate3d(calc(${node.x}px - 50%), calc(${node.y}px - 50%), 0);`;
 });
}

效果如下: