Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              <div class="wrapper" id="wrapper">
    <svg class="graph" id="graph"></svg>
  </div>
            
          
!
            
              * {
  margin: 0;
  padding: 0;
  background-color: #AAA;
  color: #000000;
  font-family: 'Lato', sans-serif;
}
.wrapper {
  width: 1200px;
  margin: 0 auto;
  background-color: #CCC;
  position: relative;
  /* overflow: hidden; */
}
.graph {
  background-color: #edf1f0;
  display: block;
  
}
.node {
  fill:#ccc;
  stroke:#000;
  stroke-width: 2px;
}
.link {
  stroke:#000;
  stroke-width:2px;
}
.title {
  font-size: 20px;
}
.sign {
  font-size: 12px;
  fill: #999;
}

.tooltip {
  background-color: #3a84cb;
  position: absolute;
  z-index:2;
  color: #000000;
  font-size: 14px;
  padding: 5px;
  border: 0;
  border-radius: 5px;
  text-align: center;
}
/*!
 * Generated with CSS Flag Sprite generator (https://www.flag-sprites.com/)
 */

.flag {
    display: inline-block;
    width: 25px;
    height: 15px;
    background: url('http://mybytes.pl/projects/flags.png') no-repeat;
    z-index: 1;
    position: absolute;
}


.flag.flag-af {
    background-position: -50px 0;
}

.flag.flag-bf {
    background-position: -100px -15px;
}

.flag.flag-tk {
    background-position: -175px -195px;
}

.flag.flag-no {
    background-position: -100px -150px;
}

.flag.flag-tm {
    background-position: -225px -195px;
}

.flag.flag-co {
    background-position: -350px -30px;
}

.flag.flag-bz {
    background-position: -75px -30px;
}

.flag.flag-vg {
    background-position: -250px -210px;
}

.flag.flag-sl {
    background-position: -200px -180px;
}

.flag.flag-ai {
    background-position: -100px 0;
}

.flag.flag-hr {
    background-position: -375px -75px;
}

.flag.flag-li {
    background-position: -350px -105px;
}

.flag.flag-fi {
    background-position: -50px -60px;
}

.flag.flag-vc {
    background-position: -200px -210px;
}

.flag.flag-km {
    background-position: -100px -105px;
}

.flag.flag-sk {
    background-position: -175px -180px;
}

.flag.flag-mp {
    background-position: -50px -135px;
}

.flag.flag-lk {
    background-position: -375px -105px;
}

.flag.flag-hk {
    background-position: -300px -75px;
}

.flag.flag-bt {
    background-position: -375px -15px;
}

.flag.flag-eh {
    background-position: -325px -45px;
}

.flag.flag-th {
    background-position: -125px -195px;
}

.flag.flag-pg {
    background-position: -325px -150px;
}

.flag.flag-ir {
    background-position: -200px -90px;
}

.flag.flag-kr {
    background-position: -175px -105px;
}

.flag.flag-me {
    background-position: -225px -120px;
}

.flag.flag-gl {
    background-position: -25px -75px;
}

.flag.flag-wf {
    background-position: -350px -210px;
}

.flag.flag-ht {
    background-position: 0 -90px;
}

.flag.flag-rw {
    background-position: -325px -165px;
}

.flag.flag-st {
    background-position: -325px -180px;
}

.flag.flag-tz {
    background-position: 0 -210px;
}

.flag.flag-mh {
    background-position: -300px -120px;
}

.flag.flag-cn {
    background-position: -325px -30px;
}

.flag.flag-um {
    background-position: -75px -210px;
}

.flag.flag-sc {
    background-position: 0 -180px;
}

.flag.flag-am {
    background-position: -150px 0;
}

.flag.flag-ro {
    background-position: -250px -165px;
}

.flag.flag-to {
    background-position: -275px -195px;
}

.flag.flag-gm {
    background-position: -50px -75px;
}

.flag.flag-ng {
    background-position: -25px -150px;
}

.flag.flag-jm {
    background-position: -325px -90px;
}

.flag.flag-ga {
    background-position: -200px -60px;
}

.flag.flag-gw {
    background-position: -250px -75px;
}

.flag.flag-sb {
    background-position: -375px -165px;
}

.flag.flag-pr {
    background-position: -75px -165px;
}

