This and the next page contain several exercises to set you up on a path to become proficient in generating SVGs for visualizing data. For each exercise, a "desired viz" is given. You need to modify the code block and the template block to come up with your own solution to create a visualization as close to the desired visualization as possible. The SVG code of the desired viz is shown to give you a target as to what set of SVG tags and attributes you need to generate in order to render the desired visualization. You can also see the SVG code your code generates. You want to get your version of the SVG code as close as possible to the target SVG code.
By close, you don't need to get to the exact precision. For instance, if
you see x='143.31413124123'
in a SVG tag in the target code, it is good enough
for your code to somehow get x
to that range (e.g., 142, 143, 144)
to produce a visualization that look almost identical to human eyes.
Note that the solution template code is slightly modified from the previous page in order to put all Javascript code in the same code block.
<rect x="0"
y="0"
width="20"
height="400"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="20"
y="0"
width="20"
height="363.7298169958114"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="40"
y="0"
width="20"
height="92.57762865891063"
style="fill:blue;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="60"
y="0"
width="20"
height="72.5542186586242"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="0"
width="20"
height="400"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="20"
y="0"
width="20"
height="363.7298169958114"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="40"
y="0"
width="20"
height="92.57762865891063"
style="fill:blue;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="60"
y="0"
width="20"
height="72.5542186586242"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="${d.x}"
y="0"
width="20"
height="${d.height}"
style="fill:${d.color};
stroke-width:3;
stroke:rgb(0,0,0)" />
function computeX(d, i) {
return i * 20
}
function computeHeight(d, i) {
return d.pop * (400 / 1393783836)// TODO
}
function computeColor(d, i) {
if(d.name == 'USA'){
return 'blue'
}
return 'red'
}
var viz = _.map(data, function(d, i){
return {
x: computeX(d, i),
height: computeHeight(d, i),
color: computeColor(d, i)
}
})
console.log(viz)
var result = _.map(viz, function(d){
// invoke the compiled template function on each viz data
return template({d: d})
})
return result.join('\n')
<rect x="0"
y="0"
width="20"
height="400"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="20"
y="36.270183004188596"
width="20"
height="363.7298169958114"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="40"
y="307.4223713410894"
width="20"
height="92.57762865891063"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="60"
y="327.4457813413758"
width="20"
height="72.5542186586242"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="0"
width="20"
height="400"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="20"
y="36.270183004188596"
width="20"
height="363.7298169958114"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="40"
y="307.4223713410894"
width="20"
height="92.57762865891063"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="60"
y="327.4457813413758"
width="20"
height="72.5542186586242"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="${d.x}"
y="${d.y}"
width="20"
height="${d.height}"
style="fill:${d.color};
stroke-width:3;
stroke:rgb(0,0,0)" />
function computeX(d, i) {
return i * 20
}
function computeHeight(d, i) {
return d.pop * (400 / 1393783836)
}
function computeY(d, i) {
return 400 - d.pop * (400 / 1393783836)
}
function computeColor(d, i) {
return 'red'
}
var viz = _.map(data, function(d, i){
return {
x: computeX(d, i),
y: computeY(d, i),
height: computeHeight(d, i),
color: computeColor(d, i)
}
})
console.log(viz)
var result = _.map(viz, function(d){
// invoke the compiled template function on each viz data
return template({d: d})
})
return result.join('\n')
<rect x="0"
y="0"
width="20"
height="400"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="30"
y="36.270183004188596"
width="20"
height="363.7298169958114"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="60"
y="307.4223713410894"
width="20"
height="92.57762865891063"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="90"
y="327.4457813413758"
width="20"
height="72.5542186586242"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="0"
width="20"
height="400"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="30"
y="36.270183004188596"
width="20"
height="363.7298169958114"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="60"
y="307.4223713410894"
width="20"
height="92.57762865891063"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="90"
y="327.4457813413758"
width="20"
height="72.5542186586242"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="${d.x}"
y="${d.y}"
width="20"
height="${d.height}"
style="fill:${d.color};
stroke-width:3;
stroke:rgb(0,0,0)" />
function computeX(d, i) {
return i * 30
}
function computeHeight(d, i) {
return d.pop * (400 / 1393783836)
}
function computeY(d, i) {
return 400 - d.pop * (400 / 1393783836)
}
function computeColor(d, i) {
return 'red'
}
var viz = _.map(data, function(d, i){
return {
x: computeX(d, i),
y: computeY(d, i),
height: computeHeight(d, i),
color: computeColor(d, i)
}
})
console.log(viz)
var result = _.map(viz, function(d){
// invoke the compiled template function on each viz data
return template({d: d})
})
return result.join('\n')
<rect x="0"
y="327.4457813413758"
width="20"
height="72.5542186586242"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="20"
y="307.4223713410894"
width="20"
height="92.57762865891063"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="40"
y="36.270183004188596"
width="20"
height="363.7298169958114"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="60"
y="0"
width="20"
height="400"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="60"
y="0"
width="20"
height="400"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="40"
y="36.270183004188596"
width="20"
height="363.7298169958114"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="20"
y="307.4223713410894"
width="20"
height="92.57762865891063"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="327.4457813413758"
width="20"
height="72.5542186586242"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="${d.x}"
y="${d.y}"
width="20"
height="${d.height}"
style="fill:${d.color};
stroke-width:3;
stroke:rgb(0,0,0)" />
var size=(_.size(data)-1)*20
function computeX(d, i) {
return size-i * 20
}
function computeHeight(d, i) {
return d.pop * (400 / 1393783836)
}
function computeY(d, i) {
return 400 - computeHeight(d,i)
}
function computeColor(d, i) {
return 'red'
}
var viz = _.map(data, function(d, i){
return {
x: computeX(d, i),
y: computeY(d, i),
height: computeHeight(d, i),
color: computeColor(d, i)
}
})
console.log(viz)
var result = _.map(viz, function(d){
// invoke the compiled template function on each viz data
return template({d: d})
})
return result.join('\n')
<rect x="0"
y="0"
width="300"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="20"
width="272.79736274685854"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="40"
width="69.43322149418297"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="60"
width="54.415663993968145"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="0"
width="300"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="20"
width="272.79736274685854"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="40"
width="69.43322149418297"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="0"
y="60"
width="54.415663993968145"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<rect x="${d.x}"
y="${d.y}"
width="${d.width}"
height="${d.height}"
style="fill:${d.color};
stroke-width:3;
stroke:rgb(0,0,0)" />
function computeX(d, i) {
return 0
}
function computeHeight(d, i) {
return 20
}
function computeWidth(d, i) {
return d.pop * (300 / 1393783836)
}
function computeY(d, i) {
return 20 * i
}
function computeColor(d, i) {
return 'red'
}
var viz = _.map(data, function(d, i){
return {
x: computeX(d, i),
y: computeY(d, i),
height: computeHeight(d, i),
width: computeWidth(d, i),
color: computeColor(d, i)
}
})
console.log(viz)
var result = _.map(viz, function(d){
// invoke the compiled template function on each viz data
return template({d: d})
})
return result.join('\n')
<g transform="translate(0 0)">
<rect width="300"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<text x="330" y="10">1393783836</text>
</g>
<g transform="translate(0 20)">
<rect width="272.79736274685854"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<text x="330" y="10">1267401849</text>
</g>
<g transform="translate(0 40)">
<rect width="69.43322149418297"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<text x="330" y="10">322583006</text>
</g>
<g transform="translate(0 60)">
<rect width="54.415663993968145"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<text x="330" y="10">252812243</text>
</g>
<g transform="translate(0 0)">
<rect width="300"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<text x="100" y="10">1393783836</text>
</g>
<g transform="translate(0 20)">
<rect width="272.79736274685854"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<text x="100" y="10">1267401849</text>
</g>
<g transform="translate(0 40)">
<rect width="69.43322149418297"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<text x="100" y="10">322583006</text>
</g>
<g transform="translate(0 60)">
<rect width="54.415663993968145"
height="20"
style="fill:red;
stroke-width:3;
stroke:rgb(0,0,0)" />
<text x="100" y="10">252812243</text>
</g>
<g transform="translate(${d.x} ${d.y})">
<rect width="${d.width}"
height="${d.height}"
style="fill:${d.color};
stroke-width:3;
stroke:rgb(0,0,0)" />
<text x="100" y="10">${d.label}</text>
</g>
function computeX(d, i) {
return 0
}
function computeHeight(d, i) {
return 20
}
function computeWidth(d, i) {
return d.pop * (300 / 1393783836)
}
function computeY(d, i) {
return 20 * i
}
function computeColor(d, i) {
return 'red'
}
function computeLabel(d, i) {
return d.pop
}
var viz = _.map(data, function(d, i){
return {
x: computeX(d, i),
y: computeY(d, i),
height: computeHeight(d, i),
width: computeWidth(d, i),
color: computeColor(d, i),
label: computeLabel(d, i)
}
})
console.log(viz)
var result = _.map(viz, function(d){
// invoke the compiled template function on each viz data
return template({d: d})
})
return result.join('\n')