D3:x轴的平移不起作用

时间:2016-11-17 12:43:48

标签: javascript d3.js charts zoom axis

我正在实施一个条形图,在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>

1 个答案:

答案 0 :(得分:0)

设置初始.x后,您需要设置缩放功能的.domain。我还建议您不要在将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>