function normal_pic(z1, z2, size) {
let width, height;
if (size) {
width = size;
height = size / 2;
} else {
width = 400;
height = 200;
}
let pad = 5;
let div = d3
.create('div')
.attr('class', 'pic')
.style('width', `${width}px`)
.style('height', `${height + 40}px`)
.style('text-align', 'center');
let pic_container = div
.append('div')
.style('width', `${width + 1}px`)
.style('height', `${height + 1}px`);
let pic = pic_container
.append('svg')
.attr('width', width)
.attr('height', height)
.style('background-color', 'white');
let xmin = -3.4;
let xmax = 3.4;
let ymin = -0.05;
let ymax = 0.5;
let x_scale = d3
.scaleLinear()
.domain([xmin, xmax])
.range([pad, width - pad]);
let y_scale = d3
.scaleLinear()
.domain([ymin, ymax])
.range([height - pad, pad]);
let pts_to_path = d3
.line()
.x(function(d) {
return x_scale(d[0]);
})
.y(function(d) {
return y_scale(d[1]);
});
let dx = 0.01;
let fill_pts;
if (!(isNaN(parseFloat(z1)) || isNaN(parseFloat(z2)))) {
let Z1, Z2;
if (z1 < xmin) {
Z1 = xmin;
} else {
Z1 = z1;
}
if (z1 > xmax) {
Z1 = xmax;
} else {
Z1 = z1;
}
if (z1 === -Infinity) {
Z1 = -4;
}
if (z2 < xmin) {
Z2 = xmin;
} else {
Z2 = z2;
}
if (z2 > xmax) {
Z2 = xmax;
} else {
Z2 = z2;
}
fill_pts = d3.range(Z1, Z2, dx).map(x => [x, normal_pdf(x)]);
fill_pts = [[Z1, 0]].concat(fill_pts).concat([[Z2, 0]]);
pic
.append('path')
.attr('class', 'fill')
.attr('d', pts_to_path(fill_pts))
.attr('stroke', 'none')
.attr('fill', 'lightblue');
}
pic
.append('line')
.attr('x1', x_scale(xmin))
.attr('x2', x_scale(xmax))
.attr('y1', y_scale(0))
.attr('y2', y_scale(0))
.attr('stroke', 'black');
pic
.append('line')
.attr('x1', x_scale(0))
.attr('x2', x_scale(0))
.attr('y1', y_scale(ymin))
.attr('y2', y_scale(ymax))
.attr('stroke', 'black');
let x_ticks = [-3, -2, -1, 1, 2, 3];
pic
.selectAll('line.xtick')
.data(x_ticks)
.join('line')
.attr('class', 'xtick')
.attr('x1', x => x_scale(x))
.attr('x2', x => x_scale(x))
.attr('y1', y_scale(0))
.attr('y2', y_scale(ymin / 3))
.attr('stroke', 'black');
pic
.selectAll('text.xtick')
.data(x_ticks)
.join('text')
.attr('class', 'xtick')
.attr('x', x => x_scale(x) - width / 100)
.attr('y', y_scale(1.05 * ymin))
.text(x => x);
let pts = d3.range(xmin, xmax + dx, dx).map(x => [x, normal_pdf(x)]);
console.log([xmin, xmax, dx]);
pic
.append('path')
.attr('class', 'curve')
.attr('d', pts_to_path(pts))
.attr('stroke', 'black')
.attr('stroke-width', 2.5)
.attr('fill', 'none');
if (!isNaN(parseFloat(z2))) {
let p, tex_string;
if (z1 === -Infinity) {
p = 0.5 + 0.5 * ss.errorFunction(z2 / Math.sqrt(2));
tex_string = `P(Z<${ff(z2)})`;
} else {
p =
.5 *
(ss.errorFunction(z2 / Math.sqrt(2)) -
ss.errorFunction(z1 / Math.sqrt(2)));
tex_string = `P(${ff(z1)}<Z<${ff(z2)})`;
}
div.append(() => tex`${tex_string} \approx ${ff(p)}`);
}
return div.node();
}