{
const data = [
{ dummy_date: new Date("2000-01-01"), ano_pi: 0.5, decade: "2000" },
{ dummy_date: new Date("2000-02-01"), ano_pi: 1.0, decade: "2000" },
{ dummy_date: new Date("2000-03-01"), ano_pi: 1.2, decade: "2000" },
{ dummy_date: new Date("2000-04-01"), ano_pi: 0.8, decade: "2000" },
{ dummy_date: new Date("2000-01-01"), ano_pi: 0.3, decade: "2010" },
{ dummy_date: new Date("2000-02-01"), ano_pi: 0.7, decade: "2010" },
{ dummy_date: new Date("2000-03-01"), ano_pi: 0.9, decade: "2010" },
{ dummy_date: new Date("2000-04-01"), ano_pi: 0.6, decade: "2010" }
];
const margin = { top: 40, right: 40, bottom: 30, left: 25 };
const totalWidth = 960;
const height = 350 - margin.top - margin.bottom;
const svg = d3
.create("svg")
.attr("viewBox", `0 0 ${totalWidth} ${height + margin.top + margin.bottom}`)
.attr("style", "max-width: 100%; height: auto; font: 10px sans-serif;");
const dataByDecade = d3.group(data, (d) => d.decade);
let facetWidth =
(totalWidth - margin.left - margin.right) / dataByDecade.size;
const y = d3
.scaleLinear()
.domain([0, d3.max(data, (d) => d.ano_pi)])
.range([height, 0]);
const x = d3
.scaleTime()
.domain(d3.extent(data, (d) => d.dummy_date))
.range([0, facetWidth - margin.right]);
const xSuperimposed = d3
.scaleTime()
.domain(d3.extent(data, (d) => d.dummy_date))
.range([0, totalWidth - margin.left - margin.right]);
const lineGenerator = d3
.line()
.x((d) => x(d.dummy_date)) // Initially set to use the 'x' scale
.y((d) => y(d.ano_pi));
let isMerged = false;
function updateFacets() {
facetWidth = isMerged
? totalWidth - margin.left - margin.right
: (totalWidth - margin.left - margin.right) / dataByDecade.size;
const currentXScale = isMerged ? xSuperimposed : x;
lineGenerator.x((d) => currentXScale(d.dummy_date));
svg
.selectAll(".facet")
.transition()
.duration(750)
.attr("transform", (_, i) =>
isMerged
? `translate(${margin.left}, ${margin.top})`
: `translate(${margin.left + i * facetWidth}, ${margin.top})`
);
svg
.selectAll(".x-axis")
.transition()
.duration(750)
.call(
d3
.axisBottom(currentXScale)
.tickFormat(d3.timeFormat("%b"))
.tickValues([
new Date("2000-01-01"),
new Date("2000-02-01"),
new Date("2000-03-01"),
new Date("2000-04-01")
])
)
.call((g) => g.select(".domain").remove())
.call((g) => g.selectAll(".tick line").attr("stroke", "#777"));
svg
.selectAll(".line")
.transition()
.duration(750)
.attr("d", (d) => lineGenerator(d));
// Debugging console.log statements
console.log("Facet Width:", facetWidth);
console.log("Is Merged:", isMerged);
}
svg.on("click", function () {
isMerged = !isMerged;
updateFacets();
});
dataByDecade.forEach((values, decade, i) => {
const xOffset = margin.left + i * facetWidth;
const facetGroup = svg
.append("g")
.attr("class", "facet")
.attr("transform", `translate(${xOffset}, ${margin.top})`);
facetGroup
.append("text")
.attr("class", "decade-label")
.attr("x", facetWidth / 2) // Center the label
.attr("y", 0 - margin.top / 2) // Adjust y position
.text(decade + "s")
.style("font-size", "16px") // Adjust font size
.attr("text-anchor", "middle");
facetGroup
.append("g")
.attr("class", "x-axis")
.attr("transform", `translate(0, ${height})`)
.call(
d3
.axisBottom(x)
.tickFormat(d3.timeFormat("%b"))
.tickValues([
new Date("2000-01-01"),
new Date("2000-02-01"),
new Date("2000-03-01"),
new Date("2000-04-01")
])
)
.call((g) => g.select(".domain").remove())
.call((g) => g.selectAll(".tick line").attr("stroke", "#777"));
facetGroup
.append("g")
.call(d3.axisLeft(y).tickValues([0, 0.5, 1, 1.5, 2]))
.call((g) => g.select(".domain").remove())
.call((g) => g.selectAll(".tick line").attr("stroke", "#777"))
.call((g) =>
g
.selectAll("line")
.attr("x2", facetWidth - margin.right)
.attr("stroke", "#ddd")
);
facetGroup
.selectAll(".line")
.data([values]) // Bind the data for each decade
.enter()
.append("path")
.attr("class", "line")
.attr("fill", "none")
.attr("stroke", "steelblue") // Adjust stroke color for visibility
.attr("stroke-width", 2) // Adjust stroke width
.attr("d", lineGenerator);
});
updateFacets();
return svg.node();
}