Search code examples
javascriptreactjsd3.jsd3-force-directed

React.js and D3, adding arrows to forced directed graphs


I was closely following an approach to combining D3 with React given here.

By this pattern structuring and rendering is done by React and calculations are handled by d3.

var links = _.map(this.props.links, (link) => {
  return (
    <line className='link' key={link.key} strokeWidth={link.size}
      x1={link.source.x} x2={link.target.x} y1={link.source.y} y2={link.target.y} />
  );
});

This code segment is used to draw edges (links) between two nodes. I'm new to d3 so I was wondering how to add an arrow indicating source->target relationship between two nodes? That arrow should be next to a destination node.


Solution

  • Using http://bl.ocks.org/fancellu/2c782394602a93921faff74e594d1bb1 as an example

    render() {
        // use React to draw all the nodes, d3 calculates the x and y
        var nodes = _.map(this.props.nodes, (node) => {
          var transform = 'translate(' + node.x + ',' + node.y + ')';
          return (
            <g className='node' key={node.key} transform={transform}>
              <circle r={node.size} />
              <text x={node.size + 5} dy='.35em'>{node.key}</text>
            </g>
          );
        });
        var links = _.map(this.props.links, (link) => {
          return (
            <line className='link' marker-end="url(#arrowhead)" key={link.key} strokeWidth={link.size}
              x1={link.source.x} x2={link.target.x} y1={link.source.y} y2={link.target.y} />
          );
        });
    
        return (
          <svg width={width} height={height}>
            <defs>
              <marker id="arrowhead" viewBox="-0 -5 10 10" refX="13" refY="0" orient="auto" markerWidth="13" markerHeight="13" xoverflow="visible">
                <path d="M 0,-5 L 10 ,0 L 0,5" fill="#999" style="stroke: none;"></path>
              </marker>
            </defs>
            <g>
              {links}
              {nodes}
            </g>
          </svg>
        );
      }