如何在D3力布局图中将图像作为节点附加?

时间:2017-08-10 18:57:59

标签: d3.js svg

所以我正在研究freecodecamp的D3力布局挑战:https://www.freecodecamp.com/challenges/show-national-contiguity-with-a-force-directed-graph

作为挑战的一部分,我正试图将旗帜图像作为力布局中的节点附加。

我设法附加旗帜,他们正在展示。单击并拖动它们时,链接也会移动。问题是他们陷入了同样的境地。

这就是我的意思:

enter image description here

javascript(它是在React中制作的):

createForceGraph() {
    const { nodes, links } = this.state;
    console.log(nodes);
    console.log(links);

    const w = 800;
    const h = 500;

    const margin = {
      top: 30,
      right: 30,
      bottom: 80,
      left: 80
    };

    const svg = d3.select('.chart')
                  .append('svg')
                  .attr('width', w)
                  .attr('height', h);

    const simulation = d3.forceSimulation()
                         .force('link', d3.forceLink().id(function(d, i) { return i }).distance(1))
                         .force('charge', d3.forceManyBody().strength(1))
                         .force('center', d3.forceCenter(w / 2, h / 2))
                         .force('collision', d3.forceCollide(12));

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

    const node = d3.select('.nodes')
                    .selectAll('img')
                    .data(nodes)
                    .enter()
                    .append('img')
                    .attr('class', d => {
                      return `flag flag-${d.code}`;
                    })
                    .call(d3.drag()
                            .on('start', dragstarted)
                            .on('drag', dragged)
                            .on('end', dragended));

    simulation.nodes(nodes)
              .on('tick', ticked);

    simulation.force('link')
              .links(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
           .style("left", function(d) { return d.x + 'px'; })
           .style("top", function(d) { return d.y + 'px'; });
    }


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

HTML:

<div>D3 Force-Directed Layout
    <div className='chart'>
      <div className='nodes'></div>
    </div>
  </div>

1 个答案:

答案 0 :(得分:-1)

也许这可以帮助您解决问题?

https://bl.ocks.org/mbostock/950642