bezel-charts 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- /*! Bezel Charts v1.3.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
- import{A as T,B as U,C as W,D as tr,E as ar,F as er,G as X,a as E,b as P,c as D,d as O,e as u,f as F,g as V,h as x,i as L,j as N,l as A,m as B,p as l,r as C,t as H,u as J,v as K,w as Q,z as R}from"./shared-L67BQ555.js";function z(r,e){var f=L(r.values).map(function(a){return Math.max(0,a)}),h=N(r.labels),m=K(r,e),o=f.length===1,g=A(f),t=x(r.max)?V(r.max,100):o?100:g;t>0||(t=1);var S=!x(r.prefix)&&!x(r.suffix)&&t===100&&o,k=function(a){return l(a,r)+(S?"%":"")},Y=T(r),Z=Y.w,b=0,G=[];if(!o&&f.length){var M=0;b=1,f.forEach(function(a,y){var i=h[y]||"#"+(y+1),w=14+B(i,12)+6+B(l(a,r),11,!0)+18;M>0&&M+w>Z&&(M=0,b++),G.push({x:M,row:b-1,l:i}),M+=w})}var _=36+(b?12+b*20:0),$=R(f,r,"");return U(r,e,_,function(a,y,i,w){if(!f.length)return Q(e,a,y,i,w);var n="",p=y+22,I=D("c"),rr=o?k(f[0])+(S?"":" of "+l(t,r)):l(g,r)+" of "+l(t,r);o&&h[0]&&(n+=C(a,y+11,h[0],'fill="'+e.fg+'" font-family="'+E+'" font-size="12"')),n+=C(a+i,y+11,rr,'text-anchor="end" fill="'+e.fg+'" font-family="'+P+'" font-size="11" font-weight="600"'),n+='<rect x="'+a+'" y="'+p+'" width="'+i+'" height="14" rx="7" fill="'+e.grid+'" fill-opacity=".7"/>',n+='<clipPath id="'+I+'"><rect x="'+a+'" y="'+p+'" width="'+i+'" height="14" rx="7"/></clipPath><g clip-path="url(#'+I+')"><g'+J(r,"bzc-gx")+">";var d=0;if(f.forEach(function(s,v){var c=Math.min(s,Math.max(0,t-d))/t*i;c>0&&(n+='<rect x="'+u(a+d/t*i)+'" y="'+p+'" width="'+u(c)+'" height="14" fill="'+m[v%m.length]+'"/>'),v>0&&c>0&&(n+='<rect x="'+u(a+d/t*i-1)+'" y="'+p+'" width="2" height="14" fill="'+(r.background||e.tile)+'"/>'),d+=s}),n+="</g></g>",x(r.goal)){var j=a+F(+r.goal/t,0,1)*i;n+='<line x1="'+u(j)+'" x2="'+u(j)+'" y1="'+(p-4)+'" y2="'+(p+18)+'" stroke="'+e.fg+'" stroke-width="2" stroke-linecap="round"/>'}return d=0,f.forEach(function(s,v){var c=Math.min(s,Math.max(0,t-d))/t*i;c>0&&(n+=H(a+d/t*i,p-4,c,22,(h[v]||(o?"Progress":"#"+(v+1)))+": "+k(s)+(o?"":" ("+Math.round(s/t*100)+"%)"))),d+=s}),G.forEach(function(s,v){var c=a+s.x,q=p+14+12+s.row*20+8;n+='<circle cx="'+u(c+4)+'" cy="'+u(q)+'" r="4" fill="'+m[v%m.length]+'"/><text x="'+u(c+14)+'" y="'+u(q+4)+'" fill="'+e.fg+'" font-family="'+E+'" font-size="12">'+O(s.l)+'<tspan dx="6" fill="'+e.muted+'" font-family="'+P+'" font-size="11">'+O(l(f[v],r))+"</tspan></text>"}),n},{stat:$,summary:o?k(f[0])+(S?"":" of "+l(t,r)):l(g,r)+" of "+l(t,r)})}z.table=function(r){var e=L(r.values).map(function(g){return Math.max(0,g)}),f=N(r.labels),h=e.length===1,m=x(r.max)?V(r.max,100):h?100:A(e);m>0||(m=1);var o=!x(r.prefix)&&!x(r.suffix)&&m===100&&h;return h?{head:["Label","Value"],rows:[[f[0]||"Progress",l(e[0],r)+(o?"%":" of "+l(m,r))]]}:{head:["Label","Value","Share"],rows:e.map(function(g,t){return[f[t]||"#"+(t+1),l(g,r),Math.round(g/m*100)+"%"]})}};W("progress",z);X("progress");export{er as BezelChart,tr as render,ar as toSVG};
1
+ /*! Bezel Charts v1.5.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
+ import{A as T,B as U,C as W,D as tr,E as ar,F as er,G as X,a as E,b as P,c as D,d as O,e as u,f as F,g as V,h as x,i as L,j as N,l as A,m as B,p as l,r as C,t as H,u as J,v as K,w as Q,z as R}from"./shared-WQEE2V6C.js";function z(r,e){var f=L(r.values).map(function(a){return Math.max(0,a)}),h=N(r.labels),m=K(r,e),o=f.length===1,g=A(f),t=x(r.max)?V(r.max,100):o?100:g;t>0||(t=1);var S=!x(r.prefix)&&!x(r.suffix)&&t===100&&o,k=function(a){return l(a,r)+(S?"%":"")},Y=T(r),Z=Y.w,b=0,G=[];if(!o&&f.length){var M=0;b=1,f.forEach(function(a,y){var i=h[y]||"#"+(y+1),w=14+B(i,12)+6+B(l(a,r),11,!0)+18;M>0&&M+w>Z&&(M=0,b++),G.push({x:M,row:b-1,l:i}),M+=w})}var _=36+(b?12+b*20:0),$=R(f,r,"");return U(r,e,_,function(a,y,i,w){if(!f.length)return Q(e,a,y,i,w);var n="",p=y+22,I=D("c"),rr=o?k(f[0])+(S?"":" of "+l(t,r)):l(g,r)+" of "+l(t,r);o&&h[0]&&(n+=C(a,y+11,h[0],'fill="'+e.fg+'" font-family="'+E+'" font-size="12"')),n+=C(a+i,y+11,rr,'text-anchor="end" fill="'+e.fg+'" font-family="'+P+'" font-size="11" font-weight="600"'),n+='<rect x="'+a+'" y="'+p+'" width="'+i+'" height="14" rx="7" fill="'+e.grid+'" fill-opacity=".7"/>',n+='<clipPath id="'+I+'"><rect x="'+a+'" y="'+p+'" width="'+i+'" height="14" rx="7"/></clipPath><g clip-path="url(#'+I+')"><g'+J(r,"bzc-gx")+">";var d=0;if(f.forEach(function(s,v){var c=Math.min(s,Math.max(0,t-d))/t*i;c>0&&(n+='<rect x="'+u(a+d/t*i)+'" y="'+p+'" width="'+u(c)+'" height="14" fill="'+m[v%m.length]+'"/>'),v>0&&c>0&&(n+='<rect x="'+u(a+d/t*i-1)+'" y="'+p+'" width="2" height="14" fill="'+(r.background||e.tile)+'"/>'),d+=s}),n+="</g></g>",x(r.goal)){var j=a+F(+r.goal/t,0,1)*i;n+='<line x1="'+u(j)+'" x2="'+u(j)+'" y1="'+(p-4)+'" y2="'+(p+18)+'" stroke="'+e.fg+'" stroke-width="2" stroke-linecap="round"/>'}return d=0,f.forEach(function(s,v){var c=Math.min(s,Math.max(0,t-d))/t*i;c>0&&(n+=H(a+d/t*i,p-4,c,22,(h[v]||(o?"Progress":"#"+(v+1)))+": "+k(s)+(o?"":" ("+Math.round(s/t*100)+"%)"))),d+=s}),G.forEach(function(s,v){var c=a+s.x,q=p+14+12+s.row*20+8;n+='<circle cx="'+u(c+4)+'" cy="'+u(q)+'" r="4" fill="'+m[v%m.length]+'"/><text x="'+u(c+14)+'" y="'+u(q+4)+'" fill="'+e.fg+'" font-family="'+E+'" font-size="12">'+O(s.l)+'<tspan dx="6" fill="'+e.muted+'" font-family="'+P+'" font-size="11">'+O(l(f[v],r))+"</tspan></text>"}),n},{stat:$,summary:o?k(f[0])+(S?"":" of "+l(t,r)):l(g,r)+" of "+l(t,r)})}z.table=function(r){var e=L(r.values).map(function(g){return Math.max(0,g)}),f=N(r.labels),h=e.length===1,m=x(r.max)?V(r.max,100):h?100:A(e);m>0||(m=1);var o=!x(r.prefix)&&!x(r.suffix)&&m===100&&h;return h?{head:["Label","Value"],rows:[[f[0]||"Progress",l(e[0],r)+(o?"%":" of "+l(m,r))]]}:{head:["Label","Value","Share"],rows:e.map(function(g,t){return[f[t]||"#"+(t+1),l(g,r),Math.round(g/m*100)+"%"]})}};W("progress",z);X("progress");export{er as BezelChart,tr as render,ar as toSVG};
@@ -1,2 +1,2 @@
1
- /*! Bezel Charts v1.3.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
- import{B as P,C as Q,D as Y,E as Z,F as _,G as R,a as N,b as q,d as w,e as r,f as V,g as S,h as d,i as j,j as A,n as D,p as y,r as x,s as F,v as I,w as J,z as K}from"./shared-L67BQ555.js";function O(t,i){var e=j(t.values),l=A(t.labels),u=I(t,i),p=S(t.max,100)||100,T=S(t.height,140),B=!d(t.prefix)&&!d(t.suffix)&&p===100,b=function(a){return y(a,t)+(B?"%":"")},U=K(e,t,"");return P(t,i,T,function(a,v,h,k){if(!e.length)return J(i,a,v,h,k);var c="",z=e.length===1,f=Math.min(k,z?h:h*.55),g=z?a+h/2:a+f/2,o=v+k/2,m=z?f*.12:V(f*.42/(e.length*1.35),5,16),W=m*.38;if(e.forEach(function(M,n){var s=f/2-m/2-n*(m+W);if(!(s<=m/2)){var C=V(M/p*100,0,100),G=u[n%u.length];c+='<circle cx="'+r(g)+'" cy="'+r(o)+'" r="'+r(s)+'" fill="none" stroke="'+G+'" stroke-opacity=".16" stroke-width="'+r(m)+'"/>',C>0&&(c+='<circle cx="'+r(g)+'" cy="'+r(o)+'" r="'+r(s)+'" fill="none" stroke="'+G+'" stroke-width="'+r(m)+'" stroke-linecap="round" pathLength="100" transform="rotate(-90 '+r(g)+" "+r(o)+')" style="stroke-dasharray:'+r(C)+" 100"+(t.animate?";animation-delay:"+n*.12+"s":"")+'"'+(t.animate?' class="bzc-s"':"")+"/>"),c+='<circle cx="'+r(g)+'" cy="'+r(o)+'" r="'+r(s+m/2)+'" fill="#000" fill-opacity="0" class="bzc-hit" data-tip="'+w((l[n]||"#"+(n+1))+": "+b(M)+(B?"":" of "+y(p,t)))+'"/>'}}),z)c+=x(g,o+f*.08,b(e[0]),'text-anchor="middle" fill="'+i.fg+'" font-family="'+N+'" font-size="'+r(f*.22)+'" font-weight="800"'),l[0]&&(c+=x(g,o+f*.08+16,l[0],F(i,10,'text-anchor="middle"')));else{var E=a+f+22,L=Math.min(26,k/e.length),X=o-L*e.length/2;e.forEach(function(M,n){var s=X+n*L+L/2;c+='<circle cx="'+r(E+4)+'" cy="'+r(s)+'" r="4" fill="'+u[n%u.length]+'"/>'+x(E+14,s+4,D(l[n]||"#"+(n+1),Math.floor((a+h-E-60)/6.7)),'fill="'+i.fg+'" font-family="'+N+'" font-size="12"')+x(a+h,s+4,b(M),'text-anchor="end" fill="'+i.fg+'" font-family="'+q+'" font-size="11" font-weight="600"')})}return c},{stat:U,summary:e.map(function(a,v){return(l[v]?l[v]+" ":"")+b(a)}).join(", ")})}O.table=function(t){var i=A(t.labels),e=S(t.max,100)||100,l=!d(t.prefix)&&!d(t.suffix)&&e===100;return{head:["Label","Value"],rows:j(t.values).map(function(u,p){return[i[p]||"#"+(p+1),y(u,t)+(l?"%":" of "+y(e,t))]})}};Q("ring",O);R("ring");export{_ as BezelChart,Y as render,Z as toSVG};
1
+ /*! Bezel Charts v1.5.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
+ import{B as P,C as Q,D as Y,E as Z,F as _,G as R,a as N,b as q,d as w,e as r,f as V,g as S,h as d,i as j,j as A,n as D,p as y,r as x,s as F,v as I,w as J,z as K}from"./shared-WQEE2V6C.js";function O(t,i){var e=j(t.values),l=A(t.labels),u=I(t,i),p=S(t.max,100)||100,T=S(t.height,140),B=!d(t.prefix)&&!d(t.suffix)&&p===100,b=function(a){return y(a,t)+(B?"%":"")},U=K(e,t,"");return P(t,i,T,function(a,v,h,k){if(!e.length)return J(i,a,v,h,k);var c="",z=e.length===1,f=Math.min(k,z?h:h*.55),g=z?a+h/2:a+f/2,o=v+k/2,m=z?f*.12:V(f*.42/(e.length*1.35),5,16),W=m*.38;if(e.forEach(function(M,n){var s=f/2-m/2-n*(m+W);if(!(s<=m/2)){var C=V(M/p*100,0,100),G=u[n%u.length];c+='<circle cx="'+r(g)+'" cy="'+r(o)+'" r="'+r(s)+'" fill="none" stroke="'+G+'" stroke-opacity=".16" stroke-width="'+r(m)+'"/>',C>0&&(c+='<circle cx="'+r(g)+'" cy="'+r(o)+'" r="'+r(s)+'" fill="none" stroke="'+G+'" stroke-width="'+r(m)+'" stroke-linecap="round" pathLength="100" transform="rotate(-90 '+r(g)+" "+r(o)+')" style="stroke-dasharray:'+r(C)+" 100"+(t.animate?";animation-delay:"+n*.12+"s":"")+'"'+(t.animate?' class="bzc-s"':"")+"/>"),c+='<circle cx="'+r(g)+'" cy="'+r(o)+'" r="'+r(s+m/2)+'" fill="#000" fill-opacity="0" class="bzc-hit" data-tip="'+w((l[n]||"#"+(n+1))+": "+b(M)+(B?"":" of "+y(p,t)))+'"/>'}}),z)c+=x(g,o+f*.08,b(e[0]),'text-anchor="middle" fill="'+i.fg+'" font-family="'+N+'" font-size="'+r(f*.22)+'" font-weight="800"'),l[0]&&(c+=x(g,o+f*.08+16,l[0],F(i,10,'text-anchor="middle"')));else{var E=a+f+22,L=Math.min(26,k/e.length),X=o-L*e.length/2;e.forEach(function(M,n){var s=X+n*L+L/2;c+='<circle cx="'+r(E+4)+'" cy="'+r(s)+'" r="4" fill="'+u[n%u.length]+'"/>'+x(E+14,s+4,D(l[n]||"#"+(n+1),Math.floor((a+h-E-60)/6.7)),'fill="'+i.fg+'" font-family="'+N+'" font-size="12"')+x(a+h,s+4,b(M),'text-anchor="end" fill="'+i.fg+'" font-family="'+q+'" font-size="11" font-weight="600"')})}return c},{stat:U,summary:e.map(function(a,v){return(l[v]?l[v]+" ":"")+b(a)}).join(", ")})}O.table=function(t){var i=A(t.labels),e=S(t.max,100)||100,l=!d(t.prefix)&&!d(t.suffix)&&e===100;return{head:["Label","Value"],rows:j(t.values).map(function(u,p){return[i[p]||"#"+(p+1),y(u,t)+(l?"%":" of "+y(e,t))]})}};Q("ring",O);R("ring");export{_ as BezelChart,Y as render,Z as toSVG};
@@ -1,5 +1,5 @@
1
- /*! Bezel Charts v1.3.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
- import{a as T,b as va,d as da,f as ga,g as U,i as ba}from"./shared-PCFIMFLL.js";import{B as ha,C as xa,D as Oa,E as Pa,F as za,G as ya,e as n,f as F,g as oa,h as x,j as H,k as N,o as R,p as E,r as P,s as w,t as sa,v as fa,w as ua,x as ma,y as pa}from"./shared-L67BQ555.js";function Xa(a,r){var y=Math.min(a.length,r.length);if(y<2)return null;var u=0,h=0,e;for(e=0;e<y;e++)u+=a[e],h+=r[e];u/=y,h/=y;var f=0,l=0,m=0;for(e=0;e<y;e++)f+=(a[e]-u)*(a[e]-u),l+=(r[e]-h)*(r[e]-h),m+=(a[e]-u)*(r[e]-h);if(!f)return null;var b=m/f;return{slope:b,intercept:h-b*u,r:l?m/Math.sqrt(f*l):0}}function I(a,r){for(var y=N(a.x),u=N(a.y),h=H(a.series),e=H(a.labels),f=fa(a,r),l=[],m=0;m<Math.max(y.length,u.length);m++){var b=y[m]||[],S=u[m]||[],z=Math.min(b.length,S.length);l.push({xs:b.slice(0,z),ys:S.slice(0,z)})}l=l.filter(function(o){return o.xs.length});var k=l.reduce(function(o,v){return o+v.xs.length},0),ka=oa(a.height,210),J=l.length>1||h.length>0,Ma=R(a.trend),Z=function(o){return h[o]||"Group "+(o+1)},$={decimals:a.decimals,compact:a.compact,lang:a.lang},La=ma(a,e),K=ga(a.markers,da,"circle"),Ea=a.background||r.tile,j=function(o){var v=K?K(o):"circle";return v==="none"?"circle":v},wa=K&&function(o,v,X){return U(j(o),v+4,X+6,4,' fill="'+f[o%f.length]+'"')};return ha(a,r,ka,function(o,v,X,aa){if(!k)return ua(r,o,v,X,aa);var p="",s=v;if(J){var ta=va(l.map(function(t,i){return Z(i)}),f,r,o,s,X,wa);p+=ta.svg,s+=ta.height}var ra=[].concat.apply([],l.map(function(t){return t.xs})),ea=[].concat.apply([],l.map(function(t){return t.ys})),Y=Math.min.apply(null,ea),q=Math.max.apply(null,ea);x(a.goal)&&(Y=Math.min(Y,+a.goal),q=Math.max(q,+a.goal)),R(a.zero)&&(Y=Math.min(0,Y),q=Math.max(0,q));var W=T(Y,q,4),A=T(Math.min.apply(null,ra),Math.max.apply(null,ra),5),na=W.ticks.map(function(t){return E(t,a,!0)}),la=ba(na)+(x(a.yLabel)?14:0),Sa=20+(x(a.xLabel)?16:0),d=o+la,M=X-la,g=aa-(s-v)-Sa,G=function(t){return d+6+(t-A.lo)/(A.hi-A.lo)*(M-12)},L=function(t){return s+6+g-6-(t-W.lo)/(W.hi-W.lo)*(g-6)};W.ticks.forEach(function(t,i){var c=L(t);p+='<line x1="'+n(d)+'" x2="'+n(d+M)+'" y1="'+n(c)+'" y2="'+n(c)+'" stroke="'+r.grid+'" stroke-dasharray="2 4"/>'+P(d-8,c+3.5,na[i],w(r,10,'text-anchor="end"'))});var Ga=Math.max(1,Math.ceil(A.ticks.length*44/M));if(A.ticks.forEach(function(t,i){if(!(i%Ga)){var c=G(t);p+='<line x1="'+n(c)+'" x2="'+n(c)+'" y1="'+n(s)+'" y2="'+n(s+g)+'" stroke="'+r.grid+'" stroke-dasharray="2 4"/>'+P(c,s+g+15,E(t,$,!0),w(r,10,'text-anchor="middle"'))}}),x(a.xLabel)&&(p+=P(d+M/2,s+g+32,a.xLabel,w(r,10,'text-anchor="middle" font-weight="600"'))),x(a.yLabel)){var ia=s+g/2;p+='<text x="'+n(o+4)+'" y="'+n(ia)+'" transform="rotate(-90 '+n(o+4)+" "+n(ia)+')" text-anchor="middle" '+w(r,10,'font-weight="600"')+' dominant-baseline="hanging">'+String(a.yLabel).replace(/[&<>"]/g,function(t){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[t]})+"</text>"}x(a.goal)&&(p+=pa(a,r,d,d+M,L(+a.goal))),Ma&&l.forEach(function(t,i){var c=Xa(t.xs,t.ys);if(c){var B=Math.min.apply(null,t.xs),O=Math.max.apply(null,t.xs),_=c.slope*B+c.intercept,C=c.slope*O+c.intercept,D=f[i%f.length];p+='<line x1="'+n(G(B))+'" y1="'+n(F(L(_),s,s+g))+'" x2="'+n(G(O))+'" y2="'+n(F(L(C),s,s+g))+'" stroke="'+D+'" stroke-width="2" stroke-dasharray="6 4" stroke-linecap="round" stroke-opacity=".9"/>',p+=P(Math.min(G(O),d+M)-2,F(L(C),s+10,s+g)-7,"r = "+c.r.toFixed(2),w(r,10,'text-anchor="end" font-weight="600"',D))}});var V=0,Q=k>150?3:4.5;l.forEach(function(t,i){var c=f[i%f.length];t.xs.forEach(function(B,O){var _=G(B),C=L(t.ys[O]),D=(e[V]?e[V]+`
1
+ /*! Bezel Charts v1.5.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
+ import{a as T,b as va,d as da,f as ga,g as U,i as ba}from"./shared-I437GKHE.js";import{B as ha,C as xa,D as Oa,E as Pa,F as za,G as ya,e as n,f as F,g as oa,h as x,j as H,k as N,o as R,p as E,r as P,s as w,t as sa,v as fa,w as ua,x as ma,y as pa}from"./shared-WQEE2V6C.js";function Xa(a,r){var y=Math.min(a.length,r.length);if(y<2)return null;var u=0,h=0,e;for(e=0;e<y;e++)u+=a[e],h+=r[e];u/=y,h/=y;var f=0,l=0,m=0;for(e=0;e<y;e++)f+=(a[e]-u)*(a[e]-u),l+=(r[e]-h)*(r[e]-h),m+=(a[e]-u)*(r[e]-h);if(!f)return null;var b=m/f;return{slope:b,intercept:h-b*u,r:l?m/Math.sqrt(f*l):0}}function I(a,r){for(var y=N(a.x),u=N(a.y),h=H(a.series),e=H(a.labels),f=fa(a,r),l=[],m=0;m<Math.max(y.length,u.length);m++){var b=y[m]||[],S=u[m]||[],z=Math.min(b.length,S.length);l.push({xs:b.slice(0,z),ys:S.slice(0,z)})}l=l.filter(function(o){return o.xs.length});var k=l.reduce(function(o,v){return o+v.xs.length},0),ka=oa(a.height,210),J=l.length>1||h.length>0,Ma=R(a.trend),Z=function(o){return h[o]||"Group "+(o+1)},$={decimals:a.decimals,compact:a.compact,lang:a.lang},La=ma(a,e),K=ga(a.markers,da,"circle"),Ea=a.background||r.tile,j=function(o){var v=K?K(o):"circle";return v==="none"?"circle":v},wa=K&&function(o,v,X){return U(j(o),v+4,X+6,4,' fill="'+f[o%f.length]+'"')};return ha(a,r,ka,function(o,v,X,aa){if(!k)return ua(r,o,v,X,aa);var p="",s=v;if(J){var ta=va(l.map(function(t,i){return Z(i)}),f,r,o,s,X,wa);p+=ta.svg,s+=ta.height}var ra=[].concat.apply([],l.map(function(t){return t.xs})),ea=[].concat.apply([],l.map(function(t){return t.ys})),Y=Math.min.apply(null,ea),q=Math.max.apply(null,ea);x(a.goal)&&(Y=Math.min(Y,+a.goal),q=Math.max(q,+a.goal)),R(a.zero)&&(Y=Math.min(0,Y),q=Math.max(0,q));var W=T(Y,q,4),A=T(Math.min.apply(null,ra),Math.max.apply(null,ra),5),na=W.ticks.map(function(t){return E(t,a,!0)}),la=ba(na)+(x(a.yLabel)?14:0),Sa=20+(x(a.xLabel)?16:0),d=o+la,M=X-la,g=aa-(s-v)-Sa,G=function(t){return d+6+(t-A.lo)/(A.hi-A.lo)*(M-12)},L=function(t){return s+6+g-6-(t-W.lo)/(W.hi-W.lo)*(g-6)};W.ticks.forEach(function(t,i){var c=L(t);p+='<line x1="'+n(d)+'" x2="'+n(d+M)+'" y1="'+n(c)+'" y2="'+n(c)+'" stroke="'+r.grid+'" stroke-dasharray="2 4"/>'+P(d-8,c+3.5,na[i],w(r,10,'text-anchor="end"'))});var Ga=Math.max(1,Math.ceil(A.ticks.length*44/M));if(A.ticks.forEach(function(t,i){if(!(i%Ga)){var c=G(t);p+='<line x1="'+n(c)+'" x2="'+n(c)+'" y1="'+n(s)+'" y2="'+n(s+g)+'" stroke="'+r.grid+'" stroke-dasharray="2 4"/>'+P(c,s+g+15,E(t,$,!0),w(r,10,'text-anchor="middle"'))}}),x(a.xLabel)&&(p+=P(d+M/2,s+g+32,a.xLabel,w(r,10,'text-anchor="middle" font-weight="600"'))),x(a.yLabel)){var ia=s+g/2;p+='<text x="'+n(o+4)+'" y="'+n(ia)+'" transform="rotate(-90 '+n(o+4)+" "+n(ia)+')" text-anchor="middle" '+w(r,10,'font-weight="600"')+' dominant-baseline="hanging">'+String(a.yLabel).replace(/[&<>"]/g,function(t){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[t]})+"</text>"}x(a.goal)&&(p+=pa(a,r,d,d+M,L(+a.goal))),Ma&&l.forEach(function(t,i){var c=Xa(t.xs,t.ys);if(c){var B=Math.min.apply(null,t.xs),O=Math.max.apply(null,t.xs),_=c.slope*B+c.intercept,C=c.slope*O+c.intercept,D=f[i%f.length];p+='<line x1="'+n(G(B))+'" y1="'+n(F(L(_),s,s+g))+'" x2="'+n(G(O))+'" y2="'+n(F(L(C),s,s+g))+'" stroke="'+D+'" stroke-width="2" stroke-dasharray="6 4" stroke-linecap="round" stroke-opacity=".9"/>',p+=P(Math.min(G(O),d+M)-2,F(L(C),s+10,s+g)-7,"r = "+c.r.toFixed(2),w(r,10,'text-anchor="end" font-weight="600"',D))}});var V=0,Q=k>150?3:4.5;l.forEach(function(t,i){var c=f[i%f.length];t.xs.forEach(function(B,O){var _=G(B),C=L(t.ys[O]),D=(e[V]?e[V]+`
3
3
  `:J?Z(i)+`
4
4
  `:"")+(x(a.xLabel)?a.xLabel:"x")+": "+E(B,$)+`
5
5
  `+(x(a.yLabel)?a.yLabel:"y")+": "+E(t.ys[O],a);p+=U(j(i),_,C,Q,' fill="'+c+'" fill-opacity=".85" stroke="'+Ea+'" stroke-width="1.5"'+(a.animate?' class="bzc-a" style="animation-delay:'+n(Math.min(.8,V*.012))+'s"':"")),p+=sa(_-8,C-8,16,16,D),V++})});var ca=[];return l.forEach(function(t){t.xs.forEach(function(i,c){ca.push([G(i),L(t.ys[c])])})}),La.forEach(function(t){var i=ca[t.i];i&&(p+='<circle cx="'+n(i[0])+'" cy="'+n(i[1])+'" r="'+(Q+4)+'" fill="none" stroke="'+r.fg+'" stroke-width="1.5"/>'+P(F(i[0],d+30,d+M-30),i[1]-Q-9,t.text,w(r,10,'text-anchor="middle"',r.fg)))}),p},{summary:k+" points"+(J?" in "+l.length+" groups":"")})}I.table=function(a){var r=N(a.x),y=N(a.y),u=H(a.series),h=H(a.labels),e=r.length>1||u.length>0,f={decimals:a.decimals,compact:a.compact,lang:a.lang},l=[],m=0;return r.forEach(function(b,S){for(var z=y[S]||[],k=0;k<Math.min(b.length,z.length);k++,m++)l.push([h[m]||"#"+(m+1)].concat(e?[u[S]||"Group "+(S+1)]:[],[E(b[k],f),E(z[k],a)]))}),{head:["Point"].concat(e?["Group"]:[],[x(a.xLabel)?a.xLabel:"x",x(a.yLabel)?a.yLabel:"y"]),rows:l}};xa("scatter",I);ya("scatter");export{za as BezelChart,Oa as render,Pa as toSVG};
@@ -0,0 +1,2 @@
1
+ /*! Bezel Charts v1.5.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
+ import{a as q,b as B,c as C,g as Y}from"./shared-I437GKHE.js";import{e as p,f as H,h as L,m as S,r as M,s as b,t as K,u as X,y as W}from"./shared-WQEE2V6C.js";function Q(e,t,r,i,l,h,u){var a="",n=l,s=r.n,k=r.labels;if(r.names){var c=B(r.names,r.pal,t,i,n,h,r.key,r.kw);a+=c.svg,n+=c.height}var f=r.lo,v=r.hi;L(e.goal)&&(f=Math.min(f,+e.goal),v=Math.max(v,+e.goal)),r.zero&&(f=Math.min(0,f),v=Math.max(0,v));var g=q(f,v,4),F=g.ticks.map(r.tick),A=Math.max.apply(null,F.map(function(o){return S(o,10,!0)}))+10,G=k.length?20:4,m=i+A,d=h-A,y=u-(n-l)-G,z=function(o){return s===1?m+d/2:m+o*d/(s-1)},D=function(o){return n+y-(o-g.lo)/(g.hi-g.lo)*y};if(g.ticks.forEach(function(o,w){var E=D(o);a+='<line x1="'+p(m)+'" x2="'+p(m+d)+'" y1="'+p(E)+'" y2="'+p(E)+'" stroke="'+t.grid+'"'+(o===0?"":' stroke-dasharray="2 4"')+"/>"+M(m-8,E+3.5,F[w],b(t,10,'text-anchor="end"'))}),k.length){for(var I=Math.max(1,Math.ceil(s*(Math.max.apply(null,k.map(function(o){return S(o,10,!0)}))+10)/d)),x=0;x<s;x+=I)if(k[x]!=null){var J=s>1&&x===0?"start":s>1&&x===s-1?"end":"middle";a+=M(z(x),n+y+15,k[x],b(t,10,'text-anchor="'+J+'"'))}}return r.notes.forEach(function(o){if(!(o.i>=s)){var w=z(o.i);a+='<line x1="'+p(w)+'" x2="'+p(w)+'" y1="'+p(n+12)+'" y2="'+p(n+y)+'" stroke="'+t.fg+'" stroke-opacity=".4" stroke-dasharray="3 3"/>'+M(H(w,m+30,m+d-30),n+8,o.text,b(t,10,'text-anchor="middle"',t.fg))}}),{svg:a,X:z,Y:D,px:m,pw:d,top:n,ph:y}}function R(e,t,r,i,l){for(var h=L(e.goal)?W(e,t,r.px,r.px+r.pw,r.Y(+e.goal)):"",u=i>1?r.pw/(i-1):r.pw,a=0;a<i;a++)h+=K(r.X(a)-u/2,r.top,u,r.ph,l(a));return h}function T(e,t,r,i){return function(l,h,u){var a=e[l%e.length],n=t?C[t(l)]:"",s=r?r(l):"none";return'<line x1="'+p(h)+'" x2="'+p(h+18)+'" y1="'+p(u+6)+'" y2="'+p(u+6)+'" stroke="'+a+'" stroke-width="2.5" stroke-linecap="round"'+(n?' stroke-dasharray="'+n+'"':"")+"/>"+(s!=="none"?Y(s,h+9,u+6,3.5,' fill="'+a+'" stroke="'+i+'" stroke-width="1.5"'):"")}}function U(e,t,r,i,l){return l?'<path d="'+t+'" fill="none" stroke="'+r+'" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="'+l+'"'+X(e,"bzc-a",i*.15)+"/>":'<path d="'+t+'" fill="none" stroke="'+r+'" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" pathLength="1" style="stroke-dasharray:1'+(e.animate?";animation-delay:"+i*.15+"s":"")+'"'+(e.animate?' class="bzc-d"':"")+"/>"}function V(e,t,r,i,l,h,u,a){var n="",s=Math.ceil(r.length/40);return r.forEach(function(k,c){(c%s===0||c===r.length-1)&&(n+=Y(t,i(c),l(k),3.5,' fill="'+h+'" stroke="'+u+'" stroke-width="1.5"'+X(e,"bzc-a",.6+a*.15)))}),n}export{Q as a,R as b,T as c,U as d,V as e};
@@ -1,2 +1,2 @@
1
- /*! Bezel Charts v1.3.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
- import{a as w,e,j as d,k as x,m as g,p as v,r as L}from"./shared-L67BQ555.js";function m(r,t,a){if(r===t)if(r===0)t=1;else{var n=Math.abs(r)*.1;r-=n,t+=n}for(var l=(t-r)/(a||4),i=Math.pow(10,Math.floor(Math.log10(l))),u=l/i,o=(u<=1?1:u<=2?2:u<=5?5:10)*i,f=Math.floor(r/o)*o,h=Math.ceil(t/o)*o,s=[],c=f;c<=h+o/2;c+=o)s.push(+c.toFixed(10));return{lo:f,hi:h,ticks:s}}function E(r,t,a,n,l,i,u,o){var f=n,h=l,s="",c=o||13;return r.forEach(function(p,M){var S=c+g(p,12)+16;f>n&&f+S-16>n+i&&(f=n,h+=20),s+=(u?u(M,f,h):'<circle cx="'+e(f+4)+'" cy="'+e(h+6)+'" r="4" fill="'+t[M%t.length]+'"/>')+L(f+c,h+10,p,'fill="'+a.fg+'" font-family="'+w+'" font-size="12"'),f+=S}),{svg:s,height:h-l+24}}var T={solid:"",dashed:"7 5",dotted:"1 5",dashdot:"9 4 1 4"},A=["circle","square","triangle","diamond"],H=["solid","stripes","dots","grid"];function O(r,t,a){if(r==null||r===!1||r==="none"||r==="false")return null;var n=r===!0||r===""||r==="auto"?t:d(r).map(function(l){return t.indexOf(l)<0?a:l});return n.length?function(l){return n[l%n.length]}:null}function q(r,t,a,n,l){var i=n*1.15,u=n*.85;return r==="square"?'<rect x="'+e(t-u)+'" y="'+e(a-u)+'" width="'+e(2*u)+'" height="'+e(2*u)+'" rx="1"'+l+"/>":r==="triangle"?'<path d="M'+e(t)+","+e(a-i)+"L"+e(t+i)+","+e(a+u)+"L"+e(t-i)+","+e(a+u)+'Z"'+l+"/>":r==="diamond"?'<path d="M'+e(t)+","+e(a-i*1.1)+"L"+e(t+i)+","+e(a)+"L"+e(t)+","+e(a+i*1.1)+"L"+e(t-i)+","+e(a)+'Z"'+l+"/>":'<circle cx="'+e(t)+'" cy="'+e(a)+'" r="'+e(n)+'"'+l+"/>"}function N(r,t,a,n){var l=' stroke="'+n+'" stroke-opacity=".55" stroke-width="1.5"';return'<pattern id="'+r+'" width="6" height="6" patternUnits="userSpaceOnUse"'+(t==="dots"?"":' patternTransform="rotate(45)"')+'><rect width="6" height="6" fill="'+a+'"/>'+(t==="dots"?'<circle cx="3" cy="3" r="1.3" fill="'+n+'" fill-opacity=".55"/>':'<path d="M3,0V6'+(t==="grid"?"M0,3H6":"")+'"'+l+"/>")+"</pattern>"}function P(r){return Math.max.apply(null,r.map(function(t){return g(t,10,!0)}))+10}function U(r,t){for(var a=x(r.values),n=d(r.series),l=d(r.labels),i=[],u=Math.max.apply(null,[0].concat(a.map(function(c){return c.length}))),o=0;o<u;o++){var f=[l[o]||"#"+(o+1)],h=0;a.forEach(function(c){f.push(o<c.length?v(c[o],r):""),h+=o<c.length?c[o]:0}),t&&f.push(v(h,r)),i.push(f)}var s=a.length>1||n.length?a.map(function(c,p){return n[p]||"Series "+(p+1)}):["Value"];return{head:["Label"].concat(s,t?["Total"]:[]),rows:i}}export{m as a,E as b,T as c,A as d,H as e,O as f,q as g,N as h,P as i,U as j};
1
+ /*! Bezel Charts v1.5.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
+ import{a as w,e,j as d,k as x,m as g,p as v,r as L}from"./shared-WQEE2V6C.js";function m(r,t,a){if(r===t)if(r===0)t=1;else{var n=Math.abs(r)*.1;r-=n,t+=n}for(var l=(t-r)/(a||4),i=Math.pow(10,Math.floor(Math.log10(l))),u=l/i,o=(u<=1?1:u<=2?2:u<=5?5:10)*i,f=Math.floor(r/o)*o,h=Math.ceil(t/o)*o,s=[],c=f;c<=h+o/2;c+=o)s.push(+c.toFixed(10));return{lo:f,hi:h,ticks:s}}function E(r,t,a,n,l,i,u,o){var f=n,h=l,s="",c=o||13;return r.forEach(function(p,M){var S=c+g(p,12)+16;f>n&&f+S-16>n+i&&(f=n,h+=20),s+=(u?u(M,f,h):'<circle cx="'+e(f+4)+'" cy="'+e(h+6)+'" r="4" fill="'+t[M%t.length]+'"/>')+L(f+c,h+10,p,'fill="'+a.fg+'" font-family="'+w+'" font-size="12"'),f+=S}),{svg:s,height:h-l+24}}var T={solid:"",dashed:"7 5",dotted:"1 5",dashdot:"9 4 1 4"},A=["circle","square","triangle","diamond"],H=["solid","stripes","dots","grid"];function O(r,t,a){if(r==null||r===!1||r==="none"||r==="false")return null;var n=r===!0||r===""||r==="auto"?t:d(r).map(function(l){return t.indexOf(l)<0?a:l});return n.length?function(l){return n[l%n.length]}:null}function q(r,t,a,n,l){var i=n*1.15,u=n*.85;return r==="square"?'<rect x="'+e(t-u)+'" y="'+e(a-u)+'" width="'+e(2*u)+'" height="'+e(2*u)+'" rx="1"'+l+"/>":r==="triangle"?'<path d="M'+e(t)+","+e(a-i)+"L"+e(t+i)+","+e(a+u)+"L"+e(t-i)+","+e(a+u)+'Z"'+l+"/>":r==="diamond"?'<path d="M'+e(t)+","+e(a-i*1.1)+"L"+e(t+i)+","+e(a)+"L"+e(t)+","+e(a+i*1.1)+"L"+e(t-i)+","+e(a)+'Z"'+l+"/>":'<circle cx="'+e(t)+'" cy="'+e(a)+'" r="'+e(n)+'"'+l+"/>"}function N(r,t,a,n){var l=' stroke="'+n+'" stroke-opacity=".55" stroke-width="1.5"';return'<pattern id="'+r+'" width="6" height="6" patternUnits="userSpaceOnUse"'+(t==="dots"?"":' patternTransform="rotate(45)"')+'><rect width="6" height="6" fill="'+a+'"/>'+(t==="dots"?'<circle cx="3" cy="3" r="1.3" fill="'+n+'" fill-opacity=".55"/>':'<path d="M3,0V6'+(t==="grid"?"M0,3H6":"")+'"'+l+"/>")+"</pattern>"}function P(r){return Math.max.apply(null,r.map(function(t){return g(t,10,!0)}))+10}function U(r,t){for(var a=x(r.values),n=d(r.series),l=d(r.labels),i=[],u=Math.max.apply(null,[0].concat(a.map(function(c){return c.length}))),o=0;o<u;o++){var f=[l[o]||"#"+(o+1)],h=0;a.forEach(function(c){f.push(o<c.length?v(c[o],r):""),h+=o<c.length?c[o]:0}),t&&f.push(v(h,r)),i.push(f)}var s=a.length>1||n.length?a.map(function(c,p){return n[p]||"Series "+(p+1)}):["Value"];return{head:["Label"].concat(s,t?["Total"]:[]),rows:i}}export{m as a,E as b,T as c,A as d,H as e,O as f,q as g,N as h,P as i,U as j};
@@ -0,0 +1,2 @@
1
+ /*! Bezel Charts v1.5.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
+ var g={dark:{tile:"#15151d",bezel:"#000000",fg:"#f2f1f7",muted:"#8c8aa0",grid:"#2a2935",up:"#5EE6C8",down:"#F675A8",palette:["#9FA1FF","#F675A8","#5EE6C8","#FFC857","#7CC4FF","#FF8A5B"]},light:{tile:"#ffffff",bezel:"#000000",fg:"#17161f",muted:"#6b6980",grid:"#e8e6ef",up:"#12a383",down:"#d63f7c",palette:["#6E70F0","#E2508C","#16A884","#D99A0E","#2F8FE0","#EE6431"]}};var x="ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif",w="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace",W=0;function nt(t){return"bzc"+t+(++W).toString(36)+Math.random().toString(36).slice(2,6)}function h(t){return String(t??"").replace(/[&<>"']/g,function(e){return{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[e]})}function s(t){return Math.round(t*100)/100}function u(t,e,r){return Math.max(e,Math.min(r,t))}function v(t,e){var r=parseFloat(t);return isFinite(r)?r:e}function c(t){return t!=null&&t!==""}function T(t){return Array.isArray(t)?t.map(function(e){var r=+e;return isFinite(r)?r:0}):c(t)?String(t).split(/[\s,;]+/).filter(Boolean).map(function(e){var r=+e;return isFinite(r)?r:0}):[]}function V(t){return Array.isArray(t)?t.map(String):c(t)?String(t).split(",").map(function(e){return e.trim()}):[]}function at(t){return Array.isArray(t)?Array.isArray(t[0])?t.map(T):[T(t)]:c(t)?String(t).split("|").map(T).filter(function(e){return e.length}):[]}function Y(t){return t.reduce(function(e,r){return e+r},0)}function ot(t,e,r){return String(t).length*e*(r?.6:.56)}function st(t,e){return t=String(t),t.length>e?t.slice(0,Math.max(1,e-1))+"\u2026":t}function C(t){return t===!0||t===""||t==="true"||t==="1"}function k(t,e,r){if(!isFinite(t))return"\u2013";var i=Math.abs(t),n;c(e.decimals)?n=u(parseInt(e.decimals,10)||0,0,6):n=t%1===0?0:i<10?2:i<100?1:0;var a={maximumFractionDigits:n,minimumFractionDigits:c(e.decimals)?n:0};(C(e.compact)||r)&&i>=1e4&&(a={notation:"compact",maximumFractionDigits:1});var o;try{o=new Intl.NumberFormat(e.lang||"en-GB",a).format(i)}catch{o=String(s(i))}return(t<0?"\u2212":"")+(e.prefix||"")+o+(e.suffix||"")}function lt(t,e){if(!t.length)return"";for(var r="M"+s(t[0][0])+","+s(t[0][1]),i=1;i<t.length;i++){var n=t[i-1],a=t[i];if(e)r+="L"+s(a[0])+","+s(a[1]);else{var o=(n[0]+a[0])/2;r+="C"+s(o)+","+s(n[1])+" "+s(o)+","+s(a[1])+" "+s(a[0])+","+s(a[1])}}return r}function p(t,e,r,i){return'<text x="'+s(t)+'" y="'+s(e)+'" '+(i||"")+">"+h(r)+"</text>"}function F(t,e,r,i){return'fill="'+(i||t.muted)+'" font-family="'+w+'" font-size="'+(e||10)+'"'+(r?" "+r:"")}function ct(t,e,r,i,n){return'<rect class="bzc-hit" x="'+s(t)+'" y="'+s(e)+'" width="'+s(Math.max(1,r))+'" height="'+s(Math.max(1,i))+'" fill="#000" fill-opacity="0" data-tip="'+h(n)+'"/>'}function ht(t,e,r){return t.animate?' class="'+e+'"'+(r?' style="animation-delay:'+s(r)+'s"':""):""}function ut(t,e){var r=V(t.color).filter(Boolean);return r.length?r:e.palette}function dt(t,e,r,i,n){return p(e+i/2,r+n/2+4,"No data yet",'text-anchor="middle" fill="'+t.muted+'" font-family="'+x+'" font-size="13"')}function ft(t,e){return c(t.notes)?String(t.notes).split(";").map(function(r){var i=r.indexOf(":");if(i<0)return null;var n=r.slice(0,i).trim(),a=r.slice(i+1).trim(),o=e.map(String).indexOf(n);return o<0&&String(parseInt(n,10))===n&&(o=parseInt(n,10)),o>=0&&a?{i:o,text:a}:null}).filter(Boolean):[]}function mt(t,e,r,i,n){var a=(c(t.goalLabel)?t.goalLabel:"Goal")+" "+k(v(t.goal,0),t);return'<line x1="'+s(r)+'" x2="'+s(i)+'" y1="'+s(n)+'" y2="'+s(n)+'" stroke="'+e.fg+'" stroke-opacity=".55" stroke-width="1.25" stroke-dasharray="4 4"/>'+p(i,n-5,a,F(e,10,'text-anchor="end"'))}function pt(t,e,r){var i=String(c(e.stat)?e.stat:r||"").toLowerCase();if(!i||i==="none"||!t.length)return null;var n=Y(t),a={last:t[t.length-1],total:n,sum:n,average:n/t.length,avg:n/t.length,max:Math.max.apply(null,t),min:Math.min.apply(null,t)};if(!(i in a))return null;var o=null;return i==="last"&&t.length>1&&e.delta!=="none"&&(o=t[t.length-1]-t[0]),{val:a[i],delta:o}}var N=["spark","line","area","bars","histogram","scatter","ring","donut","gauge","progress","heatmap"],A={};function wt(t,e){A[t]=e}var X=t=>t.replace(/-([a-z])/g,(e,r)=>r.toUpperCase());function U(t,e){if(!A[t])throw new Error(N.includes(t)?`Bezel Charts: the ${t} chart isn't loaded. Add import 'bezel-charts/${t}', or load dist/charts/${t}.js.`:`Bezel Charts: unknown chart type "${t}". Choose one of: ${N.join(", ")}.`);let r={};for(let[i,n]of Object.entries(e))r[X(i)]=n;return r}function S(t,e={}){let r=U(t,e);r.animate=C(r.animate),r.frame=r.frame==="none"?"none":"bezel";let i=r.theme==="light"||r.theme==="dark"?r.theme:r.autoTheme||"dark";return A[t](r,g[i])}function j(t,e={}){return A[t].table(U(t,e))}function $(t){return t.replace(/<rect class="bzc-hit"[^>]*\/>/g,"").replace(/<circle[^>]* class="bzc-hit"[^>]*\/>/g,"").replace(/ data-tip="[^"]*"/g,"")}function yt(t,e={}){return $(S(t,{...e,animate:!1}))}var q=["type","values","labels","series","heading","prefix","suffix","decimals","compact","color","theme","frame","width","height","goal","goal-label","notes","show-values","stat","delta","delta-label","max","min","value","zones","horizontal","straight","zero","start","lang","corners","background","center-label","highlight","x","y","x-label","y-label","trend","static","no-tooltips","stacked","angle-labels","dash","markers","patterns","bins","bin-width","mark","percent"],_=`:host{display:block;position:relative;max-width:100%}:host([hidden]){display:none}svg{display:block;max-width:100%;height:auto;overflow:visible}.tip{position:absolute;left:0;top:0;pointer-events:none;background:#0b0b10;color:#f2f1f7;font:600 12px/1.5 ${w};padding:7px 10px;border-radius:10px;white-space:pre;opacity:0;transform:translate(-50%,calc(-100% - 12px));transition:opacity .12s;z-index:3;border:1px solid #2a2935;box-shadow:0 8px 24px rgba(0,0,0,.35)}.tip.on{opacity:1}.c{outline:none}.c:focus-visible{outline:2px solid #fff;outline-offset:3px;box-shadow:0 0 0 7px #000}.k{stroke:currentColor;stroke-width:2;stroke-opacity:1}.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@media (forced-colors:active){.c:focus-visible{outline-color:Highlight}}`,Q={ArrowLeft:-1,ArrowUp:-1,ArrowRight:1,ArrowDown:1},J=()=>typeof matchMedia=="function"?matchMedia("(prefers-color-scheme: dark)"):null,K=()=>{let t=typeof document<"u"&&document.documentElement?.getAttribute?.("data-theme");return t==="light"||t==="dark"?t:null},R=new Set;typeof MutationObserver=="function"&&typeof document<"u"&&document.documentElement&&new MutationObserver(()=>R.forEach(t=>t.refresh())).observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]});var Z=typeof HTMLElement>"u"?class{}:HTMLElement,z=class extends Z{static get observedAttributes(){return q}static get themes(){return g}get resolvedTheme(){let e=this.getAttribute("theme");return e==="light"||e==="dark"?e:this.options.autoTheme}get chartType(){return this.getAttribute("type")||"spark"}connectedCallback(){this.shadowRoot||(this.attachShadow({mode:"open"}).innerHTML=`<style>${_}</style><div class="c" role="group" aria-roledescription="chart"></div><p class="sr" id="h">Use the arrow keys to step through the values.</p><div class="tip" aria-hidden="true"></div><div class="sr" aria-live="polite"></div><div class="sr"></div>`,[,this.#t,,this.#r,this.#s,this.#h]=this.shadowRoot.children,this.shadowRoot.addEventListener("pointermove",e=>this.#d(e)),this.shadowRoot.addEventListener("pointerdown",e=>this.#d(e)),this.addEventListener("pointerleave",()=>this.#r.classList.remove("on")),this.#t.addEventListener("keydown",e=>this.#g(e)),this.#t.addEventListener("blur",()=>this.#b())),R.add(this),this.#i=J(),this.#i?.addEventListener?.("change",this.#u),typeof ResizeObserver=="function"?(this.#o=new ResizeObserver(([e])=>{let r=Math.round(e.contentRect.width);(!this.#n||!this.hasAttribute("width")&&r>0&&Math.abs(r-this.#l)>1)&&this.#a()}),this.#o.observe(this)):this.#a()}disconnectedCallback(){R.delete(this),this.#o?.disconnect(),this.#i?.removeEventListener?.("change",this.#u)}attributeChangedCallback(){!this.#n||this.#c||(this.#c=!0,queueMicrotask(()=>{this.#c=!1,this.#a()}))}get options(){let e={};for(let r of q)this.hasAttribute(r)&&(e[r]=this.getAttribute(r));return e.width||(e.width=this.#l||360),e.autoTheme=K()||(this.#i?this.#i.matches?"dark":"light":"dark"),e}refresh(){this.#n&&this.#a()}toSVG(e={}){return $(S(this.chartType,{...this.options,...e,animate:!1}))}download(e){let r=URL.createObjectURL(new Blob([this.toSVG()],{type:"image/svg+xml"})),i=Object.assign(document.createElement("a"),{href:r,download:`${(e||this.getAttribute("heading")||this.chartType).replace(/[^\w-]+/g,"-").toLowerCase()}.svg`});document.body.append(i),i.click(),i.remove(),setTimeout(()=>URL.revokeObjectURL(r),1e3)}#o=null;#t=null;#r=null;#s=null;#h=null;#e=-1;#i=null;#l=0;#n=!1;#c=!1;#u=()=>{let e=this.getAttribute("theme");(!e||e==="auto")&&this.refresh()};#a(){if(!this.shadowRoot)return;let e=Math.round(this.getBoundingClientRect?.().width||0);this.#l=e>0?e:360;let r=this.options;r.animate=!this.#n&&!this.hasAttribute("static");let i,n=null;try{i=S(this.chartType,r),n=j(this.chartType,r)}catch(d){i=`<p style="font:13px ${x};color:#d63f7c">${h(d.message)}</p>`}let a=this.#t;a.innerHTML=i.replace(/<title>[\s\S]*?<\/title>/,"");let o=a.querySelector("svg");o?(a.setAttribute("aria-label",o.getAttribute("aria-label")),o.removeAttribute("role"),o.removeAttribute("aria-label"),o.setAttribute("aria-hidden","true")):a.removeAttribute("aria-label");let l=!!o&&!this.hasAttribute("no-tooltips");l?(a.setAttribute("tabindex","0"),a.setAttribute("aria-describedby","h")):(a.removeAttribute("tabindex"),a.removeAttribute("aria-describedby")),a.style.color=g[r.theme==="light"||r.theme==="dark"?r.theme:r.autoTheme].fg,a.style.borderRadius=`${r.frame==="none"?4:u(+r.corners||22,0,60)}px`,this.#h.innerHTML=n&&n.rows.length?tt(r.heading,n):"",this.#e>=0&&l&&this.shadowRoot.activeElement===a?this.#p(this.#e):this.#e=-1,this.#n=!0,this.dispatchEvent(new CustomEvent("bezel-render",{bubbles:!0}))}#d(e){if(this.hasAttribute("no-tooltips"))return;let r=e.target?.closest?.("[data-tip]");if(!r){this.#r.classList.remove("on");return}this.#f(r,e.clientX,e.clientY)}#f(e,r,i){let n=this.#r;n.textContent=e.getAttribute("data-tip");let a=this.getBoundingClientRect?.()||{left:0,top:0,width:0},o=n.offsetWidth/2;n.style.left=`${u(r-a.left,o,Math.max(o,a.width-o))}px`,n.style.top=`${i-a.top}px`,n.classList.add("on")}#m(){return[...this.#t.querySelectorAll("[data-tip]:not([data-skip])")]}#g(e){let r=this.#m(),i=r.length;if(!i)return;let n=this.#e,a=Q[e.key];if(a)this.chartType==="heatmap"&&/Left|Right/.test(e.key)&&(a*=7),n=n<0?a>0?0:i-1:u(n+a,0,i-1);else if(e.key==="Home"||e.key==="End")n=e.key==="Home"?0:i-1;else{e.key==="Escape"&&this.#b();return}e.preventDefault(),this.#p(n,!0)}#p(e,r){let i=this.#m();if(!i.length)return;e=u(e,0,i.length-1),this.#t.querySelector(".k")?.classList.remove("k");let n=i[e],a=n.getBoundingClientRect?.()||{left:0,top:0,width:0};n.classList.add("k"),this.#e=e,this.#f(n,a.left+a.width/2,a.top),r&&(this.#s.textContent=`${n.getAttribute("data-tip").replace(/\n/g,", ")}. ${e+1} of ${i.length}`)}#b(){this.#t.querySelector(".k")?.classList.remove("k"),this.#r.classList.remove("on"),this.#s.textContent="",this.#e=-1}};function tt(t,{head:e,rows:r}){let i=n=>n.map((a,o)=>o?`<td>${h(a)}</td>`:`<th scope="row">${h(a)}</th>`).join("");return`<table><caption>${h(t||"Chart data")}</caption><thead><tr>${e.map(n=>`<th scope="col">${h(n)}</th>`).join("")}</tr></thead><tbody>${r.map(n=>`<tr>${i(n)}</tr>`).join("")}</tbody></table>`}function zt(t){typeof customElements>"u"||typeof HTMLElement>"u"||(customElements.get(`bezel-${t}`)||customElements.define(`bezel-${t}`,class extends z{get chartType(){return t}}),customElements.get("bezel-chart")||customElements.define("bezel-chart",class extends z{}))}function et(t){var e=Math.round(u(v(t.width,360),160,2400)),r=t.frame==="none"?0:4,i=t.frame==="none"?8:20;return{W:e,b:r,P:i,w:e-2*(r+i)}}var rt=".bzc-a{animation:bzc-in .6s ease both}.bzc-d{animation:bzc-draw 1.1s cubic-bezier(.3,.7,.2,1) both}.bzc-g{transform-box:fill-box;transform-origin:50% 100%;animation:bzc-grow .7s cubic-bezier(.2,.8,.2,1) both}.bzc-gn{transform-box:fill-box;transform-origin:50% 0;animation:bzc-grow .7s cubic-bezier(.2,.8,.2,1) both}.bzc-gx{transform-box:fill-box;transform-origin:0 50%;animation:bzc-growx .8s cubic-bezier(.2,.8,.2,1) both}.bzc-s{animation:bzc-sweep 1.1s cubic-bezier(.2,.8,.2,1) both}@keyframes bzc-in{from{opacity:0}}@keyframes bzc-draw{from{stroke-dashoffset:1}}@keyframes bzc-grow{from{transform:scaleY(0)}}@keyframes bzc-growx{from{transform:scaleX(0)}}@keyframes bzc-sweep{from{stroke-dasharray:0 100}}@media (prefers-reduced-motion:reduce){[class^=bzc-]{animation:none!important}}";function Ft(t,e,r,i,n){var a=et(t),o=a.W,l=a.b,d=a.P,O=a.w,E=u(v(t.corners,22),0,60),f=l+d,y="";c(t.heading)&&(y+=p(l+d,f+10,String(t.heading).toUpperCase(),F(e,11,'font-weight="600" letter-spacing="1.3"')),f+=24);var m=n&&n.stat;if(m){if(y+=p(l+d,f+30,k(m.val,t),'fill="'+e.fg+'" font-family="'+x+'" font-size="32" font-weight="800" letter-spacing="-0.5"'),m.delta!=null){var M=m.delta>0,H=m.delta===0,I=t.delta==="inverse"?!M:M,D=H?e.muted:I?e.up:e.down,P=(H?"\u25CF ":M?"\u25B2 ":"\u25BC ")+k(Math.abs(m.delta),t)+" "+(c(t.deltaLabel)?t.deltaLabel:"since start");y+=p(l+d+O,f+28,P,'text-anchor="end" fill="'+D+'" font-family="'+w+'" font-size="11" font-weight="600"')}f+=44}var G=i(l+d,f,O,r),b=Math.round(f+r+d+l),L="";t.frame!=="none"?L='<rect width="'+o+'" height="'+b+'" rx="'+E+'" fill="'+e.bezel+'"/><rect x="'+l+'" y="'+l+'" width="'+(o-2*l)+'" height="'+(b-2*l)+'" rx="'+Math.max(0,E-l)+'" fill="'+(t.background||e.tile)+'"/>':c(t.background)&&(L='<rect width="'+o+'" height="'+b+'" rx="'+E+'" fill="'+t.background+'"/>');var B=(c(t.heading)?t.heading+": ":"")+(n&&n.summary||"chart");return'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 '+o+" "+b+'" width="'+o+'" height="'+b+'" role="img" aria-label="'+h(B)+'"><title>'+h(B)+"</title>"+(t.animate?"<style>"+rt+"</style>":"")+L+y+G+"</svg>"}export{x as a,w as b,nt as c,h as d,s as e,u as f,v as g,c as h,T as i,V as j,at as k,Y as l,ot as m,st as n,C as o,k as p,lt as q,p as r,F as s,ct as t,ht as u,ut as v,dt as w,ft as x,mt as y,pt as z,et as A,Ft as B,wt as C,S as D,yt as E,z as F,zt as G};
@@ -1,2 +1,2 @@
1
- /*! Bezel Charts v1.3.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
- import{B as H,C as J,D as U,E as W,F as _,G as K,c as I,e as n,f as N,g as P,h as y,i as b,j as x,o as L,p as h,q as X,r as M,s as E,t as Y,u as z,v as Z,w as q,x as A,y as D,z as F}from"./shared-L67BQ555.js";function k(t,l){var r=b(t.values),o=Z(t,l)[0],Q=P(t.height,64),G=x(t.labels),R=A(t,G),T=F(r,t,"last");return H(t,l,Q,function(i,c,p,f){if(!r.length)return q(l,i,c,p,f);var v=r.length===1?[r[0],r[0]]:r,u=Math.min.apply(null,v),m=Math.max.apply(null,v);y(t.goal)&&(u=Math.min(u,+t.goal),m=Math.max(m,+t.goal));var V=(m-u||Math.abs(m)||1)*.12;u-=V,m+=V;var O=function(a){return i+a*p/(v.length-1)},S=function(a){return c+f-(a-u)/(m-u)*f},d=v.map(function(a,e){return[O(e),S(a)]}),j=X(d,L(t.straight)),B=I("g"),g=d[d.length-1],s='<defs><linearGradient id="'+B+'" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="'+o+'" stop-opacity=".32"/><stop offset="1" stop-color="'+o+'" stop-opacity="0"/></linearGradient></defs>';[1/3,2/3].forEach(function(a){s+='<line x1="'+i+'" x2="'+(i+p)+'" y1="'+n(c+f*a)+'" y2="'+n(c+f*a)+'" stroke="'+l.grid+'" stroke-dasharray="2 4"/>'}),s+='<path d="'+j+"L"+n(g[0])+","+(c+f)+"L"+i+","+(c+f)+'Z" fill="url(#'+B+')"'+z(t,"bzc-a")+"/>",s+='<path d="'+j+'" fill="none" stroke="'+o+'" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" pathLength="1" style="stroke-dasharray:1"'+z(t,"bzc-d")+"/>",y(t.goal)&&(s+=D(t,l,i,i+p,S(+t.goal))),R.forEach(function(a){if(!(a.i>=r.length)){var e=d[a.i];s+='<circle cx="'+n(e[0])+'" cy="'+n(e[1])+'" r="3.5" fill="'+l.fg+'"/>'+M(N(e[0],i+30,i+p-30),e[1]-9,a.text,E(l,10,'text-anchor="middle"',l.fg))}}),s+='<circle cx="'+n(g[0])+'" cy="'+n(g[1])+'" r="9" fill="'+o+'" fill-opacity=".25"/><circle cx="'+n(g[0])+'" cy="'+n(g[1])+'" r="4.5" fill="'+o+'"/>',L(t.showValues)&&d.forEach(function(a,e){e<r.length&&(s+=M(a[0],a[1]-8,h(r[e],t,!0),E(l,9,'text-anchor="middle"')))});var C=r.length>1?p/(r.length-1):p;return r.forEach(function(a,e){s+=Y(O(e)-C/2,c-6,C,f+12,(G[e]||"#"+(e+1))+": "+h(a,t))}),s},{stat:T,summary:r.length?"latest "+h(r[r.length-1],t):"no data"})}k.table=function(t){var l=x(t.labels);return{head:["Label","Value"],rows:b(t.values).map(function(r,o){return[l[o]||"#"+(o+1),h(r,t)]})}};J("spark",k);K("spark");export{_ as BezelChart,U as render,W as toSVG};
1
+ /*! Bezel Charts v1.5.0 | MIT | github.com/ShazMoghaddam/bezel-charts */
2
+ import{B as H,C as J,D as U,E as W,F as _,G as K,c as I,e as n,f as N,g as P,h as y,i as b,j as x,o as L,p as h,q as X,r as M,s as E,t as Y,u as z,v as Z,w as q,x as A,y as D,z as F}from"./shared-WQEE2V6C.js";function k(t,l){var r=b(t.values),o=Z(t,l)[0],Q=P(t.height,64),G=x(t.labels),R=A(t,G),T=F(r,t,"last");return H(t,l,Q,function(i,c,p,f){if(!r.length)return q(l,i,c,p,f);var v=r.length===1?[r[0],r[0]]:r,u=Math.min.apply(null,v),m=Math.max.apply(null,v);y(t.goal)&&(u=Math.min(u,+t.goal),m=Math.max(m,+t.goal));var V=(m-u||Math.abs(m)||1)*.12;u-=V,m+=V;var O=function(a){return i+a*p/(v.length-1)},S=function(a){return c+f-(a-u)/(m-u)*f},d=v.map(function(a,e){return[O(e),S(a)]}),j=X(d,L(t.straight)),B=I("g"),g=d[d.length-1],s='<defs><linearGradient id="'+B+'" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="'+o+'" stop-opacity=".32"/><stop offset="1" stop-color="'+o+'" stop-opacity="0"/></linearGradient></defs>';[1/3,2/3].forEach(function(a){s+='<line x1="'+i+'" x2="'+(i+p)+'" y1="'+n(c+f*a)+'" y2="'+n(c+f*a)+'" stroke="'+l.grid+'" stroke-dasharray="2 4"/>'}),s+='<path d="'+j+"L"+n(g[0])+","+(c+f)+"L"+i+","+(c+f)+'Z" fill="url(#'+B+')"'+z(t,"bzc-a")+"/>",s+='<path d="'+j+'" fill="none" stroke="'+o+'" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" pathLength="1" style="stroke-dasharray:1"'+z(t,"bzc-d")+"/>",y(t.goal)&&(s+=D(t,l,i,i+p,S(+t.goal))),R.forEach(function(a){if(!(a.i>=r.length)){var e=d[a.i];s+='<circle cx="'+n(e[0])+'" cy="'+n(e[1])+'" r="3.5" fill="'+l.fg+'"/>'+M(N(e[0],i+30,i+p-30),e[1]-9,a.text,E(l,10,'text-anchor="middle"',l.fg))}}),s+='<circle cx="'+n(g[0])+'" cy="'+n(g[1])+'" r="9" fill="'+o+'" fill-opacity=".25"/><circle cx="'+n(g[0])+'" cy="'+n(g[1])+'" r="4.5" fill="'+o+'"/>',L(t.showValues)&&d.forEach(function(a,e){e<r.length&&(s+=M(a[0],a[1]-8,h(r[e],t,!0),E(l,9,'text-anchor="middle"')))});var C=r.length>1?p/(r.length-1):p;return r.forEach(function(a,e){s+=Y(O(e)-C/2,c-6,C,f+12,(G[e]||"#"+(e+1))+": "+h(a,t))}),s},{stat:T,summary:r.length?"latest "+h(r[r.length-1],t):"no data"})}k.table=function(t){var l=x(t.labels);return{head:["Label","Value"],rows:b(t.values).map(function(r,o){return[l[o]||"#"+(o+1),h(r,t)]})}};J("spark",k);K("spark");export{_ as BezelChart,U as render,W as toSVG};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bezel-charts",
3
- "version": "1.3.0",
4
- "description": "Small, polished charts as zero-dependency web components. Sparklines, lines, bars, rings, donuts, gauges, progress bars and heatmaps, with one-click static SVG export for READMEs.",
3
+ "version": "1.5.0",
4
+ "description": "Small, polished charts as zero-dependency web components. Sparklines, lines, areas, bars, histograms, rings, donuts, gauges, progress bars and heatmaps, with one-click static SVG export for READMEs.",
5
5
  "type": "module",
