jointDataInteractive = {
const n = 80;
const data = [];
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
const y1 = i / (n - 1);
const y2 = j / (n - 1);
const inRegion = region_type === "Triangular" ? (y2 <= y1) : true;
if (inRegion) {
const density = Math.pow(y1 + 0.01, power_a) * Math.pow(y2 + 0.01, power_b);
data.push({y1, y2, density});
}
}
}
// For triangular region, add zero-density boundary points to prevent contour bleeding
if (region_type === "Triangular") {
for (let i = 0; i < n; i++) {
const y1 = i / (n - 1);
for (let j = Math.ceil(y1 * (n-1)) + 1; j < n; j++) {
const y2 = j / (n - 1);
data.push({y1, y2, density: 0});
}
}
}
return data;
}
constraintLine = region_type === "Triangular"
? Array.from({length: 100}, (_, i) => ({y1: i / 99, y2: i / 99}))
: [];
// Create a vertical band to highlight the conditioning slice
sliceBand = (() => {
const bandwidth = 0.015;
const ymax = region_type === "Triangular" ? sliceY1 : 1;
return [{
x1: sliceY1 - bandwidth,
x2: sliceY1 + bandwidth,
y1: 0,
y2: ymax
}];
})();
// Points for the conditional range marker
conditionalDots = (() => {
const points = [];
const ymax = region_type === "Triangular" ? sliceY1 : 1;
for (let i = 0; i <= 35; i++) {
points.push({y1: sliceY1, y2: (i / 35) * ymax});
}
return points;
})();
plot = Plot.plot({
width: 600,
height: 380,
marginLeft: 55,
marginBottom: 45,
color: {scheme: "YlOrRd", legend: true, label: "Density"},
x: {domain: [0, 1], label: "Yโ"},
y: {domain: [0, 1], label: "Yโ"},
title: region_type === "Rectangular"
? "Rectangle: Support is 0<Yโ<1, 0<Yโ<1 (full square)"
: "Triangle: Support is 0<YโโคYโ<1 (LOWER triangle)",
marks: [
Plot.contour(jointDataInteractive, {x: "y1", y: "y2", fill: "density", blur: 1, thresholds: 14}),
// Vertical band highlighting the slice
Plot.rect(sliceBand, {x1: "x1", x2: "x2", y1: "y1", y2: "y2", fill: "#3b82f6", fillOpacity: 0.12}),
// Constraint boundary
constraintLine.length ? Plot.line(constraintLine, {x: "y1", y: "y2", stroke: "#1f2937", strokeWidth: 3, strokeDasharray: "8,4"}) : null,
// Conditional range dots
Plot.dot(conditionalDots, {x: "y1", y: "y2", r: 3, fill: "#1d4ed8", opacity: 0.9}),
// Slice marker line
Plot.ruleX([sliceY1], {stroke: "#1d4ed8", strokeWidth: 3}),
// Constraint label
constraintLine.length ? Plot.text([{y1: 0.78, y2: 0.84, text: "yโ = yโ"}], {x: "y1", y: "y2", text: "text", fontSize: 13, fontWeight: "bold", fill: "#1f2937"}) : null,
Plot.frame()
].filter(Boolean)
});
html`<div>
${plot}
<div style="margin-top: 5px; font-size: 0.9em; line-height: 1.3;">
<strong style="color: #1d4ed8;">Blue band at Yโ=${sliceY1.toFixed(2)}:</strong> Shows Yโ's feasible range. ${region_type === "Triangular" ? `Only [0, ${sliceY1.toFixed(2)}] allowed.` : "Always [0, 1] allowed."}
</div>
</div>`