Public
Edited
May 1
Insert cell
Insert cell
chart = {
const margin = {top: 20, right:20, bottom: 20, left: 20 }
const svgWidth = 800;
const svgHeight = 700;
const chartWidth = 200;
const chartHeight = 150;
const chartPadding = 30;
const cols = 4;
const rows = 3;

const groupped = Array.from(d3.group(aggregated, d => d.country), ([key, values]) => ({ key, values }));
// let min = d3.min(data, d => d.mean_SD);
// let max = d3.max(data, d => d.mean_SD)

const xScale = d3.scaleTime()
.domain([new Date("2000-01-01"), new Date("2025-01-01")])
.range([0, chartWidth - chartPadding]);

const yScale = d3.scaleLinear()
.range([chartHeight - chartPadding - chartPadding, 0])

const line = d3.line()
.x(d => xScale(d.year))
.y(d => yScale(d.mean_SD))

const svg = d3.create("svg")
.attr("width", svgWidth)
.attr("height", svgHeight);
const g = svg.selectAll('g.group')
.data(groupped)
.join("g")
.attr("class", "group")
.attr('transform', (d, i) => {
let col = i % cols;
let row = Math.floor(i/cols);
return `translate(${col * (chartWidth + chartPadding)}, ${row * chartHeight + chartPadding + chartPadding})`
});


g.each(function(dat, i){
let min = d3.min(dat.values, d => d.mean_SD);
let max = d3.max(dat.values, d => d.mean_SD)
yScale.domain([min, max])
d3.select(this)
.append("text")
.attr("x", 0)
.attr("y", -10)
.text(dat.key)
d3.select(this)
.datum(dat.values)
.append("path")
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("d", line)
})

return svg.node()
}
Insert cell
chart2 = {
const svgWidth = 800;
const svgHeight = 800;
const chartWidth = 250;
const chartHeight = 150;
const chartPadding = {v: 20, h:20 };

//
const wrapper = d3.create("div")
.attr("id", "svg-wrapper")
const cols = 4;
const rows = 3;

const groupped = Array.from(d3.group(aggregated, d => d.country), ([key, values]) => ({ key, values }));
let min = d3.min(data, d => d.mean_SD);
let max = d3.max(data, d => d.mean_SD);

const xScale = d3.scaleTime()
.domain([new Date("2000-01-01"), new Date("2025-01-01")])
.range([0, chartWidth - chartPadding.h]);

const yScale = d3.scaleLinear()
.domain([min, max])
.range([chartHeight - chartPadding.v - chartPadding.v, 0])

const line = d3.line()
.x(d => xScale(d.year))
.y(d => yScale(d.mean_SD));


groupped.forEach(function(dat, i){
const svg = wrapper
.append("svg")
.attr("width", chartWidth)
.attr("height", chartHeight);

const g = svg.append("g")
.attr("class", "group")
.attr('transform', (d, i) => {
return `translate(${chartPadding.h}, ${chartPadding.v})`
});

g.append("text")
.attr("x", 0)
.attr("y", 0)
.text(dat.key)

g.append("path")
.datum(dat.values)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("d", line)

})

return wrapper.node()
}
Insert cell
aggregated = grouped.flatMap(([country, yearGroup]) =>
yearGroup.map(([year, mean_SD]) => ({ country, year, mean_SD }))
);
Insert cell
// Step 2: Group by country and year, then compute mean
grouped = d3.rollups(
dataWithYear,
v => d3.mean(v, d => d.mean_SD),
d => d.country,
d => new Date(d.year)
);
Insert cell
dataWithYear = data.map(d => ({
...d,
year: new Date(d.Month).getFullYear() + '-01-01'
}));


Insert cell
mean_SD_by_country_by_month.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
monarch_mariage = FileAttachment("monarch_mariage.png").image({ width: 600 })
Insert cell
untitled = FileAttachment("Знімок екрана 2025-04-30 о 01.58.02.png").image({width: 800})
Insert cell
untitled1 = FileAttachment("Знімок екрана 2025-04-30 о 01.58.12.png").image({width: 800})
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