Public
Edited
Jan 12, 2024
7 stars
Insert cell
Insert cell
Insert cell
Insert cell
int_pic = {
let w = entry_width;
let h = 0.6 * w;
let svg = d3.create("svg").attr("width", w).attr("height", h);
svg
.append("rect")
.attr("width", w)
.attr("height", h)
.attr("fill", "white")
.attr("opacity", 0.9);

let xmin = -2;
let xmax = 2;
let x_scale = d3.scaleLinear().domain([xmin, xmax]).range([0, w]);
let ymin = -0.5;
let ymax = 2;
let y_scale = d3.scaleLinear().domain([ymin, ymax]).range([h, 0]);
let pts_to_path = d3
.line()
.x((d) => x_scale(d[0]))
.y((d) => y_scale(d[1]));
let f = (x) => (x ** 3 - x) / 2 + 1;
let pts = d3.range(xmin, xmax, 0.01).map((x) => [x, f(x)]);

let shade = svg.append("g");
svg
.append("line")
.attr("x1", x_scale(0))
.attr("x2", x_scale(0))
.attr("y1", y_scale(ymin))
.attr("y2", y_scale(ymax - 0.2))
.attr("stroke", "black");
svg
.append("line")
.attr("x1", x_scale(xmin + 0.2))
.attr("x2", x_scale(xmax))
.attr("y1", y_scale(0))
.attr("y2", y_scale(0))
.attr("stroke", "black");
svg
.append("path")
.attr("d", pts_to_path(pts))
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", "3px");

let a = -1.3;
let b = 1.2;
function add_shade() {
let shade_pts = [[a, 0]]
.concat(d3.range(a, b, 0.002).map((x) => [x, f(x)]))
.concat([[b, 0]]);
shade
.append("path")
.attr("d", pts_to_path(shade_pts))
.attr("fill", "lightgray");
}
add_shade();

function add_rects(n) {
let xs = d3.range(a, b, (b - a) / n);
xs.forEach(function (x) {
shade
.append("rect")
.attr("class", "temp")
.attr("x", x_scale(x))
.attr("y", y_scale(f(x)))
.attr("width", x_scale(x + (b - a) / n) - x_scale(x))
.attr("height", y_scale(0) - y_scale(f(x)))
.attr("fill", "lightgray")
.attr("stroke", "black");
});
}

let n = 1;
let interval_id;
svg
.on("mouseenter", function () {
svg
.attr("transform", "scale(1)")
.transition()
.duration(1000)
.attr("transform", "scale(2)");
shade.selectAll("path").remove();
interval_id = setInterval(function () {
shade.selectAll(".temp").remove();
add_rects(n);
n = n + 1;
}, 100);
})
.on("mouseleave", function () {
svg
.attr("transform", "scale(2)")
.transition()
.duration(500)
.attr("transform", "scale(1)");
clearInterval(interval_id);
n = 1;
shade.selectAll(".temp").remove();
add_shade();
})
.on("click", function () {
clearInterval(interval_id);
});
svg.selectAll("*").style("pointer-events", "none");

return svg.node();
}
Insert cell
diff_pic = {
let w = entry_width;
let h = 0.6 * w;
let svg = d3.create("svg").attr("width", w).attr("height", h);
svg
.append("rect")
.attr("width", w)
.attr("height", h)
.attr("fill", "white")
.attr("opacity", 0.9);

let xmin = -2;
let xmax = 2;
let x_scale = d3.scaleLinear().domain([xmin, xmax]).range([0, w]);
let ymin = -0.5;
let ymax = 2;
let y_scale = d3.scaleLinear().domain([ymin, ymax]).range([h, 0]);
let pts_to_path = d3
.line()
.x((d) => x_scale(d[0]))
.y((d) => y_scale(d[1]));

let x0 = -1;
let f = (x) => (x ** 3 - x) / 2 + 1;
let fp = (x) => (3 * x ** 2 - 1) / 2;
let L = (x) => f(x0) + fp(x0) * (x - x0);
let LL = (x, h) => f(x0) + ((f(x0 + h) - f(x0)) * (x - x0)) / h;
let pts = d3.range(xmin, xmax, 0.01).map((x) => [x, f(x)]);
svg
.append("line")
.attr("x1", x_scale(0))
.attr("x2", x_scale(0))
.attr("y1", y_scale(ymin))
.attr("y2", y_scale(ymax - 0.2))
.attr("stroke", "black");
svg
.append("line")
.attr("x1", x_scale(xmin + 0.2))
.attr("x2", x_scale(xmax))
.attr("y1", y_scale(0))
.attr("y2", y_scale(0))
.attr("stroke", "black");
svg
.append("path")
.attr("d", pts_to_path(pts))
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", "3px");
let lines = svg.append("g");
lines
.append("line")
.attr("x1", x_scale(xmin))
.attr("x2", x_scale(xmax))
.attr("y1", y_scale(L(xmin)))
.attr("y2", y_scale(L(xmax)))
.attr("stroke", "black");
let circles = svg.append("g");
circles
.append("circle")
.attr("cx", x_scale(-1))
.attr("cy", y_scale(f(-1)))
.attr("r", 4)
.attr("fill", "green")
.attr("stroke", "darkgreen");

let secant_line, secant_pt;
let dx = 0.4;
let interval_id;
//interval_ids = [];
svg
.on("mouseenter", async function () {
svg
.attr("transform", "scale(1)")
.transition()
.duration(1000)
.attr("transform", "scale(2)");
svg.selectAll(".temp").remove();
secant_line = lines
.append("line")
.attr("class", "temp")
.attr("x1", x_scale(xmin))
.attr("x2", x_scale(xmax))
.attr("y1", y_scale(LL(xmin, dx)))
.attr("y2", y_scale(LL(xmax, dx)))
.attr("stroke", "black");
secant_pt = circles
.append("circle")
.attr("class", "temp")
.attr("cx", x_scale(x0 + dx))
.attr("cy", y_scale(f(x0 + dx)))
.attr("r", 4)
.attr("fill", "red")
.attr("stroke", "darkred");

await Promises.delay(1000);
interval_id = setInterval(function () {
dx = 0.95 * dx;
svg.selectAll(".temp").remove();
secant_line = lines
.append("line")
.attr("class", "temp")
.attr("x1", x_scale(xmin))
.attr("x2", x_scale(xmax))
.attr("y1", y_scale(LL(xmin, dx)))
.attr("y2", y_scale(LL(xmax, dx)))
.attr("stroke", "black");
secant_pt = circles
.append("circle")
.attr("class", "temp")
.attr("cx", x_scale(x0 + dx))
.attr("cy", y_scale(f(x0 + dx)))
.attr("r", 4)
.attr("fill", "red")
.attr("stroke", "darkred");
}, 50);
// interval_ids.push(interval_id);
})
.on("mouseleave", function () {
clearInterval(interval_id);
secant_line.remove();
secant_pt.remove();
dx = 0.4;
svg
.attr("transform", "scale(2)")
.transition()
.duration(500)
.attr("transform", "scale(1)");
})
.on("click", function () {
clearInterval(interval_id);
});

svg.selectAll("*").style("pointer-events", "none");

return svg.node();
}
Insert cell
style = html`<style>
.top_header {
font-weight: bold;
font-size: 20px;
display: inline-block;
width: ${entry_width}px;
text-align: center;
}
.left_header {
font-weight: bold;
font-size: 18px;
display: inline-block;
width: 200px;
padding: 2px;
}
.entry {
font-size: 16px;
text-align: center;
display: inline-block;
width: ${entry_width}px;
padding: 2px;
}
.final-entry {
font-size: 16px;
text-align: center;
display: inline-block;
width: ${2 * entry_width}px;
padding: 10px;
}
.separator {
width: ${100 + 2 * entry_width}px;
height: 0;
margin: 6px auto;
border-bottom: solid 0.4px gray;
}
</style>`
Insert cell
entry_width = 300
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