简体   繁体   中英

How to draw a simple directed graph

I can draw a simple directed force graph like this:

<html>
<head>
    <meta charset='utf-8'>
    <title>Force Layout Example 1</title>
    <style>

.node {
    fill: #ccc;
    stroke: #fff;
    stroke-width: 2px;
}

.link {
    stroke: #777;
    stroke-width: 2px;
}

    </style>
</head>
<body>
    <script src='http://d3js.org/d3.v3.min.js'></script>
    <script>

var width = 640,
    height = 480;
    constant = 174

var nodes = [
    { x:   constant, y: 215 , width:50,height:50  },
    { x: 2*constant, y: 215 ,width:50,height:50 },
    { x: 3*constant, y: 215 ,width:50,height:50 },
    { x: 4*constant, y: 215 ,width:50,height:50 }
];


var links = [
    { source: 0, target: 1 }
];

var svg = d3.select('body').append('svg')
    .attr('width', width)
    .attr('height', height);


var force = d3.layout.force()
    .size([width, height])
    .nodes(nodes)
    .links(links);


force.linkDistance(width/2);


var link = svg.selectAll('.link')
    .data(links)
    .enter().append('line')
    .attr('class', 'link');


var node = svg.selectAll('.node')
    .data(nodes)
    .enter().append('rect')
    .attr('class', 'node');

force.on('end', function() {

    node.attr('x', function(d) { return d.x; })
        .attr('y', function(d) { return 215; })
        .attr('width', function(d) { return d.width; })
        .attr('height', function(d) { return d.height; });

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

});


force.start();

    </script>
</body>
</html>

which gives me output like:

在此处输入图像描述

I want to achieve this:

在此处输入图像描述

I'm not sure how I can change the above code to add the text inside the rectangle. I also want the rectangle to be rounded!

I tried the following for the text piece:

node.append('text').text('A')
    .attr('x', 174)
    .attr('y', 250)
    .attr('fill', 'black')

However, that doesn't work. I'm not sure how to achieve that. Any clue?

Thanks in advance.

The actual code for inserting text in that style would be as follows:

node.append("text").style("text-anchor", "middle")
    .style("pointer-events", "none")
    .style("font-weight", 900)
    .attr("fill", "white")
    .style("stroke-width", "0.3px")
    .style("font-size", "16px")
    .attr("y", function (d){return d.height/2+6;})
    .attr("x", function (d){return d.width/2;})
    .text(function (d) {return d.label;});

Here is a Fiddle that is very similar to your image. Some notable changes:

  • Nodes have an additional field of 'label' (A,B,C,D). Could also use an integer->char to automatically assign this using the index of the node.
  • Added all the necessary links
  • 'Node' variable now contains g (group) elements which then have the rect AND text added. These elements are then translated according to the node.x and node.y fields, which moves both text and rect at once.
  • Stylized rectangles. Rounded using rx and ry , and coloured using .style("fill", "#2376B2") .

Hope this helps!

I've made a free and lightweight library that may be useful to others:

Arg-Graph is a simple free library for creating directed SVG graphs or diagram using JQuery. 有向图

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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