Public
Edited
Dec 4, 2023
1 star
Insert cell
Insert cell
chart({
title_dy: -80,
title_dx: 0,
startvalue_dy: -130, endvalue_dy: -130, startvalue_dx: 10, endvalue_dx: -10,
})
Insert cell
import {read} from "@open-numbers/read-google-spreadsheet"
Insert cell
import {
customFont,
fontFamily,
weight,
weightTitle,
fontSizeRegular,
black,
margin,
fillBad,
fillGood,
markTitles,
markFirstLastValues,
fontFace,
dateFormat
} from "@gapminder/a-simple-linechart"
Insert cell
customFont

Insert cell
data = read("https://docs.google.com/spreadsheets/d/1BSbOU9prPy-38rZhcFhg5l8cHDk5b8P8WrQmVInXu4I/edit#gid=1941360676", "Overexploited fish stocks")
Insert cell
dataFolded = {
const result = []
for (let d of data) {
result.push({
year: d3.utcParse("%Y")(d.Year),
status: "ok",
value: +d["Proportion of fish stocks within biologically sustainable levels (not overexploited) % OK"]
});
result.push({
year: d3.utcParse("%Y")(d.Year),
status: "notok",
value: +d["Proportion of fish stocks overexploited % overexploited"]
});
}
return result.toSorted((a,b) => a.year - b.year);
}
Insert cell
chart = ({
width = 1050,
height = 700,
data = dataFolded,
numberFormat = (n)=>d3.format("d")(n)+"%",
title_dy = -10,
title_dx = 0,
startvalue_dy = 0, endvalue_dy = 0, startvalue_dx = 0, endvalue_dx = 0,
} = {}) => {

const plot = Plot.plot({
width,
height,
marginTop: 100,
marginBottom: margin.bottom,
marginLeft: 60,
marginRight: margin.right,
style: {fontFamily: fontFamily, fontWeight: weight, fontSize: fontSizeRegular, fill: black},
x: {label: "", labelArrow: "none", tickFormat: dateFormat, tickSpacing: 100, fontVariant: "none"},
y: {label: "", labelArrow: "none", tickSpacing: 50},
marks: [
Plot.areaY(data, {x, z, y, fill: ({status}) => status == "ok"? fillGood : fillBad}),
Plot.ruleY([0]),
...markTitles(data, x, y, title_dy, title, subtitle, source),
...markFirstLastValues(data.filter(f => f.status == "ok"), x, y, numberFormat)
]
});



const xTickLabelW = title_dx;

d3.select(plot).select('g[aria-description="title"]')
.attr("transform", `translate(${0.5 - xTickLabelW/2},${0.5 -140 - (+title_dy || 0)})`)
d3.select(plot).select('g[aria-description="subtitle"]')
.attr("transform", `translate(${0.5 - xTickLabelW/2},${0.5 -100 - (+title_dy || 0)})`)
d3.select(plot).select('g[aria-description="source"]')
.attr("transform", `translate(${0.5 - xTickLabelW/2},${0.5 + 60})`)

d3.select(plot).select('g[aria-description="valueLeft"]')
.attr("transform", `translate(${0.5 - xTickLabelW/2 + +startvalue_dx},${0.5 - 35 - +startvalue_dy})`)
d3.select(plot).select('g[aria-description="dateLeft"]')
.attr("transform", `translate(${0.5 - xTickLabelW/2 + +startvalue_dx},${0.5 - 85 - +startvalue_dy})`)
d3.select(plot).select('g[aria-description="valueRight"]')
.attr("transform", `translate(${0.5 + xTickLabelW/2 + +endvalue_dx},${0.5 - 40 - +endvalue_dy})`)
d3.select(plot).select('g[aria-description="dateRight"]')
.attr("transform", `translate(${0.5 + xTickLabelW/2 + +endvalue_dx},${0.5 - 90 - +endvalue_dy})`)
d3.select(plot).select('g[aria-description="compareRight"]')
.attr("transform", `translate(${0.5 + xTickLabelW/2 + +endvalue_dx},${0.5 - 40 - +endvalue_dy})`)


plot.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "style"))
.innerHTML = fontFace;
return plot;

}
Insert cell
x = "year"
Insert cell
y = "value"
Insert cell
z = "status"
Insert cell
title = "Overfishing"
Insert cell
subtitle = "Proportion of fish stocks within biologically sustainable levels (not overexploited) %"
Insert cell
source = "Source: FAO"
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