.flag.flag-ua {
    background-position: -25px -210px;
}

.flag.flag-va {
    background-position: -175px -210px;
}

.flag.flag-sv {
    background-position: -350px -180px;
}

.flag.flag-tf {
    background-position: -75px -195px;
}

.flag.flag-az {
    background-position: -375px 0;
}

.flag.flag-gy {
    background-position: -275px -75px;
}

.flag.flag-ne {
    background-position: -375px -135px;
}

.flag.flag-tj {
    background-position: -150px -195px;
}

.flag.flag-ug {
    background-position: -50px -210px;
}

.flag.flag-kz {
    background-position: -250px -105px;
}

.flag.flag-bm {
    background-position: -250px -15px;
}

.flag.flag-tr {
    background-position: -300px -195px;
}

.flag.flag-eu {
    background-position: -25px -60px;
}

.flag.flag-fj {
    background-position: -75px -60px;
}

.flag.flag-fm {
    background-position: -125px -60px;
}

.flag.flag-bw {
    background-position: -25px -30px;
}

.flag.flag-ma {
    background-position: -150px -120px;
}

.flag.flag-re {
    background-position: -225px -165px;
}

.flag.flag-sy {
    background-position: -375px -180px;
}

.flag.flag-nf {
    background-position: 0 -150px;
}

.flag.flag-tv {
    background-position: -350px -195px;
}

.flag.flag-gp {
    background-position: -100px -75px;
}

.flag.flag-sm {
    background-position: -225px -180px;
}

.flag.flag-tt {
    background-position: -325px -195px;
}

.flag.flag-pm {
    background-position: -25px -165px;
}

.flag.flag-nl {
    background-position: -75px -150px;
}

.flag.flag-de {
    background-position: -100px -45px;
}

.flag.flag-uz {
    background-position: -150px -210px;
}

.flag.flag-so {
    background-position: -275px -180px;
}

.flag.flag-bh {
    background-position: -150px -15px;
}

.flag.flag-hu {
    background-position: -25px -90px;
}

.flag.flag-mn {
    background-position: 0 -135px;
}

.flag.flag-il {
    background-position: -100px -90px;
}

.flag.flag-ae {
    background-position: -25px 0;
}

.flag.flag-sd {
    background-position: -25px -180px;
}

.flag.flag-fr {
    background-position: -175px -60px;
}

.flag.flag-by {
    background-position: -50px -30px;
}

.flag.flag-lb {
    background-position: -300px -105px;
}

.flag.flag-kn {
    background-position: -125px -105px;
}

.flag.flag-nz {
    background-position: -200px -150px;
}

.flag.flag-uy {
    background-position: -125px -210px;
}

.flag.flag-md {
    background-position: -200px -120px;
}

.flag.flag-ge {
    background-position: -275px -60px;
}

.flag.flag-sg {
    background-position: -75px -180px;
}

.flag.flag-np {
    background-position: -125px -150px;
}

.flag.flag-ch {
    background-position: -200px -30px;
}

.flag.flag-bg {
    background-position: -125px -15px;
}

.flag.flag-ba {
    background-position: 0 -15px;
}

.flag.flag-iq {
    background-position: -175px -90px;
}

.flag.flag-gi {
    background-position: 0 -75px;
}

.flag.flag-gq {
    background-position: -125px -75px;
}

.flag.flag-mu {
    background-position: -175px -135px;
}

.flag.flag-pk {
    background-position: -375px -150px;
}

.flag.flag-gh {
    background-position: -375px -60px;
}

.flag.flag-vi {
    background-position: -275px -210px;
}

.flag.flag-al {
    background-position: -125px 0;
}

.flag.flag-us {
    background-position: -100px -210px;
}

.flag.flag-cu {
    background-position: 0 -45px;
}

.flag.flag-mm {
    background-position: -375px -120px;
}

.flag.flag-bn {
    background-position: -275px -15px;
}

.flag.flag-vu {
    background-position: -325px -210px;
}

.flag.flag-zm {
    background-position: -75px -225px;
}

.flag.flag-ps {
    background-position: -100px -165px;
}

.flag.flag-ve {
    background-position: -225px -210px;
}

.flag.flag-ao {
    background-position: -200px 0;
}

