• No results found

Create a Stage for the Visualization

In document Custom Visualizations with D3.js (Page 32-34)

Creating a Unique Visualization

Step 3: Create a Stage for the Visualization

As with our other D3.js examples, we start by creating an <svg> container for the visualization. Within that container, we’ll also add a group (<g>) element.

var width = 640, height = 400,

u maxRadius = Math.min(width, height) / 2;

var svg = d3.select("#chart").append("svg") .attr("width", width)

.attr("height", height);

var g = svg.append("g");

v .attr("transform", "translate(" + (width / 2) + "," +

(height / 2) + ")");

This code contains a couple of new wrinkles. First, at u, we calculate the maximum radius for the visualization. This value—which is half of the height or the width, whichever is smaller—will come in handy in the code that follows. More interestingly, starting at v, we translate the inner <g> container so that its coordi- nate system places the point (0,0) right in the center of the visualization. This trans- lation makes it easy to center the sunburst and calculate sunburst parameters.

Step 4: Create Scales

When it’s complete, our visualization will consist of areas corresponding to regions in the United States; larger areas will represent regions with more tornadoes. Because we’re dealing with areas, we’ll need two dimensions for each region. But we’re not going to draw our areas as simple rectangles; instead we’re going to use arcs. That will require a bit of trigonometry, but fortunately, D3.js provides a lot of help. We’ll start by defining some scale objects. We first saw scales in Step 4 of “Adapting a Traditional Chart Type” on page 227, where we used them to translate data values to SVG coordinates. The scales in the following code do much the same, except they’re using polar coordinates.

var theta = d3.scale.linear() .range([0, 2 * Math.PI]);

var radius= d3.scale.sqrt() .range([0, maxRadius]);

As you can see, the angular scale is a linear scale that ranges from 0 to 2π (or 360°). The radial scale ranges from 0 to the maximum radius, but it’s not linear. Instead, this scale is a square root scale; D3.js takes the square root of the input before computing the output. The area of an arc varies as the square of its radius, and the square root scale compensates for this effect.

QNote: In prior examples, we’ve set both ranges (outputs) and domains (inputs) for our scales. In this case, however, we won’t need to set domains explicitly. The default domain of [0,1] is exactly what we need for both scales.

The scales we’ve defined come in handy in the next bit of code, where we define a function that calculates the SVG path for a single arc. Most of the work takes place in the D3.js function d3.svg.arc(), which computes an arc’s path. That function, though, needs four parameters: the starting and ending angles and the starting and ending radii for the arc. The values for those parameters come from our scales.

When we use our arc() function later in the code, we’re going to call it with a D3.js selection. That selection will have a data value associated with it, and the data value will include four properties:

.x the starting x–position for the data

.dx the data’s length along the x–axis (∆x)

.y the starting y–position for the data

.dx the data’s length along the y–axis (∆y)

Given those properties, here’s the code that generates the arc path.

var arc = d3.svg.arc() .startAngle(function(d) {

return Math.max(0, Math.min(2 * Math.PI, theta(d.x))); })

.endAngle(function(d) {

return Math.max(0, Math.min(2 * Math.PI, theta(d.x + d.dx))); })

.innerRadius(function(d) {

return Math.max(0, radius(d.y)); })

.outerRadius(function(d) {

return Math.max(0, radius(d.y + d.dy)); });

The code itself is pretty straightforward, but a picture helps explain why we’re using the code this way. Assume that the data associated with a selection has an (x,y) position of (12.5,10), a width of 25, and a height of 30. The data proper- ties would then be:

> .x = 12.5 > .dx = 25 > .y = 10 > .dy = 30

With Cartesian coordinates, we could draw the selection as on the left side of Figure 7-12. Our scales and arc function will transform the rectangle to the arc shown on the right side of the figure.

dy=30 dx=25 x=12.5 y=10 start=45° end=135° inner=79 outer=158

Cartesian coordinates Polar coordinates

Figure 7-12: D3.js helps transform a rectangular area into an arc.

We haven’t specified the ranges of the x- and y-scales, but assume for now that each ranges from 0 to 100. The starting x-value of 12.5, therefore, is 12.5 per- cent of the full range. When we convert that value to polar coordinates, the result will be 12.5 percent of the full 360°. That’s 45°, or π/4. The x-value extends another 25 percent, so the final x-value adds another 90°, or π/2, to the starting value. For the y-values, our scales take the square root and map the results to the domain from 0 to 250 (maxRadius). The initial value of 10, therefore, is divided by 100 (for the range) and transformed to 0 1 250. ×

, or 79. The final value of 10 + 30 results in a radius of 0 4 250. ×

, or 158. That’s the process that creates an SVG for each data value.

In document Custom Visualizations with D3.js (Page 32-34)

Related documents