Small multiples

스몰 멀티플

Repeats the same small chart, same scale, once per category — instead of cramming everything into one chart, it lays them side by side.

Also known as: Trellis chart패널 차트격자 차트
···
html
<div class="viz" id="viz"></div>
css
body{display:block}
.viz{width:100%;height:100%;display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(2,1fr);gap:2px;box-sizing:border-box;padding:4px}
.cell{position:relative;border:1px solid var(--line);border-radius:4px;overflow:hidden}
.cell svg{display:block;width:100%;height:100%}
.cell .ttl{position:absolute;top:2px;left:4px;font:700 8px/1 system-ui,sans-serif;color:var(--muted);z-index:1}
@media (min-width:460px){ .cell .ttl{font-size:11px} }
js
var viz = document.getElementById('viz');
var NS = 'http://www.w3.org/2000/svg';
function se(t){ return document.createElementNS(NS,t); }
function sa(e,o){ for (var k in o) e.setAttribute(k,o[k]); }
function R(a,b){ return a + Math.random()*(b-a); }

var PANELS = ['1월','2월','3월','4월','5월','6월'];
var HL = 0;
var Nm = 6;
var svgs = [];
PANELS.forEach(function(name){
  var cell = document.createElement('div');
  cell.className = 'cell';
  var ttl = document.createElement('div');
  ttl.className = 'ttl';
  ttl.textContent = name;
  var svg = se('svg');
  cell.appendChild(ttl);
  cell.appendChild(svg);
  viz.appendChild(cell);
  svgs.push(svg);
});

var series = PANELS.map(function(){
  var v=50, out=[];
  for (var i=0;i<Nm;i++){ v=Math.max(10,Math.min(90, v+R(-20,20))); out.push(v); }
  return out;
});
var cur = series.map(function(a){ return a.slice(); });

function drawPanel(svg, vals, isHL){
  svg.innerHTML = '';
  var r = svg.getBoundingClientRect();
  var W = Math.max(r.width,10), H = Math.max(r.height,10);
  sa(svg,{ viewBox:'0 0 '+W+' '+H });
  var padL=4, padR=4, padT=13, padB=4;
  var pw=W-padL-padR, ph=H-padT-padB;
  var base = se('line');
  sa(base,{x1:padL,y1:padT+ph,x2:W-padR,y2:padT+ph,stroke:'var(--line)','stroke-width':1});
  svg.appendChild(base);
  var pts = vals.map(function(v,i){ return { x:padL+(pw*i)/(Nm-1), y:padT+ph-(v/100)*ph }; });
  var d = pts.map(function(p,i){ return (i===0?'M':'L')+p.x.toFixed(1)+','+p.y.toFixed(1); }).join(' ');
  var path = se('path');
  sa(path,{ d:d, fill:'none', stroke: isHL?'var(--accent)':'var(--muted)', 'stroke-width': isHL?2.2:1.4, 'stroke-linecap':'round', 'stroke-linejoin':'round', opacity: isHL?1:0.55 });
  svg.appendChild(path);
}

function drawAll(){
  svgs.forEach(function(svg,i){ drawPanel(svg, cur[i], i===HL); });
}

function animate(target){
  var from = cur.map(function(a){ return a.slice(); });
  var t0 = performance.now();
  function step(t){
    var p = Math.min(1,(t-t0)/800);
    var e = 1-Math.pow(1-p,3);
    cur = from.map(function(row,ri){ return row.map(function(v,i){ return v+(target[ri][i]-v)*e; }); });
    drawAll();
    if (p<1) requestAnimationFrame(step);
  }
  requestAnimationFrame(step);
}

new ResizeObserver(function(){ drawAll(); }).observe(viz);
drawAll();
setInterval(function(){
  var target = PANELS.map(function(){
    var v=50, out=[];
    for (var i=0;i<Nm;i++){ v=Math.max(10,Math.min(90, v+R(-20,20))); out.push(v); }
    return out;
  });
  animate(target);
}, 3800);

Edward Tufte called this "one of the most powerful design principles." Instead of five lines tangled into spaghetti, five small charts sharing the same y-range sit in a grid where each series' shape stays fully visible, unobstructed by the others.

The one rule that makes it work is a shared axis. If each panel gets its own y-range, small changes look big and big changes look small, and any cross-panel comparison collapses. Lock the scale across every panel, and label it once — on the first panel or in the margin — rather than repeating it everywhere.

To emphasize one panel, give just that one a strong color and mute the rest — there's no need for a different hue per panel, since position and title already tell them apart.

When to use

Use it once you have more than ~4 series that would tangle into spaghetti on one chart, and you need to compare them on the same scale.