D3单击放大到特定节点

时间:2018-07-25 08:13:58

标签: javascript html d3.js

我在下面的代码中包含一个D3 Force定向图,该图带有一个突出显示最重节点的按钮。我目前试图完成的是,当我单击按钮时,它将放大该节点。有没有简单的方法可以做到这一点?任何帮助将不胜感激,谢谢!

var graph = {"nodes":[{"id":"Myriel","group":1},{"id":"Napoleon","group":1},{"id":"Mlle.Baptistine","group":1},{"id":"Mme.Magloire","group":1},{"id":"CountessdeLo","group":1},{"id":"Geborand","group":1},{"id":"Champtercier","group":1},{"id":"Cravatte","group":1},{"id":"Count","group":1},{"id":"OldMan","group":1},{"id":"Labarre","group":2},{"id":"Valjean","group":2},{"id":"Marguerite","group":3},{"id":"Mme.deR","group":2},{"id":"Isabeau","group":2},{"id":"Gervais","group":2},{"id":"Tholomyes","group":3},{"id":"Listolier","group":3},{"id":"Fameuil","group":3},{"id":"Blacheville","group":3},{"id":"Favourite","group":3},{"id":"Dahlia","group":3},{"id":"Zephine","group":3},{"id":"Fantine","group":3},{"id":"Mme.Thenardier","group":4},{"id":"Thenardier","group":4},{"id":"Cosette","group":5},{"id":"Javert","group":4},{"id":"Fauchelevent","group":0},{"id":"Bamatabois","group":2},{"id":"Perpetue","group":3},{"id":"Simplice","group":2},{"id":"Scaufflaire","group":2},{"id":"Woman1","group":2},{"id":"Judge","group":2},{"id":"Champmathieu","group":2},{"id":"Brevet","group":2},{"id":"Chenildieu","group":2},{"id":"Cochepaille","group":2},{"id":"Pontmercy","group":4},{"id":"Boulatruelle","group":6},{"id":"Eponine","group":4},{"id":"Anzelma","group":4},{"id":"Woman2","group":5},{"id":"MotherInnocent","group":0},{"id":"Gribier","group":0},{"id":"Jondrette","group":7},{"id":"Mme.Burgon","group":7},{"id":"Gavroche","group":8},{"id":"Gillenormand","group":5},{"id":"Magnon","group":5},{"id":"Mlle.Gillenormand","group":5},{"id":"Mme.Pontmercy","group":5},{"id":"Mlle.Vaubois","group":5},{"id":"Lt.Gillenormand","group":5},{"id":"Marius","group":8},{"id":"BaronessT","group":5},{"id":"Mabeuf","group":8},{"id":"Enjolras","group":8},{"id":"Combeferre","group":8},{"id":"Prouvaire","group":8},{"id":"Feuilly","group":8},{"id":"Courfeyrac","group":8},{"id":"Bahorel","group":8},{"id":"Bossuet","group":8},{"id":"Joly","group":8},{"id":"Grantaire","group":8},{"id":"MotherPlutarch","group":9},{"id":"Gueulemer","group":4},{"id":"Babet","group":4},{"id":"Claquesous","group":4},{"id":"Montparnasse","group":4},{"id":"Toussaint","group":5},{"id":"Child1","group":10},{"id":"Child2","group":10},{"id":"Brujon","group":4},{"id":"Mme.Hucheloup","group":8}],"links":[{"source":"Napoleon","target":"Myriel","value":1,"type":"A"},{"source":"Mlle.Baptistine","target":"Myriel","value":8,"type":"A"},{"source":"Mme.Magloire","target":"Myriel","value":10,"type":"A"},{"source":"Mme.Magloire","target":"Mlle.Baptistine","value":6,"type":"A"},{"source":"CountessdeLo","target":"Myriel","value":1,"type":"A"},{"source":"Geborand","target":"Myriel","value":1,"type":"A"},{"source":"Champtercier","target":"Myriel","value":1,"type":"A"},{"source":"Cravatte","target":"Myriel","value":1,"type":"A"},{"source":"Count","target":"Myriel","value":2,"type":"A"},{"source":"OldMan","target":"Myriel","value":1,"type":"A"},{"source":"Valjean","target":"Labarre","value":1,"type":"A"},{"source":"Valjean","target":"Mme.Magloire","value":3,"type":"A"},{"source":"Valjean","target":"Mlle.Baptistine","value":3,"type":"A"},{"source":"Valjean","target":"Myriel","value":5,"type":"A"},{"source":"Marguerite","target":"Valjean","value":1,"type":"A"},{"source":"Mme.deR","target":"Valjean","value":1,"type":"A"},{"source":"Isabeau","target":"Valjean","value":1,"type":"A"},{"source":"Gervais","target":"Valjean","value":1,"type":"A"},{"source":"Listolier","target":"Tholomyes","value":4,"type":"A"},{"source":"Fameuil","target":"Tholomyes","value":4,"type":"A"},{"source":"Fameuil","target":"Listolier","value":4,"type":"A"},{"source":"Blacheville","target":"Tholomyes","value":4,"type":"A"},{"source":"Blacheville","target":"Listolier","value":4,"type":"A"},{"source":"Blacheville","target":"Fameuil","value":4,"type":"A"},{"source":"Favourite","target":"Tholomyes","value":3,"type":"A"},{"source":"Favourite","target":"Listolier","value":3,"type":"A"},{"source":"Favourite","target":"Fameuil","value":3,"type":"A"},{"source":"Favourite","target":"Blacheville","value":4,"type":"A"},{"source":"Dahlia","target":"Tholomyes","value":3,"type":"A"},{"source":"Dahlia","target":"Listolier","value":3,"type":"A"},{"source":"Dahlia","target":"Fameuil","value":3,"type":"A"},{"source":"Dahlia","target":"Blacheville","value":3,"type":"A"},{"source":"Dahlia","target":"Favourite","value":5,"type":"A"},{"source":"Zephine","target":"Tholomyes","value":3,"type":"A"},{"source":"Zephine","target":"Listolier","value":3,"type":"A"},{"source":"Zephine","target":"Fameuil","value":3,"type":"A"},{"source":"Zephine","target":"Blacheville","value":3,"type":"A"},{"source":"Zephine","target":"Favourite","value":4,"type":"A"},{"source":"Zephine","target":"Dahlia","value":4,"type":"A"},{"source":"Fantine","target":"Tholomyes","value":3,"type":"A"},{"source":"Fantine","target":"Listolier","value":3,"type":"A"},{"source":"Fantine","target":"Fameuil","value":3,"type":"A"},{"source":"Fantine","target":"Blacheville","value":3,"type":"A"},{"source":"Fantine","target":"Favourite","value":4,"type":"A"},{"source":"Fantine","target":"Dahlia","value":4,"type":"A"},{"source":"Fantine","target":"Zephine","value":4,"type":"A"},{"source":"Fantine","target":"Marguerite","value":2,"type":"A"},{"source":"Fantine","target":"Valjean","value":9,"type":"A"},{"source":"Mme.Thenardier","target":"Fantine","value":2,"type":"A"},{"source":"Mme.Thenardier","target":"Valjean","value":7,"type":"A"},{"source":"Thenardier","target":"Mme.Thenardier","value":13,"type":"A"},{"source":"Thenardier","target":"Fantine","value":1,"type":"A"},{"source":"Thenardier","target":"Valjean","value":12,"type":"A"},{"source":"Cosette","target":"Mme.Thenardier","value":4,"type":"A"},{"source":"Cosette","target":"Valjean","value":31,"type":"A"},{"source":"Cosette","target":"Tholomyes","value":1,"type":"A"},{"source":"Cosette","target":"Thenardier","value":1,"type":"A"},{"source":"Javert","target":"Valjean","value":17,"type":"A"},{"source":"Javert","target":"Fantine","value":5,"type":"A"},{"source":"Javert","target":"Thenardier","value":5,"type":"A"},{"source":"Javert","target":"Mme.Thenardier","value":1,"type":"A"},{"source":"Javert","target":"Cosette","value":1,"type":"A"},{"source":"Fauchelevent","target":"Valjean","value":8,"type":"A"},{"source":"Fauchelevent","target":"Javert","value":1,"type":"A"},{"source":"Bamatabois","target":"Fantine","value":1,"type":"A"},{"source":"Bamatabois","target":"Javert","value":1,"type":"A"},{"source":"Bamatabois","target":"Valjean","value":2,"type":"A"},{"source":"Perpetue","target":"Fantine","value":1,"type":"A"},{"source":"Simplice","target":"Perpetue","value":2,"type":"A"},{"source":"Simplice","target":"Valjean","value":3,"type":"A"},{"source":"Simplice","target":"Fantine","value":2,"type":"A"},{"source":"Simplice","target":"Javert","value":1,"type":"A"},{"source":"Scaufflaire","target":"Valjean","value":1,"type":"A"},{"source":"Woman1","target":"Valjean","value":2,"type":"A"},{"source":"Woman1","target":"Javert","value":1,"type":"A"},{"source":"Judge","target":"Valjean","value":3,"type":"A"},{"source":"Judge","target":"Bamatabois","value":2,"type":"A"},{"source":"Champmathieu","target":"Valjean","value":3,"type":"A"},{"source":"Champmathieu","target":"Judge","value":3,"type":"A"},{"source":"Champmathieu","target":"Bamatabois","value":2,"type":"A"},{"source":"Brevet","target":"Judge","value":2,"type":"A"},{"source":"Brevet","target":"Champmathieu","value":2,"type":"A"},{"source":"Brevet","target":"Valjean","value":2,"type":"A"},{"source":"Brevet","target":"Bamatabois","value":1,"type":"A"},{"source":"Chenildieu","target":"Judge","value":2,"type":"A"},{"source":"Chenildieu","target":"Champmathieu","value":2,"type":"A"},{"source":"Chenildieu","target":"Brevet","value":2,"type":"A"},{"source":"Chenildieu","target":"Valjean","value":2,"type":"A"},{"source":"Chenildieu","target":"Bamatabois","value":1,"type":"A"},{"source":"Cochepaille","target":"Judge","value":2,"type":"A"},{"source":"Cochepaille","target":"Champmathieu","value":2,"type":"A"},{"source":"Cochepaille","target":"Brevet","value":2,"type":"A"},{"source":"Cochepaille","target":"Chenildieu","value":2,"type":"A"},{"source":"Cochepaille","target":"Valjean","value":2,"type":"A"},{"source":"Cochepaille","target":"Bamatabois","value":1,"type":"A"},{"source":"Pontmercy","target":"Thenardier","value":1,"type":"A"},{"source":"Boulatruelle","target":"Thenardier","value":1,"type":"A"},{"source":"Eponine","target":"Mme.Thenardier","value":2,"type":"A"},{"source":"Eponine","target":"Thenardier","value":3,"type":"A"},{"source":"Anzelma","target":"Eponine","value":2,"type":"A"},{"source":"Anzelma","target":"Thenardier","value":2,"type":"A"},{"source":"Anzelma","target":"Mme.Thenardier","value":1,"type":"A"},{"source":"Woman2","target":"Valjean","value":3,"type":"A"},{"source":"Woman2","target":"Cosette","value":1,"type":"A"},{"source":"Woman2","target":"Javert","value":1,"type":"A"},{"source":"MotherInnocent","target":"Fauchelevent","value":3,"type":"A"},{"source":"MotherInnocent","target":"Valjean","value":1,"type":"A"},{"source":"Gribier","target":"Fauchelevent","value":2,"type":"A"},{"source":"Mme.Burgon","target":"Jondrette","value":1,"type":"A"},{"source":"Gavroche","target":"Mme.Burgon","value":2,"type":"A"},{"source":"Gavroche","target":"Thenardier","value":1,"type":"A"},{"source":"Gavroche","target":"Javert","value":1,"type":"A"},{"source":"Gavroche","target":"Valjean","value":1,"type":"A"},{"source":"Gillenormand","target":"Cosette","value":3,"type":"A"},{"source":"Gillenormand","target":"Valjean","value":2,"type":"A"},{"source":"Magnon","target":"Gillenormand","value":1,"type":"A"},{"source":"Magnon","target":"Mme.Thenardier","value":1,"type":"A"},{"source":"Mlle.Gillenormand","target":"Gillenormand","value":9,"type":"A"},{"source":"Mlle.Gillenormand","target":"Cosette","value":2,"type":"A"},{"source":"Mlle.Gillenormand","target":"Valjean","value":2,"type":"A"},{"source":"Mme.Pontmercy","target":"Mlle.Gillenormand","value":1,"type":"A"},{"source":"Mme.Pontmercy","target":"Pontmercy","value":1,"type":"A"},{"source":"Mlle.Vaubois","target":"Mlle.Gillenormand","value":1,"type":"A"},{"source":"Lt.Gillenormand","target":"Mlle.Gillenormand","value":2,"type":"A"},{"source":"Lt.Gillenormand","target":"Gillenormand","value":1,"type":"A"},{"source":"Lt.Gillenormand","target":"Cosette","value":1,"type":"A"},{"source":"Marius","target":"Mlle.Gillenormand","value":6,"type":"A"},{"source":"Marius","target":"Gillenormand","value":12,"type":"A"},{"source":"Marius","target":"Pontmercy","value":1,"type":"A"},{"source":"Marius","target":"Lt.Gillenormand","value":1,"type":"A"},{"source":"Marius","target":"Cosette","value":21,"type":"A"},{"source":"Marius","target":"Valjean","value":19,"type":"A"},{"source":"Marius","target":"Tholomyes","value":1,"type":"A"},{"source":"Marius","target":"Thenardier","value":2,"type":"A"},{"source":"Marius","target":"Eponine","value":5,"type":"A"},{"source":"Marius","target":"Gavroche","value":4,"type":"A"},{"source":"BaronessT","target":"Gillenormand","value":1,"type":"A"},{"source":"BaronessT","target":"Marius","value":1,"type":"A"},{"source":"Mabeuf","target":"Marius","value":1,"type":"A"},{"source":"Mabeuf","target":"Eponine","value":1,"type":"A"},{"source":"Mabeuf","target":"Gavroche","value":1,"type":"A"},{"source":"Enjolras","target":"Marius","value":7,"type":"A"},{"source":"Enjolras","target":"Gavroche","value":7,"type":"A"},{"source":"Enjolras","target":"Javert","value":6,"type":"A"},{"source":"Enjolras","target":"Mabeuf","value":1,"type":"A"},{"source":"Enjolras","target":"Valjean","value":4,"type":"A"},{"source":"Combeferre","target":"Enjolras","value":15,"type":"A"},{"source":"Combeferre","target":"Marius","value":5,"type":"A"},{"source":"Combeferre","target":"Gavroche","value":6,"type":"A"},{"source":"Combeferre","target":"Mabeuf","value":2,"type":"A"},{"source":"Prouvaire","target":"Gavroche","value":1,"type":"A"},{"source":"Prouvaire","target":"Enjolras","value":4,"type":"A"},{"source":"Prouvaire","target":"Combeferre","value":2,"type":"A"},{"source":"Feuilly","target":"Gavroche","value":2,"type":"A"},{"source":"Feuilly","target":"Enjolras","value":6,"type":"A"},{"source":"Feuilly","target":"Prouvaire","value":2,"type":"A"},{"source":"Feuilly","target":"Combeferre","value":5,"type":"A"},{"source":"Feuilly","target":"Mabeuf","value":1,"type":"A"},{"source":"Feuilly","target":"Marius","value":1,"type":"A"},{"source":"Courfeyrac","target":"Marius","value":9,"type":"A"},{"source":"Courfeyrac","target":"Enjolras","value":17,"type":"A"},{"source":"Courfeyrac","target":"Combeferre","value":13,"type":"A"},{"source":"Courfeyrac","target":"Gavroche","value":7,"type":"A"},{"source":"Courfeyrac","target":"Mabeuf","value":2,"type":"A"},{"source":"Courfeyrac","target":"Eponine","value":1,"type":"A"},{"source":"Courfeyrac","target":"Feuilly","value":6,"type":"A"},{"source":"Courfeyrac","target":"Prouvaire","value":3,"type":"A"},{"source":"Bahorel","target":"Combeferre","value":5,"type":"A"},{"source":"Bahorel","target":"Gavroche","value":5,"type":"A"},{"source":"Bahorel","target":"Courfeyrac","value":6,"type":"A"},{"source":"Bahorel","target":"Mabeuf","value":2,"type":"A"},{"source":"Bahorel","target":"Enjolras","value":4,"type":"A"},{"source":"Bahorel","target":"Feuilly","value":3,"type":"A"},{"source":"Bahorel","target":"Prouvaire","value":2,"type":"A"},{"source":"Bahorel","target":"Marius","value":1,"type":"A"},{"source":"Bossuet","target":"Marius","value":5,"type":"A"},{"source":"Bossuet","target":"Courfeyrac","value":12,"type":"A"},{"source":"Bossuet","target":"Gavroche","value":5,"type":"A"},{"source":"Bossuet","target":"Bahorel","value":4,"type":"A"},{"source":"Bossuet","target":"Enjolras","value":10,"type":"A"},{"source":"Bossuet","target":"Feuilly","value":6,"type":"A"},{"source":"Bossuet","target":"Prouvaire","value":2,"type":"A"},{"source":"Bossuet","target":"Combeferre","value":9,"type":"A"},{"source":"Bossuet","target":"Mabeuf","value":1,"type":"A"},{"source":"Bossuet","target":"Valjean","value":1,"type":"A"},{"source":"Joly","target":"Bahorel","value":5,"type":"A"},{"source":"Joly","target":"Bossuet","value":7,"type":"A"},{"source":"Joly","target":"Gavroche","value":3,"type":"A"},{"source":"Joly","target":"Courfeyrac","value":5,"type":"A"},{"source":"Joly","target":"Enjolras","value":5,"type":"A"},{"source":"Joly","target":"Feuilly","value":5,"type":"A"},{"source":"Joly","target":"Prouvaire","value":2,"type":"A"},{"source":"Joly","target":"Combeferre","value":5,"type":"A"},{"source":"Joly","target":"Mabeuf","value":1,"type":"A"},{"source":"Joly","target":"Marius","value":2,"type":"A"},{"source":"Grantaire","target":"Bossuet","value":3,"type":"A"},{"source":"Grantaire","target":"Enjolras","value":3,"type":"A"},{"source":"Grantaire","target":"Combeferre","value":1,"type":"A"},{"source":"Grantaire","target":"Courfeyrac","value":2,"type":"A"},{"source":"Grantaire","target":"Joly","value":2,"type":"A"},{"source":"Grantaire","target":"Gavroche","value":1,"type":"A"},{"source":"Grantaire","target":"Bahorel","value":1,"type":"A"},{"source":"Grantaire","target":"Feuilly","value":1,"type":"A"},{"source":"Grantaire","target":"Prouvaire","value":1,"type":"A"},{"source":"MotherPlutarch","target":"Mabeuf","value":3,"type":"A"},{"source":"Gueulemer","target":"Thenardier","value":5,"type":"A"},{"source":"Gueulemer","target":"Valjean","value":1,"type":"A"},{"source":"Gueulemer","target":"Mme.Thenardier","value":1,"type":"A"},{"source":"Gueulemer","target":"Javert","value":1,"type":"A"},{"source":"Gueulemer","target":"Gavroche","value":1,"type":"A"},{"source":"Gueulemer","target":"Eponine","value":1,"type":"A"},{"source":"Babet","target":"Thenardier","value":6,"type":"A"},{"source":"Babet","target":"Gueulemer","value":6,"type":"A"},{"source":"Babet","target":"Valjean","value":1,"type":"A"},{"source":"Babet","target":"Mme.Thenardier","value":1,"type":"A"},{"source":"Babet","target":"Javert","value":2,"type":"A"},{"source":"Babet","target":"Gavroche","value":1,"type":"A"},{"source":"Babet","target":"Eponine","value":1,"type":"A"},{"source":"Claquesous","target":"Thenardier","value":4,"type":"A"},{"source":"Claquesous","target":"Babet","value":4,"type":"A"},{"source":"Claquesous","target":"Gueulemer","value":4,"type":"A"},{"source":"Claquesous","target":"Valjean","value":1,"type":"A"},{"source":"Claquesous","target":"Mme.Thenardier","value":1,"type":"A"},{"source":"Claquesous","target":"Javert","value":1,"type":"A"},{"source":"Claquesous","target":"Eponine","value":1,"type":"A"},{"source":"Claquesous","target":"Enjolras","value":1,"type":"A"},{"source":"Montparnasse","target":"Javert","value":1,"type":"A"},{"source":"Montparnasse","target":"Babet","value":2,"type":"A"},{"source":"Montparnasse","target":"Gueulemer","value":2,"type":"A"},{"source":"Montparnasse","target":"Claquesous","value":2,"type":"A"},{"source":"Montparnasse","target":"Valjean","value":1,"type":"A"},{"source":"Montparnasse","target":"Gavroche","value":1,"type":"A"},{"source":"Montparnasse","target":"Eponine","value":1,"type":"A"},{"source":"Montparnasse","target":"Thenardier","value":1,"type":"A"},{"source":"Toussaint","target":"Cosette","value":2,"type":"A"},{"source":"Toussaint","target":"Javert","value":1,"type":"A"},{"source":"Toussaint","target":"Valjean","value":1,"type":"A"},{"source":"Child1","target":"Gavroche","value":2,"type":"A"},{"source":"Child2","target":"Gavroche","value":2,"type":"A"},{"source":"Child2","target":"Child1","value":3,"type":"A"},{"source":"Brujon","target":"Babet","value":3,"type":"A"},{"source":"Brujon","target":"Gueulemer","value":3,"type":"A"},{"source":"Brujon","target":"Thenardier","value":3,"type":"A"},{"source":"Brujon","target":"Gavroche","value":1,"type":"A"},{"source":"Brujon","target":"Eponine","value":1,"type":"A"},{"source":"Brujon","target":"Claquesous","value":1,"type":"A"},{"source":"Brujon","target":"Montparnasse","value":1,"type":"A"},{"source":"Mme.Hucheloup","target":"Bossuet","value":1,"type":"A"},{"source":"Mme.Hucheloup","target":"Joly","value":1,"type":"A"},{"source":"Mme.Hucheloup","target":"Grantaire","value":1,"type":"A"},{"source":"Mme.Hucheloup","target":"Bahorel","value":1,"type":"A"},{"source":"Mme.Hucheloup","target":"Courfeyrac","value":1,"type":"A"},{"source":"Mme.Hucheloup","target":"Gavroche","value":1,"type":"A"},{"source":"Mme.Hucheloup","target":"Enjolras","value":1,"type":"A"}]};

var svg = d3.select("svg"),
  width = +svg.attr("width"),
  height = +svg.attr("height");

var color = d3.scaleOrdinal(d3.schemeCategory20);

var zoom_handler = d3.zoom().on("zoom", zoom_actions);

// zoom_handler(svg);

var simulation = d3.forceSimulation()
  .force("link", d3.forceLink().distance(300).id(function(d) {
    return d.id;
  }))
  .force("charge", d3.forceManyBody().strength(-300))
  .force("center", d3.forceCenter(width / 2, height / 2));

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

svg.call(zoom_handler)
  .call(zoom_handler.transform, d3.zoomIdentity.translate(200, 150).scale(0.2));

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

var node = g.append("g")
  .attr("class", "nodes")
  .selectAll("g")
  .data(graph.nodes)
  .enter().append("g")
  .attr("id", function(d) {
    return d.id
  })


var circles = node.append("circle")
  .attr("r", 8)
  .attr("fill", function(d) {
    return color(d.group);
  })
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));

var lables = node.append("text") // Labeling for nodes
  .text(function(d) {
    return d.id;
  })
  .attr('x', 6)
  .attr('y', 3);

node.append("title")
  .text(function(d) {
    return d.id;
  });

simulation
  .nodes(graph.nodes)
  .on("tick", ticked);

