admin管理员组

文章数量:1315101

I used

d3.select(".graph")
  .call(d3.behavior.zoom().on("zoom", redraw)).on("dblclick.zoom", null).on("wheel.zoom", null);

function redraw() {
  console.log("here", d3.event.translate, d3.event.scale);
  g.attr("transform","translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); 
} 

to create pan, but when i create an .on event listener and call redraw() with anything other than the way i have it, it es back with nothing for d3.event.translate and d3.event.scale, so i can't update the transform. And i've seen code out there for zooming with a button for maps, but not a graph. It must be possible some how, but i don't see how. The code i have so far is...

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>

.node {
  stroke: #000;
  stroke-width: 0px;
}

.link {
  stroke: #999;
  stroke-opacity: .6;
}
.graphmap {
  border: 1px solid black;
}
</style>
</head>
<body>
<div class="graph"></div>
<script src=".v3.min.js"></script>
<script>

// start draw zoom buttons
var zoom = d3.select(".zoom").append("svg")
    .attr("width", 40)
    .attr("height", 40);



// start zoom behavior
var mapZoom = d3.behavior.zoom()
   .on("zoom", redraw);


function zoomButton(zoomDirection) {
  if (zoomDirection == "in") {
    var newZoom = mapZoom.scale() * 1.5; 
    var newX = 
      ((mapZoom.translate()[0] - (width / 2)) * 1.5) + width / 2;
    var newY = 
      ((mapZoom.translate()[1] - (height / 2)) * 1.5) + height / 2; 
  }
  else if (zoomDirection == "out") {
    var newZoom = mapZoom.scale() * .75;
    var newX = ((mapZoom.translate()[0] - (width / 2)) * .75) + width / 2;
    var newY = ((mapZoom.translate()[1] - (height / 2)) * .75) + height / 2;
  }
  mapZoom.scale(newZoom).translate([newX,newY]) 
  redraw();   
}

function zoomed() {
    projection.translate(mapZoom.translate()).scale(mapZoom.scale());
    d3.selectAll("path.graticule").attr("d", geoPath); 
    d3.selectAll("path.countries").attr("d", geoPath);
    d3.selectAll("circle.cities")
        .attr("cx", function(d) {return projection([d.x,d.y])[0]}) 
        .attr("cy", function(d) {return projection([d.x,d.y])[1]});
}

d3.select(".zoomin").on("click", function (){
    zoomButton("in");
    console.log(d3.behavior.zoom().event(d3.select(".zoomin")))
});


d3.select(".graph")
  .call(d3.behavior.zoom().on("zoom", redraw)).on("dblclick.zoom", null).on("wheel.zoom", null);

d3.select(".zoomin")
  .call(d3.behavior.zoom().on("zoom", redraw)).on("dblclick.zoom", redraw);

function redraw() {
  console.log("here", d3.event.translate, d3.event.scale);
  g.attr("transform","translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); 
} 


// start svg

var width = 1100,
    height = 900;

var color = d3.scale.category20();

var force = d3.layout.force()
    .gravity(.05)
    .charge(-700)
    .linkDistance(150)
    .size([width, height]);

var svg = d3.select(".graph").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("class", "graphmap");

zoomin = svg.append("g")
    .attr("class", "zoomin");

zoomin.append("rect")
    .attr("x", 10)
    .attr("y", 10)
    .attr("width", 30)
    .attr("height", 30)
    .attr("rx", 4)
    .attr("ry", 4)
    .attr("fill", "#dadae6");



var g = svg.append('g');


d3.json("miserables.json", function(error, graph) {
  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  var link = g.selectAll(".link")
      .data(graph.links)
    .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

  var node = g.selectAll("g")
      .data(graph.nodes)
      .enter().append("g")
      .attr("class","node")
      .call(force.drag);

  node.append("circle")
    .attr("r", function(d) { return Math.sqrt(d.group * 20); })
    .style("fill", function(d) { return color(d.group); })
    .attr("pointer-events", "auto")
    .attr("class", "circlenode");

  node.append("text")
    .attr("text-anchor", "right") 
    .attr("fill","black")
    .style("pointer-events", "none")
    .attr("font-size", function(d) { 20 + 'px'; })
    .attr("font-weight", function(d) { return "bold"; })
    .text( function(d) { return d.name + ' (' + d.group + ')';});

  setTimeout(function() {
    node.classed("fixed", function(d) { return d.fixed = true; });
  }, 9000);

  force.on("tick", function() {
    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    node.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; })
        .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")";});
  });
});
function dump(obj) {
    var out = '';
    for (var i in obj) {
        out += i + ": " + obj[i] + "\n";
    }

    // or, if you wanted to avoid alerts...

    var pre = document.createElement('pre');
    pre.innerHTML = out;
    document.body.appendChild(pre)
}
</script>

