{"id":"0175a360-5697-4df1-acae-776877c2bdfb","name":"Revenue Mix Stacked Bars","slug":"revenue-mix-stacked-bars","category":"email-charts","description":"A board-update stacked bar chart in warm paper tones: revenue (or any metric) split by plan, product or segment per month, with an auto-generated legend. Made to sit at the top of a monthly investor or team email.","sample_params":{"eyebrow":"Monthly revenue","footnote":"Unaudited · internal","hue":"28","labels":"Jan,Feb,Mar,Apr,May,Jun","series":"Starter:8.2,8.9,9.4,10.1,10.9,11.6|Pro:14.5,15.2,16.8,18.1,19.7,21.4|Enterprise:6.0,6.0,7.5,7.5,9.0,10.5","subtitle":"H1 2026 · EUR thousands","title":"MRR by plan"},"spec":{"name":"revenue-mix-stacked-bars","width":1200,"height":630,"scale":2,"html":"\u003c!doctype html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n\u003cmeta charset='utf-8'\u003e\n\u003cstyle\u003e\n*{margin:0;padding:0;box-sizing:border-box}\nhtml,body{width:100%;height:100%}\nbody{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;overflow:hidden}\n.eyebrow{font-size:20px;font-weight:700;letter-spacing:.16em;text-transform:uppercase}\n.chip{display:inline-block;font-size:22px;font-weight:700;padding:6px 18px;border-radius:999px;vertical-align:middle}\n.chip.up{color:#0a7d4f;background:#e2f5ea}\n.chip.down{color:#b3261e;background:#fde9e7}\n.chip.flat{color:#5b6472;background:#eef0f4}\n\nbody{background:#fbfaf7;color:#191817}\n.card{width:100vw;height:100vh;padding:56px 64px 46px;display:flex;flex-direction:column}\n.head{display:flex;justify-content:space-between;align-items:flex-start}\n.eyebrow{color:hsl(var(--h) 45% 48%)}\nh1{font-size:50px;font-weight:800;letter-spacing:-0.02em;margin-top:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:700px}\n.subtitle{margin-top:8px;font-size:24px;color:#7d7a74}\n.legend{display:flex;gap:26px;margin-top:14px;flex-wrap:wrap;justify-content:flex-end;max-width:380px}\n.legend span{display:flex;align-items:center;gap:9px;font-size:22px;font-weight:600;color:#4d4a45;white-space:nowrap}\n.legend i{width:16px;height:16px;border-radius:5px}\n.chartbox{flex:1;margin-top:30px}\n.foot{margin-top:18px;display:flex;justify-content:space-between;font-size:19px;color:#a39f97;letter-spacing:.06em;text-transform:uppercase}\n\u003c/style\u003e\n\u003c/head\u003e\n\u003cbody style='--h: {{.hue}}'\u003e\n\u003cdiv class='card'\u003e\n  \u003cdiv class='head'\u003e\n    \u003cdiv\u003e\n      \u003cp class='eyebrow'\u003e{{.eyebrow}}\u003c/p\u003e\n      \u003ch1\u003e{{.title}}\u003c/h1\u003e\n      {{if .subtitle}}\u003cp class='subtitle'\u003e{{.subtitle}}\u003c/p\u003e{{end}}\n    \u003c/div\u003e\n    \u003cdiv class='legend' id='legend'\u003e\u003c/div\u003e\n  \u003c/div\u003e\n  \u003cdiv class='chartbox'\u003e\u003ccanvas id='c' width='1072' height='330'\u003e\u003c/canvas\u003e\u003c/div\u003e\n  \u003cdiv class='foot'\u003e\u003cspan\u003emedia0\u003c/span\u003e\u003cspan\u003e{{.footnote}}\u003c/span\u003e\u003c/div\u003e\n\u003c/div\u003e\n\u003cscript src='https://cdn.jsdelivr.net/npm/chart.js@4.4.9/dist/chart.umd.js'\u003e\u003c/script\u003e\n\u003cscript\u003e\nvar HUE=Number({{.hue}});\nvar labels={{.labels}}.split(',');\nvar series={{.series}}.split('|').map(function(s){\n  var i=s.indexOf(':');\n  return {name:s.slice(0,i),values:s.slice(i+1).split(',').map(Number)};\n});\nvar n=series.length;\nfunction shade(i){var l=n\u003c2?52:38+ i*(36/(n-1));return 'hsl('+HUE+' 62% '+l+'%)'}\nvar lg=document.getElementById('legend');\nseries.forEach(function(s,i){\n  var el=document.createElement('span');\n  var dot=document.createElement('i');dot.style.background=shade(i);\n  el.appendChild(dot);el.appendChild(document.createTextNode(s.name));\n  lg.appendChild(el);\n});\nChart.defaults.font.family=\"-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif\";\nChart.defaults.color='#8b877f';\nnew Chart(document.getElementById('c'),{\n  type:'bar',\n  data:{labels:labels,datasets:series.map(function(s,i){return {\n    label:s.name,data:s.values,backgroundColor:shade(i),\n    borderRadius:5,borderSkipped:false,maxBarThickness:110,categoryPercentage:.62\n  }})},\n  options:{\n    responsive:false,animation:false,devicePixelRatio:window.devicePixelRatio,\n    plugins:{legend:{display:false},tooltip:{enabled:false}},\n    scales:{\n      x:{stacked:true,grid:{display:false},border:{display:false},ticks:{font:{size:23,weight:600}}},\n      y:{stacked:true,beginAtZero:true,grid:{color:'#eeece6'},border:{display:false},ticks:{maxTicksLimit:5,font:{size:20}}}\n    }\n  }\n});\n\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n","params":{"eyebrow":{"type":"string","default":"Monthly revenue","maxLen":40,"description":"Small uppercase kicker above the title."},"footnote":{"type":"string","maxLen":60,"description":"Small right-aligned footer note."},"hue":{"type":"number","default":"28","maxLen":5,"description":"Base hue 0-360; series are rendered as light-to-dark shades of it."},"labels":{"type":"string","required":true,"maxLen":300,"description":"Comma-separated x-axis labels (e.g. months): Jan,Feb,Mar."},"series":{"type":"string","required":true,"maxLen":900,"description":"Stacked series as name:values pairs joined by |, e.g. Starter:8,9,10|Pro:14,15,16. Values are comma-separated and match labels by position."},"subtitle":{"type":"string","maxLen":90,"description":"Supporting line under the title, e.g. period and unit."},"title":{"type":"string","required":true,"maxLen":70,"description":"Chart headline, e.g. MRR by plan."}}}}
