简体   繁体   English

d3.js / svg-如何将文本动态附加到弧中

[英]d3.js / svg - how to dynamically append text to my arcs

I am trying to complete the last bit of a d3 project which dynamically creates these blue arcs, over which I need to place arc text, as shown in this image: 我正在尝试完成d3项目的最后一部分,该项目动态创建这些蓝色弧,我需要在其上放置弧文本,如下图所示:

在此处输入图片说明

The image above is something I've done by placing the arc text statically, through trial and error, but I want to place it dynamically, based on the blue arcs which sit beneath the text. 上面的图片是我通过反复试验将弧形文本静态放置的方式来完成的,但是我想根据位于文本下方的蓝色弧形将其动态放置。 This is the code that dynamically creates the arcs: 这是动态创建弧的代码:

var groupData = data_group.selectAll("g.group")
    .data(nodes.filter(function(d) { console.log(d.__data__.key); return (d.key=='Employers' ||{exp:channel:entries category="13" backspace="2"} d.key == '{url_title}' ||{/exp:channel:entries}) && d.children; }))
    .enter().append("group")
    .attr("class", "group");

arc_group.selectAll("g.arc")
    .data(groupData[0])
    .enter().append("svg:path")
    .attr("d", groupArc)
    .attr("class", "groupArc")
    .style("fill", "#1f77b4")
    .style("fill-opacity", 0.5);

The {exp:} content is preparsed data I'm pulling from my content management system in expression engine if it looks confusing. {exp:}内容是准备从表达式引擎中的内容管理系统中提取的准备好的数据,如果看起来令人困惑。

So, I have my arcs. 所以,我有弧线。 Now you'll notice in the groupData code block I have a console.log statement, that will give me the names I want to appear in the arc text: 现在,您会在groupData代码块中注意到我有一个console.log语句,它将为我提供要显示在弧文本中的名称:

console.log(d.__data__.key);

Now, the code I was using to place the arc text statically was this: 现在,我用来静态放置弧文本的代码是:

var arcData = [
  {aS: 0, aE: 45,rI:radius - chartConfig.linePadding + chartConfig.arcPadding,rO:radius - chartConfig.linePadding + chartConfig.textPadding-chartConfig.arcPadding}
];

var arcJobsData = d3.svg.arc().innerRadius(arcData[0].rI).outerRadius(arcData[0].rO).startAngle(degToRad(1)).endAngle(degToRad(15));
var g = d3.select(".chart").append("svg:g").attr("class","arcs");
var arcJobs = d3.select(".arcs").append("svg:path").attr("d",arcJobsData).attr("id","arcJobs").attr("class","arc");
g.append("svg:text").attr("x",3).attr("dy",15).append("svg:textPath").attr("xlink:href","#arcJobs").text("JOBS").attr("class","arcText"); //x shifts x pixels from the starting point of the arc. dy shifts the text y units from the top of the arc

And in this above code, the only thing left that I should need to do is dynamically assign an ID to the arcs, and then reference that ID in the xlink:href attribute, as well as replace the text("JOBS") with text that pulls from d. 在上面的代码中,我唯一需要做的就是为圆弧动态分配一个ID,然后在xlink:href属性中引用该ID,并用text替换text(“ JOBS”)从d拉出。 data__key. data__key。 Given the code above which dynamically creates the arcs, and given that I know how to dynamically create and retrieve the text I want to place in the arcs using d.__data .key, I should be able to finish this thing off, but I can't figure out how write code in d3 that will take the data and place it in the arcs. 鉴于上面的代码可以动态创建弧,并且鉴于我知道如何使用d .__ data .key 动态创建和检索要放置在弧中的文本 ,我应该能够完成此工作,但是我可以没有弄清楚如何在d3中编写代码来获取数据并将其放置在弧中。 Can anybody help with this? 有人可以帮忙吗?

You should give this blog post on nested selections a read; 您应该阅读有关嵌套选择博客文章 I believe it'll explain what you're trying to do. 我相信它会解释您要做什么。

Here's the gist. 这是要点。 When you add data to your selection, assign the selection to a variable: 将数据添加到选择中时,请将选择分配给变量:

var g = data_group.selectAll("g.group")
    .data(nodes.filter(function(d) { /* stuff */ }));

That way, you can perform subselections on it, which will receive a single element of the data bound to your g selection. 这样,您可以对其执行子选择,这将接收绑定到g选择的数据的单个元素。 You can use this to add your arcs and text: 您可以使用它来添加圆弧和文本:

g.enter().append('group') // Question: Are you sure you mean 'group' here?
    .attr('class', 'group')

g.selectAll('g.arc')
    .data(function(d, i) { return d; })
  enter().append('path')
     // Setup the path here

g.selectAll('text')
    .data(function(d, i) { return d; })
  .enter().append('text')
    .attr('text', function(d) { return d.__data__.key })

The functions that are being used to do data binding in the nested selections (ie, the g.selectAll() s) are being passed a single element of the data attached to g as d , and i is its index. 正在用来做数据在嵌套选择结合的功能(即, g.selectAll() S)被传递附加到数据的单个元素 gd ,并且i是它的索引。

Figured this out. 想通了。 Changed the structure of things a bit so it made a little more sense, but essentially what I did is this: 改变了事物的结构,使它更具意义,但实际上我所做的是:

var groupData = data_group.selectAll("g.group")
    .data(nodes.filter(function(d) { return (d.key=='Employers' ||{exp:channel:entries category="13" backspace="2"} d.key == '{url_title}' ||{/exp:channel:entries}) && d.children; }))
    .enter().append("group")
    .attr("class", "group"); //MH - why do we need this group - these elements are empty. Shouldn't this just be an array? Find out how to delete the svg elements without getting rid of the data, which is needed below.


  var groupArc = d3.svg.arc()
    .innerRadius(ry - 177)
    .outerRadius(ry - 157)
    .startAngle(function(d) { return (findStartAngle(d.__data__.children)-2) * pi / 180;})
    .endAngle(function(d) { console.log(d.__data__.key); return (findEndAngle(d.__data__.children)+2) * pi / 180});

  var arc_and_text = arc_group.selectAll("g.arc")
    .data(groupData[0])
    .enter().append("svg:g")
    .attr("class","arc_and_text");

  var arc_path = arc_and_text.append("svg:path")
    .attr("d", groupArc)
    .attr("class", "groupArc")
    .attr("id", function(d, i) { return "arc" + i; })
    .style("fill", "#1f77b4")
    .style("fill-opacity", 0.5); //MH: (d.__data__.key) gives names of groupings

  var arc_text = arc_and_text.append("text")
    .attr("class","arc_text")
    .attr("x", 3)
    .attr("dy", 15);

  arc_text.append("textPath")
    .attr("xlink:href", function(d, i) { return "#arc" + i; })
    .attr("class","arc_text_path")
    .style("fill","#ffffff")
    .text(function(d, i) { return d.__data__.key; });

D3 still mystifies me a bit, and I'm sure this code could be much improved, but it works. D3仍然使我有些迷惑,并且我相信此代码可以进行很大的改进,但是可以工作。

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

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