exit()。remove()没有删除第一个栏

时间:2018-04-16 00:46:41

标签: d3.js

每当拖动滑块并选择新日期时,它都不会重绘第一个条形图,它会重绘所有其他条形图。例如,尝试日期09/06和09/17。 id 54042的第一个栏不会重绘。这是我的bl.ocks http://blockbuilder.org/fall16mis/87a39bc00b1b356f78dfd0954f345444

的链接

这是代码:

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <style>
    .tooltip {
              opacity: 0;
              background-color: #ffe047;
        position: absolute;
        }

    .grid line {
      stroke: lightgrey;
      shape-rendering: crispEdges;
    }

    .ticks {
      font-size: 11px;
    }

    .track,
    .track-inset,
    .track-overlay {
      stroke-linecap: round;
    }

    .track {
      stroke: #000;
      stroke-opacity: 0.3;
      stroke-width: 10px;
    }

    .track-inset {
      stroke: #ddd;
      stroke-width: 8px;
    }

    .track-overlay {
      pointer-events: stroke;
      stroke-width: 50px;
      stroke: transparent;
      cursor: crosshair;
    }

    .handle {
      fill: #fff;
      stroke: #000;
      stroke-opacity: 0.5;
      stroke-width: 1.25px;
    }

    .bar:hover{
      fill:#0f9fff;
    }

    .legend{
        color:#005ebc;
      z-index:0;
    }
  </style>
</head>