6
6
  "main": "dist/bezel-charts.js",
7
7
  "module": "dist/bezel-charts.js",
@@ -9,7 +9,9 @@
9
9
  ".": "./dist/bezel-charts.js",
10
10
  "./spark": "./dist/charts/spark.js",
11
11
  "./line": "./dist/charts/line.js",
12
+ "./area": "./dist/charts/area.js",
12
13
  "./bars": "./dist/charts/bars.js",
14
+ "./histogram": "./dist/charts/histogram.js",
13
15
  "./scatter": "./dist/charts/scatter.js",
14
16
  "./ring": "./dist/charts/ring.js",
15
17
  "./donut": "./dist/charts/donut.js",
@@ -39,7 +41,8 @@
39
41
  "svg",
40
42
  "dashboard",
41
43
  "readme",
42
- "data-visualization"
44
+ "data-visualization",
45
+ "histogram"
43
46
  ],
44
47
  "author": "Shaz Moghaddam (https://shazmoghaddam.github.io)",
45
48
  "license": "MIT",
@@ -0,0 +1,97 @@
1
+ import { newId, r2, num, list, series, bool, fmt, pathOf, text, small, palette, emptyState, parseNotes, statOf } from '../core/util.js';
2
+ import { seriesTable, styleOf, pattern, DASHES, SHAPES, PATTERNS } from '../core/series.js';
3
+ import { xyFrame, xyFinish, lineKey, seriesLine, pointMarks } from '../core/xy.js';
4
+ import { tile } from '../core/tile.js';
5
+
6
+ /**
7
+ * Areas over time. Several series overlap as see-through fills; `stacked` piles them so the top edge is the total,
8
+ * and stacked="percent" scales each column to 100% to show shares. The axis always includes zero, since an area's
9
+ * height reads as an amount.
10
+ */
11
+ export default function area(o, th) {
12
+ var S = series(o.values), names = list(o.series), labels = list(o.labels), pal = palette(o, th);
13
+ var h = num(o.height, 170), k = S.length, n = Math.max.apply(null, [0].concat(S.map(function (s) { return s.length; })));
14
+ var mode = k > 1 ? (o.stacked === 'percent' ? 'percent' : bool(o.stacked) ? 'stack' : '') : '';
15
+ var notes = parseNotes(o, labels), multi = k > 1 || names.length > 0;
16
+ var nameOf = function (j) { return names[j] || 'Series ' + (j + 1); };
17
+ var val = function (j, i) { return i < S[j].length ? S[j][i] : 0; };
18
+
19
+ // Where each band starts and ends in every column. In a stack, positive parts pile up from zero and negative parts
20
+ // down from it, as stacked bars do. In a percent stack, each column's positive parts are scaled to add up to 100.
21
+ var lows = S.map(function () { return []; }), highs = S.map(function () { return []; }), totals = [], pos = [];
22
+ for (var i = 0; i < n; i++) {
23
+ var up = 0, down = 0, t = 0, p = 0;
24
+ for (var j = 0; j < k; j++) { t += val(j, i); p += Math.max(0, val(j, i)); }
25
+ totals.push(t); pos.push(p);
26
+ for (j = 0; j < k; j++) {
27
+ var v = mode === 'percent' ? (p ? Math.max(0, val(j, i)) / p * 100 : 0) : val(j, i);
28
+ if (!mode) { lows[j].push(0); highs[j].push(v); }
29
+ else if (v >= 0) { lows[j].push(up); up += v; highs[j].push(up); }
30
+ else { lows[j].push(down); down += v; highs[j].push(down); }
31
+ }
32
+ }
33
+ var edges = [].concat.apply([], lows.concat(highs));
34
+
35
+ var dashOf = styleOf(o.dash, Object.keys(DASHES), 'solid'), markOf = styleOf(o.markers, SHAPES, 'none');
36
+ var patOf = k > 1 ? styleOf(o.patterns, PATTERNS, 'solid') : null, bg = o.background || th.tile, defs = '', fills = [];
37
+ for (var q = 0; patOf && q < k; q++) {
38
+ if (patOf(q) === 'solid') continue;
39
+ var pid = newId('g');
40
+ defs += pattern(pid, patOf(q), pal[q % pal.length], bg);
41
+ fills[q] = 'url(#' + pid + ')';
42
+ }
43
+ // The legend shows each band's pattern, or a sample of its edge when lines have dashes or markers.
44
+ var key = patOf
45
+ ? function (j, x, y) { return '<rect x="' + r2(x) + '" y="' + r2(y + 1) + '" width="10" height="10" rx="2" fill="' + (fills[j] || pal[j % pal.length]) + '"/>'; }
46
+ : (dashOf || markOf) && lineKey(pal, dashOf, markOf, bg);
47
+ var share = function (j, i) { return pos[i] ? Math.round(Math.max(0, val(j, i)) / pos[i] * 100) : 0; };
48
+
49
+ return tile(o, th, h, function (x0, y0, w, h) {
50
+ if (!n) return emptyState(th, x0, y0, w, h);
51
+ var f = xyFrame(o, th, {
52
+ n: n, names: multi ? S.map(function (_, j) { return nameOf(j); }) : null, pal: pal, key: key, kw: key && (patOf ? 15 : 24),
53
+ lo: Math.min.apply(null, edges), hi: Math.max.apply(null, edges), zero: true, labels: labels, notes: notes,
54
+ tick: mode === 'percent' ? function (t) { return fmt(t, { lang: o.lang }, true) + '%'; } : function (t) { return fmt(t, o, true); },
55
+ }, x0, y0, w, h);
56
+ var s = (defs ? '<defs>' + defs + '</defs>' : '') + f.svg, X = f.X, Y = f.Y;
57
+ // One value stretches across the chart, like a line chart does.
58
+ var pts = function (ys) {
59
+ var P = ys.map(function (y, i) { return [X(i), Y(y)]; });
60
+ return P.length === 1 ? [[f.px, P[0][1]], [f.px + f.pw, P[0][1]]] : P;
61
+ };
62
+ var straight = bool(o.straight), alpha = mode ? '.8' : '.22';
63
+ var shown = function (j) { return mode ? highs[j] : S[j]; };
64
+ // Fills first, so no band covers another's edge.
65
+ S.forEach(function (_, j) {
66
+ var top = pts(shown(j)), base = pts(mode ? lows[j] : shown(j).map(function () { return 0; })).reverse();
67
+ s += '<path d="' + pathOf(top, straight) + pathOf(base, straight).replace(/^M/, 'L') + 'Z" fill="' + (fills[j] || pal[j % pal.length]) +
68
+ '" fill-opacity="' + alpha + '"' + (o.animate ? ' class="bzc-a" style="animation-delay:' + r2(j * 0.1) + 's"' : '') + '/>';
69
+ });
70
+ S.forEach(function (_, j) {
71
+ var c = pal[j % pal.length], ys = shown(j), P = pts(ys), mk = markOf ? markOf(j) : 'none';
72
+ s += seriesLine(o, pathOf(P, straight), c, j, dashOf ? DASHES[dashOf(j)] : '');
73
+ if (mk !== 'none') s += pointMarks(o, mk, ys, X, Y, c, bg, j);
74
+ else if (!mode) s += '<circle cx="' + r2(P[P.length - 1][0]) + '" cy="' + r2(P[P.length - 1][1]) + '" r="4" fill="' + c + '" stroke="' + bg + '" stroke-width="2"/>';
75
+ if (bool(o.showValues) && !mode) ys.forEach(function (y, i) { s += text(X(i), Y(y) - 8, fmt(y, o, true), small(th, 9, 'text-anchor="middle"')); });
76
+ });
77
+ // A stack writes its total above each column. Every column of a percent stack is 100%, so it writes nothing.
78
+ if (bool(o.showValues) && mode === 'stack') {
79
+ totals.forEach(function (t, i) {
80
+ var top = Math.max.apply(null, highs.map(function (hs) { return hs[i]; }).concat([0]));
81
+ s += text(X(i), Y(top) - 8, fmt(t, o, true), small(th, 9, 'text-anchor="middle"'));
82
+ });
83
+ }
84
+ return s + xyFinish(o, th, f, n, function (i) {
85
+ var tip = labels[i] || '#' + (i + 1);
86
+ S.forEach(function (ser, j) {
87
+ if (i < ser.length) tip += '\n' + (multi ? nameOf(j) + ': ' : '') + fmt(ser[i], o) + (mode === 'percent' ? ' (' + share(j, i) + '%)' : '');
88
+ });
89
+ return tip + (mode ? '\nTotal: ' + fmt(totals[i], o) : '');
90
+ });
91
+ }, {
92
+ stat: statOf(mode ? totals : S[0] || [], o, ''),
93
+ summary: k + ' series ' + (mode === 'percent' ? 'as shares of each total' : mode ? 'stacked' : 'filled') + ' over ' + n + ' points',
94
+ });
95
+ }
96
+
97
+ area.table = function (o) { var S = series(o.values); return seriesTable(o, S.length > 1 && (o.stacked === 'percent' || bool(o.stacked))); };
@@ -0,0 +1,182 @@
1
+ import { newId, r2, num, has, list, series, bool, fmt, tw, text, small, hit, anim, palette, emptyState } from '../core/util.js';
2
+ import { niceScale, legend, styleOf, pattern, PATTERNS } from '../core/series.js';
3
+ import { tile } from '../core/tile.js';
4
+
5
+ /**
6
+ * How raw values spread out. The chart counts how many fall into each range: the ranges have round edges, include
7
+ * their lower edge and not their upper one, except the last, which includes both so the largest value is counted.
8
+ * Several series share the same ranges and overlap, so their spreads can be compared.
9
+ */
10
+ export default function histogram(o, th) {
11
+ var b = binned(o), names = list(o.series), pal = palette(o, th), h = num(o.height, 190);
12
+ var S = b ? b.S : [], k = S.length, multi = k > 1 || names.length > 0, pct = bool(o.percent);
13
+ var nameOf = function (j) { return names[j] || 'Series ' + (j + 1); };
14
+ // Range edges get as many decimals as the range width needs, so 0.5-wide ranges read 2.5, 3.0, 3.5.
15
+ var eo = Object.assign({}, o, { decimals: has(o.decimals) ? o.decimals : b ? b.dp : 0 });
16
+ var range = function (i) { return fmt(b.edge(i), eo) + ' to ' + fmt(b.edge(i + 1), eo); };
17
+ var share = function (j, i) { return Math.round(b.counts[j][i] / S[j].length * 100); };
18
+ var height = function (j, i) { return pct ? b.counts[j][i] / S[j].length * 100 : b.counts[j][i]; };
19
+ var marks = list(o.mark).filter(function (m) { return m === 'mean' || m === 'median'; });
20
+
21
+ var patOf = k > 1 ? styleOf(o.patterns, PATTERNS, 'solid') : null, defs = '', fills = [];
22
+ for (var q = 0; patOf && q < k; q++) {
23
+ if (patOf(q) === 'solid') continue;
24
+ var pid = newId('g');
25
+ defs += pattern(pid, patOf(q), pal[q % pal.length], o.background || th.tile);
26
+ fills[q] = 'url(#' + pid + ')';
27
+ }
28
+ var key = patOf && function (j, x, y) { return '<rect x="' + r2(x) + '" y="' + r2(y + 1) + '" width="10" height="10" rx="2" fill="' + (fills[j] || pal[j % pal.length]) + '"/>'; };
29
+
30
+ var peak = 0, n = 0;
31
+ if (b) {
32
+ for (var i = 0; i < b.count; i++) if (total(b, i) > total(b, peak)) peak = i;
33
+ S.forEach(function (s) { n += s.length; });
34
+ }
35
+
36
+ return tile(o, th, h, function (x0, y0, w, h) {
37
+ if (!b) return emptyState(th, x0, y0, w, h);
38
+ var s = defs ? '<defs>' + defs + '</defs>' : '', top = y0;
39
+ if (multi) {
40
+ var lg = legend(S.map(function (_, j) { return nameOf(j); }), pal, th, x0, top, w, key, key && 15);
41
+ s += lg.svg;
42
+ top += lg.height;
43
+ }
44
+ var most = 0;
45
+ S.forEach(function (_, j) { for (var i = 0; i < b.count; i++) most = Math.max(most, height(j, i)); });
46
+ var sc = niceScale(0, most || 1, 4);
47
+ var tl = sc.ticks.map(function (t) { return fmt(t, { lang: o.lang }, true) + (pct ? '%' : ''); });
48
+ var axisW = Math.max.apply(null, tl.map(function (t) { return tw(t, 10, true); })) + 10;
49
+ var px = x0 + axisW, pw = w - axisW, ph = h - (top - y0) - 20, cw = pw / b.count;
50
+ var X = function (i) { return px + i * cw; };
51
+ var Y = function (v) { return top + ph - (v - sc.lo) / (sc.hi - sc.lo) * ph; };
52
+ sc.ticks.forEach(function (t, i) {
53
+ var y = Y(t);
54
+ s += '<line x1="' + r2(px) + '" x2="' + r2(px + pw) + '" y1="' + r2(y) + '" y2="' + r2(y) + '" stroke="' + th.grid + '"' + (t === 0 ? '' : ' stroke-dasharray="2 4"') + '/>' +
55
+ text(px - 8, y + 3.5, tl[i], small(th, 10, 'text-anchor="end"'));
56
+ });
57
+ // Edge labels, thinned out when they would crowd.
58
+ var el = [];
59
+ for (var e = 0; e <= b.count; e++) el.push(fmt(b.edge(e), eo, true));
60
+ // The first and last labels hang inwards from the edges, so neighbours need one and a half labels of room.
61
+ var every = Math.max(1, Math.ceil((Math.max.apply(null, el.map(function (l) { return tw(l, 10, true); })) * 1.5 + 8) / cw));
62
+ for (e = 0; e <= b.count; e += every) {
63
+ s += text(X(e), top + ph + 15, el[e], small(th, 10, 'text-anchor="' + (e === 0 ? 'start' : e === b.count ? 'end' : 'middle') + '"'));
64
+ }
65
+ // Bars touch, with a hairline gap, because the ranges run on from each other. Several series overlap.
66
+ S.forEach(function (_, j) {
67
+ for (var i = 0; i < b.count; i++) {
68
+ var v = height(j, i);
69
+ if (!v) continue;
70
+ var y = Y(v);
71
+ s += '<rect x="' + r2(X(i) + 0.5) + '" y="' + r2(y) + '" width="' + r2(Math.max(1, cw - 1)) + '" height="' + r2(top + ph - y) + '" fill="' + (fills[j] || pal[j % pal.length]) + '"' +
72
+ (multi ? ' fill-opacity=".55"' : '') + anim(o, 'bzc-g', Math.min(0.6, i * 0.03)) + '/>';
73
+ }
74
+ });
75
+ // Mean and median lines, one per series. Their labels stack at the top beside the outermost line, on the side with
76
+ // more room, so no label crosses a line.
77
+ var lo = b.edge(0), span = b.edge(b.count) - lo, lines = [];
78
+ S.forEach(function (ser, j) {
79
+ marks.forEach(function (m) {
80
+ var v = m === 'mean' ? mean(ser) : median(ser);
81
+ lines.push({ x: px + (v - lo) / span * pw, c: multi ? pal[j % pal.length] : th.fg, t: (multi ? nameOf(j) + ' ' : '') + m + ' ' + fmt(v, o) });
82
+ });
83
+ });
84
+ if (lines.length) {
85
+ var xs = lines.map(function (l) { return l.x; }), left = (Math.min.apply(null, xs) + Math.max.apply(null, xs)) / 2 > px + pw / 2;
86
+ var lx = left ? Math.min.apply(null, xs) - 5 : Math.max.apply(null, xs) + 5;
87
+ lines.forEach(function (l, r) {
88
+ s += '<line x1="' + r2(l.x) + '" x2="' + r2(l.x) + '" y1="' + r2(top) + '" y2="' + r2(top + ph) + '" stroke="' + l.c + '" stroke-width="1.5" stroke-dasharray="4 3"/>' +
89
+ text(lx, top + 9 + r * 12, l.t, small(th, 10, 'text-anchor="' + (left ? 'end' : 'start') + '"', multi ? l.c : th.fg));
90
+ });
91
+ }
92
+ for (i = 0; i < b.count; i++) {
93
+ var tip = range(i);
94
+ S.forEach(function (_, j) { tip += '\n' + (multi ? nameOf(j) + ': ' : '') + b.counts[j][i] + ' (' + share(j, i) + '%)'; });
95
+ s += hit(X(i), top, cw, ph, tip);
96
+ }
97
+ return s;
98
+ }, {
99
+ summary: b ? (multi ? k + ' series, ' : '') + n + ' values in ' + b.count + ' ranges from ' + fmt(b.edge(0), eo) + ' to ' + fmt(b.edge(b.count), eo) + ', most in ' + range(peak) : 'no data',
100
+ });
101
+ }
102
+
103
+ histogram.table = function (o) {
104
+ var b = binned(o), names = list(o.series);
105
+ if (!b) return { head: ['Range', 'Count'], rows: [] };
106
+ var multi = b.S.length > 1 || names.length > 0, eo = Object.assign({}, o, { decimals: has(o.decimals) ? o.decimals : b.dp }), rows = [];
107
+ for (var i = 0; i < b.count; i++) {
108
+ var row = [fmt(b.edge(i), eo) + ' to ' + fmt(b.edge(i + 1), eo)];
109
+ if (multi) b.S.forEach(function (_, j) { row.push(String(b.counts[j][i])); });
110
+ else row.push(String(b.counts[0][i]), Math.round(b.counts[0][i] / b.S[0].length * 100) + '%');
111
+ rows.push(row);
112
+ }
113
+ return { head: ['Range'].concat(multi ? b.S.map(function (_, j) { return names[j] || 'Series ' + (j + 1); }) : ['Count', 'Share']), rows: rows };
114
+ };
115
+
116
+ /**
117
+ * The round width (1, 2, 2.5 or 5 times a power of ten) nearest to raw, and the decimals it needs. Nearest on a log
118
+ * scale: the thresholds sit halfway between the steps, at √2, √5, √12.5 and √50.
119
+ */
120
+ function niceWidth(raw) {
121
+ var e = Math.floor(Math.log10(raw)), p = Number('1e' + e), f = raw / p;
122
+ var m = f < 1.4142 ? 1 : f < 2.2361 ? 2 : f < 3.5355 ? 2.5 : f < 7.0711 ? 5 : 10;
123
+ return { w: m * p, dp: Math.max(0, m === 10 ? -e - 1 : -e) + (m === 2.5 ? 1 : 0) };
124
+ }
125
+
126
+ /**
127
+ * Sorts every value into ranges. bin-width sets the width; otherwise bins sets roughly how many ranges, and by default
128
+ * there are about log2(n) + 1. Returns null when there is nothing to count.
129
+ */
130
+ function binned(o) {
131
+ var S = series(o.values), all = [].concat.apply([], S);
132
+ if (!all.length) return null;
133
+ var lo = Math.min.apply(null, all), hi = Math.max.apply(null, all), w = num(o.binWidth, 0), dp, nice;
134
+ if (w > 0 && (hi - lo) / w <= 200) {
135
+ var str = String(o.binWidth), dot = str.indexOf('.');
136
+ dp = dot < 0 ? 0 : Math.min(6, str.length - dot - 1);
137
+ } else {
138
+ var k = num(o.bins, 0) > 0 ? Math.round(num(o.bins, 0)) : Math.ceil(Math.log2(all.length) + 1);
139
+ k = Math.min(Math.max(k, 1), 50);
140
+ nice = niceWidth(hi > lo ? (hi - lo) / k : Math.abs(lo) || 1);
141
+ w = nice.w;
142
+ dp = nice.dp;
143
+ }
144
+ // Edges are whole multiples of the width, rounded to the width's decimals so 3 × 0.1 is 0.3, not 0.30000000000000004.
145
+ // Counting compares values against these same edges, so a value typed as 0.3 lands in the range that starts at 0.3.
146
+ var s0 = Math.floor(lo / w);
147
+ var edge = function (i) { return Number(((s0 + i) * w).toFixed(dp + 3)); };
148
+ while (edge(0) > lo) s0--;
149
+ // Just enough ranges to reach the largest value, which the last range includes even when it sits on an edge.
150
+ var count = Math.max(1, Math.ceil((hi - edge(0)) / w));
151
+ while (count > 1 && edge(count - 1) >= hi) count--;
152
+ while (edge(count) < hi) count++;
153
+ var counts = S.map(function (ser) {
154
+ var c = [];
155
+ for (var i = 0; i < count; i++) c.push(0);
156
+ ser.forEach(function (x) {
157
+ var i = Math.min(count - 1, Math.max(0, Math.floor((x - edge(0)) / w)));
158
+ while (i > 0 && x < edge(i)) i--;
159
+ while (i < count - 1 && x >= edge(i + 1)) i++;
160
+ c[i]++;
161
+ });
162
+ return c;
163
+ });
164
+ return { S: S, edge: edge, count: count, counts: counts, dp: dp };
165
+ }
166
+
167
+ function total(b, i) {
168
+ var t = 0;
169
+ b.counts.forEach(function (c) { t += c[i]; });
170
+ return t;
171
+ }
172
+
173
+ function mean(v) {
174
+ var t = 0;
175
+ v.forEach(function (x) { t += x; });
176
+ return t / v.length;
177
+ }
178
+
179
+ function median(v) {
180
+ var s = v.slice().sort(function (a, b) { return a - b; }), m = Math.floor(s.length / 2);
181
+ return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2;
182
+ }
@@ -1,5 +1,6 @@
1
- import { newId, r2, clamp, num, has, list, series, tw, bool, fmt, pathOf, text, small, hit, anim, palette, emptyState, parseNotes, goalLine, statOf } from '../core/util.js';
2
- import { niceScale, legend, seriesTable, styleOf, marker, DASHES, SHAPES } from '../core/series.js';
1
+ import { newId, r2, num, list, series, bool, fmt, pathOf, text, small, anim, palette, emptyState, parseNotes, statOf } from '../core/util.js';
2
+ import { seriesTable, styleOf, DASHES, SHAPES } from '../core/series.js';
3
+ import { xyFrame, xyFinish, lineKey, seriesLine, pointMarks } from '../core/xy.js';
3
4
  import { tile } from '../core/tile.js';