.flag.flag-kg {
    background-position: -25px -105px;
}

.flag.flag-dk {
    background-position: -150px -45px;
}

.flag.flag-mt {
    background-position: -150px -135px;
}

.flag.flag-mw {
    background-position: -225px -135px;
}

.flag.flag-se {
    background-position: -50px -180px;
}

.flag.flag-lr {
    background-position: 0 -120px;
}

.flag.flag-gr {
    background-position: -150px -75px;
}

.flag.flag-ec {
    background-position: -250px -45px;
}

.flag.flag-be {
    background-position: -75px -15px;
}

.flag.flag-mq {
    background-position: -75px -135px;
}

.flag.flag-lu {
    background-position: -75px -120px;
}

.flag.flag-ml {
    background-position: -350px -120px;
}

.flag.flag-ye {
    background-position: 0 -225px;
}

.flag.flag-rs {
    background-position: -275px -165px;
}

.flag.flag-jo {
    background-position: -350px -90px;
}

.flag.flag-mo {
    background-position: -25px -135px;
}

.flag.flag-td {
    background-position: -50px -195px;
}

.flag.flag-at {
    background-position: -275px 0;
}

.flag.flag-cd {
    background-position: -125px -30px;
}

.flag.flag-mk {
    background-position: -325px -120px;
}

.flag.flag-ax {
    background-position: -350px 0;
}

.flag.flag-as {
    background-position: -250px 0;
}

.flag.flag-ad {
    background-position: 0 0;
}

.flag.flag-la {
    background-position: -275px -105px;
}

.flag.flag-fo {
    background-position: -150px -60px;
}

.flag.flag-bd {
    background-position: -50px -15px;
}

.flag.flag-ly {
    background-position: -125px -120px;
}

.flag.flag-mg {
    background-position: -275px -120px;
}

.flag.flag-nr {
    background-position: -150px -150px;
}

.flag.flag-gt {
    background-position: -200px -75px;
}

.flag.flag-om {
    background-position: -225px -150px;
}

.flag.flag-dm {
    background-position: -175px -45px;
}

.flag.flag-tl {
    background-position: -200px -195px;
}

.flag.flag-cz {
    background-position: -75px -45px;
}

.flag.flag-dz {
    background-position: -225px -45px;
}

.flag.flag-pa {
    background-position: -250px -150px;
}

.flag.flag-sz {
    background-position: 0 -195px;
}

.flag.flag-pt {
    background-position: -125px -165px;
}

.flag.flag-yt {
    background-position: -25px -225px;
}

.flag.flag-ck {
    background-position: -250px -30px;
}

.flag.flag-an {
    background-position: -175px 0;
}

.flag.flag-gs {
    background-position: -175px -75px;
}

.flag.flag-kp {
    background-position: -150px -105px;
}

.flag.flag-gg {
    background-position: -350px -60px;
}

.flag.flag-pn {
    background-position: -50px -165px;
}

.flag.flag-es {
    background-position: -375px -45px;
}

.flag.flag-ki {
    background-position: -75px -105px;
}

.flag.flag-mc {
    background-position: -175px -120px;
}

.flag.flag-sa {
    background-position: -350px -165px;
}

.flag.flag-cr {
    background-position: -375px -30px;
}

.flag.flag-ws {
    background-position: -375px -210px;
}

.flag.flag-ru {
    background-position: -300px -165px;
}

.flag.flag-pf {
    background-position: -300px -150px;
}

.flag.flag-aw {
    background-position: -325px 0;
}

.flag.flag-gb {
    background-position: -225px -60px;
}

.flag.flag-bb {
    background-position: -25px -15px;
}

.flag.flag-cv {
    background-position: -25px -45px;
}

.flag.flag-cy {
    background-position: -50px -45px;
}

.flag.flag-py {
    background-position: -175px -165px;
}

.flag.flag-et {
    background-position: 0 -60px;
}

.flag.flag-sn {
    background-position: -250px -180px;
}

.flag.flag-er {
    background-position: -350px -45px;
}

.flag.flag-ag {
    background-position: -75px 0;
}

.flag.flag-ni {
    background-position: -50px -150px;
}

.flag.flag-bv {
    background-position: 0 -30px;
}

.flag.flag-is {
    background-position: -225px -90px;
}

