@martinomagnifico/tablechart 1.3.0 → 1.4.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.
- package/CHANGELOG.md +27 -0
- package/README.md +5 -4
- package/dist/tablechart-additional-types.d.mts +2 -2
- package/dist/tablechart-additional-types.js +1 -1
- package/dist/tablechart-additional-types.mjs +184 -90
- package/dist/tablechart-core.d.mts +1 -1
- package/dist/tablechart-core.mjs +1 -1
- package/dist/tablechart-shared.d.mts +86 -6
- package/dist/tablechart-shared.mjs +1209 -1013
- package/dist/tablechart-summary.d.mts +3 -31
- package/dist/tablechart-summary.js +1 -1
- package/dist/tablechart-summary.mjs +292 -174
- package/dist/tablechart.css +1 -1
- package/dist/tablechart.d.mts +1 -1
- package/dist/tablechart.js +1 -1
- package/dist/tablechart.mjs +1 -1
- package/package.json +1 -3
|
@@ -1,35 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export interface SummaryWords {
|
|
3
|
-
up: string;
|
|
4
|
-
down: string;
|
|
5
|
-
flat: string;
|
|
6
|
-
unclear: string;
|
|
7
|
-
above: string;
|
|
8
|
-
below: string;
|
|
9
|
-
}
|
|
10
|
-
export interface SummaryConfig {
|
|
11
|
-
/** The charts that may have a summary. */
|
|
12
|
-
selector: string;
|
|
13
|
-
/** Around a placeholder, such as `{highest.value}`. A template engine that uses single braces needs others, such as `["[[", "]]"]`. */
|
|
14
|
-
delimiters: [string, string];
|
|
15
|
-
/** The attribute for translation keys, as in Tablechart. A name in a sentence keeps its key. */
|
|
16
|
-
langattribute: string | false;
|
|
17
|
-
/** Locale for numbers and lists. Unset, the language of the page is used and followed when it changes. */
|
|
18
|
-
locale?: string;
|
|
19
|
-
/** A trend or a change of less than this percentage is flat. */
|
|
20
|
-
flat: number;
|
|
21
|
-
/** A value more than this percentage away from the trend is an outlier. */
|
|
22
|
-
outliers: number;
|
|
23
|
-
/** For `{trend}`, `{change}` and `{side}`. A sentence per outcome, with `data-when`, translates better. */
|
|
24
|
-
words: SummaryWords;
|
|
25
|
-
}
|
|
26
|
-
export declare const summaryDefaults: SummaryConfig;
|
|
27
|
-
/** Fills the sentences of one chart again, from its table as it is now. */
|
|
28
|
-
export declare const fill: (figure: HTMLElement, options?: Partial<SummaryConfig>) => void;
|
|
29
|
-
/** Fills the summary of every chart now, again when its table is ready or changes, and when a translation changes a sentence or the language. */
|
|
30
|
-
export declare const init: (options?: Partial<SummaryConfig>) => void;
|
|
1
|
+
import { a as summaryDefaults, i as SummaryWords, n as fill, r as SummaryConfig, t as init } from "./tablechart-shared.mjs";
|
|
31
2
|
export declare const Summary: {
|
|
32
3
|
init: (options?: Partial<SummaryConfig>) => void;
|
|
33
4
|
fill: (figure: HTMLElement, options?: Partial<SummaryConfig>) => void;
|
|
34
5
|
defaults: SummaryConfig;
|
|
35
|
-
};
|
|
6
|
+
};
|
|
7
|
+
export { type SummaryConfig, type SummaryWords, fill, init, summaryDefaults };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e){var t=e=>{const t=e.length,n=e.reduce((e,t)=>e+t.x,0)/t,a=e.reduce((e,t)=>e+t.y,0)/t,r=e.reduce((e,t)=>e+(t.x-n)**2,0),o=r?e.reduce((e,t)=>e+(t.x-n)*(t.y-a),0)/r:0,s=e=>a+o*(e-n),c=t>2?Math.sqrt(e.reduce((e,t)=>e+(t.y-s(t.x))**2,0)/(t-2)):0,l=r?c/Math.sqrt(r):0;return{at:s,spread:c,t:l?o/l:o?Number.POSITIVE_INFINITY:0,n:t}},n=[12.71,4.3,3.18,2.78,2.57,2.45,2.36,2.31,2.26,2.23,2.2,2.18,2.16,2.14,2.13],a=e=>{const t=e.map(e=>e.y),n=Math.min(...t),a=Math.max(...t),r=n<0&&a>0,o=a-n||1;return{mean:t.reduce((e,t)=>e+t,0)/t.length,share:(e,t)=>e/(r?o:Math.abs(t)||o)*100}},r={selector:"[data-chart]:not(th)",delimiters:["{","}"],langattribute:"data-i18n",flat:5,outliers:25,words:{up:"up",down:"down",flat:"flat",unclear:"unclear",above:"above",below:"below"}},o="chart-summary",s="data-summary-ready",c="data-summary-template",l="data-summary-text",u=["line","area"],i=["extremes","range","change","trend","outliers","notes"],d=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),f=0,h=new Set,m=t=>{h.has(t)||(h.add(t),console.warn(`[${e.LIBRARY_NAME}] ${t}`))},w=t=>{const n=t.filter(e=>!e.missing),a=n.reduce((t,n)=>(0,e.decimalsIn)(n.number)>(0,e.decimalsIn)(t.number)?n:t,n[0]??t[0]);if(!a)return;const r=n.reduce((e,t)=>e+t.value,0);return{...a,raw:"",number:r.toFixed((0,e.decimalsIn)(a.number)),missing:!n.length,value:r}},g=(r,o,s,c)=>{const l=(0,e.readTable)(r,s.langattribute),i=(0,e.readSeries)(r,l.filter(e=>!e.isTotal),s.langattribute),d=o<0,f=l.filter(e=>!e.isTotal).map(e=>d?{...e,cells:[w(e.cells.slice(0,i.length))].filter(e=>!!e)}:e),h=d?0:o,m=d?void 0:i[o],g=(e,t)=>{if(!t||!s.langattribute)return e;const n=document.createElement("span");return n.setAttribute(s.langattribute,t),n.textContent=e,n},b=Math.max(0,...f.map(t=>(0,e.decimalsIn)(t.cells[h]?.number??""))),p=(t,n,a=b)=>{const[r,o]=(0,e.splitSign)(t,a,c);return n.prefix+r+o+n.suffix},v=e=>new Intl.NumberFormat(c,{style:"percent",maximumFractionDigits:Math.abs(e)<10?1:0}).format(e/100),y=e=>g(e.label,e.key),M=r.querySelector(":scope > figcaption"),$=M?.querySelector("b, strong")??M,x={values:{title:g(($?.textContent??"").trim(),s.langattribute&&$?.getAttribute(s.langattribute)||null),rows:(0,e.splitSign)(f.length,0,c).join(""),series:m?g(m.name,m.key):""},counts:{rows:f.length}},O=f.filter(e=>e.note),j=O.length?{values:{"notes.count":(0,e.splitSign)(O.length,0,c).join("")},counts:{"notes.count":O.length},items:O.map(e=>({name:y(e),note:g(e.note??"",e.noteKey)}))}:null,A=f.flatMap((e,t)=>{const n=e.cells[h];return n&&!n.missing?[{row:e,cell:n,x:t,y:n.value}]:[]});if(!A.length)return{chart:x,notes:j,extremes:null,range:null,change:null,trend:null,outliers:null};let F=A[0],N=A[0];for(const e of A)e.y>F.y&&(F=e),e.y<N.y&&(N=e);const S={values:{"highest.name":y(F.row),"highest.value":p(F.y,F.cell),"lowest.name":y(N.row),"lowest.value":p(N.y,N.cell)}},E=d?void 0:l.find(e=>e.isTotal)?.cells[h],I=E&&!E.missing?E.value:A.reduce((e,t)=>e+t.y,0);S.values.total=p(I,F.cell),I>0&&A.every(e=>e.y>=0)&&(S.values["highest.share"]=v(F.y/I*100),S.values["lowest.share"]=v(N.y/I*100));const k={values:{"range.from":p(N.y,N.cell),"range.to":p(F.y,F.cell),"range.difference":p(F.y-N.y,F.cell)}},D=r.getAttribute("data-chart")||"column";if(!u.includes(D)&&!r.hasAttribute("data-chart-ordered"))return{chart:x,notes:j,extremes:S,range:k};if(A.length<2)return{chart:x,notes:j,extremes:S,range:k,change:null,trend:null,outliers:null};const{share:L}=a(A),T=e=>Math.abs(e)<s.flat?"flat":e>0?"up":"down",q=A[0],B=A[A.length-1],C=L(B.y-q.y,q.y),H={values:{"first.name":y(q.row),"first.value":p(q.y,q.cell),"last.name":y(B.row),"last.value":p(B.y,B.cell),"change.difference":p(Math.abs(B.y-q.y),B.cell),"change.percent":v(Math.abs(C)),change:s.words[T(C)]},when:T(C)},R=((e,r=5,o=25)=>{if(e.length<4)return null;const{mean:s,share:c}=a(e),l=t=>e.filter(e=>Math.abs(c(e.y-t(e.x),t(e.x)))>o),u=t=>t.length<=e.length/5;let i=t(e),d=l(i.at);d.length&&u(d)&&(i=t(e.filter(e=>!d.includes(e))),d=l(i.at)),u(d)||(i=t(e),d=[]);const f=i.at,h=e[0],m=e[e.length-1],w=c(f(m.x)-f(h.x),s),g=Math.abs(i.t)>=(b=i.n-2,n[b-1]??(b<30?2.1:2));var b;const p=Math.abs(c(i.spread,s))<r,v=Math.abs(w)<r?"flat":w>0?"up":"down",y="flat"===v?p?"flat":"unclear":g?v:"unclear";return{course:y,line:f,outside:"unclear"===y?[]:d}})(A,s.flat,s.outliers);if(!R)return{chart:x,notes:j,extremes:S,range:k,change:H,trend:null,outliers:null};const{course:W,line:z,outside:G}=R,J={values:{trend:s.words[W],"trend.percent":v(Math.abs(L(z(B.x)-z(q.x),z(q.x)))),"trend.from":p(z(q.x),q.cell),"trend.to":p(z(B.x),B.cell),"flat.percent":v(s.flat),"outliers.percent":v(s.outliers)},when:W};return"unclear"===W?{chart:x,notes:j,extremes:S,range:k,change:H,trend:J}:{chart:x,notes:j,extremes:S,range:k,change:H,trend:J,outliers:G.length?{values:{"outliers.count":(0,e.splitSign)(G.length,0,c).join("")},counts:{"outliers.count":G.length},items:G.map(e=>({name:y(e.row),value:p(e.y,e.cell),expected:p(z(e.x),e.cell),deviation:v(Math.abs(L(e.y-z(e.x),z(e.x)))),side:s.words[e.y>z(e.x)?"above":"below"]}))}:null}},b=(e,t,n,a,r)=>{const[o,s]=a.delimiters,c=new RegExp(`${d(o)}([\\w.]+)(\\|.*?)?${d(s)}`,"g"),l=document.createTreeWalker(e,NodeFilter.SHOW_TEXT),u=[];for(;l.nextNode();)u.push(l.currentNode);for(const i of u){const e=i.textContent??"",a=[];let o=0;for(const s of e.matchAll(c)){const[c,l,u]=s;let i=t[l];if(void 0!==i){if(u&&void 0!==n[l]){const e=Object.fromEntries(u.slice(1).split("|").map(e=>[e.slice(0,e.indexOf(":")),e.slice(e.indexOf(":")+1)])),t=e[new Intl.PluralRules(r).select(n[l])]??e.other;void 0!==t&&(i=t.replace("#","string"==typeof i?i:i.textContent??""))}a.push(e.slice(o,s.index),"string"==typeof i?i:i.cloneNode(!0)),o=(s.index??0)+c.length}else m(`A summary has the placeholder ${c}, which no analysis fills.`)}a.length&&(a.push(e.slice(o)),i.replaceWith(...a))}},p=(e,t)=>{const n=e.dataset.summary;if(void 0===n)return!0;if(i.includes(n)||m(`A summary asks for the analysis "${n}", which does not exist.`),!(n in t))return!1;const a=t[n],r=e.dataset.when;return e.hasAttribute("data-none")?!a:!(!a||r&&a.when!==r)},v=(e,t,n,a)=>{const r=e.cloneNode(!0);for(const l of[c,"hidden","id","data-summary","data-none","data-when","data-series",...n.langattribute?[n.langattribute]:[]])r.removeAttribute(l);r.setAttribute(l,"");const o=Object.values(t).filter(e=>!!e),s=Object.assign({},...o.map(e=>e.values)),u=Object.assign({},...o.map(e=>e.counts??{}));for(const c of r.querySelectorAll("[data-summary]"))if(p(c,t))for(const e of["data-summary","data-none","data-when"])c.removeAttribute(e);else c.remove();for(const c of r.querySelectorAll("[data-each]")){const e=(t[c.dataset.each??""]?.items??[]).map(e=>{const t=c.cloneNode(!0);return t.removeAttribute("data-each"),b(t,{...s,...e},u,n,a),t}),r=new Intl.ListFormat(a,{type:"conjunction"}).formatToParts(e.map((e,t)=>String(t)));c.replaceWith(...r.map(t=>"element"===t.type?e[Number(t.value)]:t.value))}return b(r,s,u,n,a),r},y=(e,t={})=>{const n={...r,...t},a=n.locale||document.documentElement.lang||void 0,s=e.querySelector(`:scope > .${o}`);if(!s||!e.querySelector("tbody tr"))return;s.id||(s.id="tablechart-summary-"+ ++f);const u=(e.getAttribute("aria-describedby")??"").split(/\s+/).filter(Boolean);u.includes(s.id)||e.setAttribute("aria-describedby",[...u,s.id].join(" "));for(const r of s.querySelectorAll(`:scope > [${l}]`))r.remove();const i=new Map;for(const r of s.querySelectorAll(":scope > *")){r.setAttribute(c,""),r.hidden=!0;const t="total"===r.dataset.series?-1:Math.max(1,Number.parseInt(r.dataset.series??"1",10)||1)-1;i.has(t)||i.set(t,g(e,t,n,a));const o=i.get(t);p(r,o)&&r.after(v(r,o,n,a))}},M=null,$={init:(e={})=>{const t={...r,...e,words:{...r.words,...e.words}};if(M)return;M=t;const n=()=>Array.from(document.querySelectorAll(t.selector)).filter(e=>e.querySelector(`:scope > .${o}`)),a=new Set,l=document.documentElement,u=()=>{a.size||l.hasAttribute(s)||!n().every(e=>e.querySelector("tbody tr"))||(l.setAttribute(s,""),document.dispatchEvent(new CustomEvent("tablechart:summary-ready")))},i=e=>{l.removeAttribute(s),a.size||requestAnimationFrame(()=>{const e=[...a];a.clear();for(const n of e)y(n,t);u()}),a.add(e)},d=new WeakSet,f=e=>{y(e,t),(e=>{const t=[...e.querySelectorAll(`:scope > .${o} > [${c}]`),...e.querySelectorAll(":scope > table")];for(const n of t)d.has(n)||(d.add(n),new MutationObserver(()=>i(e)).observe(n,{subtree:!0,childList:!0,characterData:!0}))})(e)};for(const r of n())f(r);u(),document.addEventListener("tablechart:table",e=>{const n=e.target;n instanceof HTMLElement&&n.matches(t.selector)&&n.querySelector(`:scope > .${o}`)&&(f(n),u())}),t.locale||new MutationObserver(()=>{for(const e of n())i(e)}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"]})},fill:y,defaults:r};window.Tablechart.Summary=$}(Tablechart.kit);
|
|
1
|
+
!function(t){var e=t=>{const e=t.length,n=t.reduce((t,e)=>t+e.x,0)/e,r=t.reduce((t,e)=>t+e.y,0)/e,o=t.reduce((t,e)=>t+(e.x-n)**2,0),a=o?t.reduce((t,e)=>t+(e.x-n)*(e.y-r),0)/o:0,s=t=>r+a*(t-n),c=e>2?Math.sqrt(t.reduce((t,e)=>t+(e.y-s(e.x))**2,0)/(e-2)):0,u=o?c/Math.sqrt(o):0;return{at:s,spread:c,t:u?a/u:a?Number.POSITIVE_INFINITY:0,n:e}},n=[12.71,4.3,3.18,2.78,2.57,2.45,2.36,2.31,2.26,2.23,2.2,2.18,2.16,2.14,2.13],r=t=>{const e=t.map(t=>t.y),n=Math.min(...e),r=Math.max(...e),o=n<0&&r>0,a=r-n||1;return{mean:e.reduce((t,e)=>t+e,0)/e.length,share:(t,e)=>t/(o?a:Math.abs(e)||a)*100}},o={selector:"[data-chart]:not(th)",delimiters:["{","}"],langattribute:"data-i18n",flat:5,outliers:25,words:{up:"up",down:"down",flat:"flat",unclear:"unclear",above:"above",below:"below"},groups:10},a={config:null},s=["delimiters","locale","flat","outliers","words","groups"],c="chart-summary",u="data-summary-ready",l="data-summary-template",i="data-summary-text",d=["line","area","candlestick"],h={candlestick:4},m=["extremes","range","change","trend","outliers","notes","groups"],f=new Set(["rank","rank.low"]),g=new Set,w=e=>{g.has(e)||(g.add(e),console.warn(`[${t.LIBRARY_NAME}] ${e}`))},v=(t,e)=>{const n=Math.max(1,Math.min(Math.round(e),t.length));return Array.from({length:n},(e,r)=>t.slice(Math.floor(r*t.length/n),Math.floor((r+1)*t.length/n)))},p=e=>{const n=e.filter(t=>!t.missing),r=n.reduce((e,n)=>(0,t.decimalsIn)(n.number)>(0,t.decimalsIn)(e.number)?n:e,n[0]??e[0]);if(!r)return;const o=n.reduce((t,e)=>t+e.value,0);return{...r,raw:"",number:o.toFixed((0,t.decimalsIn)(r.number)),missing:!n.length,value:o}},b=(o,a,s,c)=>{const u=(0,t.readTable)(o,s.langattribute),l=(0,t.readSeries)(o,u.filter(t=>!t.isTotal),s.langattribute),i=a<0,h=u.filter(t=>!t.isTotal).map(t=>i?{...t,cells:[p(t.cells.slice(0,l.length))].filter(t=>!!t)}:t),m=i?0:a,f=i?void 0:l[a],g=(t,e)=>{if(!e||!s.langattribute)return t;const n=document.createElement("span");return n.setAttribute(s.langattribute,e),n.textContent=t,n},w=Math.max(0,...h.map(e=>(0,t.decimalsIn)(e.cells[m]?.number??""))),b=(e,n,r=w)=>{const[o,a]=(0,t.splitSign)(e,r,c);return n.prefix+o+a+n.suffix},y=t=>new Intl.NumberFormat(c,{style:"percent",maximumFractionDigits:Math.abs(t)<10?1:0}).format(t/100),M=t=>g(t.label,t.key),$=o.querySelector(":scope > figcaption"),x=$?.querySelector("b, strong")??$,k={values:{title:g((x?.textContent??"").trim(),s.langattribute&&x?.getAttribute(s.langattribute)||null),rows:(0,t.splitSign)(h.length,0,c).join(""),series:f?g(f.name,f.key):""},counts:{rows:h.length}},O=h.flatMap((t,e)=>{const n=t.cells[m];return n&&!n.missing?[{row:t,cell:n,x:e,y:n.value}]:[]});k.values.values=(0,t.splitSign)(O.length,0,c).join(""),k.counts.values=O.length;const j=(N=O.map(t=>t.y),t=>({high:1+N.filter(e=>e>t).length,low:1+N.filter(e=>e<t).length}));var N;const S=(e,n)=>{if(void 0===n)return{values:e};const r=(e=>{const{high:n,low:r}=j(e);return{values:{rank:(0,t.splitSign)(n,0,c).join(""),"rank.low":(0,t.splitSign)(r,0,c).join("")},counts:{rank:n,"rank.low":r}}})(n);return{values:{...e,...r.values},counts:r.counts}},A=h.filter(t=>t.note),F=A.length?{values:{"notes.count":(0,t.splitSign)(A.length,0,c).join("")},counts:{"notes.count":A.length},items:A.map(t=>{const e=t.cells[m],n=e&&!e.missing?e:void 0,r={name:M(t),note:g(t.note??"",t.noteKey)};return n&&(r.value=b(n.value,n)),S(r,n?.value)})}:null;if(!O.length)return{chart:k,notes:F,extremes:null,range:null,change:null,trend:null,outliers:null,groups:null};let E=O[0],I=O[0];for(const t of O)t.y>E.y&&(E=t),t.y<I.y&&(I=t);const D={values:{"highest.name":M(E.row),"highest.value":b(E.y,E.cell),"lowest.name":M(I.row),"lowest.value":b(I.y,I.cell)}},J=i?void 0:u.find(t=>t.isTotal)?.cells[m],L=J&&!J.missing?J.value:O.reduce((t,e)=>t+e.y,0);D.values.total=b(L,E.cell),L>0&&O.every(t=>t.y>=0)&&(D.values["highest.share"]=y(E.y/L*100),D.values["lowest.share"]=y(I.y/L*100));const T={values:{"range.from":b(I.y,I.cell),"range.to":b(E.y,E.cell),"range.difference":b(E.y-I.y,E.cell)}},q=o.getAttribute("data-chart")||"column";if(!d.includes(q)&&!o.hasAttribute("data-chart-ordered"))return{chart:k,notes:F,extremes:D,range:T};if(O.length<2)return{chart:k,notes:F,extremes:D,range:T,change:null,trend:null,outliers:null,groups:null};const B={values:{},items:v(O,s.groups).map(t=>{const e=t.map(t=>t.y),n=t[0].cell;return{values:{from:M(t[0].row),to:M(t[t.length-1].row),lowest:b(Math.min(...e),n),average:b(e.reduce((t,e)=>t+e,0)/e.length,n),highest:b(Math.max(...e),n)}}})},{share:C}=r(O),H=t=>Math.abs(t)<s.flat?"flat":t>0?"up":"down",R=O[0],W=O[O.length-1],z=C(W.y-R.y,R.y),G={values:{"first.name":M(R.row),"first.value":b(R.y,R.cell),"last.name":M(W.row),"last.value":b(W.y,W.cell),"change.difference":b(Math.abs(W.y-R.y),W.cell),"change.percent":y(Math.abs(z)),change:s.words[H(z)]},when:H(z)},K=((t,o=5,a=25)=>{if(t.length<4)return null;const{mean:s,share:c}=r(t),u=e=>t.filter(t=>Math.abs(c(t.y-e(t.x),e(t.x)))>a),l=e=>e.length<=t.length/5;let i=e(t),d=u(i.at);d.length&&l(d)&&(i=e(t.filter(t=>!d.includes(t))),d=u(i.at)),l(d)||(i=e(t),d=[]);const h=i.at,m=t[0],f=t[t.length-1],g=c(h(f.x)-h(m.x),s),w=Math.abs(i.t)>=(v=i.n-2,n[v-1]??(v<30?2.1:2));var v;const p=Math.abs(c(i.spread,s))<o,b=Math.abs(g)<o?"flat":g>0?"up":"down",y="flat"===b?p?"flat":"unclear":w?b:"unclear";return{course:y,line:h,outside:"unclear"===y?[]:d}})(O,s.flat,s.outliers);if(!K)return{chart:k,notes:F,extremes:D,range:T,change:G,groups:B,trend:null,outliers:null};const{course:P,line:Q,outside:U}=K,V={values:{trend:s.words[P],"trend.percent":y(Math.abs(C(Q(W.x)-Q(R.x),Q(R.x)))),"trend.from":b(Q(R.x),R.cell),"trend.to":b(Q(W.x),W.cell),"flat.percent":y(s.flat),"outliers.percent":y(s.outliers)},when:P};return"unclear"===P?{chart:k,notes:F,extremes:D,range:T,change:G,groups:B,trend:V}:{chart:k,notes:F,extremes:D,range:T,change:G,groups:B,trend:V,outliers:U.length?{values:{"outliers.count":(0,t.splitSign)(U.length,0,c).join("")},counts:{"outliers.count":U.length},items:U.map(t=>S({name:M(t.row),value:b(t.y,t.cell),expected:b(Q(t.x),t.cell),deviation:y(Math.abs(C(t.y-Q(t.x),Q(t.x)))),side:s.words[t.y>Q(t.x)?"above":"below"]},t.y))}:null}},y=t=>t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),M=(t,e,n,r,o)=>{const[a,s]=r.delimiters,c=new RegExp(`${y(a)}([\\w.]+)(\\|.*?)?${y(s)}`,"g"),u=document.createTreeWalker(t,NodeFilter.SHOW_TEXT),l=[];for(;u.nextNode();)l.push(u.currentNode);for(const i of l){const t=i.textContent??"",r=[];let a=0;for(const s of t.matchAll(c)){const[c,u,l]=s;let i=e[u];if(void 0!==i){if(l&&void 0!==n[u]){const t=Object.fromEntries(l.slice(1).split("|").map(t=>[t.slice(0,t.indexOf(":")),t.slice(t.indexOf(":")+1)])),e=t[new Intl.PluralRules(o,{type:f.has(u)?"ordinal":"cardinal"}).select(n[u])]??t.other;void 0!==e&&(i=e.replace("#","string"==typeof i?i:i.textContent??""))}r.push(t.slice(a,s.index),"string"==typeof i?i:i.cloneNode(!0)),a=(s.index??0)+c.length}else w(`A summary has the placeholder ${c}, which no analysis fills.`)}r.length&&(r.push(t.slice(a)),i.replaceWith(...r))}},$="data-summary-options",x=(e,n,r)=>{try{return JSON.parse(e)}catch{return void console.warn(`[${t.LIBRARY_NAME}] ${r} needs JSON.`,n)}},k=(t,e)=>{const n=t.getAttribute(`data-summary-${e}`)?.trim();if(!n)return;if("locale"===e)return n;if("words"===e)return x(n,t,"data-summary-words");if("delimiters"===e){const t=n.split(/\s+/);return 2===t.length?t:void 0}const r=Number.parseFloat(n);return Number.isFinite(r)?r:void 0},O=t=>Array.from(t.querySelectorAll("table")).find(t=>!t.closest(".chart-summary"))??null,j=0,N=(t,e)=>{const n=t.dataset.summary;if(void 0===n)return!0;if(m.includes(n)||w(`A summary asks for the analysis "${n}", which does not exist.`),!(n in e))return!1;const r=e[n],o=t.dataset.when;return t.hasAttribute("data-none")?!r:!(!r||o&&r.when!==o)},S=(t,e,n,r)=>{const o=t.cloneNode(!0);for(const u of[l,"hidden","id","data-summary","data-none","data-when","data-series",...n.langattribute?[n.langattribute]:[]])o.removeAttribute(u);o.setAttribute(i,"");const a=Object.values(e).filter(t=>!!t),s=Object.assign({},...a.map(t=>t.values)),c=Object.assign({},...a.map(t=>t.counts??{}));for(const u of o.querySelectorAll("[data-summary]"))if(N(u,e))for(const t of["data-summary","data-none","data-when"])u.removeAttribute(t);else u.remove();for(const u of o.querySelectorAll("[data-each]")){const t=(e[u.dataset.each??""]?.items??[]).map(t=>{const e=u.cloneNode(!0);return e.removeAttribute("data-each"),M(e,{...s,...t.values},{...c,...t.counts},n,r),e});if(u.matches("tr, li")){u.replaceWith(...t);continue}const o=new Intl.ListFormat(r,{type:"conjunction"}).formatToParts(t.map((t,e)=>String(e)));u.replaceWith(...o.map(e=>"element"===e.type?t[Number(e.value)]:e.value))}return M(o,s,c,n,r),o},A=(t,e=a.config??{})=>{const n=((t,e)=>{const n=[];for(let a=t;a;a=a.parentElement){const t=a.getAttribute($),e=t?x(t,a,$):void 0;e&&"object"==typeof e&&n.unshift(e)}const r={};for(const a of s){const e=k(t,a);void 0!==e&&(r[a]=e)}n.push(r);let o=e;for(const a of n){const t=Object.fromEntries(Object.entries(a).filter(([t])=>s.includes(t)));o={...o,...t,words:{...o.words,...t.words}}}return o})(t,{...o,...e,words:{...o.words,...e.words}}),r=n.locale||document.documentElement.lang||void 0,u=t.querySelector(`:scope > .${c}`);if(!u||!O(t)?.querySelector("tbody tr"))return;u.id||(u.id="tablechart-summary-"+ ++j);const d=(t.getAttribute("aria-describedby")??"").split(/\s+/).filter(Boolean);d.includes(u.id)||t.setAttribute("aria-describedby",[...d,u.id].join(" "));for(const o of u.querySelectorAll(`:scope > [${i}]`))o.remove();const m=new Map;for(const o of u.querySelectorAll(":scope > *")){o.setAttribute(l,""),o.hidden=!0;const e=String(h[t.getAttribute("data-chart")??""]??1),a="total"===o.dataset.series?-1:Math.max(1,Number.parseInt(o.dataset.series??e,10)||1)-1;m.has(a)||m.set(a,b(t,a,n,r));const s=m.get(a);N(o,s)&&o.after(S(o,s,n,r))}},F={init:(t={})=>{const e={...o,...t,words:{...o.words,...t.words}};if(a.config)return;a.config=e;const n=()=>Array.from(document.querySelectorAll(e.selector)).filter(t=>t.querySelector(`:scope > .${c}`)),r=new Set,s=document.documentElement,i=()=>{r.size||s.hasAttribute("data-summary-ready")||!n().every(t=>O(t)?.querySelector("tbody tr"))||(s.setAttribute(u,""),document.dispatchEvent(new CustomEvent("tablechart:summary-ready")))},d=t=>{s.removeAttribute(u),r.size||requestAnimationFrame(()=>{const t=[...r];r.clear();for(const n of t)A(n,e);i()}),r.add(t)},h=new WeakSet,m=t=>{A(t,e),(t=>{const e=[...t.querySelectorAll(`:scope > .${c} > [${l}]`),...t.querySelectorAll(":scope > table")];for(const n of e)h.has(n)||(h.add(n),new MutationObserver(()=>d(t)).observe(n,{subtree:!0,childList:!0,characterData:!0}))})(t)};for(const o of n())m(o);i(),document.addEventListener("tablechart:table",t=>{const n=t.target;n instanceof HTMLElement&&n.matches(e.selector)&&n.querySelector(":scope > .chart-summary")&&(m(n),i())}),e.locale||new MutationObserver(()=>{for(const t of n())d(t)}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"]})},fill:A,defaults:o};window.Tablechart.Summary=F}(Tablechart.kit);
|