[D3] Drawing path in D3


Here we have a force layout with three nodes.

In the example, we will link three nodes with line and path:

import React, {Component} from 'react';
import * as d3  from 'd3';

const nodesData = [
    {name: 'Alice', id: 0},
    {name: 'Eve', id: 1},
    {name: 'Bob', id: 2}
];

const linksData = [
    {source: 0, target: 1},
    {source: 1, target: 2},
    {source: 2, target: 0}
];

export default class SimpleExample extends Component {

    componentDidMount() {

        const {width, height} = this.props;
        // Create svg inside container
        const svg = d3.select(this.refs.mountSvg)
            .append('svg')
            .attr('width', width)
            .attr('height', height);
        // Create Force layout
        const simulation = d3.forceSimulation()
            .force("link", d3.forceLink().id(function (d) {
                return d.id;
            }))
            .force("charge", d3.forceManyBody())
            .force("center", d3.forceCenter(width / 2, height / 2));



        // Create node
        const nodes = svg
            .append('g')
            .attr('class', 'nodes')
            .selectAll('circle')
            .data(nodesData)
            .enter().append('circle')
            .attr('r', width * 0.05)
            .attr('fill', '#c3c3c3')
            .call(d3.drag()
                .on('start', dragstarted)
                .on('drag', dragged)
                .on('end', dragended));
        simulation
            .nodes(nodesData)
            .on('tick', ticked);

        // Create link
        const link = svg
            .append('g')
            .attr('class', 'links')
            .selectAll('line')
            .data(linksData)
            .enter().append('line')
            .attr('stroke', '#c2c2c2')
            .attr('stroke-width', d => Math.sqrt(d.value));

        const path = svg
            .append('g')
            .selectAll('path')
            .data(linksData)
            .enter().append('path')
            .attr('fill', 'none')
            .attr('stroke', '#777')
            .attr('stroke-width', '2px')
            .attr('class', 'link');

        simulation
            .force('link')
            .distance(height / 2)
            .links(linksData);

        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);
            nodes
                .attr('cx',(d, i)=> d.x)
                .attr('cy',(d, i)=> d.y);

            path
                .attr('d', (d, i) => {
                    const dx = d.target.x - d.source.x;
                    const dy = d.target.y - d.source.y;
                    const dr = Math.sqrt(dx * dx + dy * dy);
                    return `M${d.source.x},${d.source.y}A${dr},${dr} 0 0,1 ${d.target.x},${d.target.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;
        }
    }

    render() {
        const {width, height} = this.props;
        const style = {
            width,
            height,
            border: '1px solid black',
            margin: '10px auto'
        };
        return (
            <div style={style} ref="mountSvg"></div>
        );
    }
}

优质内容筛选与推荐>>
1、Python的学习之旅———函数对象、函数嵌套、名称空间与作用域、装饰器
2、我的博客园开通
3、Microsoft Visual Studio 2010 破解教程
4、[Javascript] Iterate Over Items with JavaScript's for-of Loop
5、用VSCode写python的正确姿势(转载)


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号