d3.js / svg - 如何动态地将文本附加到我的弧上

时间:2013-01-05 13:44:50

标签: javascript svg d3.js expressionengine data-visualization

我正在尝试完成动态创建这些蓝色弧的d3项目的最后一点,我需要在其上放置弧形文本,如下图所示:

enter image description here

上面的图片是我通过试验和错误静态放置弧形文本所做的事情,但我想根据文本下方的蓝色弧线动态放置它。这是动态创建弧的代码:

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);

{exp:}内容是我在表达引擎中从我的内容管理系统中提取的预先准备好的数据,如果它看起来很混乱。

所以,我有我的弧线。现在您将在groupData代码块中注意到我有一个console.log语句,它将为我提供我想在弧文本中显示的名称:

console.log(d.__data__.key);

现在,我用来静态放置弧文本的代码就是:

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

在上面的代码中,我唯一需要做的就是动态地为弧分配一个ID,然后在xlink:href属性中引用该ID,以及替换文本(&#34) ; JOBS")文本来自d。 data__key。鉴于上面的动态创建弧的代码,并且我知道如何使用d .__ data .key动态创建和检索我想要放置在弧中的文本,我应该能够完成这个,但我无法弄清楚如何在d3中编写代码来获取数据并将其放在弧中。任何人都可以帮忙吗?

2 个答案:

答案 0 :(得分:5)

你应该给this blog post on nested selections读一读;我相信它会解释你要做的事情。

这是要点。向选择中添加数据时,请将选择分配给变量:

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

这样,您就可以对其执行子选择,该子选择将接收绑定到g选择的数据的单个元素。您可以使用它来添加弧和文本:

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 })

用于在嵌套选择中进行数据绑定的函数(即g.selectAll() s)正在传递附加到{{1}的数据的单个元素 } gd是其索引。

答案 1 :(得分:0)

想出来了。改变了事物的结构,所以它更有意义,但基本上我做的是:

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仍然让我感到困惑,我确信这段代码可以大大改进,但它确实有效。