function cobweb_pic(r, x0, opts_in = {}) {
let f = (x) => lambda2 * Math.sin(x);
let { w = 800, h = 400 } = opts_in;
let opts = {
xdomain: [-2 * Math.PI, 2 * Math.PI],
ydomain: [-Math.PI, Math.PI],
marginTop: (10 * w) / 300,
marginRight: (10 * w) / 300,
marginBottom: 0,
marginLeft: 0,
inset: 6,
insetTop: 6,
insetRight: 6,
insetBottom: 0,
insetLeft: 0,
width: w,
height: h,
strokeWidth: 2.5,
xticks: [0],
yticks: false
};
let x_scale = d3.scaleLinear(opts.xdomain, [
opts.marginLeft + opts.insetLeft,
opts.width - opts.marginRight - opts.insetRight
]);
let y_scale = d3
.scaleLinear(opts.ydomain, [
opts.height - opts.marginBottom - opts.insetBottom,
opts.marginTop + opts.insetTop
])
.nice();
let pts_to_path = d3
.line()
.x(function (d) {
return x_scale(d[0]);
})
.y(function (d) {
return y_scale(d[1]);
});
let plot = funplot([f, (x) => x], opts);
let cobweb = make_cobweb(f, x0, -2 * Math.PI, 2 * Math.PI);
let svg = d3.select(plot);
svg
.append("path")
.attr("d", pts_to_path(cobweb))
.style("stroke", "black")
.style("stroke-width", 0.4)
.style("fill", "none")
.style("opacity", 0.4);
svg
.append("line")
.attr("x1", 0)
.attr("x2", w)
.attr("y1", y_scale(0))
.attr("y2", y_scale(0))
.attr("stroke", "black");
svg
.append("line")
.attr("y1", 0)
.attr("y2", h)
.attr("x1", x_scale(0))
.attr("x2", x_scale(0))
.attr("stroke", "black");
svg
.append("circle")
.attr("cx", x_scale(x0))
.attr("cy", y_scale(x0))
.attr("fill", "#3d3")
.attr("stroke", "black")
.attr("r", 3);
return plot;
}