</body>
</html>

You'll see i was playing around with making a zoomButton function but i don't know how to see how to set it up to make it work. I've seen some demos out there of different ideas with the zoom functionality but i don't really understand how they work and what the functions are for. And the d3 documentation doesn't seem to provide much insight. And i haven't found any tutorials that go over what each of the functions do and how to handle events. Any help an explanation of how the zoom functions actually work would be appreciated.

I used

d3.select(".graph")
  .call(d3.behavior.zoom().on("zoom", redraw)).on("dblclick.zoom", null).on("wheel.zoom", null);

function redraw() {
  console.log("here", d3.event.translate, d3.event.scale);
  g.attr("transform","translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); 
} 

to create pan, but when i create an .on event listener and call redraw() with anything other than the way i have it, it es back with nothing for d3.event.translate and d3.event.scale, so i can't update the transform. And i've seen code out there for zooming with a button for maps, but not a graph. It must be possible some how, but i don't see how. The code i have so far is...

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>

.node {
  stroke: #000;
  stroke-width: 0px;
}

.link {
  stroke: #999;
  stroke-opacity: .6;
}
.graphmap {
  border: 1px solid black;
}
</style>
</head>
<body>
<div class="graph"></div>
<script src="http://d3js/d3.v3.min.js"></script>
<script>

// start draw zoom buttons
var zoom = d3.select(".zoom").append("svg")
    .attr("width", 40)
    .attr("height", 40);



// start zoom behavior
var mapZoom = d3.behavior.zoom()
   .on("zoom", redraw);


function zoomButton(zoomDirection) {
  if (zoomDirection == "in") {
    var newZoom = mapZoom.scale() * 1.5; 
    var newX = 
      ((mapZoom.translate()[0] - (width / 2)) * 1.5) + width / 2;
    var newY = 
      ((mapZoom.translate()[1] - (height / 2)) * 1.5) + height / 2; 
  }
  else if (zoomDirection == "out") {
    var newZoom = mapZoom.scale() * .75;
    var newX = ((mapZoom.translate()[0] - (width / 2)) * .75) + width / 2;
    var newY = ((mapZoom.translate()[1] - (height / 2)) * .75) + height / 2;
  }
  mapZoom.scale(newZoom).translate([newX,newY]) 
  redraw();   
}

function zoomed() {
    projection.translate(mapZoom.translate()).scale(mapZoom.scale());
    d3.selectAll("path.graticule").attr("d", geoPath); 
    d3.selectAll("path.countries").attr("d", geoPath);
    d3.selectAll("circle.cities")
        .attr("cx", function(d) {return projection([d.x,d.y])[0]}) 
        .attr("cy", function(d) {return projection([d.x,d.y])[1]});
}

d3.select(".zoomin").on("click", function (){
    zoomButton("in");
    console.log(d3.behavior.zoom().event(d3.select(".zoomin")))
});


d3.select(".graph")
  .call(d3.behavior.zoom().on("zoom", redraw)).on("dblclick.zoom", null).on("wheel.zoom", null);

d3.select(".zoomin")
  .call(d3.behavior.zoom().on("zoom", redraw)).on("dblclick.zoom", redraw);

function redraw() {
  console.log("here", d3.event.translate, d3.event.scale);
  g.attr("transform","translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); 
} 


// start svg

var width = 1100,
    height = 900;

var color = d3.scale.category20();

var force = d3.layout.force()
    .gravity(.05)
    .charge(-700)
    .linkDistance(150)
    .size([width, height]);

var svg = d3.select(".graph").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("class", "graphmap");

zoomin = svg.append("g")
    .attr("class", "zoomin");

zoomin.append("rect")
    .attr("x", 10)
    .attr("y", 10)
    .attr("width", 30)
    .attr("height", 30)
    .attr("rx", 4)
    .attr("ry", 4)
    .attr("fill", "#dadae6");



var g = svg.append('g');


d3.json("miserables.json", function(error, graph) {
  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  var link = g.selectAll(".link")
      .data(graph.links)
    .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

  var node = g.selectAll("g")
      .data(graph.nodes)
      .enter().append("g")
      .attr("class","node")
      .call(force.drag);

  node.append("circle")
    .attr("r", function(d) { return Math.sqrt(d.group * 20); })
    .style("fill", function(d) { return color(d.group); })
    .attr("pointer-events", "auto")
    .attr("class", "circlenode");

  node.append("text")
    .attr("text-anchor", "right") 
    .attr("fill","black")
    .style("pointer-events", "none")
    .attr("font-size", function(d) { 20 + 'px'; })
    .attr("font-weight", function(d) { return "bold"; })
    .text( function(d) { return d.name + ' (' + d.group + ')';});

  setTimeout(function() {
    node.classed("fixed", function(d) { return d.fixed = true; });
  }, 9000);

  force.on("tick", function() {
    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    node.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; })
        .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")";});
  });
});
function dump(obj) {
    var out = '';
    for (var i in obj) {
        out += i + ": " + obj[i] + "\n";
    }

    // or, if you wanted to avoid alerts...

    var pre = document.createElement('pre');
    pre.innerHTML = out;
    document.body.appendChild(pre)
}
</script>

</body>
</html>

You'll see i was playing around with making a zoomButton function but i don't know how to see how to set it up to make it work. I've seen some demos out there of different ideas with the zoom functionality but i don't really understand how they work and what the functions are for. And the d3 documentation doesn't seem to provide much insight. And i haven't found any tutorials that go over what each of the functions do and how to handle events. Any help an explanation of how the zoom functions actually work would be appreciated.

Share Improve this question asked Apr 7, 2015 at 15:37 razraz 1611 silver badge9 bronze badges 4
  • change the value of d3.behaviour.scale() – AJ_91 Commented Apr 7, 2015 at 15:59
  • Refer this stackoverflow./questions/7871425/… – PAC Commented Apr 7, 2015 at 16:03
  • I tried changing d3.behavior.zoom.scale() Is that what you mean? It didn't work anyhow. d3.select(".zoomin").on("click", function (){ d3.select(".graphmap") .call(zoomlistener.scale(2)) }); And i did read every post in that question. They talk about making zoom behaviors with mouse but not with a button. I know how to zoom with the mouse. It still gives me the same problem that d3.event.scale and d3.event.transition are undefined when i call. – raz Commented Apr 7, 2015 at 18:07
  • 1 Figured it out. Thank you AJ. You lead me in the right direction. I needed to also add a d3.behavior.zoom.event() to my selection, and now it works! – raz Commented Apr 7, 2015 at 18:38
Add a ment  | 

1 Answer 1

Reset to default 7

It turns out to be very simple.

var zoomfactor = 1;

var zoomlistener = d3.behavior.zoom()
.on("zoom", redraw);

d3.select(".zoomin").on("click", function (){
    zoomfactor = zoomfactor + 0.2;
    zoomlistener.scale(zoomfactor).event(d3.select(".graph"));
});

d3.select(".zoomout").on("click", function (){
    zoomfactor = zoomfactor - 0.2;
    zoomlistener.scale(zoomfactor).event(d3.select(".graph"));
});

function redraw() {
  console.log("here", d3.event.translate, d3.event.scale);
  g.attr("transform","translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); 
} 

scale() sets the amount you want to zoom and event() calls the portion of the page you want to update.

本文标签: javascripthow do i add a zoom in and zoom out button in a graph on d3Stack Overflow