This week's learning objective is to become familiar with the basic four-step process of going from data to visualization.
Study the following example carefully.
data.countries = [{name: 'China', pop: 1393783836},
{name: 'India', pop: 1267401849},
{name: 'USA', pop: 322583006},
{name: 'Indonesia', pop: 25281224}]
For each data point, think about how we want to visualize it. In particular, we define how to map a data attribute to a visual attribute. In this simplest example, we are mapping the order (i-th) data attribute to the x visual attribute of a rectangle.
<rect x="${d.x}"
width="20"
height="100"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
There is a special object template
that holds user-defined template strings.
Note that a name of this particular template string is set to be foo
. The
content of the string can be accessed by template.foo
in a code block.
Next, for each data point, we want to map it to a viz object that defines the attribute values we like to populate the template with. In this simplest example, there's only one attribute, x.
function computeX(d, i) {
return i * 20
}
data.viz = _.map(data.countries, function(d, i){
return {
x: computeX(d, i)
}
})
We obtain the following array of data objects.
[ { "x": 0 }, { "x": 20 }, { "x": 40 }, { "x": 60 } ]
The final step is to populate the template with the viz data calculated earlier.
// compile the template.foo into a template function
var compiled = _.template(template.foo)
var result = _.map(data.viz, function(d){
// invoke the compiled template function on each viz data
return compiled({d: d})
})
return result.join('\n')
The resulting svg tags are rendered as below
<rect x="0"
width="20"
height="100"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<rect x="20"
width="20"
height="100"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<rect x="40"
width="20"
height="100"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<rect x="60"
width="20"
height="100"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
Now it is your turn. The following exercises are incomplete. Your learning task is to add code to complete each exercise.
data.countries = [{name: 'China', pop: 1393783836},
{name: 'India', pop: 1267401849},
{name: 'USA', pop: 322583006},
{name: 'Indonesia', pop: 25281224}]
function computeX(d, i) {
return i * 20
}
function computeHeight(d, i){
return d.pop/10000000
}
data.viz = _.map(data.countries, function(d, i){
return {
x: computeX(d, i),
height: computeHeight(d, i)
}
})
<rect x="${d.x}"
width="20"
height="${d.height}"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
// compile the template.foo into a template function
var compiled = _.template(template.foo)
var result = _.map(data.viz, function(d){
// invoke the compiled template function on each viz data
return compiled({d: d})
})
return result.join('\n')
The resulting svg tags are rendered as below
<rect x="0"
width="20"
height="139.3783836"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<rect x="20"
width="20"
height="126.7401849"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<rect x="40"
width="20"
height="32.2583006"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<rect x="60"
width="20"
height="2.5281224"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
data.countries = [{name: 'China', pop: 1393783836},
{name: 'India', pop: 1267401849},
{name: 'USA', pop: 322583006},
{name: 'Indonesia', pop: 25281224}]
function computeX(d, i) {
return i * 20
}
function computeHeight(d, i){
return d.pop/10000000
}
function computeWidth(d, i){
return 20
}
data.viz = _.map(data.countries, function(d, i){
// TODO: add a new attribute to each viz object
return {
x: computeX(d, i),
height: computeHeight(d, i),
width: computeWidth(d, i)
}
})
(TODO: add template variables for width and height)
<rect x="${d.x}"
width="${d.width}"
height="${d.height}"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
// compile the template.foo into a template function
var compiled = _.template(template.foo)
var result = _.map(data.viz, function(d){
// invoke the compiled template function on each viz data
return compiled({d: d})
})
return result.join('\n')
The resulting svg tags are rendered as below
<rect x="0"
width="20"
height="139.3783836"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<rect x="20"
width="20"
height="126.7401849"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<rect x="40"
width="20"
height="32.2583006"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
<rect x="60"
width="20"
height="2.5281224"
style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />