score:1

Accepted answer

Shorten the following code

// const nodeByID = d3.map();
// commanders.nodes.forEach(commander => {
//   nodeByID.set(commander.id, commander);
// });
// links.forEach(link => {
//   link.source = nodeByID.get(link.primary);
//   link.target = nodeByID.get(link.secondary);
// });

links = links.map(d => ({source:d.primary, target:d.secondary, value:d.value}));

And set the link objects to the objects not the d3 selection

simulation.force('link').links(links);

Then you need to play with the link distance and strength accessors.

svg {
  display: block;
  margin: auto;
}

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

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

text {
  font-family: sans-serif;
  font-size: 14px;
  font-weight: bold;
}

.primary {
  color: #af0000;
}

.secondary {
  color: #00a700;
}

div.tooltip {
  position: absolute;
  top: 10px;
  right: 10px;
  background-color: white;
  max-width: 200px;
  height: auto;
  padding: 10px;
  border-style: solid;
  border-radius: 2px;
  border-width: 1px;
  box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.5);
}

div.tooltip .Legendary {
  color: #ff9b00;
}

div.tooltip .Epic {
  color: #ac41c2;
}

div.tooltip .Elite {
  color: #058cc3;
}

div.tooltip .Advanced {
  color: #2d9830;
}

div.tooltip table {
  border: 1px solid black;
  border-collapse: collapse;
}

div.tooltip table td {
  padding: 5px;
}
<svg width="960" height="700"></svg>

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

<script>
  const svg = d3.select('svg'),
    width = +svg.attr('width'),
    height = +svg.attr('height');

  const color = d3
    .scaleOrdinal()
    .domain(['Legendary', 'Epic', 'Elite', 'Advanced'])
    .range(['#ff9b00', '#ac41c2', '#058cc3', '#2d9830']);

  const simulation = d3
    .forceSimulation()
    .force('link', d3.forceLink().id(d => d.id))
    .force(
      'charge',
      d3
      .forceManyBody()
      .strength(-20)
      .distanceMax([500])
    )
    .force('center', d3.forceCenter(width / 2, height / 2));

  d3.queue()
    .defer(d3.json, 'https://gist.githubusercontent.com/sho-87/bfe4d69be60454dccfd859b004262381/raw/ac259b468ae6f1140d5c10596f1663c743535b5a/commanders.json')
    .defer(d3.csv, 'https://gist.githubusercontent.com/sho-87/89aa3c48baffc9c388bb98e613b9a5f4/raw/896e24a0187d555d395840d7def3b36b8fb28074/links.csv')
    .await(function(error, commanders, links) {

// const nodeByID = d3.map();
    // commanders.nodes.forEach(commander => {
    //   nodeByID.set(commander.id, commander);
    // });
    // links.forEach(link => {
    //   link.source = nodeByID.get(link.primary);
    //   link.target = nodeByID.get(link.secondary);
    // });

    links = links.map(d => ({source:d.primary, target:d.secondary, value:d.value}));

      const link = svg
        .append('g')
        .attr('class', 'links')
        .selectAll('line')
        .data(links)
        .enter()
        .append('line')
        .attr('stroke-width', d => Math.sqrt(d.value * 1));

      const node = svg
        .selectAll('.node')
        .data(commanders.nodes)
        .enter()
        .append('g')
        .attr('class', 'nodes')
        .call(
          d3
          .drag()
          .on('start', dragstarted)
          .on('drag', dragged)
          .on('end', dragended)
        )
        .append('circle')
        .attr('r', 8)
        .attr('fill', d => color(d.group))

      simulation.nodes(commanders.nodes).on('tick', ticked);
      simulation.force('link').links(links);

      function ticked() {
        link
          .attr('x1', d => d.source.x)
          .attr('y1', d => d.source.y)
          .attr('x2', d => d.target.x)
          .attr('y2', d => d.target.y);

        node.attr('transform', d => `translate(${d.x},${d.y})`);
      }
    });

  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;
  }
</script>


Related Query

More Query from same tag