官术网_书友最值得收藏!

Drawing shapes with D3

D3 is a great library to create web visualizations because it includes a lot of useful abstractions when working with SVG elements. In this section, we will look at some of these SVG abstractions to draw shapes. These abstractions for drawing shapes are called generators in D3; we will mainly use the line-, area-, and arc-generators when creating visualizations.

Note

All SVG shape abstractions can be found in the D3 Github page at https://github.com/mbostock/d3/wiki/API-Reference#d3svg-svg.

Drawing Lines and Curves

If you've ever used the SVG path element and the d attribute to create custom shapes or Bézier curves, you already know that this is not as easy as it should be. Those who have never used the SVG path element only need to know that you would have to learn a special syntax to define and concatenate control points for a Bézier curve.

Note

You can find more information about the d attribute on MDN at https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d.

Thankfully, D3 provides a great abstraction to draw lines. Let's take a look at a simple example. First, let's create a dataset containing the x and y coordinates of some points:

var data = [
  [100, 100], [200, 350], [300, 50],
  [400, 200], [500, 250], [600, 40], [700, 100]
];

Now, we want to create a line generator that returns the first element of a data point as the x coordinate and the second value of the data point as the y coordinate:

var line = d3.svg.line()
  .x(function(d, i) { return d[0]; })
  .y(function(d, i) { return d[1]; });

Perfect! This is already our line generator. The advantage is that we only have to define the structure of the line generator, that is, where in the dataset it can find the x and y coordinates, and we can then draw any dataset that follows the same structure. Let's draw the line; we need to use the selection.datum() method to bind one specific datum to the selection. In contrary to the previously discussed data joins, this function will not compute a join but only returns a selection. Then, we can apply the line generator to the d attribute of the path, which will implicitly look for the bound data and creates the proper d string:

$svg.datum(data)
  .append("path")
  .attr("d", line);

The following figure shows a result of this example in the web browser:

Output of a simple line generator

In the previous example, you learned how to create a simple line generator that only connects the points of the dataset together. We can now easily define an interpolation method on the line generator in order to draw a smooth line:

var line = d3.svg.line()
  .x(function(d, i) { return d[0]; })
  .y(function(d, i) { return d[1]; })
  .interpolate('cardinal');

In the preceding example, we used the cardinal interpolation, which is a similar interpolation technique used in Bézier curves. If we look at the resulting line in the following figure, we see that the lines between the data points are now interpolated:

Output of an interpolated line

The smoothness of the interpolation can be controlled by the .tension(value) function. In the following figure, we can see the difference between tension 1, which is the edgy inner line, to tension 0.5, which is the smooth outer line:

Line with different tension values

Drawing Areas between curves

Similar to the line generator, D3 also provides an area generator that allows us to use 2 y coordinates: y0 and y1. Let's first create a dataset where the first element of the data point contains the x value, the second element the first y coordinate, and the third element the second y coordinate:

var data = [
  [100, 100, 100], [200, 350, 200], [300, 50, 50],
  [400, 200, 350], [500, 250, 375], [600, 40, 100], [700, 100, 100]
];

Now, we can create an area generator similar to the previous example:

var area = d3.svg.area()
  .x(function(d, i) { return d[0]; })
  .y0(function(d, i) { return d[1]; })
  .y1(function(d, i) { return d[2]; })
  .interpolate('cardinal');

Finally, we apply the area generator to the d attribute of the path element:

$svg.datum(data)
  .append("path")
  .attr("d", area);

The following figure shows the result of the created area path:

Output of an area generator

Drawing arcs

The third complex shape that is often used in visualizations is an arc. D3 also provides a generator function for this to easily draw arcs with polar coordinates. Again, if you have ever dealt with arcs in SVG, you will probably be very glad to know this generator.

Let's create an arc generator:

var arc = d3.svg.arc()
  .innerRadius(40)
  .outerRadius(100)
  .startAngle(0)
  .endAngle(Math.PI);

In the preceding code, we see that we can define inner and outer radius as well as the start and ending angles of the arc in radiant. Similarly to the previous example, we can now generate the d attribute for a path element:

$svg.append("path")
  .attr("d", arc)
  .attr("transform", "translate(200, 200)");

In the previous example, we observe that we need to translate the arc a little bit in order to make it visible. The output of the example in the web browser is displayed in the following figure:

Output of an arc generator

D3 provides more useful methods on the generator functions, for example, the arc.centroid() method. This function returns the center of the arc shape and suits perfectly to display labels with an arc.

主站蜘蛛池模板: 读书| 临颍县| 郴州市| 高邮市| 巴塘县| 元阳县| 甘孜| 青铜峡市| 景德镇市| 柘荣县| 广德县| 宣恩县| 华阴市| 旅游| 乐亭县| 绩溪县| 汉沽区| 安国市| 黄龙县| 渑池县| 江达县| 衡山县| 汪清县| 沙湾县| 贡嘎县| 枣阳市| 荣成市| 怀来县| 临澧县| 深州市| 张家界市| 黔南| 长乐市| 鄯善县| 苏州市| 湖州市| 芒康县| 赤峰市| 罗甸县| 房山区| 平谷区|