[英]creating new force graph with react+ts and d3
I am trying to create a simple force graph with React + TS and D3.我正在尝试使用 React + TS 和 D3 创建一个简单的力图。
Main issue Connect my nodes with a line主要问题用线连接我的节点
Here is my code:这是我的代码:
import React from "react";
import { forceSimulation, forceManyBody, forceLink, forceCenter } from 'd3-force'
import d3 ,{ SimulationNodeDatum } from "d3";
import { Box } from "@mui/system";
type Node = {
id: string;
class: string;
x?: string;
y?: string;
}
type Link = {
source: string;
target: string;
connectionType: string;
}
The data (in the same file):数据(在同一个文件中):
const { links, nodes } = {
nodes: [{
id: "honda",
class: "cars",
}, {
id: "civic",
class: "cars",
},{
id: "toyota",
class: "cars",
},{
id: "corola",
class: "cars",
}],
links: [{
source: 'civic',
target: 'honda',
connectionType: 'm2o'
},{
source: 'corola',
target: 'toyota',
connectionType: 'm2o'
}]
}
... and here's the component: ...这是组件:
function Rd4Component (): JSX.Element {
const simulation = forceSimulation(nodes as SimulationNodeDatum[]);
simulation
.force('charge', forceManyBody().strength(-100))
.force('link',
forceLink(links)
.id((d) => (d as Node).id)
.distance(75)
)
.force("center", forceCenter(300, 300));
const svg = d3.select('#Target');
const node = svg
.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r", 15)
.attr("stroke", "green")
.attr("stroke-width", 0.5)
.style("fill", "red");
const link = svg
.selectAll('path.link')
.data(links)
.enter()
.append("path")
.attr("stroke", "black")
.style("fill", "none");
function ticked() {
link
.attr("x1", function (d: any) {
return d.source.x;
})
.attr("y1", function (d: any) {
return d.source.y;
})
.attr("x2", function (d: any) {
return d.target.x;
})
.attr("y2", function (d: any) {
return d.target.y;
});
node
.attr("cx", function (d: any) {
return d.x;
})
.attr("cy", function (d: any) {
return d.y;
});
// label
// .attr("x", function (d: any) {
// return d.x + 5;
// })
// .attr("y", function (d: any) {
// return d.y + 5;
// });
}
simulation.nodes(nodes as SimulationNodeDatum[])
.on("tick", ticked)
return <Box sx={{overflowY: "scroll"}}>
<svg height={600} width={600} id="Target" />
</Box>
}
export default Rd4Component;
Here are the results:结果如下:
Replace path
with line
(or specify a d
attribute for <path>
instead of x1
, x2
, y1
, y1
used for a <line>
)用line
替换path
(或为<path>
指定d
属性,而不是为<line>
指定x1
、 x2
、 y1
、 y1
)
const { links, nodes } = { nodes: [{ id: "honda", class: "cars", }, { id: "civic", class: "cars", },{ id: "toyota", class: "cars", },{ id: "corola", class: "cars", }], links: [{ source: 'civic', target: 'honda', connectionType: 'm2o' },{ source: 'corola', target: 'toyota', connectionType: 'm2o' }] } const simulation = d3.forceSimulation(nodes); simulation.force('charge', d3.forceManyBody().strength(-50)).force('link', d3.forceLink(links).id((d) => d.id).distance(50) ).force("center", d3.forceCenter(100, 100)); const svg = d3.select('svg'); const link = svg.selectAll('line.link').data(links).enter().append("line").attr("stroke", "black").style("fill", "none"); const node = svg.selectAll("circle").data(nodes).enter().append("circle").attr("r", 15).attr("stroke", "green").attr("stroke-width", 0.5).style("fill", "red"); 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.attr("cx", function (d) { return dx; }).attr("cy", function (d) { return dy; }); // label //.attr("x", function (d: any) { // return dx + 5; // }) //.attr("y", function (d: any) { // return dy + 5; // }); } simulation.nodes(nodes).on("tick", ticked)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <svg width="200" height="200"> </svg>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.