简体   繁体   English

如何使用 d3.js 将我的圆环图的标签拆分为多条线?

[英]How do I split labels for my donut chart to multiple lines using d3.js?

I am displaying labels with my donut chart like this;我正在用我的甜甜圈图显示标签,如下所示;

this.graphGroup
      .selectAll('allLabels')
      .data(data_ready)
      .enter()
      .append('text').style('font-size', '24px')
      .text(d => {
        return d.data.name;   //LINE 1
      })
      .attr('transform',`${calculatedValue}`)
      .style('text-anchor', 'start');

I want to use this answer How do I include newlines in labels in D3 charts?我想使用这个答案如何在 D3 图表的标签中包含换行符? but adding the code after this addition of labels like this,但是在添加这样的标签之后添加代码,

this.graphGroup
    .selectAll('text')
    .each
    ( function (d) {
      var el = this.d3.select(this);
      console.log(el);
      var words = d.name.split(' ');
      console.log(words);
      el.text('');

      for (var i = 0; i < words.length; i++) {
        var tspan = el.append('tspan').text(words[i]);
        if (i > 0)
          tspan.attr('x', 0).attr('dy', '15');
      }
    });

When I use the each() on the first selection I get an error saying the selection is undefined.当我在第一个选择中使用 each() 时,我收到一条错误消息,指出选择未定义。 I tried adding the code on line 1 but I can only pass text into a d3.text().我尝试在第 1 行添加代码,但我只能将文本传递到 d3.text()。

How can I break the labels correctly?如何正确打破标签?

EDIT: I also had an error saying my local variable d3 was undefined, but it work while creating the graphGroup and all the other selections, I then imported select from d3 directly.编辑:我也有一个错误,说我的局部变量 d3 未定义,但它在创建 graphGroup 和所有其他选择时工作,然后我直接从 d3 导入 select 。

I figured out the answer;我想出了答案; each() does not work if the data() function has been called on that selection, so the answer directly from the linked post will not work.如果在该选择上调用了 data() function,则 each() 不起作用,因此直接来自链接帖子的答案将不起作用。

The other option is to use the call() on every text element made, like this;另一种选择是在每个文本元素上使用 call() ,就像这样;

this.graphGroup
      .selectAll('allLabels')
      .data(data_ready)
      .enter()
      .append('text').style('font-size', '24px')
      .attr('transform',`${calculatedValue}`)
      .style('text-anchor', 'start')
      .text(d => {
        return d.data.name;
      })
      .call(lineBreak, 40);

Where lineBreak is another function I have defined, the first parameter that gets passed into the function will be a reference to the looped element in the case, the different text elements.其中 lineBreak 是我定义的另一个 function ,传递给 function 的第一个参数将是对这种情况下的循环元素的引用,即不同的文本元素。

the linebreak function:换行符 function:

function lineBreak(text, width) {
      text.each(function () {
        var el = d3.select(this);
        let words = el.text().split(' ');
        let wordsFormatted = [];

        let string = '';
        for (let i = 0; i < words.length; i++) {
          if (words[i].length + string.length <= width) {
            string = string + words[i] + ' ';
          }
          else {
            wordsFormatted.push(string);
            string = words[i] + ' ';
          }
        }
        wordsFormatted.push(string);

        el.text('');
        for (var i = 0; i < wordsFormatted.length; i++) {
          var tspan = el.append('tspan').text(wordsFormatted[i]);
          if (i > 0)
            tspan.attr('x', 0).attr('dy', '20');
        }
      });
    }

Will optimize this function and edit later.将优化此 function 并稍后编辑。 Thanks!谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM