在使用没有命名条目的数组时,如何向饼图添加标签(How can I add labels to a pie chart, when using an array without named entries)

我写了一个javascript程序,使用d3.js生成饼图。

这工作正常,但我无法在图表中添加标签。

我使用的数据具有以下结构:

[["country", "percentage"], ["country", "percentage"],...]

或者作为一个例子:

[["A", "0.5"], ["AUS", "0.3"],....]

图表工作正常,但我没有标签显示。

任何帮助,将不胜感激。

这是代码的摘录:

var updatePie = function () { var width = 480, height = 480, radius = Math.min(width, height) / 2; var labelr = radius + 30; var formatPercent = d3.format(",.2%"); var color = d3.scale.ordinal() .domain(["A", "AUS", "B", "BG", "BR", "CDN", "CH", "CN", "CO", "CZ", "D", "DK", "E", "EST", "ET", "F", "FIN", "GB", "I", "IL", "IRL", "J", "N", "NL", "NZ", "RUS", "S", "UAE", "USA", "ZA"]) .range(["#bac5ca", "#7b95a7", "#526f8b", "#454c57", "#323540", "#a17d48", "#5e747d", "#405666", "#2a2e34", "#1f2127", "#5c482b", "#c7d0d4", "#94a9b8", "#6f8aa3", "#616c7c", "#505669", "#b49569", "#8a9ca3", "#57768b", "#41576d", "#363c45", "#292b33", "#7e623a", "#d5dbdf", "#adbdca", "#90a6ba", "#848e9c", "#747b90", "#454c57", "#c6af8c", ]), svg; function graph(_selection) { _selection.each(function(_data) { var pie = d3.layout.pie() .value(function(d) { return d[1]; }) .sort(null); var arc = d3.svg.arc() .innerRadius(radius - 100) .outerRadius(radius - 50); if (!svg){ svg = d3.select(this).append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); } var path = svg.selectAll("path").data(pie(_data)); path.enter().append("path") .attr("fill", function(d, i) { return color(i); }) .attr("d", arc) .each(function(d) {this._current = d;} ); var text = svg.selectAll("text") .data(pie(_data)); text.append('text') .attr("fill", "black") .attr("font-family", "sans-serif") .attr("transform", function(d) { var c = arc.centroid(d), x = c[0], y = c[1], h = Math.sqrt(x*x + y*y); return "translate(" + (x/h * labelr) + ',' + (y/h * labelr) + ")"; }) .attr("text-anchor", function(d) { // are we past the center? return (d.endAngle + d.startAngle)/2 > Math.PI ? "end" : "start"; }) .text(function (d) { return d[0]+ " " + formatPercent(d[1]); }); path.transition() .attrTween("d", arcTween) .duration(750); path.exit().remove() function arcTween(a) { var i = d3.interpolate(this._current, a); this._current = i(0); return function(t) { return arc(i(t)); }; } }); } return graph; } var updateFunction = updatePie(); var container = d3.select("#chartDiv"); function update(data) { container.datum(data).call(updateFunction); } var firstDataset = getChannelData("channelName1"); update(firstDataset); document.getElementById("dropdown").addEventListener("click", reDrawChart); function reDrawChart() { var e = document.getElementById("dropdown"); var strUser = e.options[e.selectedIndex].innerHTML; getChannelData("channelName2"); var secondDataset = getChannelData(strUser); update(secondDataset); }

I wrote a javascript program that produces a pie chart using d3.js.

This works fine, however I am not able to add labels to the chart.

The data I am using has the following structure:

[["country", "percentage"], ["country", "percentage"],...]

or as an example:

[["A", "0.5"], ["AUS", "0.3"],....]

The graphing works fine, but I get no labels to display.

Any help would be appreciated.

here is an excerpt of the code:

var updatePie = function () { var width = 480, height = 480, radius = Math.min(width, height) / 2; var labelr = radius + 30; var formatPercent = d3.format(",.2%"); var color = d3.scale.ordinal() .domain(["A", "AUS", "B", "BG", "BR", "CDN", "CH", "CN", "CO", "CZ", "D", "DK", "E", "EST", "ET", "F", "FIN", "GB", "I", "IL", "IRL", "J", "N", "NL", "NZ", "RUS", "S", "UAE", "USA", "ZA"]) .range(["#bac5ca", "#7b95a7", "#526f8b", "#454c57", "#323540", "#a17d48", "#5e747d", "#405666", "#2a2e34", "#1f2127", "#5c482b", "#c7d0d4", "#94a9b8", "#6f8aa3", "#616c7c", "#505669", "#b49569", "#8a9ca3", "#57768b", "#41576d", "#363c45", "#292b33", "#7e623a", "#d5dbdf", "#adbdca", "#90a6ba", "#848e9c", "#747b90", "#454c57", "#c6af8c", ]), svg; function graph(_selection) { _selection.each(function(_data) { var pie = d3.layout.pie() .value(function(d) { return d[1]; }) .sort(null); var arc = d3.svg.arc() .innerRadius(radius - 100) .outerRadius(radius - 50); if (!svg){ svg = d3.select(this).append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); } var path = svg.selectAll("path").data(pie(_data)); path.enter().append("path") .attr("fill", function(d, i) { return color(i); }) .attr("d", arc) .each(function(d) {this._current = d;} ); var text = svg.selectAll("text") .data(pie(_data)); text.append('text') .attr("fill", "black") .attr("font-family", "sans-serif") .attr("transform", function(d) { var c = arc.centroid(d), x = c[0], y = c[1], h = Math.sqrt(x*x + y*y); return "translate(" + (x/h * labelr) + ',' + (y/h * labelr) + ")"; }) .attr("text-anchor", function(d) { // are we past the center? return (d.endAngle + d.startAngle)/2 > Math.PI ? "end" : "start"; }) .text(function (d) { return d[0]+ " " + formatPercent(d[1]); }); path.transition() .attrTween("d", arcTween) .duration(750); path.exit().remove() function arcTween(a) { var i = d3.interpolate(this._current, a); this._current = i(0); return function(t) { return arc(i(t)); }; } }); } return graph; } var updateFunction = updatePie(); var container = d3.select("#chartDiv"); function update(data) { container.datum(data).call(updateFunction); } var firstDataset = getChannelData("channelName1"); update(firstDataset); document.getElementById("dropdown").addEventListener("click", reDrawChart); function reDrawChart() { var e = document.getElementById("dropdown"); var strUser = e.options[e.selectedIndex].innerHTML; getChannelData("channelName2"); var secondDataset = getChannelData(strUser); update(secondDataset); }

最满意答案

由于没有提供小提琴我没有运行代码,但它可能会有助于使用输入和退出选择时添加标签(这也可以防止更新上的重复标签)。

为此,请更改添加标签的位置:

text .enter() .append('text') //the rest of your test attributes text .exit() .remove();

现在这不会立即解决您的问题,但下一步将记录输入选择。 如果输入选择为空,则可能与绑定到文本的数据有问题(使用什么pie(_data)返回)。

如果输入选择正确输入并且具有要添加到DOM的标签,则它必须以您添加标签的方式进行。 这看起来很好,但我认为这是你绑定的数据的问题。

如果你可以添加一个pie(_data)的控制台日志和标签输入选择,我很乐意进一步提供帮助。 (或提供你的问题小提琴)。

希望这可以帮助。

As there is no fiddle provided I haven't run the code, but it would probably be helpful to use enter and exit selections when adding the labels (this also prevents duplicate labels on updates).

To do so change the bit where you add the labels:

text .enter() .append('text') //the rest of your test attributes text .exit() .remove();

Now that doesn't immediately solve your problem, but next step would be logging the enter selection. if the enter selection is empty you probably have a problem with the data you are binding to text (issue with what pie(_data) returns).

If the enter selection is coming through correctly and has the labels you want to add to the DOM it must be in the way you add the labels. This looks fine however so I assume it's a problem with the data you are binding.

If you could add a console log of pie(_data) and the label enter selection I'll be happy to help further. (Or provide a fiddle with your problem).

Hope this helps.

更多推荐