[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> ); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2016-08-30 [Redux + Webpack] Hot reloading Redux Reducers with Webpack