在D3.js中绘制一个三角形网络

时间:2017-05-03 18:52:10

标签: javascript html css d3.js

嗨伙计们, 我正在尝试在d3.js中绘制一个三角形网络(完整的图形K-3),但它不起作用。这是我在网上找到的代码我对节点列表进行了更改,所以我可以在这里绘制一个等边三角形结果:

result

// Define the dimensions of the visualization. We're using
// a size that's convenient for displaying the graphic on
// http://jsDataV.is

var width = document.getElementById('canvas').offsetWidth,
  height = document.getElementById('canvas').offsetHeight;

// Define the data for the example. In general, a force layout
// requires two data arrays. The first array, here named `nodes`,
// contains the object that are the focal point of the visualization.
// The second array, called `links` below, identifies all the links
// between the nodes. (The more mathematical term is "edges.")

// For the simplest possible example we only define two nodes. As
// far as D3 is concerned, nodes are arbitrary objects. Normally the
// objects wouldn't be initialized with `x` and `y` properties like
// we're doing below. When those properties are present, they tell
// D3 where to place the nodes before the force layout starts its
// magic. More typically, they're left out of the nodes and D3 picks
// random locations for each node. We're defining them here so we can
// get a consistent application of the layout which lets us see the
// effects of different properties.

var nodes = [{
    x: 20,
    y: 20
  },
  {
    x: (width - 20),
    y: 20
  },
  {
    x: (width - 40) / 2,
    y: width - 40
  }
];

// The `links` array contains objects with a `source` and a `target`
// property. The values of those properties are the indices in
// the `nodes` array of the two endpoints of the link.

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

// Here's were the code begins. We start off by creating an SVG
// container to hold the visualization. We only need to specify
// the dimensions for this container.

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

// Now we create a force layout object and define its properties.
// Those include the dimensions of the visualization and the arrays
// of nodes and links.

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

// There's one more property of the layout we need to define,
// its `linkDistance`. That's generally a configurable value and,
// for a first example, we'd normally leave it at its default.
// Unfortunately, the default value results in a visualization
// that's not especially clear. This parameter defines the
// distance (normally in pixels) that we'd like to have between
// nodes that are connected. (It is, thus, the length we'd
// like our links to have.)

force.linkDistance(width - 40);

// Next we'll add the nodes and links to the visualization.
// Note that we're just sticking them into the SVG container
// at this point. We start with the links. The order here is
// important because we want the nodes to appear "on top of"
// the links. SVG doesn't really have a convenient equivalent
// to HTML's `z-index`; instead it relies on the order of the
// elements in the markup. By adding the nodes _after_ the
// links we ensure that nodes appear on top of links.

// Links are pretty simple. They're just SVG lines, and
// we're not even going to specify their coordinates. (We'll
// let the force layout take care of that.) Without any
// coordinates, the lines won't even be visible, but the
// markup will be sitting inside the SVG container ready
// and waiting for the force layout.

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

// Now it's the nodes turn. Each node is drawn as a circle.

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

// We're about to tell the force layout to start its
// calculations. We do, however, want to know when those
// calculations are complete, so before we kick things off
// we'll define a function that we want the layout to call
// once the calculations are done.

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

  // When this function executes, the force layout
  // calculations have concluded. The layout will
  // have set various properties in our nodes and
  // links objects that we can use to position them
  // within the SVG container.

  // First let's reposition the nodes. As the force
  // layout runs it updates the `x` and `y` properties
  // that define where the node should be centered.
  // To move the node, we set the appropriate SVG
  // attributes to their new values. We also have to
  // give the node a non-zero radius so that it's visible
  // in the container.

  node.attr('r', width / 25)
    .attr('cx', function(d) {
      return d.x;
    })
    .attr('cy', function(d) {
      return d.y;
    });

  // We also need to update positions of the links.
  // For those elements, the force layout sets the
  // `source` and `target` properties, specifying
  // `x` and `y` values in each case.

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

});

// Okay, everything is set up now so it's time to turn
// things over to the force layout. Here we go.

force.start();

// By the time you've read this far in the code, the force
// layout has undoubtedly finished its work. Unless something
// went horribly wrong, you should see two light grey circles
// connected by a single dark grey line. If you have a screen
// ruler (such as [xScope](http://xscopeapp.com) handy, measure
// the distance between the centers of the two circles. It
// should be somewhere close to the `linkDistance` parameter we
// set way up in the beginning (480 pixels). That, in the most
// basic of all nutshells, is what a force layout does. We
// tell it how far apart we want connected nodes to be, and
// the layout keeps moving the nodes around until they get
// reasonably close to that value.

// Of course, there's quite a bit more than that going on
// under the hood. We'll take a closer look starting with
// the next example.
#canvas {
  width: 400px;
  height: 350px;
  background: aquamarine;
}

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

.link {
  stroke: #777;
  stroke-width: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>


<div id="canvas"></div>

0 个答案:

没有答案