simulation.force("link")
  .links(graph.links);


function ticked() {
  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("transform", function(d) {
      return "translate(" + d.x + "," + d.y + ")";
    })

};


d3.select("#Zooming").on("click", Zooming);

function Zooming() {
  var largest = null,
    weight = 0;
  node.each(function(d) {
    var connections = link.filter(function(l) {
      return l.source.index == d.index || l.target.index == d.index
    });
    d.weight = connections.size();
    if (d.weight > weight) {
      largest = {
        node: this,
        links: connections
      };
      weight = d.weight;

    }
  });
  if (largest) {
    d3.select(largest.node).select("circle")
      .style("fill", "red")
      .style("stroke-width", 3);
    largest.links.each(function() {
      d3.select(this).style("stroke", "red").style("stroke-width", 3);;
    })
  }
}

function zoom_actions() {
  g.attr("transform", d3.event.transform)
}

function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
  d.fx = d.x;
  d.fy = d.y;
}

function dragged(d) {
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}

function dragended(d) {
  if (!d3.event.active) simulation.alphaTarget(0);
  d.fx = null;
  d.fy = null;
}
.links line {
  stroke: #999;
  stroke-opacity: 0.6;
}

.nodes circle {
  stroke: #000;
  stroke-width: 1.5px;
}