<body>
  <div id="slider"></div>
  <script>
    var json_data = "id,date,start_time,end_time\n\
54042,2017/09/06,5.50,5.53\n\
54042,2017/09/06,7.55,9.19\n\
54042,2017/09/16,11.12,12.28\n\
54042,2017/09/23,13.56,15.03\n\
54042,2017/09/07,16.29,17.33\n\
54042,2017/09/06,19.56,20.53\n\
54042,2017/09/20,21.3,22.14\n\
98765,2017/09/06,5.1,6.51\n\
98765,2017/09/06,11.4,11.53\n\
98765,2017/09/06,12.2,12.42\n\
98765,2017/09/06,12.55,14.2\n\
98765,2017/09/16,21.42,21.59\n\
98765,2017/09/16,22.01,23.13\n\
98765,2017/09/16,23.16,23.51\n\
98765,2017/09/23,13.41,14.03\n\
65299,2017/09/06,7.23,8.21\n\
65299,2017/09/06,9.37,10.23\n\
65299,2017/09/06,11.46,13.29\n\
65299,2017/09/06,18.07,19.57\n\
65299,2017/09/17,14.41,16.22\n\
65299,2017/09/17,21.39,23.39\n\
79408,2017/09/06,9.37,10.17\n\
79408,2017/09/06,11.03,12.08\n\
79408,2017/09/06,13.14,15.53\n\
79408,2017/09/06,16.05,17.48\n\
79408,2017/09/06,19.47,20.23\n\
38338,2017/09/06,8.22,9.28\n\
38338,2017/09/06,11.34,12.17\n\
38338,2017/09/07,12.43,13.35\n\
38338,2017/09/07,14.12,15.48\n\
38338,2017/09/07,16.09,17.23\n\
38338,2017/09/07,18.31,19.19\n\
38338,2017/09/07,21.49,23.26\n\
81757,2017/09/06,6.31,7.41\n\
81757,2017/09/06,8.18,9.39\n\
81757,2017/09/06,10.18,11.23\n\
81757,2017/09/06,13.02,14.04\n\
81757,2017/09/07,15.22,17.23\n\
81757,2017/09/07,20.32,22.01\n\
68077,2017/09/06,11.1,12.45\n\
68077,2017/09/06,15.23,16.54\n\
68077,2017/09/06,17.31,19.05\n\
68077,2017/09/06,20.39,21.3\n\
68077,2017/09/06,21.41,22.37\n\
58381,2017/09/06,16.51,17.55\n\
58381,2017/09/06,19.34,20.55\n\
58381,2017/09/06,21.33,22.51\n\
58381,2017/09/07,14.46,16.15\n\
37500,2017/09/06,8.2,10.18\n\
37500,2017/09/06,11.37,13.34\n\
37500,2017/09/06,19.22,20.16\n\
37500,2017/09/06,21.55,22.09\n\
37500,2017/09/16,14.16,16.26\n\
37500,2017/09/16,16.58,17.48\n\
39146,2017/09/06,19.47,20.21\n\
39146,2017/09/06,20.35,21.29\n\
39146,2017/09/06,22.01,23.25\n\
39146,2017/09/16,8.03,9.56\n\
39146,2017/09/16,10.23,12.52\n\
39146,2017/09/16,13.25,14.28";

    window.data = d3.csvParse(json_data, function(d){ return {
      id:d.id, 
      date:d.date, 
      start_time:+d.start_time,
        end_time:+d.end_time}; });

    window.minDate = d3.min(window.data,function(d){ return d.date; });

    window.maxDate = d3.max(window.data,function(d){ return d.date; });

    window.names = window.data.map(function(d){
      return d.id; });

    var parseDate = d3.timeParse("%Y/%m/%d");
    var displayDate = d3.timeFormat("%m/%d");
    var forChartDate = d3.timeFormat("%Y/%m/%d");

    var height = 500;
    var width = 800;
    var margin = {left: 50, right: 20, bottom: 0, top: 70};

    var tooltip = d3.select("body").append("div").attr("class", "tooltip")

    var svg = d3.select("body").append("svg").attr("height","1000px").attr("width","100%");

    var chartGroup = svg.append("g").attr("transform","translate("+margin.left+","+(margin.top+10)+")");

    var legend = svg.append("g").attr("transform","translate("+margin.left+","+(margin.top+10)+")");

    var chartDate = window.minDate;

    var displaySlider = function(data){

        window.x = d3.scaleLinear()
                   .domain([0, 24])
                   .range([0, width]);

        window.y = d3.scaleBand()
                   .domain(window.names)
                   .rangeRound([height, 0])
                   .paddingInner(0.3);

      function make_y_gridlines() {
        return d3.axisLeft(y)
        };

      function make_x_gridlines() {
        return d3.axisBottom(x)
        };

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

        chartGroup.append("g")
                .attr("class","axis x")
                        .call(d3.axisBottom(x))
               .attr("transform","translate(0,"+height+")")
                .call(d3.axisBottom(x)
                            .ticks(24));

      chartGroup.append("g")
              .attr("class", "grid")
              .call(make_y_gridlines()
                .tickSize(-width)
                .tickFormat("")
              );

      chartGroup.append("g")
              .attr("class", "grid")
              .call(make_x_gridlines()
                .tickSize(height)
                .tickFormat("")
              )

        var newData = data.filter(function(d){
          return d.date==chartDate;
        })

      displayBar(newData);

      var x1 = d3.scaleTime()
                 .range([0, width])
                 .domain([parseDate(minDate), parseDate(maxDate)])
                 .clamp(true);

      var slider = svg.append("g")
                      .attr("class", "slider")
                      .attr("transform", "translate(" + margin.left + ",30)");

      slider.append("line")
            .attr("class", "track")
            .attr("x1", x1.range()[0])
            .attr("x2", x1.range()[1])
            .select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
            .attr("class", "track-inset")
            .select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
            .attr("class", "track-overlay")
            .call(d3.drag()
                  .on("start.interrupt", function() { slider.interrupt(); })
                  .on("drag end", function() { sliderFunc(x1.invert(d3.event.x)); }));

          slider.insert("g", ".track-overlay")
            .attr("class", "ticks")
            .attr("transform", "translate(0," + 10 + ")")
            .selectAll("text")
            .data(x1.ticks(15))
            .enter()
            .append("text")
            .attr("x", x1)
            .attr("y", 10)
            .attr("text-anchor", "middle")
            .text(function(d) { return displayDate(d); });

      var label = slider.append("text")  
                        .attr("class", "label")
                        .attr("text-anchor", "middle")
                        .text(minDate)
                        .attr("transform", "translate(0," + (-10) + ")");

      var handle = slider.insert("circle", ".track-overlay")
                          .attr("class", "handle")
                          .attr("r", 7);

      function sliderFunc(h) {
        handle.attr("cx", x1(h));
        label.attr("x", x1(h))
             .text(displayDate(h));
        chartDate = forChartDate(h);
        console.log(chartDate);
        newData = data.filter(function(d){
          return d.date==chartDate;
        })
        //displayText(newData);
        displayBar(newData);
      }
    };

    var displayBar = function(data){

      var bars = chartGroup.selectAll(".bar")
                                             .data(data, function(d){
                                            console.log(d);
                                                                return d;
                                                });

      bars.exit().remove();

      bar_enter = bars.enter().append("rect")

      bar_enter.attr("class", "bar")
               .attr("x", function(d) { 
        console.log(d.start_time);
        return window.x(d.start_time); })
               .attr("y", function(d) { return window.y(d.id); })
               .attr("height", window.y.bandwidth())
               .attr("fill", "green")
               .transition()
                .duration(600)
                        .attr("width", function(d) { return     window.x(d.end_time-d.start_time); });

      bar_enter.on('mousemove', function(d,i){
        tooltip.style("opacity","1")
               .style("left",(d3.event.pageX+10)+"px")
               .style("top",d3.event.pageY+"px");
        tooltip.html(" Start Time:"+d.start_time+" End Time:"+d.end_time);
      })

      bar_enter.on('mouseout', function(){
        tooltip.style("opacity","0")
      });
    };

     displaySlider(window.data);
  </script>
</body>

1 个答案:

答案 0 :(得分:1)

您不能在键功能中使用整个对象:

var bars = chartGroup.selectAll(".bar")
    .data(data, function(d){
        return d;
    });

API解释了它:

  可以通过为每个数据和元素计算字符串标识符,指定

键函数来控制将哪个数据分配给哪个元素,替换默认的索引连接。 (强调我的)

因此,不使用整个对象,而是使用属性(如id):

var bars = chartGroup.selectAll(".bar")
    .data(data, function(d){
        return d.id;
    });

以下是更新的bl.ocks:https://bl.ocks.org/GerardoFurtado/57d014aa5124bdbe5774e1457816ff43/07a233d46aa3ae91bcffb8682de9ed8376c99b9a