Lijngrafiek met vergelijking New
Area line chart for the last 12 months with a dashed line for the year before. Hover or arrow keys show a reading line with both values and the difference; an aria-live line announces it and a hidden table is the alternative. The line draws in when in view (stroke-dashoffset), instantly with reduced motion.
Fysio Kralingen · Rotterdam
Websitebezoekers per maand
Bijgewerkt ma 6 okt, 21:07
- Afgelopen 12 mnd
- Jaar ervoor
| Maand | okt | nov | dec | jan | feb | mrt | apr | mei | jun | jul | aug | sep |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Afgelopen 12 mnd | 1180 | 1240 | 960 | 1420 | 1510 | 1690 | 1620 | 1580 | 1340 | 1210 | 1460 | 1720 |
| Jaar ervoor | 980 | 1010 | 820 | 1150 | 1230 | 1300 | 1340 | 1290 | 1100 | 1010 | 1180 | 1390 |
How to use it
- Paste the HTML where the numbers & charts should appear.
- Add the CSS to your stylesheet. All classes are prefixed, so nothing clashes with your own styles.
- Add the JavaScript and call init() with the element that contains the HTML.
<!-- Lijngrafiek met vergelijking · NedDev · eigen werk. -->
<div class="jouw-container">
<figure class="lgr"><div class="lgr__hd"><div><p class="lgr__k">Fysio Kralingen · Rotterdam</p><p class="lgr__t">Websitebezoekers per maand</p></div><p class="lgr__up">Bijgewerkt ma 6 okt, 21:07</p></div>
<ul class="lgr__lg"><li><i class="lgr__sw lgr__sw--c"></i>Afgelopen 12 mnd <b class="lgr__sum" data-r="0"></b></li><li><i class="lgr__sw lgr__sw--p"></i>Jaar ervoor <b class="lgr__sum" data-r="1"></b></li></ul>
<div class="lgr__plot" tabindex="0" role="group" aria-label="Lijngrafiek bezoekers. Gebruik pijl links en rechts om per maand te lezen."><div class="lgr__tip" hidden></div></div>
<p class="lgr__sr" aria-live="polite"></p>
<table class="lgr__sr"><caption>Websitebezoekers per maand, afgelopen 12 maanden en het jaar ervoor</caption><thead><tr><th scope="row">Maand</th><th scope="col" data-f="oktober 2025">okt</th><th scope="col" data-f="november 2025">nov</th><th scope="col" data-f="december 2025">dec</th><th scope="col" data-f="januari 2026">jan</th><th scope="col" data-f="februari 2026">feb</th><th scope="col" data-f="maart 2026">mrt</th><th scope="col" data-f="april 2026">apr</th><th scope="col" data-f="mei 2026">mei</th><th scope="col" data-f="juni 2026">jun</th><th scope="col" data-f="juli 2026">jul</th><th scope="col" data-f="augustus 2026">aug</th><th scope="col" data-f="september 2026">sep</th></tr></thead><tbody><tr><th scope="row">Afgelopen 12 mnd</th><td>1180</td><td>1240</td><td>960</td><td>1420</td><td>1510</td><td>1690</td><td>1620</td><td>1580</td><td>1340</td><td>1210</td><td>1460</td><td>1720</td></tr><tr><th scope="row">Jaar ervoor</th><td>980</td><td>1010</td><td>820</td><td>1150</td><td>1230</td><td>1300</td><td>1340</td><td>1290</td><td>1100</td><td>1010</td><td>1180</td><td>1390</td></tr></tbody></table></figure>
</div>/* Lijngrafiek met vergelijking · NedDev · eigen werk. */
.lgr{position:absolute;inset:0;margin:0;box-sizing:border-box;padding:14px 16px 8px;background:#fff;color:#0a0a0a;font-family:'Switzer',system-ui,sans-serif;display:flex;flex-direction:column;gap:6px}
.lgr__hd{display:flex;justify-content:space-between;align-items:flex-start;gap:10px}
.lgr__k{margin:0;font:500 10px/1.3 'JetBrains Mono',monospace;letter-spacing:.04em;color:#5f5e5a}
.lgr__t{margin:2px 0 0;font-size:15px;font-weight:650;line-height:1.2}
.lgr__up{margin:0;font:500 9.5px 'JetBrains Mono',monospace;color:#6b6a66;text-align:right}
.lgr__lg{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:4px 14px;font-size:11px;color:#3d3c39}
.lgr__lg li{display:flex;align-items:center;gap:6px}
.lgr__lg b{font-variant-numeric:tabular-nums;color:#0a0a0a}
.lgr__sw{display:inline-block;width:16px;height:0;border-top:2px solid #F5480F}
.lgr__sw--p{border-top:2px dashed #8a8883}
.lgr__plot{position:relative;flex:1;min-height:0;border-radius:4px;outline:none;cursor:crosshair}
.lgr__plot:focus-visible{box-shadow:0 0 0 2px #fff,0 0 0 4px #0a0a0a}
.lgr__svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.lgr__grid{stroke:rgba(10,10,10,.08)}.lgr__base{stroke:rgba(10,10,10,.35)}
.lgr__ax{font:500 10px 'JetBrains Mono',monospace;fill:#6b6a66}
.lgr__area{fill:#F5480F;fill-opacity:.1;opacity:0;transition:opacity .6s .7s}
.lgr__ln{fill:none;stroke:#F5480F;stroke-width:2;stroke-linejoin:round;stroke-linecap:round;stroke-dasharray:1;stroke-dashoffset:1;transition:stroke-dashoffset 1.3s cubic-bezier(.4,0,.2,1)}
.lgr__pv{fill:none;stroke:#8a8883;stroke-width:1.5;stroke-dasharray:4 4;opacity:0;transition:opacity .5s .3s}
.lgr.is-in .lgr__ln{stroke-dashoffset:0}.lgr.is-in .lgr__area,.lgr.is-in .lgr__pv{opacity:1}
.lgr__vl{stroke:#0a0a0a;stroke-width:1;stroke-dasharray:2 3;opacity:0}
.lgr__dot{stroke:#fff;stroke-width:2;opacity:0}
.lgr__dot--c{fill:#F5480F}.lgr__dot--p{fill:#8a8883}
.lgr.is-hover .lgr__vl,.lgr.is-hover .lgr__dot{opacity:1}
.lgr__tip{position:absolute;z-index:2;pointer-events:none;top:0;transform:translateX(-50%);background:#0a0a0a;color:#fff;border-radius:4px;padding:5px 8px;font:500 11px/1.4 'Switzer',system-ui,sans-serif;white-space:nowrap;font-variant-numeric:tabular-nums}
.lgr__tip b{display:block;font-size:11px;color:#cfcdc9;font-weight:500}
.lgr__tip em{font-style:normal;color:#ffb08f}
.lgr__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0}
@media(max-width:420px){.lgr{padding:10px 12px 6px}.lgr__up{display:none}}
@media(prefers-reduced-motion:reduce){.lgr__ln,.lgr__area,.lgr__pv{transition:none}}// Lijngrafiek met vergelijking · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.lgr');if(!w)return;var NS='http://www.w3.org/2000/svg';
function el(t,a){var e=document.createElementNS(NS,t);for(var k in a)e.setAttribute(k,a[k]);return e;}
function nl(v){return v.toLocaleString('nl-NL');}
var hs=[].slice.call(w.querySelectorAll('table thead th[scope="col"]')),trs=w.querySelectorAll('table tbody tr');
var M=hs.map(function(h){return {s:h.textContent.trim(),f:h.dataset.f};});
var S=[].map.call(trs,function(tr){return [].map.call(tr.querySelectorAll('td'),function(td){return +td.textContent;});});
w.querySelectorAll('.lgr__sum').forEach(function(b){b.textContent=nl(S[+b.dataset.r].reduce(function(a,c){return a+c;},0));});
var W=380,H=150,L=36,R=10,T=10,B=20,max=2000,pw=W-L-R,ph=H-T-B,n=M.length;
function X(i){return L+i*pw/(n-1);}function Y(v){return T+ph-v/max*ph;}
var svg=el('svg',{viewBox:'0 0 '+W+' '+H,'class':'lgr__svg','aria-hidden':'true'});
[0,500,1000,1500,2000].forEach(function(t){svg.appendChild(el('line',{x1:L,x2:W-R,y1:Y(t),y2:Y(t),'class':t?'lgr__grid':'lgr__base'}));var tx=el('text',{x:L-6,y:Y(t)+3,'class':'lgr__ax','text-anchor':'end'});tx.textContent=nl(t);svg.appendChild(tx);});
M.forEach(function(m,i){if(i%2)return;var tx=el('text',{x:X(i),y:H-4,'class':'lgr__ax','text-anchor':'middle'});tx.textContent=m.s;svg.appendChild(tx);});
function line(a){return a.map(function(v,i){return (i?'L':'M')+X(i).toFixed(1)+','+Y(v).toFixed(1);}).join('');}
svg.appendChild(el('path',{'class':'lgr__area',d:line(S[0])+'L'+X(n-1)+','+Y(0)+'L'+X(0)+','+Y(0)+'Z'}));
svg.appendChild(el('path',{'class':'lgr__pv',d:line(S[1])}));
svg.appendChild(el('path',{'class':'lgr__ln',d:line(S[0]),pathLength:'1'}));
var vl=el('line',{'class':'lgr__vl',y1:T,y2:T+ph}),dp=el('circle',{'class':'lgr__dot lgr__dot--p',r:3.5}),dc=el('circle',{'class':'lgr__dot lgr__dot--c',r:4.5});
svg.appendChild(vl);svg.appendChild(dp);svg.appendChild(dc);
var plot=w.querySelector('.lgr__plot'),tip=w.querySelector('.lgr__tip'),live=w.querySelector('p.lgr__sr'),idx=-1;plot.insertBefore(svg,tip);
function pct(i){return Math.round((S[0][i]-S[1][i])/S[1][i]*100);}
function show(i,say){idx=i;var x=X(i);vl.setAttribute('x1',x);vl.setAttribute('x2',x);dc.setAttribute('cx',x);dc.setAttribute('cy',Y(S[0][i]));dp.setAttribute('cx',x);dp.setAttribute('cy',Y(S[1][i]));w.classList.add('is-hover');
var p=pct(i),ps=(p>0?'+':'')+p+'%';tip.innerHTML='<b>'+M[i].f+'</b>'+nl(S[0][i])+' bezoekers <em>'+ps+'</em><br>'+nl(S[1][i])+' jaar ervoor';tip.hidden=false;
var pt=svg.createSVGPoint();pt.x=x;pt.y=0;var c=pt.matrixTransform(svg.getScreenCTM()),pr=plot.getBoundingClientRect(),tw=tip.offsetWidth,lx=c.x-pr.left;
var left=lx+(lx>pr.width/2?-tw/2-10:tw/2+10);tip.style.left=Math.max(tw/2,Math.min(pr.width-tw/2,left))+'px';
if(say)live.textContent=M[i].f+': '+nl(S[0][i])+' bezoekers, jaar ervoor '+nl(S[1][i])+', verschil '+ps+'.';}
function hide(){w.classList.remove('is-hover');tip.hidden=true;}
plot.addEventListener('pointermove',function(e){var pt=svg.createSVGPoint();pt.x=e.clientX;pt.y=e.clientY;var s=pt.matrixTransform(svg.getScreenCTM().inverse());var i=Math.round((s.x-L)/(pw/(n-1)));show(Math.max(0,Math.min(n-1,i)),false);});
plot.addEventListener('pointerleave',function(){if(document.activeElement!==plot)hide();});
plot.addEventListener('focus',function(){show(idx<0?n-1:idx,true);});plot.addEventListener('blur',hide);
plot.addEventListener('keydown',function(e){var k=e.key,j=k==='ArrowRight'?idx+1:k==='ArrowLeft'?idx-1:k==='Home'?0:k==='End'?n-1:null;if(k==='Escape'){hide();return;}if(j!==null){e.preventDefault();show(Math.max(0,Math.min(n-1,j)),true);}});
if(matchMedia('(prefers-reduced-motion:reduce)').matches||!('IntersectionObserver' in window)){w.classList.add('is-in');}else{var io=new IntersectionObserver(function(es){if(es[0].isIntersecting){w.classList.add('is-in');io.disconnect();}},{threshold:.35});io.observe(w);}
}
init(document.querySelector('.jouw-container'));
More numbers & charts
Seen something you like?
Add it to your selection and send it over. We build your site around it, in your brand.
Get in touch →