text {
  font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
  font-size: 10px;
}
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="shortcut icon" href="//#" />

<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

<input type="button" value="Zoom" id="Zooming" />

</html>
</div>

<svg width="798" height="400"></svg>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>

1 个答案:

答案 0 :(得分:1)

要缩放到节点的位置,必须基于最大节点的位置和选定的缩放系数(我发现2为一个很好的缩放系数)来更新缩放变换。有关数学的内容,请参见Panning and Zooming with D3v4 - Empty Pipes

要防止拖动时出现“重影”效果,您应该对节点和文本进行不同的组织,并修改ticked函数。原因是您正在更改要拖动的对象的变换。

.nodes组下面将文本添加为​​单独的标签,并在更新节点位置时更新文本位置。 text标签基于节点的id(前缀't_')获得唯一的id

尝试通过W3验证器运行HTML。几乎所有标签的位置都不正确。

var nodeGroup = g.append("g")
  .attr("class", "nodes");

var node = nodeGroup.selectAll("circle")
  .data(graph.nodes)
  .enter().append("circle")
  .attr("r", 8)
  .attr("fill", function(d) { return color(d.group); })
  .attr("id", function(d) { return d.id })
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended));

function cleanId(id) { return id.replace(/\./g, '_'); }

node.append("title")
  .text(function(d) { return d.id; });