.flag.flag-ee {
    background-position: -275px -45px;
}

.flag.flag-dj {
    background-position: -125px -45px;
}

.flag.flag-tw {
    background-position: -375px -195px;
}

.flag.flag-au {
    background-position: -300px 0;
}

.flag.flag-my {
    background-position: -275px -135px;
}

.flag.flag-bs {
    background-position: -350px -15px;
}

.flag.flag-cl {
    background-position: -275px -30px;
}

.flag.flag-sr {
    background-position: -300px -180px;
}

.flag.flag-bo {
    background-position: -300px -15px;
}

.flag.flag-bl {
    background-position: -225px -15px;
}

.flag.flag-za {
    background-position: -50px -225px;
}

.flag.flag-cf {
    background-position: -150px -30px;
}

.flag.flag-cg {
    background-position: -175px -30px;
}

.flag.flag-it {
    background-position: -250px -90px;
}

.flag.flag-nu {
    background-position: -175px -150px;
}

.flag.flag-mz {
    background-position: -300px -135px;
}

.flag.flag-io {
    background-position: -150px -90px;
}

.flag.flag-kw {
    background-position: -200px -105px;
}

.flag.flag-vn {
    background-position: -300px -210px;
}

.flag.flag-gn {
    background-position: -75px -75px;
}

.flag.flag-cm {
    background-position: -300px -30px;
}

.flag.flag-gu {
    background-position: -225px -75px;
}

.flag.flag-tc {
    background-position: -25px -195px;
}

.flag.flag-br {
    background-position: -325px -15px;
}

.flag.flag-lc {
    background-position: -325px -105px;
}

.flag.flag-zw {
    background-position: -100px -225px;
}

.flag.flag-mr {
    background-position: -100px -135px;
}

.flag.flag-do {
    background-position: -200px -45px;
}

.flag.flag-je {
    background-position: -300px -90px;
}

.flag.flag-pe {
    background-position: -275px -150px;
}

.flag.flag-bi {
    background-position: -175px -15px;
}

.flag.flag-ar {
    background-position: -225px 0;
}

.flag.flag-sh {
    background-position: -100px -180px;
}

.flag.flag-lt {
    background-position: -50px -120px;
}

.flag.flag-ms {
    background-position: -125px -135px;
}

.flag.flag-lv {
    background-position: -100px -120px;
}

.flag.flag-sj {
    background-position: -150px -180px;
}

.flag.flag-ie {
    background-position: -75px -90px;
}

.flag.flag-fk {
    background-position: -100px -60px;
}

.flag.flag-na {
    background-position: -325px -135px;
}

.flag.flag-hm {
    background-position: -325px -75px;
}

.flag.flag-eg {
    background-position: -300px -45px;
}

.flag.flag-in {
    background-position: -125px -90px;
}

.flag.flag-ca {
    background-position: -100px -30px;
}

.flag.flag-tn {
    background-position: -250px -195px;
}

.flag.flag-ke {
    background-position: 0 -105px;
}

.flag.flag-ph {
    background-position: -350px -150px;
}

.flag.flag-nc {
    background-position: -350px -135px;
}

.flag.flag-hn {
    background-position: -350px -75px;
}

.flag.flag-ls {
    background-position: -25px -120px;
}

.flag.flag-pl {
    background-position: 0 -165px;
}

.flag.flag-jp {
    background-position: -375px -90px;
}

.flag.flag-ky {
    background-position: -225px -105px;
}

.flag.flag-qa {
    background-position: -200px -165px;
}

.flag.flag-ci {
    background-position: -225px -30px;
}

.flag.flag-gd {
    background-position: -250px -60px;
}

.flag.flag-mx {
    background-position: -250px -135px;
}

.flag.flag-mv {
    background-position: -200px -135px;
}

.flag.flag-id {
    background-position: -50px -90px;
}

.flag.flag-kh {
    background-position: -50px -105px;
}

.flag.flag-si {
    background-position: -125px -180px;
}

.flag.flag-mf {
    background-position: -250px -120px;
}

.flag.flag-gf {
    background-position: -300px -60px;
}

.flag.flag-tg {
    background-position: -100px -195px;
}

.flag.flag-bj {
    background-position: -200px -15px;
}

