将networkx DiGraph打印为嵌套JSON格式

t5fffqht  于 2023-02-17  发布在  其他
关注(0)|答案(2)|浏览(213)

我有一个networkx双图。

>> G = nx.DiGraph()
>> G.add_edges_from(product([0],[1,2])) # product is itertools.product 
>> G.add_edges_from(product([1],[3,4]))

图表内部如下所示:

>> G.adj  
 {0: {1: {}, 2: {}},  
  1: {3: {}, 4: {}},  
  2: {},  
  3: {},  
  4: {}}

我希望这是一个json格式打印如下:

{   
    name: 0,
    children: [ 
        {
            name: 1,
            children: [
                {
                    name: 3,
                    children: [] 
                }, 
                {
                    name: 4,
                    children: []
                }
                ]
        }, 
        {
            name: 2,
            children:[]
        }
    ]
}

(The原因是,我试图用D3可视化所采用的格式来编写它。https://gist.github.com/mbostock/4063550
我不知道该怎么做。任何帮助都非常感谢。
谢谢。

a64a0gku

a64a0gku1#

可以使用json_graph.tree_data()以嵌套格式输出数据。
从文档中

from networkx.readwrite import json_graph
import networkx as nx
import json
G = nx.DiGraph([(1,2)])
data = json_graph.tree_data(G,root=1)
s = json.dumps(data)

得到{"id": 1, "children": [{"id": 2}]}

klh5stk1

klh5stk12#

`// Set up the D3.js canvas and force layout
const svg = d3.select("svg");
const width = +svg.attr("width");
const height = +svg.attr("height");
const simulation = d3.forceSimulation()
  .force("link", d3.forceLink().id(d => d.id))
  .force("charge", d3.forceManyBody())
  .force("center", d3.forceCenter(width / 2, height / 2));

// Load the data for the graph (empty initially)
let nodes = [];
let links = [];

// Define the drag behavior for the nodes
const drag = d3.drag()
  .on("start", dragStart)
  .on("drag", dragging)
  .on("end", dragEnd);

function dragStart(event, d) {
  if (!event.active) simulation.alphaTarget(0.3).restart();
  d.fx = d.x;
  d.fy = d.y;
}

function dragging(event, d) {
  d.fx = event.x;
  d.fy = event.y;
}

function dragEnd(event, d) {
  if (!event.active) simulation.alphaTarget(0);
  d.fx = null;
  d.fy = null;
}

// Define the update function for the graph
function update() {
  // Create the link and node elements
  const link = svg.selectAll(".link")
    .data(links)
    .join("line")
      .attr("class", "link");
  const node = svg.selectAll(".node")
    .data(nodes)
    .join("circle")
      .attr("class", "node")
      .attr("r", 10)
      .call(drag);

  // Update the positions of the link and node elements
  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);
  node.attr("cx", d => d.x)
      .attr("cy", d => d.y);

  // Update the simulation with the new node and link data
  simulation.nodes(nodes).on("tick", ticked);
  simulation.force("link").links(links);

  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);
    node.attr("cx", d => d.x)
        .attr("cy", d => d.y);
  }
}

// Call the update function initially to render the empty graph
update();

// Define the event listener for adding new nodes
svg.on("click", event => {
  // Add a new node with a unique ID
  const newNode = {id: nodes.length.toString()};
  nodes.push(newNode);

  // Add a new link to any existing node
  if (nodes.length > 1) {
    const source = nodes[nodes.length - 2];
    const target = newNode;
    const newLink = {source, target};
    links.push(newLink);
  }

  // Update the graph display
  update();
});
`

相关问题