{"spec_id":"histogram-stacked","library":"echarts","language":"javascript","code":"// anyplot.ai\n// histogram-stacked: Stacked Histogram\n// Library: echarts 6.1.0 | JavaScript 22.23.2\n// Quality: 89/100 | Created: 2026-09-05\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic LCG — no Math.random) -------------------\nfunction makeLcg(seed) {\n  let state = seed >>> 0;\n  return function rng() {\n    state = (Math.imul(state, 1664525) + 1013904223) >>> 0;\n    return state / 4294967296;\n  };\n}\n\nfunction randomNormal(rng) {\n  const u1 = Math.max(rng(), 1e-9);\n  const u2 = rng();\n  return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);\n}\n\nfunction sampleWaitTimes(rng, mean, stdDev, count) {\n  const samples = [];\n  for (let i = 0; i < count; i++) {\n    samples.push(Math.max(0.2, mean + stdDev * randomNormal(rng)));\n  }\n  return samples;\n}\n\nconst rng = makeLcg(42);\nconst waitTimesDowntown = sampleWaitTimes(rng, 4.0, 1.4, 500);\nconst waitTimesUptown = sampleWaitTimes(rng, 6.5, 1.8, 500);\nconst waitTimesSuburban = sampleWaitTimes(rng, 9.0, 2.2, 500);\n\nconst allWaitTimes = [...waitTimesDowntown, ...waitTimesUptown, ...waitTimesSuburban];\nconst rangeMin = Math.min(...allWaitTimes);\nconst rangeMax = Math.max(...allWaitTimes);\nconst binCount = 14;\nconst binWidth = (rangeMax - rangeMin) / binCount;\nconst binLabels = Array.from({ length: binCount }, (_, i) => {\n  const lo = rangeMin + i * binWidth;\n  const hi = rangeMin + (i + 1) * binWidth;\n  return `${lo.toFixed(1)}–${hi.toFixed(1)}`;\n});\n\nfunction binFrequencies(values) {\n  const counts = new Array(binCount).fill(0);\n  for (const value of values) {\n    let idx = Math.floor((value - rangeMin) / binWidth);\n    if (idx >= binCount) idx = binCount - 1;\n    if (idx < 0) idx = 0;\n    counts[idx]++;\n  }\n  return counts;\n}\n\nconst frequenciesDowntown = binFrequencies(waitTimesDowntown);\nconst frequenciesUptown = binFrequencies(waitTimesUptown);\nconst frequenciesSuburban = binFrequencies(waitTimesSuburban);\n\n// --- Init ---------------------------------------------------------------\nconst chart = echarts.init(document.getElementById(\"container\"));\n\n// --- Option ---------------------------------------------------------------\nchart.setOption({\n  animation: false,\n  color: t.palette,\n  backgroundColor: \"transparent\",\n  title: {\n    text: \"histogram-stacked · javascript · echarts · anyplot.ai\",\n    left: \"center\",\n    top: 22,\n    textStyle: { color: t.ink, fontSize: 22, fontWeight: 500 },\n  },\n  legend: {\n    data: [\"Downtown\", \"Uptown\", \"Suburban\"],\n    top: 76,\n    textStyle: { color: t.inkSoft, fontSize: 16 },\n  },\n  tooltip: {\n    trigger: \"axis\",\n    axisPointer: { type: \"shadow\" },\n    backgroundColor: t.elevatedBg,\n    borderColor: t.grid,\n    textStyle: { color: t.ink },\n    formatter: (params) => {\n      const total = params.reduce((sum, p) => sum + p.value, 0);\n      const lines = params.map((p) => `${p.marker} ${p.seriesName}: ${p.value}`);\n      return `${params[0].axisValue}<br/>${lines.join(\"<br/>\")}<br/><strong>Total: ${total}</strong>`;\n    },\n  },\n  grid: { left: 100, right: 60, top: 150, bottom: 100 },\n  xAxis: {\n    type: \"category\",\n    data: binLabels,\n    name: \"Wait Time (minutes)\",\n    nameLocation: \"middle\",\n    nameGap: 54,\n    nameTextStyle: { color: t.ink, fontSize: 16 },\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    axisTick: { show: false },\n    splitLine: { show: false },\n  },\n  yAxis: {\n    type: \"value\",\n    name: \"Frequency\",\n    nameLocation: \"middle\",\n    nameGap: 64,\n    nameTextStyle: { color: t.ink, fontSize: 16 },\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { show: false },\n    axisTick: { show: false },\n    splitLine: { lineStyle: { color: t.grid } },\n  },\n  series: [\n    {\n      name: \"Downtown\",\n      type: \"bar\",\n      stack: \"total\",\n      data: frequenciesDowntown,\n      itemStyle: { color: t.palette[0], borderColor: t.pageBg, borderWidth: 1 },\n      emphasis: { focus: \"series\" },\n      barCategoryGap: \"0%\",\n    },\n    {\n      name: \"Uptown\",\n      type: \"bar\",\n      stack: \"total\",\n      data: frequenciesUptown,\n      itemStyle: { color: t.palette[1], borderColor: t.pageBg, borderWidth: 1 },\n      emphasis: { focus: \"series\" },\n    },\n    {\n      name: \"Suburban\",\n      type: \"bar\",\n      stack: \"total\",\n      data: frequenciesSuburban,\n      itemStyle: {\n        color: t.palette[2],\n        borderColor: t.pageBg,\n        borderWidth: 1,\n        borderRadius: [6, 6, 0, 0],\n      },\n      emphasis: { focus: \"series\" },\n    },\n  ],\n});\n"}