d3: set panning limit

by Ram Tobolski

HTML

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

CSS

.links line {
  stroke: #999;
  stroke-opacity: 0.6;
}

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

svg {
  border: 1px solid red;
}

JavaScript

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

var point = svg.node().createSVGPoint();
console.log("point = "+point);

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

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

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
    },
*/
  ],
  "links": [
  /*
  {
    "source": "Napoleon",
    "target": "Myriel",
    "value": 1
  }, {
    "source": "Mlle.Baptistine",
    "target": "Myriel",
    "value": 8
  }, {
    "source": "Mme.Magloire",
    "target": "Myriel",
    "value": 10
  }, {
    "source": "Mme.Magloire",
    "target": "Mlle.Baptistine",
    "value": 6
  }, {
    "source": "CountessdeLo",
    "target": "Myriel",
    "value": 1
  }, {
    "source": "Geborand",
    "target": "Myriel",
    "value": 1
  }, {
    "source": "Champtercier",
    "target": "Myriel",
    "value": 1
  }, {
    "source": "Cravatte",
    "target": "Myriel",
    "value": 1
  }, {
    "source": "Count",
    "target": "Myriel",
   ...