Public
Edited
May 9
Insert cell
Insert cell
Insert cell
Inputs.table(aiddata)
Insert cell
import {Swatches} from "@d3/color-legend"
Insert cell
aiddata = {
const data = await d3.csv(googleSheetCsvUrl, row => ({
yearDate: d3.timeParse('%Y')(row.year),
yearInt: +row.year,
donor: row.donor,
recipient: row.recipient,
amount: +row.commitment_amount_usd_constant,
purpose: row.coalesced_purpose_name,
}));
data.columns = Object.keys(data[0]);
return data;
}
Insert cell
Insert cell
Insert cell
filteredData = aiddata.filter(d =>
d.donor === selectedCountry || d.recipient === selectedCountry
)

Insert cell
dataByYear = Array.from(
d3.group(filteredData, d => d.yearInt),
([year, records]) => ({
year,
donated: d3.sum(records, d => d.donor === selectedCountry ? d.amount : 0),
received: d3.sum(records, d => d.recipient === selectedCountry ? d.amount : 0)
})
).sort((a, b) => d3.ascending(a.year, b.year))

Insert cell
colorDonRec = d3.scaleOrdinal()
.domain(["Donado", "Recibido"])
.range(["#d73027", "#4575b4"])

Insert cell
Insert cell
Insert cell
{
const width = 1000;
const height = 500;
const margin = {top: 30, right: 100, bottom: 40, left: 80};

const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

const x = d3.scaleLinear()
.domain(d3.extent(dataByYear, d => d.year))
.range([margin.left, width - margin.right]);

const y = d3.scaleLinear()
.domain([0, d3.max(dataByYear, d => Math.max(d.donated, d.received))]).nice()
.range([height - margin.bottom, margin.top]);

const lineDonated = d3.line()
.x(d => x(d.year))
.y(d => y(d.donated));

const lineReceived = d3.line()
.x(d => x(d.year))
.y(d => y(d.received));

svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(d3.format("d")));

svg.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y));

svg.append("path")
.datum(dataByYear)
.attr("fill", "none")
.attr("stroke", "#d73027")
.attr("stroke-width", 2)
.attr("d", lineDonated);

svg.append("path")
.datum(dataByYear)
.attr("fill", "none")
.attr("stroke", "#4575b4")
.attr("stroke-width", 2)
.attr("d", lineReceived);

return svg.node();
}

Insert cell
Insert cell
Insert cell
dataFiltrada = aiddata.filter(d => d.purpose !== "UNSPECIFIED")

Insert cell
topPurposes = Array.from(
d3.rollup(dataFiltrada, v => d3.sum(v, d => d.amount), d => d.purpose)
)
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 10)
.map(d => d[0])

Insert cell
dataByPurposeAndYear = Array.from(
d3.group(
dataFiltrada.filter(d => topPurposes.includes(d.purpose)),
d => d.purpose
),
([purpose, values]) => ({
purpose,
values: Array.from(
d3.rollup(values, v => d3.sum(v, d => d.amount), d => d.yearInt),
([year, amount]) => ({ year, amount })
).sort((a, b) => d3.ascending(a.year, b.year))
})
)

Insert cell
color = d3.scaleOrdinal()
.domain(topPurposes)
.range(d3.schemeCategory10);

Insert cell
Insert cell
{
const width = 900;
const height = 500;
const margin = {top: 40, right: 10, bottom: 40, left: 80};

const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

const allYears = dataByPurposeAndYear.flatMap(d => d.values.map(v => v.year));
const allAmounts = dataByPurposeAndYear.flatMap(d => d.values.map(v => v.amount));

const x = d3.scaleLinear()
.domain(d3.extent(allYears))
.range([margin.left, width - margin.right]);

const y = d3.scaleLinear()
.domain([0, d3.max(allAmounts)]).nice()
.range([height - margin.bottom, margin.top]);

const line = d3.line()
.defined(d => !isNaN(d.amount))
.x(d => x(d.year))
.y(d => y(d.amount));

svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(d3.format("d")));

svg.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y));

svg.selectAll("path")
.data(dataByPurposeAndYear)
.join("path")
.attr("fill", "none")
.attr("stroke", d => color(d.purpose))
.attr("stroke-width", 2)
.attr("d", d => line(d.values));

return svg.node();
}

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
d3 = require('d3@7')
Insert cell
googleSheetCsvUrl = 'https://docs.google.com/spreadsheets/d/1YiuHdfZv_JZ-igOemKJMRaU8dkucfmHxOP6Od3FraW8/gviz/tq?tqx=out:csv'
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