简体   繁体   English

使用 react+ts 和 d3 创建新的力图

[英]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>指定x1x2y1y1

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM