Featured image of post 使用Antv X6绘图包时节点自适应大小的实现

使用Antv X6绘图包时节点自适应大小的实现

 

需求

在编辑节点名称的时候,我们希望节点框的大小随着内容的大小进行变化。简单来说就是节点根据内容自适应大小。如何获取内容文本的大小下面有两种方法实现。

实现

水平文本测量大小的实现

这种方式仅对水平文本有效,能测量出文本的宽度,测量文本的高度无效。

1
2
3
4
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
context!.font = '14px Arial, helvetica, sans-serif'; // 设置字体和字号,根据你要测的文本设置
const textWidth = context!.measureText(node.getAttrs()['text']['text']?.toString()!).width;

主要思路就是利用 HTML5 Canvas 的绘图功能来测量文本的宽度,然后根据文本的宽度动态调整节点的尺寸,以确保文本内容完全显示在节点内部。

  1. 创建画布和上下文

    • 首先,通过 document.createElement('canvas') 创建了一个 HTML5 Canvas 元素。
    • 然后,通过 getContext('2d') 获取了 2D 绘图上下文,以便后续进行文本测量。
  2. 设置字体和字号

    • 使用 context.font 设置了绘制文本时所使用的字体和字号。这个需要和你节点内容字体、字号相匹配,否则存在误差
  3. 测量文本宽度

    • 调用了 context.measureText() 方法来测量给定文本在当前字体和字号下的宽度。measureText() 方法返回一个 TextMetrics 对象,其中包含了文本的宽度等信息。

另一种实现方式

这种方式类似于打一个草稿,先创建一个svg然后渲染然后获得文本的宽高,这个对于水平排列的文本和竖直排列的文本都有效。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 创建一个包含字符串的 svg 元素
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute('width', '100');
svg.setAttribute('height', '100');

// 创建一个 <text> 元素
const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
text.setAttribute('font-family', 'Microsoft YaHei');
text.setAttribute('font-size', '14');
text.setAttribute('white-space', 'nowrap');
text.setAttribute('writing-mode', 'vertical-rl');
text.style.textOrientation = 'upright'
text.textContent = node.getAttrs()['text']['text']?.toString()!

// 将 <text> 元素添加到 <svg> 中
svg.appendChild(text);

// 将 <svg> 元素添加到文档中
document.body.appendChild(svg);

// 获取字符串的宽高
const textHeight = text.getBBox().height;
const textWidth = text.getBBox().width;

主要思路和水平节点的测量相同,不过因为竖直节点的定义和水平节点的不同,竖直节点中的内容是竖直排列,而canvas不能测量文本的高度,所以这里创建和antv X6中svg节点相同的元素,把文本放在其中渲染,然后获取高度,最后完成节点高度的动态调整。

  • 其中,竖直节点的实现是在css上加上下面三个属性:
1
2
3
white-space: 'nowrap';
writing-mode: 'vertical-rl';
text-orientation = 'upright';

其他

刚开始我尝试的方法是先修改节点的名称,再通过DOM的getBoundingClientRect获取修改后的文本宽高,但是因为X6 实现了异步的渲染调度算法,所以会出现获取不到DOM元素的情况,如果通过settimeout设置一定的时延再获取,容易造成修改时的频闪,或者有时未动态调整的情况。

Licensed under CC BY-NC-SA 4.0
最后更新于 May 24, 2024 23:28 CST
总访问量  |  总访客数  
Built with Hugo   主题 StackJimmy 设计