【问题标题】:D3: How to set text inside a circleD3:如何在圆圈内设置文字
【发布时间】:2020-05-12 18:05:46
【问题描述】:

我是 D3.js 的新手,我正在尝试将文本放在一个圆圈内,但我只能使用其中一个而不是所有圆圈。

您可以在此片段中找到所有代码

我创建圆圈并尝试将文本放入其中的函数是“setPointsToCanvas”

  setPointsToCanvas(canvas, data, scales, x_label, y_label, lang) {
    canvas
      .selectAll("circle")
      .data(data)
      .enter()
      .append("circle")
      .attr("class", "dot")
      .attr("r", 20) //Radius size, could map to another dimension
      .attr("cx", function(d) {
        return scales.xScale(parseFloat(d.value_x));
      }) //x position
      .attr("cy", function(d) {
        return scales.yScale(parseFloat(d.value_y));
      }) //y position
      .style("fill", "#FFC107")
      .on("mouseover", tipMouseOver)
      .on("mouseout", tipMouseOut);

//Ad label for each circle
canvas
  .data(data)
  //.enter()
  .append("text")
  .attr("x", function(d) {
    return scales.xScale(parseFloat(d.value_x));
  })
  .attr("y", function(d) {
    return scales.yScale(parseFloat(d.value_y) - 0.9);
  })
  .text(function(d) {
    return d.name.substring(0, 3);
  })
  .style("text-anchor", "middle")
  .style("font-weight", "bold")
  .style("font-size", "10pt")
  .style("fill", "#344761");

let tooltip = d3
  //.select("#" + this.props.idContainer)
  .select("body")
  .append("div")
  .attr("class", "tooltip-player")
  .style("opacity", 0);

/**
 * We define this function inside of setPointsToCanvas to get access to canvas, data, scales and tooltip
 * @param {*} d
 * @param {*} iter
 */
function tipMouseOver(d, iter) {
  let players = data.filter(p => {
    if (p.value_x === d.value_x && p.value_y === d.value_y) {
      return p;
    }
  });
  let html = "";
  for (let i = 0; i < players.length; i++) {
    let text_x =
      lang === "es"
        ? String(parseFloat(players[i].value_x).toFixed(2)).replace(
            ".",
            ","
          )
        : parseFloat(players[i].value_x).toFixed(2);
    let text_y =
      lang === "es"
        ? String(parseFloat(players[i].value_y).toFixed(2)).replace(
            ".",
            ","
          )
        : parseFloat(players[i].value_y).toFixed(2);
    if (i > 0) html += "<hr>";
    html +=
      players[i].name +
      "<br><b>" +
      x_label +
      ": </b>" +
      text_x +
      "%<br/>" +
      "<b>" +
      y_label +
      ": </b>" +
      text_y +
      "%";
  }
  tooltip
    .html(html)
    .style("left", d3.event.pageX + 15 + "px")
    .style("top", d3.event.pageY - 28 + "px")
    .transition()
    .duration(200) // ms
    .style("opacity", 0.9); // started as 0!

  // Use D3 to select element, change color and size
  d3.select(this)
    //.attr("r", 10)
    .style("cursor", "pointer");
}

/**
 * We create this function inside of setPointsToCanvas to get access to tooltip
 */
function tipMouseOut() {
  tooltip
    .transition()
    .duration(500) // ms
    .style("opacity", 0); // don't care about position!
  //d3.select(this).attr("r", 5);
}
  }

在这里您可以看到我如何只能在一个圆圈内获取一个文本,而不是在所有圆圈内获取文本。

我做错了什么?

【问题讨论】:

  • 您输入圆圈和文本的方式不同,如果您使用与圆圈相同的方法,则可以创建文本:canvas.selectAll("text").data(data).enter().append("text")...,但是,如果文本已经存在,则不要'不想将数据绑定到这些现有的文本元素(在轴上),所以如果只是输入文本,您可以使用canvas.selectAll(null),或者如果您希望能够重新选择那些特定的文本元素,则可以按类名选择更新/退出标签。
  • 有效!!!非常感谢您的宝贵帮助!!!
  • @AndrewReid,为了d3j.s 标签的健康,请停止在 cmets 中回答并使用正确的答案!
  • @PabloEM,请随时添加答案(@José,你也一样),还有比我写的更多的要说。我并不总是有时间输入我认为令人满意的答案 - 这对我来说也意味着解释为什么会看到错误行为(在这种情况下,我在评论时没有看到它,尽管在重新阅读时我'我有点失望,我没有看到它)。另外,我最初的看法是这可能是重复的,虽然可能很难找到,但同时评论可以确认问题(虽然我找不到很快,也许我今晚会添加一个答案)。
  • 是的,我完全理解你的意思。但是,另一方面,您的 cmets 通常对 OP 来说已经足够好和有用了,因为他可以解决他的问题,尽管更全面的答案会更好。

标签: javascript reactjs d3.js


【解决方案1】:

遵循@Pablo EM 的建议并感谢@Andrew Reid 的感谢帮助,我发布了我的问题的解决方案。

@Andrew Reid 如何说如果我对 selectAll("text") 有问题,我必须将其更改为另一个文本分组。我是如何拥有它的,我通过 selectAll("textCircle") 进行了更改,一切对我来说都很好。

这是在每个圆圈内写入文本的代码。您可以在“setPointsToCanvas”方法中找到这段代码。

//Ad label for each circle
canvas
  .selectAll("textCircle")
  .data(data)
  .enter()
  .append("text")
  .attr("x", function(d) {
    return scales.xScale(parseFloat(d.value_x));
  })
  .attr("y", function(d) {
    return scales.yScale(parseFloat(d.value_y) - 0.9);
  })
  .text(function(d) {
    return d.name.substring(0, 3);
  })
  .style("text-anchor", "middle")
  .style("font-weight", "bold")
  .style("font-size", "10pt")
  .style("fill", "#344761");

现在,这里是最终结果的图像:

如果您通过发布的 CodeSandBox 访问代码,您可以访问所有代码并检查它是如何完美运行的。

【讨论】:

    猜你喜欢
    • 2012-08-01
    • 1970-01-01
    • 2021-09-24
    • 2013-12-03
    • 1970-01-01
    • 2019-01-02
    • 2016-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多