• [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>
            );
        }
    }

  • 相关阅读:
    luogu P3804 【模板】后缀自动机 (SAM)
    莫队
    luogu P4688 [Ynoi2016]掉进兔子洞
    FZOJ 2331 LYK loves graph
    字典树
    luogu P6623 [省选联考 2020 A 卷] 树
    luogu P6018 [Ynoi2010]Fusion tree
    luogu P3264 [JLOI2015]管道连接
    最小斯坦纳树
    9. 回文数
  • 原文地址:https://www.cnblogs.com/Answer1215/p/7451185.html
Copyright © 2020-2023  润新知