Spaces:
Paused
Paused
| <div id="ob-vq" role="img" aria-label="Good-side push versus bad-side push for six models. Optimistic models inflate both axes; Sonnet's pessimism is one-sided, underestimating good outcomes while keeping bad-outcome estimates near accurate."></div> | |
| <style> | |
| #ob-vq { font: 13px/1.4 system-ui, sans-serif; color: var(--text-color,#222); width:100%; max-width:480px; margin:0 auto; position:relative; } | |
| #ob-vq svg { display:block; width:100%; height:auto; overflow:visible; } | |
| #ob-vq .vq-tip { position:absolute; pointer-events:none; z-index:20; opacity:0; transform:translate(-50%,-100%); transition:opacity .1s; background:var(--surface-bg,#fff); color:var(--text-color,#222); border:1px solid var(--border-color,#ccc); border-radius:8px; padding:7px 9px; font-size:12px; line-height:1.5; box-shadow:0 6px 24px rgba(0,0,0,.18); white-space:nowrap; } | |
| #ob-vq .vq-tip b { font-weight:650; } | |
| </style> | |
| <script> | |
| (function () { | |
| var root = document.getElementById("ob-vq"); | |
| if (!root || !window.d3) { return; } | |
| var d3 = window.d3; | |
| var svg = d3.select(root).append("svg"); | |
| var tip = document.createElement("div"); tip.className = "vq-tip"; root.appendChild(tip); | |
| function cssVar(n, fb) { var v = getComputedStyle(document.documentElement).getPropertyValue(n); return (v && v.trim()) || fb; } | |
| var DATA = null; | |
| // hand-tuned label placement to avoid overlap in the top cluster | |
| var LBL = { | |
| "GPT-5.4-mini": [9, -9, "start"], "GPT-5.4": [0, -11, "middle"], "Haiku 4.5": [0, 16, "middle"], | |
| "Flash 3": [9, 13, "start"], "Pro 3.1": [0, -11, "middle"], "Sonnet 4.6": [10, 4, "start"] | |
| }; | |
| function draw() { | |
| if (!DATA) { return; } | |
| var OPT = cssVar("--opt", "#e07a5f"), PES = cssVar("--pes", "#3d5a80"), | |
| MUT = cssVar("--muted-color", "#666"), TXT = cssVar("--text-color", "#222"), | |
| BD = cssVar("--border-color", "#ccc"), SF = cssVar("--surface-bg", "#fff"); | |
| var W = Math.min(460, root.clientWidth || 460), H = W, m = 50, LIM = 11; | |
| var x = d3.scaleLinear().domain([-LIM, LIM]).range([m, W - m]); | |
| var y = d3.scaleLinear().domain([-LIM, LIM]).range([H - m, m]); | |
| svg.attr("viewBox", "0 0 " + W + " " + H).attr("height", H).selectAll("*").remove(); | |
| // faint quadrant tints (optimism quadrant warm, pessimism cool) | |
| function tint(qx, qy, c) { svg.append("rect").attr("x", x(qx)).attr("y", y(qy + LIM)).attr("width", (W - 2 * m) / 2).attr("height", (H - 2 * m) / 2).attr("fill", c).attr("opacity", 0.05); } | |
| tint(0, 0, OPT); tint(-LIM, -LIM, PES); | |
| // quadrant labels | |
| [[7.5, 9.4, "OVERCLAIM", "#7d6440"], [-7.5, -9.4, "UNDERCLAIM", "#6b6358"], | |
| [-7.5, 9.4, "PESSIMISM", PES], [7.5, -9.4, "OPTIMISM", OPT]].forEach(function (q) { | |
| svg.append("text").attr("x", x(q[0])).attr("y", y(q[1])).attr("text-anchor", "middle").attr("fill", q[3]).attr("opacity", 0.7).attr("font-size", 10).attr("font-weight", 700).attr("letter-spacing", "0.03em").text(q[2]); | |
| }); | |
| // axes only (no diagonal) | |
| svg.append("line").attr("x1", x(-LIM)).attr("x2", x(LIM)).attr("y1", y(0)).attr("y2", y(0)).attr("stroke", BD); | |
| svg.append("line").attr("x1", x(0)).attr("x2", x(0)).attr("y1", y(-LIM)).attr("y2", y(LIM)).attr("stroke", BD); | |
| var pos = {}; DATA.models.forEach(function (mm) { pos[mm.name] = [x(mm.good), y(mm.bad)]; }); | |
| var defs = svg.append("defs"); | |
| DATA.pairs.forEach(function (p, i) { | |
| var c = MUT; | |
| defs.append("marker").attr("id", "vqa" + i).attr("viewBox", "0 0 10 10").attr("refX", 8).attr("refY", 5).attr("markerWidth", 6).attr("markerHeight", 6).attr("orient", "auto").append("path").attr("d", "M0,0L10,5L0,10").attr("fill", c).attr("opacity", 0.4); | |
| svg.append("line").attr("x1", pos[p[0]][0]).attr("y1", pos[p[0]][1]).attr("x2", pos[p[1]][0]).attr("y2", pos[p[1]][1]).attr("stroke", c).attr("stroke-width", 1).attr("stroke-dasharray", "3 3").attr("opacity", 0.35).attr("marker-end", "url(#vqa" + i + ")"); | |
| }); | |
| var PROV = { OpenAI: "#2a8f82", Anthropic: "#a66e4e", Google: "#3d5a80", Mistral: "#c4553a" }; | |
| DATA.models.forEach(function (d) { | |
| var skew = d.good + d.bad, c = PROV[d.provider] || MUT; | |
| var g = svg.append("g").style("cursor", "pointer"); | |
| g.append("circle").attr("cx", x(d.good)).attr("cy", y(d.bad)).attr("r", 7).attr("fill", c).attr("stroke", SF).attr("stroke-width", 1.6); | |
| var L = LBL[d.name] || [10, 4, "start"]; | |
| g.append("text").attr("x", x(d.good) + L[0]).attr("y", y(d.bad) + L[1]).attr("text-anchor", L[2]).attr("fill", TXT).attr("font-size", 11).attr("font-weight", 500).text(d.name); | |
| g.on("mousemove", function (ev) { var pr = root.getBoundingClientRect(); tip.innerHTML = "<b>" + d.name + "</b><br>good-side push: " + (d.good > 0 ? "+" : "") + d.good + "<br>bad-side push: " + (d.bad > 0 ? "+" : "") + d.bad + "<br>Skew " + (skew > 0 ? "+" : "") + skew.toFixed(1); tip.style.left = (ev.clientX - pr.left) + "px"; tip.style.top = (ev.clientY - pr.top - 8) + "px"; tip.style.opacity = 1; }).on("mouseleave", function () { tip.style.opacity = 0; }); | |
| }); | |
| svg.append("text").attr("x", (m + W - m) / 2).attr("y", H - 10).attr("text-anchor", "middle").attr("fill", MUT).attr("font-size", 11).text("good-side push P(good) − 50"); | |
| svg.append("text").attr("transform", "translate(13," + H / 2 + ") rotate(-90)").attr("text-anchor", "middle").attr("fill", MUT).attr("font-size", 11).text("bad-side push P(bad) − 50"); | |
| } | |
| fetch("data/valence.json").then(function (r) { if (!r.ok) { throw new Error("x"); } return r.json(); }).then(function (j) { DATA = j; draw(); }).catch(function () {}); | |
| if (window.ResizeObserver) { var t = null; new ResizeObserver(function () { clearTimeout(t); t = setTimeout(draw, 130); }).observe(root); } else { window.addEventListener("resize", draw); } | |
| new MutationObserver(draw).observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] }); | |
| })(); | |
| </script> | |