D3:x 轴平移不起作用

D3: Translation of x axis not working

我正在 D3 中实现一个沿 x 轴滚动的条形图。我写了我的缩放功能和我的缩放行为,但每当我试图沿着我的图表平移时,我的 x 轴上的值就会消失。有人知道为什么吗?

这是我的代码:

var zoom = d3.behavior.zoom()
                .scaleExtent([1, 1])
                .x(x)
                .on("zoom", zoomed);

function zoomed() {
        console.log("Entered zoom function!!!");
    var t = zoom.translate(),
    tx = t[0],
    ty = t[1];

    tx = Math.min(tx, 0);
    tx = Math.max(tx, w - d3.max(data, function(d) { return d.ppm_value; }));
    zoom.translate([tx, ty]);
    chart.select(".x.axis")
        .call(xAxis);
    bars.attr('transform', 'translate(' + d3.event.translate[0] + ',0) '
                                + 'scale(' + d3.event.scale + ',1)');

}

我不知道我错过了什么。有人可以帮帮我吗? 提前致谢!

//holds the data 
        var data =  [  {"yy":12,"mm":01,ppm_value:90000},           {"yy":11,"mm":02,ppm_value:50000}];

        //formats the date
        var format = d3.time.format("%Y-%m-%d");
        
        //define margins, height and width
        var margin = {
                top: 20,
                right: 30,
                bottom: 30,
                left: 40
            },
            w = 4000 - margin.left - margin.right,
            h = 500 - margin.top - margin.bottom;
        
        var x = d3.time.scale()
         .range([0, w]);

        var y = d3.scale.linear()
            .range([h, 0]);

        var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom")
            .ticks(60)
         .tickFormat(d3.time.format("%m.%Y"));

        var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left");
        
        var zoom = d3.behavior.zoom()
               .scaleExtent([1, 1])
               .x(x)
               //.xExtent([d3.min(data, function(d) { return new Date(d.date); }), d3.max(data, function(d) { return new Date(d.date); })])
               .on("zoom", zoomed);

        //create the svg 
        var chart = d3.select("#testChart").append("svg")
            .attr("width", w + margin.left + margin.right)
            .attr("height", h + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
         .call(zoom);
        
        var rect = chart.append("rect")
            .attr("width", w)
            .attr("height", h)
            .style("fill", "none")
            .style("pointer-events", "all");

        //loops through data
        data.forEach(function (d) {
         //coerce to number
         d.ppm_value = +d.ppm_value;
         d.yy = +d.yy;
         d.mm = +d.mm;
         d.date = new Date("20" + d.yy + "/" +d.mm);
         var dateTick = format(d.date);
         d.date = dateTick;
         console.log(d.ppm_value);
        });
        
        //map values onto x axis
         x.domain([d3.min(data, function(d) { return new Date(d.date); }), d3.max(data, function(d) { return new Date(d.date); })])
        
         //map values onto y axis
         y.domain([0, d3.max(data, function(d) { return d.ppm_value; })]);

        chart.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + h + ")")
            .call(xAxis)

        chart.append("g")
            .attr("class", "y axis")
            .call(yAxis);

        var bars = chart.append("g")
            .attr("class", "chartobjects");

        bars.selectAll(".rect")
            .data(data)
            .enter().append("rect")
            .attr("class", "rectBar")
            .on("click",hello)
            .attr('x', function(d) {
             console.log(d.date);
                return x(new Date(d.date));
            })
            .attr("y", function(d) {
                return y(d.ppm_value);
                console.log(d.ppm_value);
            })
            .attr("height", function(d) {
                return h - y(d.ppm_value);
            })
            .attr("width", 15)
            .attr("fill", function(d) {
                return d.ppm_value > 35000 ? "blue" : "red"
            });

        function hello() {
            alert("Hello world!!");
        }

        function zoomed() {
         console.log("Entered zoom function!!!");
         var t = zoom.translate(),
              tx = t[0],
              ty = t[1];

          tx = Math.min(tx, 0);
          tx = Math.max(tx, w - d3.max(data, function(d) { return d.ppm_value; }));
          zoom.translate([tx, ty]);
          chart.select(".x.axis")
            .call(xAxis);
          
          bars.attr('transform', 'translate(' + d3.event.translate[0] + ',0) '
            + 'scale(' + d3.event.scale + ',1)');
          
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.1.0/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>

<!-- Panel -->
<div class="row">
    <div class="col-lg-12 col-xs-12 col-sm-12 col-md-12">
        <div class="panel panel-primary">
            <div class="panel-heading">
                Test chart done in D3
            </div>
    <div class="panel-body">
     <!-- <div style="overflow: scroll;"> -->
     <div id="testChart">
    <!-- </div> -->
    </div>
   </div>
  </div>
</div>
</div>

您需要在设置初始 .domain 后设置缩放功能的 .x。我还建议您不要在将 x 值视为 stringdate 之间来回跳转。让他们约会并一起去:

//map values onto x axis
x.domain(d3.extent(data, function(d) {
  return d.date;
}));
zoom.x(x);

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="style.css">
  <script src="script.js"></script>
</head>

<body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.1.0/d3.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>

  <!-- Panel -->
  <div class="row">
    <div class="col-lg-12 col-xs-12 col-sm-12 col-md-12">
      <div class="panel panel-primary">
        <div class="panel-heading">
          Test chart done in D3
        </div>
        <div class="panel-body">
          <!-- <div style="overflow: scroll;"> -->
          <div id="testChart">
            <!-- </div> -->
          </div>
        </div>
      </div>
    </div>
  </div>

  <script>
    //holds the data 
    var data = [{
      "yy": 12,
      "mm": 01,
      ppm_value: 90000
    }, {
      "yy": 11,
      "mm": 02,
      ppm_value: 50000
    }];

    //formats the date
    var format = d3.time.format("%Y-%m-%d");

    //define margins, height and width
    var margin = {
        top: 20,
        right: 30,
        bottom: 30,
        left: 40
      },
      w = 4000 - margin.left - margin.right,
      h = 500 - margin.top - margin.bottom;

    var x = d3.time.scale()
      .range([0, w]);

    var y = d3.scale.linear()
      .range([h, 0]);

    var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom")
      .ticks(60)
      .tickFormat(d3.time.format("%m.%Y"));

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

    var zoom = d3.behavior.zoom()
      .scaleExtent([1, 1])
      .on("zoom", zoomed);

    //create the svg 
    var chart = d3.select("#testChart").append("svg")
      .attr("width", w + margin.left + margin.right)
      .attr("height", h + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .call(zoom);

    var rect = chart.append("rect")
      .attr("width", w)
      .attr("height", h)
      .style("fill", "none")
      .style("pointer-events", "all");

    //loops through data
    data.forEach(function(d) {
      //coerce to number
      d.ppm_value = +d.ppm_value;
      d.yy = +d.yy;
      d.mm = +d.mm;
      d.date = new Date("20" + d.yy + "/" + d.mm);
      //var dateTick = format(d.date);
      //d.date = dateTick;
      //console.log(d.ppm_value);
    });

    //map values onto x axis
    x.domain(d3.extent(data, function(d) {
      return d.date;
    }));
    zoom.x(x);

    //map values onto y axis
    y.domain([0, d3.max(data, function(d) {
      return d.ppm_value;
    })]);

    chart.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + h + ")")
      .call(xAxis)

    chart.append("g")
      .attr("class", "y axis")
      .call(yAxis);

    var bars = chart.append("g")
      .attr("class", "chartobjects");

    bars.selectAll(".rect")
      .data(data)
      .enter().append("rect")
      .attr("class", "rectBar")
      .on("click", hello)
      .attr('x', function(d) {
        console.log(d.date);
        return x(new Date(d.date));
      })
      .attr("y", function(d) {
        return y(d.ppm_value);
        console.log(d.ppm_value);
      })
      .attr("height", function(d) {
        return h - y(d.ppm_value);
      })
      .attr("width", 15)
      .attr("fill", function(d) {
        return d.ppm_value > 35000 ? "blue" : "red"
      });

    function hello() {
      alert("Hello world!!");
    }

    function zoomed() {
      console.log("Entered zoom function!!!");
      var t = zoom.translate(),
        tx = t[0],
        ty = t[1];

      tx = Math.min(tx, 0);
      tx = Math.max(tx, w - d3.max(data, function(d) {
        return d.ppm_value;
      }));
      zoom.translate([tx, ty]);
      
      console.log(x.domain())
      
      chart.select(".x.axis")
        .call(xAxis);

      bars.attr('transform', 'translate(' + d3.event.translate[0] + ',0) ' + 'scale(' + d3.event.scale + ',1)');

    }
  </script>

</body>

</html>