确实,这是一个非常特定的包,更具体地说,是@vasturiano的React Force Graph。但是,由于它大量使用了 HTML Canvas 和 D3.js,我想也许这里有人可以阐明如何解决它。
我想做的事情已经在该项目的issue #433上报告过,但尚未收到任何答复。无论如何,我想在节点顶部添加文本,并且所述文本不会溢出节点圆边界,如下所示:
我认为你现在能做的最好的事情就是这样——实际上我只能通过 React Force 3D 来做类似的事情——:
通过使用 @vasturiano (ctx.fillText(...)
) 提供的
2D 文本节点示例,我已成功将文本添加到圆形节点,但无论我将其放在哪里,它都会以某种方式结束在其后面:
<ForceGraph2D
graphData={dataMemo}
nodeCanvasObjectMode={() => "before"}
nodeCanvasObject={(node, ctx) => {
ctx.beginPath();
ctx.arc(node.x!, node.y!, NODE_R * 1.4, 0, 2 * Math.PI, false);
ctx.fill();
ctx.fillText("hello", node.x!, node.y!);
}
/>
有谁知道如何堆叠文本并正确分隔它?我希望文本至少位于节点圆的顶部,因为它应该是稍后绘制的,我相信(我不认为
<canvas>
上有 z 索引,所以我认为这不是一个可行的方向).
您的问题有多个问题隐藏在一个问题中,您正在处理一个复杂的问题...
首先阅读有关在画布中绘制文本时如何对齐文本的更多信息:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign#examples
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline#examples
现在你的问题是,你必须计算文本是否适合给定的圆圈,为此你需要知道或至少获得文本大小的近似值,更多阅读:
有了所有这些,您应该能够计算文本是否适合(如果不拆分它)或尝试一些“使其适合”,然后循环直到得到适合的内容
这是我为其他项目编写的一些代码...
在该代码中,我更改了字体大小,以使字母在圆圈中看起来更好
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
function textFits(text, max) {
let m = ctx.measureText(text);
let h = m.actualBoundingBoxAscent + m.actualBoundingBoxDescent;
return Math.sqrt(m.width * m.width + h * h) < max;
}
function draw(x, y, r, text) {
ctx.beginPath();
ctx.fillStyle = "black";
ctx.arc(x, y, r, 0, 2 * Math.PI, false);
ctx.fill();
let size = 300;
do {
this.font = ctx.font = size + "px monospace";
size -= 2;
} while (!textFits(text, r*1.8));
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = size + "px monospace"
ctx.fillStyle = "red";
ctx.fillText(text, x, y);
}
draw(240, 110, 120, "m")
draw(30, 140, 30, "o")
draw(60, 60, 50, "w")
<canvas id="c" width=600 height=200></canvas>