D3 V4 Rect在堆积条形图中绑定数据

时间:2016-10-03 12:36:23

标签: d3.js charts bar-chart

在规范化堆叠条形图中,我试图在条形图中的所有矩形中绑定数据,但传递了错误的值。我从这个example采用了我的代码并使其成为横向。下面是我的代码,我也创建了plunker。在.text函数中传递整个对象。有人可以在我出错的地方帮助我

var svg = d3.select("svg"),
            margin = {
                top: 20,
                right: 60,
                bottom: 30,
                left: 40
            },
            /*width = +svg.attr("width") - margin.left - margin.right,
            height = +svg.attr("height") - margin.top - margin.bottom,*/
            width = 120,
            height = 120,
            g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        var y = d3.scaleBand()
            .rangeRound([0, width])
            .padding(0.1)
            .align(0.1);

        var x = d3.scaleLinear()
            .rangeRound([height, 0]);

        var z = d3.scaleOrdinal()
            .range(['#02CA22', '#FB5652', '#FFB005']);

        var stack = d3.stack()
            .offset(d3.stackOffsetExpand);

        d3.csv("data.csv", type, function (error, data) {
            if (error) throw error;

            /*data.sort(function(a, b) {
              return b[data.columns[1]] / b.total - a[data.columns[1]] / a.total;
            });*/

            y.domain(data.map(function (d) {
                return d.State;
            }));
            z.domain(data.columns.slice(1));

            var serie = g.selectAll(".serie")
                .data(stack.keys(data.columns.slice(1))(data))
                .enter().append("g")
                .attr("class", "serie")
                .attr("fill", function (d) {
                    return z(d.key);
                });

            var rect = serie.selectAll("rect")
                .data(function (d) {
                    return d;
                }).enter();

            rect.append("rect")
                .attr("y", function (d) {
                    return y(d.data.State);
                })
                .attr("x", function (d) {
                    return x(d[1]);
                })
                .attr("width", function (d) {
                    return x(d[0]) - x(d[1]);
                })
                .attr("height", y.bandwidth());

            rect.append("text")
                .text(function (d) {
                    console.log('d');
                    console.log(d);
                    console.log(d.data.key);
                    return 'val';
                })
                .attr("y", function (d) { return y(d.data.State) + y.bandwidth() / 2; })
                .attr("x", function (d) {
                    return x(d[1]);
                });


            /* g.append("g")
               .attr("class", "axis axis--x")
               .attr("transform", "translate(0," + height + ")")
               .call(d3.axisBottom(x).ticks(2, "%"));*/

            g.append("g")
                .attr("class", "axis axis--y")
                .call(d3.axisLeft(y));

            var legend = serie.append("g")
                .attr("class", "legend")
                .attr("transform", function (d) {
                    var d = d[0];
                    return "translate(" + ((x(d[0]) + x(d[1])) / 2) + ", " + (y(d.data.State) - y.bandwidth()) + ")";
                });

            /*legend.append("line")
                .attr("y1", 5)
                .attr("x1", 15)
                .attr("x2", 15)
                .attr("y2", 12)
                .attr("stroke", "#000");

            legend.append("text")
                .attr("x", 9)
                .attr("dy", "0.35em")
                .attr("fill", "#000")
                .style("font", "10px sans-serif")
                .text(function (d) {
                    return d.key;
                }); */
        });

        function type(d, i, columns) {
            var t;
            for (i = 1, t = 0; i < columns.length; ++i) t += d[columns[i]] = +d[columns[i]];
            d.total = t;
            return d;
        }

1 个答案:

答案 0 :(得分:2)

我认为最好的方法是修改您的子选择数据绑定以包含该信息:

var rect = serie.selectAll("rect")
  .data(function (d) {
    // return all the data you need as flat as possible
    var rv = d.map(function(da){
      return {p: da, key: d.key, state: da.data.State}
    });
    return rv;
  }).enter();

该文本随后可用:

rect.append("text")
  .text(function (d) {
    return d.key;
  })
  .attr("y", function (d) { return y(d.state) + y.bandwidth() / 2; })
  .attr("x", function (d) {
    return x(d.p[1]);
  });

更新了Plunker