.flag.flag-pw {
    background-position: -150px -165px;
}

            
          
!
            
              const url ='https://raw.githubusercontent.com/DealPete/forceDirected/master/countries.json';
let data = [];
const graph = document.getElementById("graph");
let wrapperBox = document.getElementById("wrapper");
const width = 1200;
const height = 580;

fetch(url).then((resp)=> resp.json())
  .then(function(receivedData) {
      data = receivedData;
      /* data processing */
      //console.log(data);
      let nodes = data.nodes;
      let links = data.links;

      let svg = d3.select(graph)
            .attr("width",width)
            .attr("height",height);

      let linkForce = d3.forceLink().id(link => link.index).distance(40);

      let simulation = d3.forceSimulation()
              .force('link',linkForce)
              .force("charge", d3.forceManyBody().strength(-6))
              .force("center",d3.forceCenter(width/2,height/2))

      let dragDrop = d3.drag().on('start', function (node) {
            node.fx = node.x
            node.fy = node.y
          }).on('drag', function (node) {
            simulation.alphaTarget(0.7).restart()
            node.fx = d3.event.x
            node.fy = d3.event.y
          }).on('end', function (node) {
            if (!d3.event.active) {
              simulation.alphaTarget(0)
            }
            node.fx = null
            node.fy = null
          });

/* signature */
        svg.append('text').text('created by Sebastian Sporek')
              .attr('x', 20)
              .attr('y', 35)
              .attr("class", "sign");
        svg.append('text').text("National Contiguity")
              .attr("class", "title")
              .attr('x', 10)
              .attr('y',20)
              .attr('fill', 'black');

/* drawing */
      const flags = d3.select(wrapperBox)
            .selectAll('div')
            .data(nodes)
            .enter().append('div')
            .call(dragDrop);

      const nodeElements = svg.append('g')
            .selectAll('circle')
            .data(nodes)
            .enter().append('circle')
            .attr('r',5)
            .attr('fill','red')
            .call(dragDrop);

       const textElements = svg.append('g')
        .selectAll('text')
        .data(nodes)
        .enter().append('text')
          .text(node => node.code)
          .attr('font-size', 15)
          .attr('dx', 15)
          .attr('dy', 4);

       const linkElements = svg.append('g')
              .attr('class','link')
              .selectAll('line')
              .data(links)
              .enter().append('line')
              .attr('stroke-width',1)
              .attr('stroke','black');

        let radius = 20;
          simulation.nodes(nodes).on('tick', () => {
          nodeElements
              //.attr('cx', node => node.x)
              //.attr('cy', node => node.y)
              .attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); })
              .attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); });
            textElements
              .attr('x', node => node.x)
              .attr('y', node => node.y)
            linkElements
              .attr('x1', link => link.source.x)
              .attr('y1', link => link.source.y)
              .attr('x2', link => link.target.x)
              .attr('y2', link => link.target.y)
            flags
            .attr('style', function(d) {
              return " left:" + Math.round(Math.max(radius, Math.min(width - radius, d.x))-13) +
              "px;top: " + Math.round(Math.max(radius, Math.min(height - radius, d.y))-8) +
              "px;"; })
             .attr('class', function(d){ return "flag flag-" + d.code; })
             .attr("id", function(d){ return data.nodes.indexOf(d)+1;})
          })
          simulation.force('link').links(links);

/* tooltip */
      let tooltip = document.createElement("div");
      tooltip.classList.add('tooltip');
      tooltip.setAttribute("id", "tooltip");
      tooltip.style.display="none";
      wrapperBox.appendChild(tooltip);
      wrapperBox.addEventListener("mouseover", function(event){
        let ev = parseInt(event.target.id)-1;
        if (!isNaN(ev)) {
          //console.log(event);
          let top = event.pageY-10;
          let left = event.pageX+30;
          tooltip.innerHTML =( data.nodes[ev].country );
          tooltip.style.top = top.toString()+"px";
          tooltip.style.left = left.toString()+"px";
          tooltip.style.zIndex= "2";
          tooltip.style.display="block";
        } else {
          tooltip.style.zIndex= "-2";
          tooltip.style.display="none";
        }
      }, false);
})
  .catch(function(error){
    console.log(error);
  });

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.

Console