-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.min.js
1 lines (1 loc) · 10.1 KB
/
index.min.js
1
export class AccessibleSVG{constructor(e){this.type=e.type,this.title=e.title,this.description=e.description,this.data=e.data,this.injection=e.injection,this.options=e.options,this.type==="pie"||this.type=="donut"?this.pie(this.data,this.injection):this.type==="bar"?this.bar(this.data,this.injection):this.type==="scatterplot"?this.scatterplot(this.data,this.injection):this.type==="line"?this.line(this.data,this.injection):this.type==="progress-bar"?this.progressBar(this.data,this.injection):this.type==="area"&&this.area(this.data,this.injection)}pie(e,c){const o=(r,x,y)=>{const h=document.createElement("circle");let b="25";h.setAttribute("r",b+"%"),h.setAttribute("cx","50%"),h.setAttribute("cy","50%"),b=16;const u=2*Math.PI*b,d=u*(r/100),m=d+","+u;return h.style.strokeDasharray=m,h.style.stroke=x,h.style.strokeDashoffset=String(y),{element:h,value:d}},a=r=>{let x=0;return r.forEach(y=>{x+=y.percentage}),x},n=r=>{let x="This pie is contains: ";return r.forEach(y=>{x+=String(y.percentage+"% for "+y.title+" and it's colored "+y.color+". ")}),x};if(a(e)!==100){console.log("The percentages for the pie must add up to exactly 100%.");return}const p=this.createSVG(0,0,64,64);let s=0;const i=p.querySelector("desc");i.innerText+=n(e);const l=[];if(e.forEach(r=>{const x=o(r.percentage,r.color,-s),y=document.createElement("title");y.setAttribute("role","tooltip"),y.innerText=r.title+": "+r.percentage+"%",s+=x.value,x.element.appendChild(y),l.push(x.element)}),p.classList.add("asg-pie"),this.options.animation==!0){let r=o("0","white",-s+.53096491487338).element;r.classList.add("asg-reveal"),r.style.animation="rotate "+this.options.duration+"s ease-in-out forwards reverse",r.style.transform="rotate(0deg) scale(1,-1)",r.style.transformOrigin="center",l.push(r)}l.forEach(r=>{p.appendChild(r)}),this.type==="donut"&&(p.innerHTML+='<circle r="35%" cx="50%" cy="50%" style="fill:white;"></circle>',p.style.border="none"),this.addDataType(p,this.type),this.hook(c,p)}bar(e,c){const o=e.length,a=10,n=e.map(u=>u.value),t=Math.max(...n),p=a,s=30,i=o*s+a*o+p*2,l=i;let r=a+p;const x=this.createSVG(0,0,i+2*a,l+2*a),y=(u,d,m,f)=>{const g=document.createElement("rect");return g.setAttribute("x",String(u)),g.setAttribute("width",String(d)),g.setAttribute("height",String(m)),g.setAttribute("y",String(l-m-a)),g.style.fill=f,g.setAttribute("transform","scale(1,-1) translate(0,-"+String(l+(l-m))+")"),this.options.animation&&(g.innerHTML='<animate attributeName="height" from="0" to="'+String(m)+'" dur="'+this.options.duration+'s" fill="freeze" />'),g};Object.keys(this.options).length!==0&&this.options.order&&(this.options.order==="desc"?e.sort((u,d)=>u.value<d.value?1:u.value>d.value?-1:0):this.options.order==="asc"&&e.sort((u,d)=>u.value>d.value?1:u.value<d.value?-1:0)),e.forEach((u,d)=>{const m=u.value,f=u.color===""?"black":u.color,g=u.title,A=m/t*l,S=y(r,s,A,f),M=this.text(g,r+u.title.length,l+a+a*.75,"8px"),v=this.createGTag(),C=document.createElement("title");C.innerText=g+": "+u.value,C.id="accessible-svg-graphs"+this.randomID(),C.setAttribute("role","tooltip"),v.appendChild(C),v.setAttribute("aria-labelledby",C.id),v.appendChild(S),v.appendChild(M),x.appendChild(v),r+=s+a});const h=this.drawLine(0,l+a,i,l+a,"0.2px"),b=this.drawLine(a,0,a,l+a,"0.5px");if(this.options.yAxis){const u=this.yAxisValues(this.options.yAxis,t,l,i,a,8);x.appendChild(u)}x.appendChild(h),x.appendChild(b),this.addDataType(x,this.type),this.hook(c,x)}scatterplot(e,c){const o=e.map(h=>h.x),a=Math.floor(Math.max(...o)*1),n=100,t=e.map(h=>h.y),p=Math.max(...t),s=4,i=p>a?n:Math.floor(p/a*n),l=this.createSVG(0,0,n+s,i+2*s),r=(h,b,u,d,m,f,g)=>{const A=document.createElement("circle");let S=document.createElement("title");return S.innerText="x: "+String(u)+", y: "+String(d)+", "+f,S.setAttribute("role","tooltip"),A.setAttribute("cx",String(h)),A.setAttribute("cy",String(b)),A.setAttribute("r",String(m)),A.style.strokeWidth="0.2px",A.style.stroke="gray",A.style.fill=g,this.options.animation===!0&&(A.setAttribute("opacity","0"),A.innerHTML+='<animate attributeName="opacity" repeatCount="1" from="0" to="1" dur="'+this.options.duration+'s" fill="freeze" />'),A.appendChild(S),A};e.forEach(h=>{const b=h.x/a*(n-s)+s,u=(p-h.y)/p*i+s,d=h.title,m=this.options.radius?this.options.radius:1,f=r(b,u,h.x,h.y,m,d,h.color);l.appendChild(f)});const x=this.drawLine(s,i+s,n+s,i+s,"0.1px"),y=this.drawLine(s,0,s,i+s,"0.3px");if(this.options.yAxis){const h=this.yAxisValues(this.options.yAxis,p,i,n,s,2.2);l.appendChild(h)}if(this.options.xAxis){const h=this.xAxisValue(this.options.xAxis,i,s,3,0,a,n);l.appendChild(h)}l.appendChild(x),l.appendChild(y),this.addDataType(l,this.type),this.hook(c,l)}line(e,c){const o=e.map(d=>d.x),a=e.map(d=>d.y),n=Math.max(...a),t=4,p=o.length,s=p*t*2,i=s,l=Math.floor((s+t)/p),r=this.createSVG(0,0,s+2*t,i+2*t);e.sort((d,m)=>d.x>m.x?1:d.x<m.x?-1:0);const x=e.length;let y="";for(let d=0;d<x-1;d++){const m=d===0?2*t:l*d+t+t;let f=i-e[d].y/n*i+t;const g=l*(d+1)+t+t;let A=i-e[d+1].y/n*i+t;d===0?y="M "+Math.floor(m)+" "+Math.floor(f)+" L "+Math.floor(g)+" "+Math.floor(A):y+=" L "+Math.floor(g)+" "+Math.floor(A)}const h=this.options.fontSize?this.doPath(y,this.options.strikeWidth):this.doPath(y);r.appendChild(h);const b=this.drawLine(t,i+t,s+t,i+t,"0.2px"),u=this.drawLine(t,0,t,i+t,"0.2px");if(this.options.yAxis){const d=this.options.fontSize?this.yAxisValues(this.options.yAxis,n,i,s,t,this.options.fontSize):this.yAxisValues(this.options.yAxis,n,i,s,t,3);r.appendChild(d)}if(this.options.xAxis){const d=this.options.fontSize?this.xAxisValue(this.options.xAxis,i,t,this.options.fontSize,l):this.xAxisValue(this.options.xAxis,i,t,3,l);r.appendChild(d)}r.appendChild(b),r.appendChild(u),this.addDataType(r,this.type),this.hook(c,r)}progressBar(e,c){const o=e,a=100,n=10,t=this.createSVG(0,0,100,10),p=(r,x,y)=>{const h=document.createElement("rect");return h.setAttribute("x","0"),h.setAttribute("width",String(r)),h.setAttribute("height",String(n)),h.setAttribute("y","0"),h.style.fill=x,this.options.animation&&this.options.duration&&y&&(h.innerHTML='<animate attributeName="width" from="0" to="'+String(o)+'" dur="'+this.options.duration+'s" fill="freeze" />'),h},s=this.createGTag(!1);s.appendChild(p(a,this.options.outterColor,!1));const i=this.createGTag(!0),l=document.createElement("title");l.innerText="70%",i.appendChild(l),i.appendChild(p(o,this.options.innerColor,!0)),t.appendChild(s),t.appendChild(i),this.addDataType(t,this.type),this.hook(c,t)}area(e,c){const o=e.map(f=>f.x),a=e.map(f=>f.y),n=Math.max(...a),t=4,p=o.length,s=p*t*2,i=s,l=Math.floor((s+t)/p),r=this.createSVG(0,0,s+2*t,i+2*t);e.sort((f,g)=>f.x>g.x?1:f.x<g.x?-1:0);const x=2*t,y=i-e[0].y/n*i+t;let h=`M ${Math.floor(x)} ${Math.floor(y)}`;for(let f=1;f<e.length;f++){const g=l*f+t+t,A=i-e[f].y/n*i+t;h+=` L ${Math.floor(g)} ${Math.floor(A)}`}const b=l*(e.length-1)+t+t;h+=` L ${Math.floor(b)} ${i+t}`,h+=` L ${Math.floor(x)} ${i+t} Z`;const u=this.options.fontSize?this.doPath(h,this.options.strikeWidth):this.doPath(h);u.setAttribute("fill",this.options.innerColor?this.options.innerColor:"lightblue"),this.options.animation?(u.setAttribute("fill-opacity","0"),u.innerHTML+=`<animate attributeName="fill-opacity" from="0" to="0.6" dur="${this.options.duration}s" fill="freeze" />`):u.setAttribute("fill-opacity","0.6"),r.appendChild(u);const d=this.drawLine(t,i+t,s+t,i+t,"0.2px"),m=this.drawLine(t,0,t,i+t,"0.2px");if(this.options.yAxis){const f=this.options.fontSize?this.yAxisValues(this.options.yAxis,n,i,s,t,this.options.fontSize):this.yAxisValues(this.options.yAxis,n,i,s,t,3);r.appendChild(f)}if(this.options.xAxis){const f=this.options.fontSize?this.xAxisValue(this.options.xAxis,i,t,this.options.fontSize,l):this.xAxisValue(this.options.xAxis,i,t,3,l);r.appendChild(f)}r.appendChild(d),r.appendChild(m),this.addDataType(r,this.type),this.hook(c,r)}createSVG(e=0,c=0,o=64,a=64){const n=document.createElement("svg");n.setAttribute("viewBox",e+" "+c+" "+o+" "+a),n.setAttribute("xmlns","http://www.w3.org/2000/svg"),n.setAttribute("tabindex",String(0)),n.classList.add("asg-graph");const t=document.createElement("title");t.innerText=this.title,t.id="accessible-svg-graphs"+this.randomID(),n.appendChild(t);const p=document.createElement("desc");return p.innerText=this.description,p.id="accessible-svg-graphs"+this.randomID(),n.appendChild(p),n.setAttribute("aria-labelledby",t.id+" "+p.id),n}createGTag(e=!0){const c=document.createElement("g");return e&&c.setAttribute("tabindex","0"),c}randomID(){return String(Math.floor(Math.random()*1e4))}drawLine(e,c,o,a,n){const t=document.createElement("line");return t.setAttribute("x1",String(e)),t.setAttribute("y1",String(c)),t.setAttribute("x2",String(o)),t.setAttribute("y2",String(a)),t.setAttribute("stroke","black"),t.setAttribute("stroke-width",n),t}text(e,c,o,a){const n=document.createElement("text");return n.innerText=e,n.setAttribute("x",String(c)),n.setAttribute("y",String(o)),n.style.fill="black",n.style.fontSize=a,n}doPath(e,c=3){const o=document.createElement("path");return o.setAttribute("d",e),this.options.animation===!0&&(o.classList.add("asg-path"),o.style.animation="asg-dash "+this.options.duration+"s ease-in-out forwards"),o.setAttribute("stroke","black"),o.setAttribute("stroke-width",String(c)+"px"),o.setAttribute("fill","transparent"),o}yAxisValues(e,c,o,a,n,t){const p=this.createGTag(!1);return e.forEach(s=>{const i=(c-s)/c*o+n;p.appendChild(this.text(String(s),0,i,String(t)+"px")),p.appendChild(this.drawLine(n,i,a+n,i,"0.1px"))}),p}xAxisValue(e,c,o,a,n,t,p){const s=this.createGTag(!1);return this.type==="scatterplot"&&t&&p?e.forEach(i=>{const l=i/t*p+o;s.appendChild(this.text(String(i),l,c+o+o*.75,String(a)+"px")),s.appendChild(this.drawLine(l,c+o,l,o,"0.1px"))}):(this.type==="line"||this.type==="area")&&n&&e.forEach((i,l)=>{const r=l===0?2*o:n*l+2*o;s.appendChild(this.text(String(i),r,c+o+o*.75,String(a)+"px")),s.appendChild(this.drawLine(r,c+o,r,c+o+o/2,"0.1px"))}),s}addDataType(e,c){return e.setAttribute("data-type",c)}hook(e,c){let o=document.querySelector(e);this.options.animation?this.observe(e,o,c):o&&(o.innerHTML+=c.outerHTML)}observe(e,c,o){const a=document.querySelectorAll(e),n=s=>{s.map(i=>{i.isIntersecting&&c&&!c.querySelector(".asg-graph")&&(c.innerHTML+=o.outerHTML)})},t={threshold:.8},p=new IntersectionObserver(n,t);a&&a.forEach(s=>{p.observe(s)})}}