4
5
 
5
6
  export default function line(o, th) {
@@ -10,49 +11,17 @@ export default function line(o, th) {
10
11
  var dashOf = styleOf(o.dash, Object.keys(DASHES), 'solid'), markOf = styleOf(o.markers, SHAPES, 'none');
11
12
  var bg = o.background || th.tile;
12
13
  // With dashes or markers, the legend shows a short sample of each line instead of a dot.
13
- var key = (dashOf || markOf) && function (k, x, y) {
14
- var c = pal[k % pal.length], dk = dashOf ? DASHES[dashOf(k)] : '', mk = markOf ? markOf(k) : 'none';
15
- return '<line x1="' + r2(x) + '" x2="' + r2(x + 18) + '" y1="' + r2(y + 6) + '" y2="' + r2(y + 6) + '" stroke="' + c + '" stroke-width="2.5" stroke-linecap="round"' +
16
- (dk ? ' stroke-dasharray="' + dk + '"' : '') + '/>' + (mk !== 'none' ? marker(mk, x + 9, y + 6, 3.5, ' fill="' + c + '" stroke="' + bg + '" stroke-width="1.5"') : '');
17
- };
14
+ var key = (dashOf || markOf) && lineKey(pal, dashOf, markOf, bg);
15
+ var nameOf = function (k) { return names[k] || 'Series ' + (k + 1); };
18
16
  return tile(o, th, h, function (x0, y0, w, h) {
19
17
  if (!n) return emptyState(th, x0, y0, w, h);
20
- var s = '', top = y0;
21
- if (multi) {
22
- var lg = legend(S.map(function (_, k) { return names[k] || 'Series ' + (k + 1); }), pal, th, x0, top, w, key, key && 24);
23
- s += lg.svg;
24
- top += lg.height;
25
- }
26
18
  var all = [].concat.apply([], S);
27
- var mn = Math.min.apply(null, all), mx = Math.max.apply(null, all);
28
- if (has(o.goal)) { mn = Math.min(mn, +o.goal); mx = Math.max(mx, +o.goal); }
29
- if (bool(o.zero)) { mn = Math.min(0, mn); mx = Math.max(0, mx); }
30
- var sc = niceScale(mn, mx, 4);
31
- var tl = sc.ticks.map(function (t) { return fmt(t, o, true); });
32
- var axisW = Math.max.apply(null, tl.map(function (t) { return tw(t, 10, true); })) + 10;
33
- var bottom = labels.length ? 20 : 4;
34
- var px = x0 + axisW, pw = w - axisW, ph = h - (top - y0) - bottom;
35
- var X = function (i) { return n === 1 ? px + pw / 2 : px + i * pw / (n - 1); };
36
- var Y = function (v) { return top + ph - (v - sc.lo) / (sc.hi - sc.lo) * ph; };
37
- sc.ticks.forEach(function (t, i) {
38
- var y = Y(t);
39
- s += '<line x1="' + r2(px) + '" x2="' + r2(px + pw) + '" y1="' + r2(y) + '" y2="' + r2(y) + '" stroke="' + th.grid + '"' + (t === 0 ? '' : ' stroke-dasharray="2 4"') + '/>' +
40
- text(px - 8, y + 3.5, tl[i], small(th, 10, 'text-anchor="end"'));
41
- });
42
- if (labels.length) {
43
- var every = Math.max(1, Math.ceil(n * (Math.max.apply(null, labels.map(function (l) { return tw(l, 10, true); })) + 10) / pw));
44
- for (var i = 0; i < n; i += every) {
45
- if (labels[i] == null) continue;
46
- var anchor = n > 1 && i === 0 ? 'start' : n > 1 && i === n - 1 ? 'end' : 'middle';
47
- s += text(X(i), top + ph + 15, labels[i], small(th, 10, 'text-anchor="' + anchor + '"'));
48
- }
49
- }
50
- notes.forEach(function (nt) {
51
- if (nt.i >= n) return;
52
- var x = X(nt.i);
53
- s += '<line x1="' + r2(x) + '" x2="' + r2(x) + '" y1="' + r2(top + 12) + '" y2="' + r2(top + ph) + '" stroke="' + th.fg + '" stroke-opacity=".4" stroke-dasharray="3 3"/>' +
54
- text(clamp(x, px + 30, px + pw - 30), top + 8, nt.text, small(th, 10, 'text-anchor="middle"', th.fg));
55
- });
19
+ var f = xyFrame(o, th, {
20
+ n: n, names: multi ? S.map(function (_, k) { return nameOf(k); }) : null, pal: pal, key: key, kw: key && 24,
21
+ lo: Math.min.apply(null, all), hi: Math.max.apply(null, all), zero: bool(o.zero), labels: labels, notes: notes,
22
+ tick: function (t) { return fmt(t, o, true); },
23
+ }, x0, y0, w, h);
24
+ var s = f.svg, X = f.X, Y = f.Y, px = f.px, pw = f.pw, top = f.top, ph = f.ph;
56
25
  S.forEach(function (v, k) {
57
26
  var c = pal[k % pal.length];
58
27
  var P = v.map(function (y, i) { return [X(i), Y(y)]; });
@@ -63,31 +32,21 @@ export default function line(o, th) {
63
32
  s += '<defs><linearGradient id="' + g + '" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="' + c + '" stop-opacity=".26"/><stop offset="1" stop-color="' + c + '" stop-opacity="0"/></linearGradient></defs>' +
64
33
  '<path d="' + d + 'L' + r2(last[0]) + ',' + r2(top + ph) + 'L' + r2(P[0][0]) + ',' + r2(top + ph) + 'Z" fill="url(#' + g + ')"' + anim(o, 'bzc-a') + '/>';
65
34
  }
66
- var dk = dashOf ? DASHES[dashOf(k)] : '', mk = markOf ? markOf(k) : 'none';
67
- // The draw-in animation is itself a dash, so dashed lines fade in instead.
68
- s += dk
69
- ? '<path d="' + d + '" fill="none" stroke="' + c + '" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="' + dk + '"' + anim(o, 'bzc-a', k * 0.15) + '/>'
70
- : '<path d="' + d + '" fill="none" stroke="' + c + '" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" pathLength="1" style="stroke-dasharray:1' + (o.animate ? ';animation-delay:' + k * 0.15 + 's' : '') + '"' + (o.animate ? ' class="bzc-d"' : '') + '/>';
35
+ var mk = markOf ? markOf(k) : 'none';
36
+ s += seriesLine(o, d, c, k, dashOf ? DASHES[dashOf(k)] : '');
71
37
  if (mk !== 'none') {
72
- // Long series get a marker on every few points, and always on the last.
73
- var every = Math.ceil(v.length / 40);
74
- v.forEach(function (y, i) {
75
- if (i % every === 0 || i === v.length - 1) s += marker(mk, X(i), Y(y), 3.5, ' fill="' + c + '" stroke="' + bg + '" stroke-width="1.5"' + anim(o, 'bzc-a', 0.6 + k * 0.15));
76
- });
38
+ s += pointMarks(o, mk, v, X, Y, c, bg, k);
77
39
  } else {
78
40
  var e = P[P.length - 1];
79
41
  s += '<circle cx="' + r2(e[0]) + '" cy="' + r2(e[1]) + '" r="4" fill="' + c + '" stroke="' + bg + '" stroke-width="2"/>';
80
42
  }
81
43
  if (bool(o.showValues)) v.forEach(function (y, i) { s += text(X(i), Y(y) - 8, fmt(y, o, true), small(th, 9, 'text-anchor="middle"')); });
82
44
  });
83
- if (has(o.goal)) s += goalLine(o, th, px, px + pw, Y(+o.goal));
84
- var step = n > 1 ? pw / (n - 1) : pw;
85
- for (var j = 0; j < n; j++) {
45
+ return s + xyFinish(o, th, f, n, function (j) {
86
46
  var tip = labels[j] || '#' + (j + 1);
87
- S.forEach(function (v, k) { if (j < v.length) tip += '\n' + (multi ? (names[k] || 'Series ' + (k + 1)) + ': ' : '') + fmt(v[j], o); });
88
- s += hit(X(j) - step / 2, top, step, ph, tip);
89
- }
90
- return s;
47
+ S.forEach(function (v, k) { if (j < v.length) tip += '\n' + (multi ? nameOf(k) + ': ' : '') + fmt(v[j], o); });
48
+ return tip;
49
+ });
91
50
  }, { stat: st, summary: S.length + ' series over ' + n + ' points' });
92
51
  }
93
52