{"spec_id":"histogram-basic","library":"echarts","language":"javascript","code":"// anyplot.ai\n// histogram-basic: Basic Histogram\n// Library: echarts 6.1.0 | JavaScript 22.23.2\n// Quality: 88/100 | Created: 2026-08-26\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ---------------------------------------\n// Parcel delivery times (minutes) — right-skewed: most deliveries are quick,\n// a long tail of delayed ones (Erlang-distributed via a fixed-seed LCG).\nfunction makeLcg(seed) {\n  let state = seed;\n  return function random() {\n    state = (state * 1664525 + 1013904223) % 4294967296;\n    return state / 4294967296;\n  };\n}\nconst random = makeLcg(42);\n\nconst sampleCount = 400;\nconst deliveryTimes = [];\nfor (let i = 0; i < sampleCount; i++) {\n  let erlangSum = 0;\n  for (let j = 0; j < 3; j++) {\n    erlangSum += -Math.log(random());\n  }\n  deliveryTimes.push(8 + erlangSum * 6);\n}\n\nconst binCount = 22;\nconst minValue = Math.min(...deliveryTimes);\nconst maxValue = Math.max(...deliveryTimes);\nconst binWidth = (maxValue - minValue) / binCount;\nconst binCounts = new Array(binCount).fill(0);\ndeliveryTimes.forEach((value) => {\n  const index = Math.min(\n    Math.floor((value - minValue) / binWidth),\n    binCount - 1,\n  );\n  binCounts[index]++;\n});\nconst binLabels = binCounts.map((_, i) => Math.round(minValue + i * binWidth));\n\nconst mean = deliveryTimes.reduce((sum, v) => sum + v, 0) / deliveryTimes.length;\nconst meanBinIndex = Math.min(\n  Math.floor((mean - minValue) / binWidth),\n  binCount - 1,\n);\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-basic · javascript · echarts · anyplot.ai\",\n    left: \"center\",\n    textStyle: { color: t.ink, fontSize: 22 },\n  },\n  grid: { left: 100, right: 60, top: 100, bottom: 110 },\n  xAxis: {\n    type: \"category\",\n    data: binLabels,\n    name: \"Delivery Time (minutes)\",\n    nameLocation: \"middle\",\n    nameGap: 45,\n    nameTextStyle: { color: t.ink, fontSize: 16 },\n    axisLabel: { color: t.inkSoft, fontSize: 14, interval: \"auto\" },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    axisTick: { show: false },\n    splitLine: { show: false },\n  },\n  yAxis: {\n    type: \"value\",\n    min: 0,\n    name: \"Frequency\",\n    nameLocation: \"middle\",\n    nameGap: 65,\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      type: \"bar\",\n      data: binCounts,\n      barCategoryGap: \"0%\",\n      itemStyle: { color: t.palette[0], borderColor: t.pageBg, borderWidth: 1 },\n      markLine: {\n        symbol: \"none\",\n        silent: true,\n        lineStyle: { color: t.ink, type: \"dashed\", width: 2 },\n        label: {\n          formatter: `Mean: ${mean.toFixed(1)} min`,\n          color: t.ink,\n          fontSize: 13,\n          position: \"insideEndTop\",\n        },\n        data: [{ xAxis: meanBinIndex }],\n      },\n    },\n  ],\n});\n"}