{"spec_id":"area-stacked-percent","library":"echarts","language":"javascript","code":"// anyplot.ai\n// area-stacked-percent: 100% Stacked Area Chart\n// Library: echarts 6.1.0 | JavaScript 22.23.2\n// Quality: 91/100 | Created: 2026-09-02\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Cloud infrastructure market share by provider, quarterly, in $M spend.\nconst quarters = [\n  \"2022 Q1\", \"2022 Q2\", \"2022 Q3\", \"2022 Q4\",\n  \"2023 Q1\", \"2023 Q2\", \"2023 Q3\", \"2023 Q4\",\n  \"2024 Q1\", \"2024 Q2\", \"2024 Q3\", \"2024 Q4\",\n];\nconst rawSpend = {\n  \"Cascade Cloud\": [820, 880, 930, 1010, 1080, 1160, 1230, 1310, 1390, 1470, 1540, 1610],\n  \"Meridian Cloud\": [640, 690, 730, 760, 790, 810, 830, 850, 860, 870, 880, 890],\n  \"Nimbus Systems\": [510, 520, 540, 560, 590, 610, 640, 670, 710, 750, 790, 830],\n  \"Anchorpoint\": [300, 310, 300, 310, 300, 290, 280, 270, 260, 250, 240, 230],\n  \"Other providers\": [230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120],\n};\nconst providers = Object.keys(rawSpend);\n\nconst totals = quarters.map((_, i) =>\n  providers.reduce((sum, name) => sum + rawSpend[name][i], 0)\n);\nconst sharePct = {};\nproviders.forEach((name) => {\n  sharePct[name] = rawSpend[name].map((v, i) => (100 * v) / totals[i]);\n});\n\n// Give each band a little depth: a vertical gradient fill (richer near the\n// band's own boundary, softer toward the stack) instead of a flat opacity.\nfunction hexToRgba(hex, alpha) {\n  const n = parseInt(hex.slice(1), 16);\n  return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${alpha})`;\n}\nfunction bandGradient(hex) {\n  return new echarts.graphic.LinearGradient(0, 0, 0, 1, [\n    { offset: 0, color: hexToRgba(hex, 0.92) },\n    { offset: 1, color: hexToRgba(hex, 0.6) },\n  ]);\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: \"Cloud Spend Share · area-stacked-percent · javascript · echarts · anyplot.ai\",\n    left: \"center\",\n    textStyle: { color: t.ink, fontSize: 20, fontWeight: 500 },\n  },\n  grid: { left: 90, right: 40, top: 130, bottom: 110 },\n  legend: {\n    top: 68,\n    left: \"center\",\n    icon: \"roundRect\",\n    itemWidth: 16,\n    itemHeight: 10,\n    textStyle: { color: t.inkSoft, fontSize: 14 },\n  },\n  tooltip: { trigger: \"axis\" },\n  xAxis: {\n    type: \"category\",\n    data: quarters,\n    boundaryGap: false,\n    axisLabel: { color: t.inkSoft, fontSize: 14, rotate: 30 },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    axisTick: { show: false },\n    splitLine: { show: false },\n  },\n  yAxis: {\n    type: \"value\",\n    min: 0,\n    max: 100,\n    interval: 20,\n    axisLabel: { color: t.inkSoft, fontSize: 14, formatter: \"{value}%\" },\n    axisLine: { show: false },\n    axisTick: { show: false },\n    splitLine: { lineStyle: { color: t.grid } },\n  },\n  series: providers.map((name, i) => ({\n    name,\n    type: \"line\",\n    stack: \"share\",\n    areaStyle: { color: bandGradient(t.palette[i]), opacity: 0.9 },\n    lineStyle: { width: 1, color: t.pageBg },\n    showSymbol: false,\n    emphasis: { focus: \"series\" },\n    data: sharePct[name],\n  })),\n});\n"}