D3更新垂直堆积条形图

时间:2017-04-01 06:49:24

标签: d3.js

我有一个垂直堆积条形图,想要动态删除rect个元素。为此,我遵循基本的输入/更新/退出程序。但是,即使宽度= 0,条形似乎也会被添加;

var drawBars = function(data) {
  var margin = {top: 5, right: 20, bottom: 5, left: 170},
      width = 1020 - margin.left - margin.right,
      height = 1820 - margin.top - margin.bottom,
      scope = this;

  var x = d3.scale.linear()
      .rangeRound([0, width-150]);

  var y = d3.scale.ordinal()
      .rangeBands([0,height], .2, 3);

  var color = d3.scale.category20c();

  var xAxis = d3.svg.axis()
      .scale(x)
      .orient("top")
      .tickSize(0)
      .tickFormat(d3.format("s"));

  var yAxis = d3.svg.axis()
      .scale(y)
      .tickSize(0)
      .orient("left");

  var svg = d3.select('#barchart svg')
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  var createData = function(filter) {
    var data = d3.nest()
      .key(function(d) { return d.org; })
      .key(function(d){ return d.taskforce_id })
      .rollup(function(v){ return v.length })
      .entries(scope.rawData['participants']);

      _.each(data, d => {
          _.extend(d, _.object(_.map(d.values, c => {
            if (typeof filter !== 'undefined') {
              if (c.key == filter) {
                return [c.key, c.values];
              }
              return [c.key, 0];
            }
            return [c.key, c.values];
          })));
          delete d.values;
      });

    data.forEach(function(d) {
      var y0 = 0;
      d.orgs = ["A", "B", "C"].map(function(org) {
        if (d[org] === undefined) {
          return {name: org, y0: 0, y1: 0};
        } else {
          return {name: org, y0: y0, y1: y0 += +d[org]};
        }

      });
      d.total = d3.max(d.orgs, d => { return d.y1; });
    });

    data.sort(function(x, y){
       return d3.descending(x.total, y.total);
    });
    return data;
  };

  var redrawChart = function(filter) {
    var data = createData(filter);
    console.log(data);

    x.domain([0, d3.max(data, function(d) { return d.total; })]);
    y.domain(data.map(function(d) { return d.key; }));
    color.domain(d3.keys(data[0]).filter(function(key) { return key !== "key"; }));

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + 15 + ")")
      .call(xAxis);

    svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end");

    /////////
      //ENTER//
      /////////
    var chartRow = svg.selectAll("g.chartRow")
      .data(data);

    var newRow = chartRow
      .enter()
      .append("g")
      .attr("class", "chartRow")
      .attr("transform", function(d) { return "translate(0, " + y(d.key) + ")"; });

    var rectRow = newRow.selectAll(".bar")
      .data(function(d) { return d.orgs; });

    rectRow
      .enter()
      .append("rect")
      .attr("class", function(d) { return "bar t_"+ d.name; } )
      .attr("height", y.rangeBand())
      .on('click', function(d){
        redrawChart(d.name);
      })
      .style("fill", function(d) { return color(d.name); });

    //////////
      //UPDATE//
      //////////
    chartRow.selectAll('rect').transition()
      .duration(300)
      .attr("width", function(d) { return x(d.y1) - x(d.y0); })
      .attr("x", function(d) { return x(d.y0); })
      .attr("opacity",1);

      ////////
      //EXIT//
      ////////
    chartRow.exit().selectAll("rect.bar").transition()
      .style("opacity","0")
      .attr("transform", "translate(0," + (height + margin.top + margin.bottom) + ")")
      .remove();
  };

  redrawChart();

  var legend = svg.selectAll(".legend")
      .data(color.domain().slice().reverse());

  var legends = legend.enter().append("g")
      .attr("class", "legend")
      .attr("transform", function(d, i) { return "translate(0," + i * 25 + ")"; });

  legend.exit().remove();

  legends.append("rect")
      .attr("x", width - 28)
      .attr("width", 18)
      .attr("height", 18)
      .style("fill", color);

  legends.append("text")
      .attr("x", width - 34)
      .attr("y", 9)
      .attr("dy", ".35em")
      .style("text-anchor", "end")
      .text(function(d) { return d; });

  legends.append("text")
      .attr("x", width + 14)
      .attr("y", 9)
      .attr("class", "numbers")
      .attr("dy", ".35em")
      .style("text-anchor", "end");

};

当我console.logdata一切正常,所以过滤有效。但是,rect元素的宽度似乎使用OLD数据集。同样,传说和轴也是重复的

在这里摆弄:https://jsfiddle.net/4nm44fgt/

任何见解?

1 个答案:

答案 0 :(得分:0)

您的第二个数据绑定不应仅使用输入节点,因为在过滤后此选择将为空:

newRow.selectAll(".bar")...

而不是using System.Text; static NetworkStream serverStream = default(NetworkStream); byte[] outStream = Encoding.ASCII.GetBytes("help"); serverStream.Write(outStream, 0, outStream.Length); serverStream.Flush();