Public
Edited
Mar 30, 2024
Insert cell
Insert cell
Insert cell
<svg width="1100" height="1100">
<style>
/* edit these styles as you need */
rect {stroke: white; stroke-width: 2px;}
text {fill: white; font-family: 'Rajdhani', sans-serif;}
.maintitle {font-size: 39px; fill: black;}
.mainsubtitle {font-size: 18px; fill: black;}
.title {text-anchor: end; font-size: 32px;}
.subtext1, .subtext2, .subtext3 {text-anchor: end; font-size: 18px;}
.footprint {font-size: 15px;}
line {stroke: white; stroke-width: 1.5px;}
</style>

<text x="0" y="27" class="maintitle">Main title-this can be static</text>
<text x="0" y="50" class="mainsubtitle">Subtitle...</text>

<!-- the rest will be drawn by the data using D3 below -->
</svg>
Insert cell
Insert cell
Insert cell
{
let landguzzlersViz = d3.select(svgContainer) // select the cell called svgContainer and make it a d3 object.
landguzzlersViz.selectAll("rect")
.data(land_guzzlers) // the name of the data object (see table below)
.join("rect")
.attr("width", d => Math.sqrt(d.footprint) * 1000)
.attr("height", d => Math.sqrt(d.footprint) * 1000)
.attr("x", 0)
.attr("y", d => 1100 - (Math.sqrt(d.footprint) * 1000))
.style("fill", (d,i) => colors[i]); // I'll give you this one. Can you see how it works? See colors below.
landguzzlersViz.selectAll(".title") // notice that I'm selectingAll objects of a class called .title, to only get those text.
.data(land_guzzlers) // same dataset
.join("text") // new object type created
.attr("x", d => (Math.sqrt(d.footprint) * 1000) - 2.5)
.attr("y", d => 1100 - (Math.sqrt(d.footprint) * 1000) + 26)
.text(d => d.title) // this is how we actually write the text content
.attr("class", "title"); // tag it with the style class 'title'

landguzzlersViz.selectAll(".footprint")
.data(land_guzzlers)
.join("text")
.attr("x", d => (Math.sqrt(d.footprint) * 1000) - 15)
.attr("y", d => 1100 - (Math.sqrt(d.footprint) * 1000) + 33)
.text(d => "Eco-footprint: " + d["footprint"] + " hectares")
.attr("transform", (d,i,nodes) => "rotate(90 " + nodes[i].getAttribute("x") + " " + nodes[i].getAttribute("y") + ")")
// ^^ OK, so you would not have gotten this one on your own easily. See if you can figure it out.
// also compare this back against your manual SVG code for the rotate. Similar?
.attr("class", "footprint"); // tag it with the style class 'title'

// ... what other objects


landguzzlersViz.selectAll(".subtext1") // notice that I'm selectingAll objects of a class called .title, to only get those text.
.data(land_guzzlers) // same dataset
.join("text") // new object type created
.attr("x", d => (Math.sqrt(d.footprint) * 1000) - 27)
.attr("y", d => 1100 - (Math.sqrt(d.footprint) * 1000) + 55)
.text(d => d.subtitle) // this is how we actually write the text content
.attr("class", "subtext1"); // tag it with the style class 'title'

landguzzlersViz.selectAll(".subtext2") // notice that I'm selectingAll objects of a class called .title, to only get those text.
.data(land_guzzlers) // same dataset
.join("text") // new object type created
.attr("x", d => (Math.sqrt(d.footprint) * 1000) - 27)
.attr("y", d => 1100 - (Math.sqrt(d.footprint) * 1000) + 70)
.text(d => d.subtitle2) // this is how we actually write the text content
.attr("class", "subtext1"); // tag it with the style class 'title'


landguzzlersViz.selectAll(".subtext3") // notice that I'm selectingAll objects of a class called .title, to only get those text.
.data(land_guzzlers) // same dataset
.join("text") // new object type created
.attr("x", d => (Math.sqrt(d.footprint) * 1000) - 27)
.attr("y", d => 1100 - (Math.sqrt(d.footprint) * 1000) + 90)
.text(d => d.subtitle3) // this is how we actually write the text content
.attr("class", "subtext1"); // tag it with the style class 'title'

// MEDIUM-SIZED DOG
landguzzlersViz.append("line")
//horizonta line
.attr("x1", "640") //left part of horizontal line. Larger # the shorter line gets from left
.attr("y1", "219") //horizontal, larger # lower it gets
.attr("x2", "896") //right part of horizontal line. Larger # the longer line gets from the right
.attr("y2", "219") //horizontal, larger # lower it gets
landguzzlersViz.append("line")
//vertical line
.attr("x1", "895") // vertical line, lesser #= shift left
.attr("y1", "218") //top part of the vertical line, smaller # the line gets longer on the top
.attr("x2", "895") // vertical line, less #= shiftleft
.attr("y2", "270") // bottom part of vertica line, larger the line gets longer in the bottom

// TOYOTA LAND CRUISER lines
landguzzlersViz.append("line")
.attr("x1", "320")
.attr("y1", "490")
.attr("x2", "620")
.attr("y2", "490")
landguzzlersViz.append("line")
.attr("x1", "620")
.attr("y1", "490")
.attr("x2", "620")
.attr("y2", "530")

}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
colors = ["#a5620b","#c29657","#cc1f5e","#a71949","#f7991d","#231f20"]; // in order Large Dog to Hamster. Reference as colors[i]
Insert cell
land_guzzlers.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
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