{"spec_id":"venn-basic","library":"echarts","language":"javascript","code":"// anyplot.ai\n// venn-basic: Venn Diagram\n// Library: echarts 6.1.0 | JavaScript 22.23.2\n// Quality: 94/100 | Created: 2026-09-09\n//# anyplot-orientation: square\n\nconst t = window.ANYPLOT_TOKENS;\nconst { width, height } = window.ANYPLOT_SIZE;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Primary programming languages reported by software engineers in a skills\n// survey. Each set is the total engineers who know that language; the\n// overlap counts are the engineers who know two or all three.\nconst SET_A = { name: \"Python\", total: 120, color: t.palette[0] };\nconst SET_B = { name: \"JavaScript\", total: 100, color: t.palette[1] };\nconst SET_C = { name: \"SQL\", total: 90, color: t.palette[2] };\n\nconst REGIONS = {\n  aOnly: 55,\n  bOnly: 40,\n  cOnly: 40,\n  abOnly: 30,\n  acOnly: 20,\n  bcOnly: 15,\n  abc: 15,\n};\n\n// --- Geometry -----------------------------------------------------------\n// Symmetric 3-circle layout: centers sit on a small circle around the\n// canvas center, 120 degrees apart. Each circle's radius is scaled by\n// sqrt(set total / average total) so the diagram visually hints at the\n// differing set sizes (proportional/Euler-style approximation) instead of\n// three identical circles. Region labels are placed along the same radial\n// directions at hand-tuned radii - scaled to each region's own circle(s)\n// so they still land inside the intended lens/petal without touching\n// neighbors now that radii differ.\nconst cx = width / 2;\nconst cy = height / 2;\nconst r = Math.min(width, height) * 0.22;\nconst centerOffset = r * 0.62;\n\nconst AVG_TOTAL = (SET_A.total + SET_B.total + SET_C.total) / 3;\nconst radiusFor = (total) => r * Math.sqrt(total / AVG_TOTAL);\nconst RADIUS_A = radiusFor(SET_A.total);\nconst RADIUS_B = radiusFor(SET_B.total);\nconst RADIUS_C = radiusFor(SET_C.total);\nconst RADII = [RADIUS_A, RADIUS_B, RADIUS_C];\n\nconst polar = (angleDeg, radius) => ({\n  x: cx + radius * Math.cos((angleDeg * Math.PI) / 180),\n  y: cy - radius * Math.sin((angleDeg * Math.PI) / 180),\n});\n\nconst ANGLE_A = 150;\nconst ANGLE_B = 30;\nconst ANGLE_C = 270;\nconst ANGLE_AB = 90;\nconst ANGLE_AC = 210;\nconst ANGLE_BC = 330;\n\nconst CIRCLE_A = polar(ANGLE_A, centerOffset);\nconst CIRCLE_B = polar(ANGLE_B, centerOffset);\nconst CIRCLE_C = polar(ANGLE_C, centerOffset);\n\nconst onlyLabelRadiusFor = (radius) => centerOffset + radius * 0.45;\nconst pairLabelRadiusFor = (radiusI, radiusJ) => ((radiusI + radiusJ) / 2) * 0.75;\n\n// Nudged up from the canonical 0.5 midpoint so each additional overlapping\n// circle adds more opacity - single/double/triple regions stay distinct by\n// lightness alone, which keeps them distinguishable under CVD simulation\n// even when the blended hues are hard to tell apart.\nconst OVERLAP_ALPHA = 0.55;\n\nconst hexToRgba = (hex, alpha) => {\n  const n = parseInt(hex.slice(1), 16);\n  const red = (n >> 16) & 255;\n  const green = (n >> 8) & 255;\n  const blue = n & 255;\n  return `rgba(${red}, ${green}, ${blue}, ${alpha})`;\n};\n\n// --- Title --------------------------------------------------------------\nconst TITLE = \"venn-basic · javascript · echarts · anyplot.ai\";\nconst titleFontSize = TITLE.length > 67 ? Math.round(22 * (67 / TITLE.length)) : 22;\n\n// --- Graphic elements -----------------------------------------------------\nconst circles = [SET_A, SET_B, SET_C].map((set, i) => {\n  const centerPoint = [CIRCLE_A, CIRCLE_B, CIRCLE_C][i];\n  return {\n    type: \"circle\",\n    shape: { cx: centerPoint.x, cy: centerPoint.y, r: RADII[i] },\n    style: {\n      fill: hexToRgba(set.color, OVERLAP_ALPHA),\n      stroke: t.pageBg,\n      lineWidth: 4,\n    },\n    z: 2,\n  };\n});\n\nconst setLabels = [SET_A, SET_B, SET_C].map((set, i) => {\n  const angle = [ANGLE_A, ANGLE_B, ANGLE_C][i];\n  const pos = polar(angle, RADII[i] * 1.55);\n  return {\n    type: \"text\",\n    left: pos.x,\n    top: pos.y,\n    style: {\n      text: `${set.name}\\n${set.total}`,\n      fill: t.ink,\n      stroke: t.pageBg,\n      lineWidth: 3,\n      font: \"bold 28px sans-serif\",\n      textAlign: \"center\",\n      textVerticalAlign: \"middle\",\n      lineHeight: 32,\n    },\n    z: 5,\n  };\n});\n\nconst regionLabelSpecs = [\n  { count: REGIONS.aOnly, pos: polar(ANGLE_A, onlyLabelRadiusFor(RADIUS_A)) },\n  { count: REGIONS.bOnly, pos: polar(ANGLE_B, onlyLabelRadiusFor(RADIUS_B)) },\n  { count: REGIONS.cOnly, pos: polar(ANGLE_C, onlyLabelRadiusFor(RADIUS_C)) },\n  { count: REGIONS.abOnly, pos: polar(ANGLE_AB, pairLabelRadiusFor(RADIUS_A, RADIUS_B)) },\n  { count: REGIONS.acOnly, pos: polar(ANGLE_AC, pairLabelRadiusFor(RADIUS_A, RADIUS_C)) },\n  { count: REGIONS.bcOnly, pos: polar(ANGLE_BC, pairLabelRadiusFor(RADIUS_B, RADIUS_C)) },\n];\n\nconst regionLabels = regionLabelSpecs.map((region) => ({\n  type: \"text\",\n  left: region.pos.x,\n  top: region.pos.y,\n  style: {\n    text: String(region.count),\n    fill: t.ink,\n    stroke: t.pageBg,\n    lineWidth: 3,\n    font: \"bold 26px sans-serif\",\n    textAlign: \"center\",\n    textVerticalAlign: \"middle\",\n  },\n  z: 5,\n}));\n\n// Focal point: the triple-overlap is the smallest and most noteworthy\n// relationship (engineers who know all three languages) - a subtle ring\n// plus a larger, bolder count gives it visual weight instead of treating\n// all seven regions identically.\nconst abcRing = {\n  type: \"circle\",\n  shape: { cx, cy, r: 34 },\n  style: { fill: \"transparent\", stroke: t.ink, lineWidth: 1.5, opacity: 0.55 },\n  z: 4,\n};\n\nconst abcLabel = {\n  type: \"text\",\n  left: cx,\n  top: cy,\n  style: {\n    text: String(REGIONS.abc),\n    fill: t.ink,\n    stroke: t.pageBg,\n    lineWidth: 3,\n    font: \"bold 32px sans-serif\",\n    textAlign: \"center\",\n    textVerticalAlign: \"middle\",\n  },\n  z: 6,\n};\n\n// --- Init + option ------------------------------------------------------\nconst chart = echarts.init(document.getElementById(\"container\"));\n\nchart.setOption({\n  animation: false,\n  backgroundColor: \"transparent\",\n  title: {\n    text: TITLE,\n    left: \"center\",\n    top: height * 0.04,\n    textStyle: { color: t.ink, fontSize: titleFontSize },\n  },\n  graphic: {\n    elements: [...circles, ...setLabels, ...regionLabels, abcRing, abcLabel],\n  },\n});\n"}