Radar: profil umiejętności
Wizualizacja danychPodgląd
Ładowanie podglądu…
Wykres radarowy porównuje dwa profile umiejętności na pięciu osiach.
Kod źródłowy
Licencja MIT — także do użytku komercyjnego. Zachowaj informacje o autorze i licencji.
HTML
<main><header><div><h1>Radar: profil umiejętności</h1><p>Przykładowe dane</p></div><label for="view">Scenariusz<select id="view"><option value="base">Widok bazowy</option><option value="compare">Porównanie</option></select></label></header><figure aria-label="Radar: profil umiejętności"><svg id="chart" viewBox="0 0 700 310" role="img" aria-labelledby="chart-title"><title id="chart-title">Radar: profil umiejętności</title></svg><figcaption class="legend"><span>Fiolet: profil bazowy</span><span>Złoto: porównanie</span></figcaption></figure><p id="status" class="status" aria-live="polite">Aktualny widok: Widok bazowy</p><details><summary>Dane i opis wykresu</summary><table><caption>Wykres radarowy porównuje dwa profile umiejętności na pięciu osiach.</caption><thead><tr><th scope="col">Element</th><th scope="col">Wartość</th><th scope="col">Porównanie</th></tr></thead><tbody id="values"></tbody></table></details></main>
CSS
:root{--paper:#f2edf8;--ink:#402859;--accent:#74569e}*{box-sizing:border-box}body{margin:0;background:var(--paper);color:var(--ink);font:16px/1.45 system-ui,sans-serif}main{max-width:900px;margin:auto;padding:26px}header{display:flex;justify-content:space-between;gap:20px;align-items:start}h1{font-size:clamp(24px,4vw,34px);margin:0 0 4px;font-weight:750;letter-spacing:-.03em}p{margin:0}header p{font-size:14px}label{font-weight:600;display:grid;gap:5px;font-size:13px}select{font:inherit;color:var(--ink);background:var(--paper);border:1px solid var(--ink);padding:10px;min-height:44px;border-radius:0}select:focus-visible,summary:focus-visible{outline:3px solid var(--accent);outline-offset:3px}figure{margin:20px 0 10px}svg{display:block;width:100%;height:auto;max-height:315px}svg text{font-family:inherit;fill:var(--ink);font-size:17px}.legend{display:flex;flex-wrap:wrap;gap:12px 20px;font-size:14px}.legend i{width:12px;height:12px;display:inline-block;margin-right:5px}.status{font-size:13px;margin-top:12px}details{margin-top:12px;font-size:13px}summary{cursor:pointer;min-height:36px}table{border-collapse:collapse;width:100%;margin-top:10px}td,th{text-align:left;border-bottom:1px solid var(--ink);padding:7px}caption{text-align:left;padding-bottom:10px}svg [data-point]:hover{opacity:.7}@media(max-width:520px){main{padding:18px}header{display:block}label{margin-top:14px;max-width:240px}figure{margin-top:24px}svg{min-height:190px}svg text:not([style]){font-size:22px}.legend{gap:8px 14px}h1{line-height:1.15}}@media(prefers-reduced-motion:no-preference){svg [data-point]{transition:opacity .2s}}
JavaScript
const labels=["HTML", "CSS", "JS", "UX", "Dane"],first=[85, 75, 56, 68, 40],second=[58, 49, 88, 52, 83];
const chart=document.querySelector('#chart'),select=document.querySelector('#view');
function grid(){return [0,25,50,75,100].map(v=>`<path d="M45,${260-v*2} H675" stroke="var(--ink)" opacity=".15"/><text x="35" y="${266-v*2}" text-anchor="end">${v}</text>`).join('')}
function textColor(hex,alpha=1){if(hex==='var(--accent)')hex=getComputedStyle(document.documentElement).getPropertyValue('--accent').trim();const paper=getComputedStyle(document.documentElement).getPropertyValue('--paper').trim();const rgb=h=>[1,3,5].map(i=>parseInt(h.slice(i,i+2),16));const bg=rgb(paper);const linear=rgb(hex).map((c,i)=>(c*alpha+bg[i]*(1-alpha))/255).map(c=>c<=.04045?c/12.92:((c+.055)/1.055)**2.4);const l=linear.reduce((v,c,i)=>v+c*[.2126,.7152,.0722][i],0);return l>.179?'#000':'#fff'}
function draw(a,b){const xy=(i,v)=>[320+Math.sin(i*Math.PI*2/5)*v*1.05,154-Math.cos(i*Math.PI*2/5)*v*1.05],poly=vs=>vs.map((v,i)=>xy(i,v).join(',')).join(' ');return [25,50,75,100].map(v=>`<polygon points="${poly(a.map(()=>v))}" fill="none" stroke="var(--ink)" opacity=".2"/>`).join('')+`<polygon data-point points="${poly(b)}" fill="#b58b34" fill-opacity=".2" stroke="#9c731c" stroke-width="3"><title>Profil porównawczy</title></polygon><polygon data-point points="${poly(a)}" fill="var(--accent)" fill-opacity=".25" stroke="var(--accent)" stroke-width="3"><title>Profil wybrany</title></polygon>`+labels.map((l,i)=>{const p=xy(i,124);return `<text x="${p[0]}" y="${p[1]+5}" text-anchor="middle">${l} ${a[i]}</text>`}).join('');}
function update(){const compare=select.value==='compare',a=compare?second:first,b=compare?first:second;chart.innerHTML='<title id="chart-title">'+"Radar: profil umiejętności"+'</title>'+draw(a,b);document.querySelector('#values').innerHTML=labels.map((l,i)=>`<tr><th scope="row">${l}</th><td>${a[i]}</td><td>${b[i]}</td></tr>`).join('');document.querySelector('#status').textContent='Aktualny widok: '+select.selectedOptions[0].textContent}
select.addEventListener('change',update);update();
Edytuj swój pen
Podaj adres e-mail użyty przy zapisie. Wyślemy link do edycji.