Public
Edited
Apr 13, 2023
Insert cell
<svg width="1000" height="1060">
<style>
.title {
font-size: 42px;
font-family:TheSans Light, sans-serif;
margin-bottom:0;
}
.subtitle {
font-size: 18px;
font-family: verdana, sans-serif;
white-space: nowrap;
margin : 0;
padding-top:0;
}
.newscientist{
font-size: 22px;
font-family: verdana, sans-serif;
font-weight: bold;
text-anchor: end;
fill: #909090;
}
.guzzlerrects {
stroke: white;
stroke-width: 2px;
}
.guzzlertitles {
font-family:verdana, sans-serif;
text-anchor: end;
test-align: right-justify;
fill: #fff;
font-size: 30px;
}
.guzzlersubtitles1, .guzzlersubtitles2, .guzzlersubtitles3 {
font-family:verdana, sans-serif;
font-size: 16px;
fill: #fff;
text-anchor: end;
}
.rotatedtext {
font-family:verdana, sans-serif;
font-size: 20px;
fill: #fff;
text-anchor: start;
}
.vline, .hline {
stroke: white;
stroke-width: 1;
}
</style>

<text x=10 y=30 class="title">Land guzzlers</text>
<text x=10 y=55 class="subtitle">The ecological footprints of our pets can make SUVs look positively eco-friendly</text>
<text x=995 y=30 class="newscientist">&copyNewScientist</text>
</svg>
Insert cell
Insert cell
landguzzlers = d3.select(svgContainer) // selects the cell called svgContainer and make it a d3 object.
Insert cell
data = FileAttachment("land_guzzlers.csv").csv()
Insert cell
basepointY = 1000
Insert cell
colors = ["#a5620b", "#c29657", "#cc1f5e", "#a71949", "#f7991d", "#231f20"]
Insert cell
data_rotated = data.filter(d => d.title != "VOLKSWAGEN GOLF" && d.title != "HAMSTER")
Insert cell
data_lines = data.filter(d => d.title == "MEDIUM-SIZED DOG" || d.title == "TOYOTA LAND CRUISER")
Insert cell
{
landguzzlers.selectAll(".guzzlerrects")
.data(data)
.join("rect")
.attr("x", 0)
.attr("y", d => basepointY - Math.sqrt(Number(d["footprint"]))*954+60)
.attr("width", d => Math.sqrt(Number(d["footprint"]))*954)
.attr("height", d => Math.sqrt(Number(d["footprint"]))*954)
.style("fill", (d,i) => colors[i])
.attr("class", "guzzlerrects");

landguzzlers.selectAll(".guzzlertitles")
.data(data)
.join("text")
.text(d => d["title"])
.attr('x', function(d,i) {
if (i == 5) {
return Math.sqrt(Number(d["footprint"]))*954 + 147
} else {
return Math.sqrt(Number(d["footprint"]))*954 - 5
}})
.attr("y", d => basepointY - Math.sqrt(Number(d["footprint"]))*954 + 90)
.attr("class", "guzzlertitles");

landguzzlers.selectAll(".guzzlersubtitles1")
.data(data)
.join("text")
.text(function(d,i) {
if (i==5) {
return "Eco-footprint:"
} else {
return d["subtitle"]
}
})
.attr("x", function(d,i) {
if (i==5) {
return Math.sqrt(Number(d["footprint"]))*954 + 115
} else {
return Math.sqrt(Number(d["footprint"]))*954 - 30
}
})
.attr("y", function(d,i) {
if (i==5) {
return basepointY - Math.sqrt(Number(d["footprint"]))*954 + 110
} else {
return basepointY - Math.sqrt(Number(d["footprint"]))*954 + 120
}
})
.attr("class", "guzzlersubtitles1");

landguzzlers.selectAll(".guzzlersubtitles2")
.data(data)
.join("text")
.text(function(d,i) {
if (i==5) {
return d["footprint"] + " hectares"
} else {
return d["subtitle2"]
}
})
.attr("x", function(d,i) {
if (i==5) {
return Math.sqrt(Number(d["footprint"]))*954 + 125
} else {
return Math.sqrt(Number(d["footprint"]))*954 - 30
}
})
.attr("y", function(d,i) {
if (i==5) {
return basepointY - Math.sqrt(Number(d["footprint"]))*954 + 130
} else {
return basepointY - Math.sqrt(Number(d["footprint"]))*954 + 140
}
})
.attr("class", "guzzlersubtitles2");

landguzzlers.selectAll(".guzzlersubtitles3")
.data(data)
.join("text")
.text(d => d["subtitle3"])
.attr("x", d => Math.sqrt(Number(d["footprint"]))*954 - 30)
.attr("y", d => basepointY - Math.sqrt(Number(d["footprint"]))*954 + 160)
.attr("class", "guzzlersubtitles3");

landguzzlers.selectAll(".rotatedtext")
.data(data_rotated)
.join("text")
.text(d => "Eco-footprint: " + d["footprint"] + " hectares")
.classed('rotation', true)
.attr('transform', d =>{
return 'translate( '+(Math.sqrt(Number(d["footprint"]))*954 - 20)+' , '+(basepointY - Math.sqrt(Number(d["footprint"]))*954 + 100)+'),'+ 'rotate(90)';})
.attr("class", "rotatedtext");

landguzzlers.selectAll(".hline")
.data(data_lines)
.join("line")
.attr("x1", d => Math.sqrt(Number(d["footprint"]))*954 - 370)
.attr("x2", d => Math.sqrt(Number(d["footprint"]))*954 - 27)
.attr("y1", d => basepointY - Math.sqrt(Number(d["footprint"]))*954 + 100)
.attr("y2", d => basepointY - Math.sqrt(Number(d["footprint"]))*954 + 100)
.attr("class", "hline");

landguzzlers.selectAll(".vline")
.data(data_lines)
.join("line")
.attr("x1", d => Math.sqrt(Number(d["footprint"]))*954 - 27)
.attr("x2", d => Math.sqrt(Number(d["footprint"]))*954 - 27)
.attr("y1", d => basepointY - Math.sqrt(Number(d["footprint"]))*954 + 100)
.attr("y2", d => basepointY - Math.sqrt(Number(d["footprint"]))*954 + 170)
.attr("class", "vline");

}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more