{
const bins = transpose(slider_bins);
const outline = transpose(slider_outline);
const thresholds = transpose(slider_thresholds);
const roc = transpose(slider_roc);
const now = thresholds[Math.round(t * 100) - 1];
const classes = ["No (negative)", "Yes (positive)"];
const flagged = k => bins
.filter(d => d.class === k && d.x1 > now.cutoff)
.map(d => ({...d, x0: Math.max(d.x0, now.cutoff)}));
const densityPlot = Plot.plot({
width: 700, height: 400, style: {fontSize: "16px"},
x: {label: "LDA log posterior odds of default"},
y: {label: "Density within class"},
color: {domain: classes, range: slider_colors, legend: true},
marks: [
Plot.rect(flagged(classes[0]),
{x1: "x0", x2: "x1", y1: 0, y2: "density", fill: "class",
fillOpacity: 0.2}),
Plot.rect(flagged(classes[1]),
{x1: "x0", x2: "x1", y1: 0, y2: "density", fill: "class",
fillOpacity: 0.45}),
Plot.line(outline.filter(d => d.class === classes[0]),
{x: "x", y: "density", stroke: "class", strokeWidth: 2}),
Plot.line(outline.filter(d => d.class === classes[1]),
{x: "x", y: "density", stroke: "class", strokeDasharray: "6,4",
strokeWidth: 2}),
Plot.ruleX([now.cutoff], {strokeDasharray: "2,3"})
]
});
const rocPlot = Plot.plot({
width: 420, height: 400, style: {fontSize: "16px"},
x: {domain: [0, 1], label: "False positive rate (1 − specificity)"},
y: {domain: [0, 1], label: "True positive rate (sensitivity)"},
marks: [
Plot.line([[0, 0], [1, 1]], {stroke: "gray", strokeDasharray: "4,4"}),
Plot.line(roc, {x: "fpr", y: "tpr", strokeWidth: 2}),
Plot.dot([now], {x: "fpr", y: "tpr", r: 6, fill: "white", stroke: "black",
strokeWidth: 2})
]
});
return html`<p style="text-align: center"><b>t = ${t.toFixed(2)}</b>,
cutoff c = ${now.cutoff.toFixed(2)}; sensitivity = ${now.tpr.toFixed(3)},
specificity = ${(1 - now.fpr).toFixed(3)}</p>
<div style="display: flex; flex-wrap: wrap; gap: 1rem; justify-content: center">
${densityPlot}${rocPlot}
</div>`;
}