将有界文本添加到 React Force 2D(HTML Canvas)

问题描述 投票:0回答:1

确实,这是一个非常特定的包,更具体地说,是@vasturianoReact 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 索引,所以我认为这不是一个可行的方向).

javascript reactjs d3.js graph html5-canvas
1个回答
0
投票

您的问题有多个问题隐藏在一个问题中,您正在处理一个复杂的问题...

首先阅读有关在画布中绘制文本时如何对齐文本的更多信息:

现在你的问题是,你必须计算文本是否适合给定的圆圈,为此你需要知道或至少获得文本大小的近似值,更多阅读:

有了所有这些,您应该能够计算文本是否适合(如果不拆分它)或尝试一些“使其适合”,然后循环直到得到适合的内容


这是我为其他项目编写的一些代码...
在该代码中,我更改了字体大小,以使字母在圆圈中看起来更好

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>

© www.soinside.com 2019 - 2024. All rights reserved.