3

我有一个用 D3.js 制作的带有图例的饼图。PHP 文件解析 JSON,然后使用该数据填充图表。一切都按照我想要的方式工作,除了我无法让图例标签与正确的颜色相匹配。这是我的代码

var w = 490,
h = 400,
r = 180,
inner = 70,
color = d3.scale.category20c();

d3.json("script.php", function (data) {
    var max = d3.max(data, function(d) { return d.value; });
    var sum = d3.sum(data, function(d) { return d.value; });

    var vis = d3.select("#chart")
        .append("svg:svg")
        .data([data])
        .attr("width", w)
        .attr("height", h)
        .append("svg:g")
        .attr("transform", "translate(" + r * 1.5 + "," + (r + 10) + ")")

    var arc = d3.svg.arc()
        .innerRadius(inner)
        .outerRadius(r);

    var arcOver = d3.svg.arc()
        .innerRadius(inner + 5)
        .outerRadius(r + 5);

    var arcLine = d3.svg.arc()
        .innerRadius(inner)
        .outerRadius(inner + 5);

    var pie = d3.layout.pie()
        .value(function(d) { return d.value; });

    var textTop = vis.append("text")
        .attr("dy", ".35em")
        .style("text-anchor", "middle")
        .attr("class", "textTop")
        .text( "TOTAL" )
        .attr("y", -10),
    textBottom = vis.append("text")
        .attr("dy", ".35em")
        .style("text-anchor", "middle")
        .attr("class", "textBottom")
        .text(sum.toFixed(2) + "m")
        .attr("y", 10);

    var arcs = vis.selectAll("g.slice")
        .data(pie)
        .enter()
            .append("svg:g")
            .attr("class", "slice")
            .on("mouseover", function(d) {
                d3.select(this).select("path").transition()
                    .duration(100)
                    .attr("d", arcOver)

                textTop.text( d3.select(this).datum().data.label )
                textBottom.text( d3.select(this).datum().data.value.toFixed(2) + "m")
            })
            .on("mouseout", function(d) {
                d3.select(this).select("path").transition()
                    .duration(100)
                    .attr("d", arc);

                textTop.text( "TOTAL" )
                textBottom.text(sum.toFixed(2) + "m");
            });

    arcs.append("svg:path")
            .attr("fill", function(d, i) { return color(i); } )
            .attr("d", arc);

    var legend = d3.select("#chart").append("svg")
        .attr("class", "legend")
        .attr("width", 100)
        .attr("height", 350)
        .selectAll("g")
        .data(color.domain().slice().reverse())
        .enter().append("g")
        .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; })

    legend.append("rect")
        .attr("width", 18)
        .attr("height", 18)
        .style("fill", color);

    legend.append("text")
        .attr("x", 24)
        .attr("y", 9)
        .attr("dy", ".35em")
        .text(function(d) { return d; });
})

JSFIDDLE

我想我把问题缩小到.text(function(d) { return d; });. 现在,我假设它返回索引号。如果我将此行更改为.text(function(d, i) { return data[i].label; });,则标签与颜色不匹配。我从这里得到了这个传说。我也看过其他例子(我无法链接它们,因为我的声誉不够高),我无法正确整合它们。

有人可以帮我找出问题所在吗?谢谢!

4

1 回答 1

13

要获得正确的标签,请将用于饼图的相同数据传递给图例:

var legend = d3.select("#chart").append("svg")
  .attr("class", "legend")
  .attr("width", r)
  .attr("height", r * 2)
  .selectAll("g")
  .data(data)
  .enter().append("g")
  .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

legend.append("rect")
  .attr("width", 18)
  .attr("height", 18)
  .style("fill", function(d, i) { return color(i); });

legend.append("text")
  .attr("x", 24)
  .attr("y", 9)
  .attr("dy", ".35em")
  .text(function(d) { return d.label; });

Jsfiddle在这里

于 2013-06-18T14:43:59.637 回答