node.each(d => {
  nodeGroup.append("text") // Labelling for nodes
    .attr("id", 't_' + cleanId(d.id) )
    .text(d.id); });

function ticked() {
  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; })
    .each(d => { d3.select('#t_' + cleanId(d.id)).attr('x', d.x + 10).attr('y', d.y + 3); });
};

simulation
  .nodes(graph.nodes)
  .on("tick", ticked);

simulation.force("link")
  .links(graph.links);

d3.select("#Zooming").on("click", Zooming);

function Zooming() {
  var largest = null,
    weight = 0;
  node.each(function(d) {
    var connections = link.filter(function(l) {
      return l.source.index == d.index || l.target.index == d.index
    });
    d.weight = connections.size();
    if (d.weight > weight) {
      largest = {
        node: this,
        links: connections
      };
      weight = d.weight;
    }
  });
  if (largest) {
    d3.select(largest.node)
      .style("fill", "red")
      .style("stroke-width", 3);
    largest.links.each(function() {
      d3.select(this).style("stroke", "red").style("stroke-width", 3);
    });
    var scaleZoom = 2;
    var nodeDatum = d3.select(largest.node).datum();
    svg.transition()
       .duration(750)
       .call(zoom_handler.transform,
             d3.zoomIdentity
               .translate(width*0.5-scaleZoom*nodeDatum.x,
                          height*0.5-scaleZoom*nodeDatum.y)
               .scale(scaleZoom));
  }
}

修改

稍微修改了代码以清理文本标签的ID,以将.替换为'_'。