Published
Edited
Nov 30, 2020
3 forks
5 stars
Insert cell
Insert cell
// Keep track of the section so that updates only happen when the section changes
mutable currentSection = 0
Insert cell
chart = {
// Overall container
const container = d3.create("div").attr("class", "scroll-container");

// Container for the narrative section
const narrativeContainer = container
.append("div")
.attr("class", "narrative-container");

// Narrative section (holds the text on the left)
const narrative = narrativeContainer.append("div").attr("class", "narrative");

// Add text
narrative
.selectAll(".section")
.data(descriptions)
.join("div")
.attr("class", "section")
.append("h1")
.text(d => d);

// Visualization container
const vis = container.append("div").attr("class", "vis-container");

// Update function (just switches the colors)
const update = section => {
// If the section hasn't changed, don't do anything!
if (section === mutable currentSection) return;
mutable currentSection = section; // If this line of code is here, the cell re-renders
let color = '';
switch (section) {
case 0:
color = "white";
break;
case 1:
color = "pink";
break;
case 2:
color = "green";
break;
case 3:
color = "black";
break;
default:
color = "blue";
break;
}
vis.style("background-color", color);
};

// Add the scrolling listener
narrativeContainer.on("scroll", () => {
// Compute section
const totalHeight = narrativeContainer.node().getBoundingClientRect().top;
const offset = narrative.node().getBoundingClientRect().y;
const section = Math.floor((totalHeight - offset + 10) / sectionHeight);
update(section);
});

return container.node();
}
Insert cell
settings = md`## Settings`
Insert cell
// Descriptions for each section
descriptions = d3.range(0, 5).map(d => "Section " + d)
Insert cell
fullHeight = 400
Insert cell
sectionHeight = 200
Insert cell
narrativeWidth = 200
Insert cell
Insert cell
html`<style>

.scroll-container {
width:${width}px;
height:${fullHeight}px;
}

.narrative-container {
height:${fullHeight}px;
overflow-y:scroll;
float:left;
}

.narrative {
width:${narrativeWidth}px;
}

.vis-container {
height:${fullHeight}px;
width:${width - narrativeWidth - 20}px;
float:right;
}

.section {
height: ${sectionHeight}px;
}
.section:last-of-type {
height:${fullHeight}px;
}
</style>`
Insert cell
d3 = require("d3")
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