@martinomagnifico/tablechart 1.1.2 → 1.2.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 +52 -0
- package/README.md +7 -6
- package/dist/tablechart-additional-types.js +1 -1
- package/dist/tablechart-additional-types.mjs +142 -76
- package/dist/tablechart-core.d.mts +2 -2
- package/dist/tablechart-core.mjs +1 -1
- package/dist/tablechart-shared.d.mts +51 -21
- package/dist/tablechart-shared.mjs +1504 -1005
- package/dist/tablechart-summary.d.mts +35 -0
- package/dist/tablechart-summary.js +1 -0
- package/dist/tablechart-summary.mjs +269 -0
- 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 +19 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.2.0] - 2026-10-28
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Summaries! They need a separate import from `@martinomagnifico/tablechart/summary`. Summaries are important for screen readers and print.
|
|
8
|
+
- A line over columns, with `data-chart="line"` on a column header.
|
|
9
|
+
- `data-chart-values` and the `values` option: which values a line shows. A long line shows only its key values.
|
|
10
|
+
- Notes: a column with `data-note`, shown as a line at its row and in the tooltip.
|
|
11
|
+
- A `quadrant` annotation for scatter charts, and one step for a scatter with `data-fragment`.
|
|
12
|
+
- `--tablechart-bubble-min`, so the smallest bubble stays visible.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Values on a line keep clear of the line, the points and each other, if possible.
|
|
17
|
+
- Line and area charts have a tick above each name. `data-chart-ticks="false"` turns them off.
|
|
18
|
+
- Scatter markers have an edge in the background colour, so they stand apart from lines and each other.
|
|
19
|
+
- Bars put their numbers after the bar by default, as columns put them above. `data-chart-labels="inside"` puts them inside, as on columns.
|
|
20
|
+
- Badges are rounded boxes instead of ellipses. They take less room.
|
|
21
|
+
- A few columns or bars start one after the other again, and their numbers come when the column is nearly grown. Many columns still grow almost together.
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Holes in a line come with the line, not after the build.
|
|
26
|
+
- A legend box is no longer shown empty before its names.
|
|
27
|
+
- Triangle markers are centred on their point.
|
|
28
|
+
- Names of a long line no longer wait seconds after the build.
|
|
29
|
+
- Grouped columns and bars no longer grow after the first resize.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## [1.1.3] - 2026-10-26
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- Fixes charts that should be shown directly. Labels and annotations now also show immediately.
|
|
38
|
+
- Trend and bracket lines stop at their badge from the start. Before, they ran through it until the chart was built.
|
|
39
|
+
- Gridlines leave a gap for a badge, as they do for text. The gap appears with the badge.
|
|
40
|
+
- Badge backgrounds no longer fade in. A fading background showed as a grey box over the marks.
|
|
41
|
+
- The mask under a badge goes on when the marks under it are done. Before, it waited for the whole chart.
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- `atOnce` in `setShown(state, shown, atOnce)` from `@martinomagnifico/tablechart/core`. It shows or hides a chart without transitions, with `AT_ONCE_CLASS`.
|
|
46
|
+
- `numbers: false` for a chart type without numbers on the chart, such as a scatter. Its numbers then stay out of the layout.
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- Legend keys no longer fade in when printing or when a chart is shown at once.
|
|
51
|
+
- Removed a layout for hidden scatter plot labels to increase performance.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
3
55
|
## [1.1.2] - 2026-10-24
|
|
4
56
|
|
|
5
57
|
### Changed
|
package/README.md
CHANGED
|
@@ -12,14 +12,15 @@
|
|
|
12
12
|
Tablechart makes simple charts from a table: an HTML table, a Markdown table or a JSON file. You write the table, Tablechart shows it as a chart.
|
|
13
13
|
|
|
14
14
|
* **Chart types:** column, bar, line, area, waterfall and donut, and scatter as an additional type
|
|
15
|
-
* **The table
|
|
16
|
-
* **Real text:** names and numbers are HTML, so they use the font of the page
|
|
17
|
-
* **CSS
|
|
15
|
+
* **The table:** the table is hidden from sight, but screen readers, search engines and translation scripts still read it.
|
|
16
|
+
* **Real text:** names and numbers are HTML, so they use the font of the page. *No more Times New Roman labels.* Text does not scale, but just uses the font size of the page or a size you define.
|
|
17
|
+
* **CSS styling:** colours, sizes and animation are CSS variables. Light and dark mode follow the page.
|
|
18
18
|
* **Annotations:** badges, brackets, trend arrows, reference lines and a break in the scale
|
|
19
19
|
* **Tooltips:** when a chart leaves numbers out, point at a row, or tap it, to see all its values
|
|
20
|
-
* **
|
|
20
|
+
* **Summary:** sometimes a table is just too large, for example when a screen reader talks through it, You try to remember the number that was said 4 sentences ago. In print too. A summary deals with that. See [Summary](https://martinomagnifico.github.io/tablechart/features/summary.html).
|
|
21
|
+
* **Print and PDF:** tablechart in a PDF flow builds the charts immediately
|
|
21
22
|
* **Step by step:** show the rows one at a time, with Previous and Next buttons
|
|
22
|
-
* **Animation:** a chart
|
|
23
|
+
* **Animation:** a chart can build when it scrolls into view
|
|
23
24
|
|
|
24
25
|
----
|
|
25
26
|
|
|
@@ -139,4 +140,4 @@ Tablechart is free and open source. If it saves you time, consider [sponsoring m
|
|
|
139
140
|
|
|
140
141
|
## License
|
|
141
142
|
|
|
142
|
-
MIT © [Martinomagnifico](https://github.com/martinomagnifico)
|
|
143
|
+
MIT © [Martinomagnifico](https://github.com/martinomagnifico)**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t){var e=["circle","triangle","square","diamond"],
|
|
1
|
+
!function(t){var o=`${t.QUADRANT_CLASS}-name`,n=["top left","top right","bottom left","bottom right"],r=(t,o)=>{if(!t)return null;if("mean"===t)return o.length?o.reduce((t,o)=>t+o,0)/o.length:null;if("median"===t){const t=[...o].sort((t,o)=>t-o),n=t.length/2;return t.length?t.length%2?t[Math.floor(n)]:(t[n-1]+t[n])/2:null}const n=Number.parseFloat(t);return Number.isFinite(n)?n:null},e=["circle","triangle","square","diamond"],a=["right","left","above","below","right","left","right","left"],s=t=>{const o=t.flatMap((t,o)=>t.group?[]:[o]);return{x:o[0],y:o[1],size:o[2],group:t.findIndex(t=>t.group)}},c=(t,o)=>o<0?[]:[...new Set(t.map(t=>t.cells[o]?.raw??""))],i=(t,o,n)=>t.cells[o]?.missing||t.cells[n]?.missing?null:`${t.cells[o]?.value} ${t.cells[n]?.value}`,l={aspect:.62,categories:"beside",columns:!0,axes:!0,numbers:!1,annotations:{quadrant:{create(r,e){for(const a of r.querySelectorAll("[data-corner]")){const r=(a.getAttribute("data-corner")??"").toLowerCase().split(/\s+/),s=`${r.find(t=>"top"===t||"bottom"===t)} ${r.find(t=>"left"===t||"right"===t)}`;if(!n.includes(s)){console.warn(`[${t.LIBRARY_NAME}] A quadrant has a corner "${a.getAttribute("data-corner")}". It takes ${n.join(", ")}.`);continue}const c=document.createElement("span");if(c.className=o,c.dataset.corner=s,c.inert=!0,a.childElementCount)for(const t of Array.from(a.children))c.append(t.cloneNode(!0));else c.textContent=(a.textContent??"").trim();for(const{name:t,value:o}of Array.from(a.attributes))"data-corner"!==t&&c.setAttribute(t,o);e.append(c)}return null},draw(n,e,a){const{frame:s,x:c,y:i,rows:l,series:u,height:f,unit:d,svg:h,plot:p,categories:g}=a;if(!s||!c)return void console.warn(`[${t.LIBRARY_NAME}] A quadrant works on a scatter chart, which has an axis across and an axis up.`);const[m,b,M,$]=s,x=u.flatMap((t,o)=>t.group?[]:[o]),v=t=>l.flatMap(o=>o.cells[x[t]]&&!o.cells[x[t]].missing?[o.cells[x[t]].value]:[]),w=r(n.getAttribute("data-x"),v(0)),y=r(n.getAttribute("data-y"),v(1)),A=null===w?m+M/2:Math.min(Math.max(c(w),m),m+M),S=null===y?b+$/2:Math.min(Math.max(i(y),b),b+$),k=h.querySelector(`:scope > .${t.GRID_CLASS}`);if(k){const t=(t,o)=>Math.abs(t-o)<d/2,o=(k.getAttribute("d")??"").match(/M[^M]+/g)??[];k.setAttribute("d",o.filter(o=>{const[,n,r,e]=o.match(/M(-?[\d.]+),(-?[\d.]+)([HV])/)??[];return!("V"===e&&t(Number(n),A)||"H"===e&&t(Number(r),S))}).join(""))}h.insertBefore((0,t.svgEl)("path",{class:t.QUADRANT_CLASS,d:`M${(0,t.short)(A)},${(0,t.short)(b)}V${(0,t.short)(b+$)}M${(0,t.short)(m)},${(0,t.short)(S)}H${(0,t.short)(m+M)}`}),h.querySelector(`:scope > .${t.POINT_CLASS}`));const q=6*d,z=[];for(const r of p.querySelectorAll(`:scope > .${o}`)){const o=r.dataset.corner??"",n=o.includes("right"),e=o.includes("bottom"),a=n?m+M-q:m+q,s=e?b+$-q:b+q;(0,t.placeAt)(r,a,s,t.VIEWBOX_WIDTH,f);const c=(0,t.sizeOf)(r).width*d,i=(0,t.sizeOf)(r).height*d;z.push([n?a-c:a,e?s-i:s,c,i])}a.taken.push(...z);for(const o of g){if(o.hidden||o.hasAttribute("data-left-out")||!o.style.left)continue;const n=(0,t.boxOf)(o,d,t.VIEWBOX_WIDTH,f,[0,0]);z.some(o=>(0,t.overlaps)(o,n))&&o.setAttribute("data-left-out","")}}}},text({figure:o,plot:n,rows:r,series:a,config:l}){const{x:u,y:f,size:d,group:h}=s(a),p=n.querySelector(":scope > .tablechart-categories")?.children??[],g=new Map;r.forEach((t,o)=>{const n=i(t,u,f);n&&(g.get(n)?.push(o)??g.set(n,[o]))});const m=t=>void 0===d?0:Math.abs(r[t].cells[d]?.value??0);for(const t of g.values()){if(t.length<2)continue;const o=t.reduce((t,o)=>m(o)>m(t)?o:t);for(const n of t){const r=p[n];n===o?r?.setAttribute("data-more",String(t.length-1)):r?.setAttribute("data-same","")}}const b=c(r,h);if(b.length<2&&void 0===d)return;const M=document.createElement("div");M.className=t.LEGEND_CLASS,M.setAttribute("aria-hidden","true"),M.inert=!0;const $=Array.from(o.querySelectorAll(`tbody tr > td:nth-of-type(${h+1})`)),x=(o,n)=>{const r=(0,t.htmlEl)(t.NAME_CLASS,M);return r.dataset.place="legend",r.dataset.line="none",r.textContent=o,n&&l.langattribute&&r.setAttribute(l.langattribute,n),r};b.length>1&&b.forEach((t,o)=>{const n=l.langattribute?$.find(o=>o.textContent?.trim()===t)?.getAttribute(l.langattribute):null,r=x(t,n);r.dataset.marker=e[o%e.length],r.style.setProperty("--n",String(o)),r.style.setProperty("--palette",`var(--tablechart-color-${o+1})`)}),void 0!==d&&(x(a[d].name,a[d].key).dataset.marker="size"),n.after(M)},draw(o){const{rows:n,series:r,x:i,y:l,frame:u,unit:f,svg:d,categories:h,height:p,config:g,plot:m}=o;if(!i||!u)return;const b=s(r),M=c(n,b.group),$=M.length>1,x=(o.length("--tablechart-marker-size","10px")??10*f)/2,v=(o.length("--tablechart-bubble-max","24px")??24*f)/2,w=(o.length("--tablechart-bubble-min","")??1.2*x)/2,y=t=>void 0===b.size?void 0:t.cells[b.size],A=(0,t.largest)(n.map(t=>Math.abs(y(t)?.value??0))),S=n.flatMap((t,o)=>{const n=t.cells[b.x],r=t.cells[b.y];if(!n||!r||n.missing||r.missing)return[];const e=y(t),a=e&&!e.missing&&A>0?Math.max(w,Math.sqrt(Math.abs(e.value)/A)*v):x,s=$?M.indexOf(t.cells[b.group]?.raw??""):-1;return[{i:o,px:i(n.value),py:l(r.value),r:a,g:s}]}),k=Math.min(S.length-1,6);m.style.setProperty("--count",String(k+1));const q=new Map([...S].sort((t,o)=>t.px-o.px||t.i-o.i).map((o,n)=>[o.i,k?(0,t.short)(n*k/(S.length-1)):0])),z=[...S].sort((t,o)=>o.r-t.r||t.i-o.i);for(const a of z){const o=$?e[a.g%e.length]:"circle";d.appendChild((0,t.markerEl)(o,a.px,a.py,a.r,{class:t.POINT_CLASS,"data-row":a.i+1,"data-marker":o,style:`--i:${q.get(a.i)}; ${$?`--n:${a.g}; --palette:var(--tablechart-color-${a.g+1})`:""}`}))}const N=m.parentElement?.getAttribute("data-chart-names"),H=null==N?g.names:"false"!==N,V=4*f,I=[u[0]+1.5*V,u[1],u[2]-1.5*V,u[3]-1.5*V],[T,j,B,C]=I,D=z.map(({i:o,px:n,py:r,r:e})=>{if(h[o].hasAttribute("data-same"))return[];const{width:a,height:s}=(0,t.sizeOf)(h[o]),c=a*f,i=s*f,l=.1*i,u=.7*e+V/2,d=(t,o)=>[Math.max(T,Math.min(t,T+B-c)),Math.max(j,Math.min(o,j+C-i))+l,c,i-2*l];return[d(n+e+V,r-i/2),d(n-e-V-c,r-i/2),d(n-c/2,r-e-V-i),d(n-c/2,r+e+V),d(n+u,r-u-i),d(n-u-c,r-u-i),d(n+u,r+u),d(n-u-c,r+u)]}),E=H?(0,t.avoidCollisions)(D,S.map(({px:t,py:o,r:n})=>[t-n,o-n,2*n,2*n]),I):z.map(()=>null);for(const t of h)t.hidden=!0,t.dataset.missing="";z.forEach((o,n)=>{const r=h[o.i],e=E[n];if(r.hidden=!1,delete r.dataset.missing,r.style.setProperty("--i",String(q.get(o.i))),r.toggleAttribute("data-left-out",null===e),null===e)return;r.dataset.side=a[e];const[s,c,,i]=D[n][e];(0,t.placeAt)(r,s,c-((0,t.sizeOf)(r).height*f-i)/2,t.VIEWBOX_WIDTH,p)}),o.rowAt=(t,o)=>{let n=null,r=6*f;for(const e of S){const a=Math.max(Math.hypot(e.px-t*f,e.py-o*f)-e.r,0);(a<r||a===r&&n&&e.r<n.r)&&(r=a,n=e)}return n?n.i:null}},tooltip(t,o){const{x:n,y:r}=s(t.series),e=i(t.rows[o],n,r),a=t.rows.flatMap((t,a)=>a===o||null!==e&&i(t,n,r)===e?[a]:[]),c=a.filter(o=>t.categories[o]?.hasAttribute("data-more"));return[...c,...a.filter(t=>!c.includes(t))].map(o=>({name:t.categories[o]?.textContent??"",value:""}))}};window.Tablechart.addType("scatter",l)}(Tablechart.kit);
|
|
@@ -1,11 +1,78 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
var
|
|
1
|
+
import { A as e, C as t, E as n, F as r, I as i, N as a, O as o, P as s, S as c, V as l, W as u, b as d, j as f, k as p, w as m, x as h, z as g } from "./tablechart-shared.mjs";
|
|
2
|
+
// src/js/annotations/quadrant.ts
|
|
3
|
+
var _ = `${l}-name`, v = [
|
|
4
|
+
"top left",
|
|
5
|
+
"top right",
|
|
6
|
+
"bottom left",
|
|
7
|
+
"bottom right"
|
|
8
|
+
], y = (e, t) => {
|
|
9
|
+
if (!e) return null;
|
|
10
|
+
if (e === "mean") return t.length ? t.reduce((e, t) => e + t, 0) / t.length : null;
|
|
11
|
+
if (e === "median") {
|
|
12
|
+
let e = [...t].sort((e, t) => e - t), n = e.length / 2;
|
|
13
|
+
return e.length ? e.length % 2 ? e[Math.floor(n)] : (e[n - 1] + e[n]) / 2 : null;
|
|
14
|
+
}
|
|
15
|
+
let n = Number.parseFloat(e);
|
|
16
|
+
return Number.isFinite(n) ? n : null;
|
|
17
|
+
}, b = {
|
|
18
|
+
create(e, t) {
|
|
19
|
+
for (let n of e.querySelectorAll("[data-corner]")) {
|
|
20
|
+
let e = (n.getAttribute("data-corner") ?? "").toLowerCase().split(/\s+/), i = `${e.find((e) => e === "top" || e === "bottom")} ${e.find((e) => e === "left" || e === "right")}`;
|
|
21
|
+
if (!v.includes(i)) {
|
|
22
|
+
console.warn(`[${r}] A quadrant has a corner "${n.getAttribute("data-corner")}". It takes ${v.join(", ")}.`);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
let a = document.createElement("span");
|
|
26
|
+
if (a.className = _, a.dataset.corner = i, a.inert = !0, n.childElementCount) for (let e of Array.from(n.children)) a.append(e.cloneNode(!0));
|
|
27
|
+
else a.textContent = (n.textContent ?? "").trim();
|
|
28
|
+
for (let { name: e, value: t } of Array.from(n.attributes)) e !== "data-corner" && a.setAttribute(e, t);
|
|
29
|
+
t.append(a);
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
},
|
|
33
|
+
draw(t, n, i) {
|
|
34
|
+
let { frame: o, x: s, y: d, rows: v, series: b, height: x, unit: S, svg: C, plot: w, categories: T } = i;
|
|
35
|
+
if (!o || !s) {
|
|
36
|
+
console.warn(`[${r}] A quadrant works on a scatter chart, which has an axis across and an axis up.`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
let [E, D, O, k] = o, A = b.flatMap((e, t) => e.group ? [] : [t]), j = (e) => v.flatMap((t) => t.cells[A[e]] && !t.cells[A[e]].missing ? [t.cells[A[e]].value] : []), M = y(t.getAttribute("data-x"), j(0)), N = y(t.getAttribute("data-y"), j(1)), P = M === null ? E + O / 2 : Math.min(Math.max(s(M), E), E + O), F = N === null ? D + k / 2 : Math.min(Math.max(d(N), D), D + k), I = C.querySelector(`:scope > .${a}`);
|
|
40
|
+
if (I) {
|
|
41
|
+
let e = (e, t) => Math.abs(e - t) < S / 2, t = (I.getAttribute("d") ?? "").match(/M[^M]+/g) ?? [];
|
|
42
|
+
I.setAttribute("d", t.filter((t) => {
|
|
43
|
+
let [, n, r, i] = t.match(/M(-?[\d.]+),(-?[\d.]+)([HV])/) ?? [];
|
|
44
|
+
return !(i === "V" && e(Number(n), P)) && !(i === "H" && e(Number(r), F));
|
|
45
|
+
}).join(""));
|
|
46
|
+
}
|
|
47
|
+
C.insertBefore(f("path", {
|
|
48
|
+
class: l,
|
|
49
|
+
d: `M${e(P)},${e(D)}V${e(D + k)}M${e(E)},${e(F)}H${e(E + O)}`
|
|
50
|
+
}), C.querySelector(`:scope > .${g}`));
|
|
51
|
+
let L = 6 * S, R = [];
|
|
52
|
+
for (let e of w.querySelectorAll(`:scope > .${_}`)) {
|
|
53
|
+
let t = e.dataset.corner ?? "", n = t.includes("right"), r = t.includes("bottom"), i = n ? E + O - L : E + L, a = r ? D + k - L : D + L;
|
|
54
|
+
p(e, i, a, u, x);
|
|
55
|
+
let o = c(e).width * S, s = c(e).height * S;
|
|
56
|
+
R.push([
|
|
57
|
+
n ? i - o : i,
|
|
58
|
+
r ? a - s : a,
|
|
59
|
+
o,
|
|
60
|
+
s
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
i.taken.push(...R);
|
|
64
|
+
for (let e of T) {
|
|
65
|
+
if (e.hidden || e.hasAttribute("data-left-out") || !e.style.left) continue;
|
|
66
|
+
let t = h(e, S, u, x, [0, 0]);
|
|
67
|
+
R.some((e) => m(e, t)) && e.setAttribute("data-left-out", "");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}, x = [
|
|
4
71
|
"circle",
|
|
5
72
|
"triangle",
|
|
6
73
|
"square",
|
|
7
74
|
"diamond"
|
|
8
|
-
],
|
|
75
|
+
], S = [
|
|
9
76
|
"right",
|
|
10
77
|
"left",
|
|
11
78
|
"above",
|
|
@@ -14,7 +81,7 @@ var d = [
|
|
|
14
81
|
"left",
|
|
15
82
|
"right",
|
|
16
83
|
"left"
|
|
17
|
-
],
|
|
84
|
+
], C = (e) => {
|
|
18
85
|
let t = e.flatMap((e, t) => e.group ? [] : [t]);
|
|
19
86
|
return {
|
|
20
87
|
x: t[0],
|
|
@@ -22,119 +89,118 @@ var d = [
|
|
|
22
89
|
size: t[2],
|
|
23
90
|
group: e.findIndex((e) => e.group)
|
|
24
91
|
};
|
|
25
|
-
},
|
|
92
|
+
}, w = (e, t) => t < 0 ? [] : [...new Set(e.map((e) => e.cells[t]?.raw ?? ""))], T = (e, t, n) => e.cells[t]?.missing || e.cells[n]?.missing ? null : `${e.cells[t]?.value} ${e.cells[n]?.value}`, E = {
|
|
26
93
|
aspect: .62,
|
|
27
94
|
categories: "beside",
|
|
28
95
|
columns: !0,
|
|
29
96
|
axes: !0,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
97
|
+
numbers: !1,
|
|
98
|
+
annotations: { quadrant: b },
|
|
99
|
+
text({ figure: e, plot: t, rows: n, series: r, config: a }) {
|
|
100
|
+
let { x: c, y: l, size: u, group: d } = C(r), f = t.querySelector(":scope > .tablechart-categories")?.children ?? [], p = /* @__PURE__ */ new Map();
|
|
101
|
+
n.forEach((e, t) => {
|
|
102
|
+
let n = T(e, c, l);
|
|
103
|
+
n && (p.get(n)?.push(t) ?? p.set(n, [t]));
|
|
35
104
|
});
|
|
36
|
-
let
|
|
37
|
-
for (let e of
|
|
105
|
+
let m = (e) => u === void 0 ? 0 : Math.abs(n[e].cells[u]?.value ?? 0);
|
|
106
|
+
for (let e of p.values()) {
|
|
38
107
|
if (e.length < 2) continue;
|
|
39
|
-
let t = e.reduce((e, t) =>
|
|
108
|
+
let t = e.reduce((e, t) => m(t) > m(e) ? t : e);
|
|
40
109
|
for (let n of e) {
|
|
41
|
-
let r =
|
|
110
|
+
let r = f[n];
|
|
42
111
|
n === t ? r?.setAttribute("data-more", String(e.length - 1)) : r?.setAttribute("data-same", "");
|
|
43
112
|
}
|
|
44
113
|
}
|
|
45
|
-
let
|
|
46
|
-
if (
|
|
47
|
-
let
|
|
48
|
-
|
|
49
|
-
let
|
|
50
|
-
let n = i
|
|
51
|
-
return n.dataset.place = "legend", n.dataset.line = "none", n.textContent = e, t &&
|
|
114
|
+
let h = w(n, d);
|
|
115
|
+
if (h.length < 2 && u === void 0) return;
|
|
116
|
+
let g = document.createElement("div");
|
|
117
|
+
g.className = s, g.setAttribute("aria-hidden", "true"), g.inert = !0;
|
|
118
|
+
let _ = Array.from(e.querySelectorAll(`tbody tr > td:nth-of-type(${d + 1})`)), v = (e, t) => {
|
|
119
|
+
let n = o(i, g);
|
|
120
|
+
return n.dataset.place = "legend", n.dataset.line = "none", n.textContent = e, t && a.langattribute && n.setAttribute(a.langattribute, t), n;
|
|
52
121
|
};
|
|
53
|
-
|
|
54
|
-
let n =
|
|
55
|
-
r.dataset.marker =
|
|
56
|
-
}), u !== void 0 && (
|
|
122
|
+
h.length > 1 && h.forEach((e, t) => {
|
|
123
|
+
let n = a.langattribute ? _.find((t) => t.textContent?.trim() === e)?.getAttribute(a.langattribute) : null, r = v(e, n);
|
|
124
|
+
r.dataset.marker = x[t % x.length], r.style.setProperty("--n", String(t)), r.style.setProperty("--palette", `var(--tablechart-color-${t + 1})`);
|
|
125
|
+
}), u !== void 0 && (v(r[u].name, r[u].key).dataset.marker = "size"), t.after(g);
|
|
57
126
|
},
|
|
58
|
-
draw(
|
|
59
|
-
let { rows: i, series:
|
|
60
|
-
if (!
|
|
61
|
-
let
|
|
62
|
-
|
|
63
|
-
let O = (e.length("--tablechart-marker-size", "10px") ?? 10 * v) / 2, k = (e.length("--tablechart-bubble-max", "24px") ?? 24 * v) / 2, A = (e) => T.size === void 0 ? void 0 : e.cells[T.size], j = u(i.map((e) => Math.abs(A(e)?.value ?? 0))), M = i.flatMap((e, t) => {
|
|
64
|
-
let n = e.cells[T.x], r = e.cells[T.y];
|
|
127
|
+
draw(r) {
|
|
128
|
+
let { rows: i, series: a, x: o, y: s, frame: l, unit: f, svg: m, categories: h, height: _, config: v, plot: y } = r;
|
|
129
|
+
if (!o || !l) return;
|
|
130
|
+
let b = C(a), T = w(i, b.group), E = T.length > 1, D = (r.length("--tablechart-marker-size", "10px") ?? 10 * f) / 2, O = (r.length("--tablechart-bubble-max", "24px") ?? 24 * f) / 2, k = (r.length("--tablechart-bubble-min", "") ?? D * 1.2) / 2, A = (e) => b.size === void 0 ? void 0 : e.cells[b.size], j = n(i.map((e) => Math.abs(A(e)?.value ?? 0))), M = i.flatMap((e, t) => {
|
|
131
|
+
let n = e.cells[b.x], r = e.cells[b.y];
|
|
65
132
|
if (!n || !r || n.missing || r.missing) return [];
|
|
66
|
-
let i = A(e), a = i && !i.missing && j > 0 ? Math.max(
|
|
133
|
+
let i = A(e), a = i && !i.missing && j > 0 ? Math.max(k, Math.sqrt(Math.abs(i.value) / j) * O) : D, c = E ? T.indexOf(e.cells[b.group]?.raw ?? "") : -1;
|
|
67
134
|
return [{
|
|
68
135
|
i: t,
|
|
69
|
-
px:
|
|
70
|
-
py:
|
|
136
|
+
px: o(n.value),
|
|
137
|
+
py: s(r.value),
|
|
71
138
|
r: a,
|
|
72
|
-
g:
|
|
139
|
+
g: c
|
|
73
140
|
}];
|
|
74
141
|
}), N = Math.min(M.length - 1, 6);
|
|
75
|
-
|
|
76
|
-
let P = new Map([...M].sort((e, t) => e.px - t.px || e.i - t.i).map((
|
|
142
|
+
y.style.setProperty("--count", String(N + 1));
|
|
143
|
+
let P = new Map([...M].sort((e, t) => e.px - t.px || e.i - t.i).map((t, n) => [t.i, N ? e(n * N / (M.length - 1)) : 0])), F = [...M].sort((e, t) => t.r - e.r || e.i - t.i);
|
|
77
144
|
for (let e of F) {
|
|
78
|
-
let
|
|
79
|
-
|
|
80
|
-
class:
|
|
145
|
+
let t = E ? x[e.g % x.length] : "circle";
|
|
146
|
+
m.appendChild(d(t, e.px, e.py, e.r, {
|
|
147
|
+
class: g,
|
|
81
148
|
"data-row": e.i + 1,
|
|
82
|
-
"data-marker":
|
|
83
|
-
style: `--i:${P.get(e.i)}; ${
|
|
149
|
+
"data-marker": t,
|
|
150
|
+
style: `--i:${P.get(e.i)}; ${E ? `--n:${e.g}; --palette:var(--tablechart-color-${e.g + 1})` : ""}`
|
|
84
151
|
}));
|
|
85
152
|
}
|
|
86
|
-
let I =
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
], [B, V, H, U] = z, W = F.map(({ i: e, px: t, py: n, r
|
|
92
|
-
if (
|
|
93
|
-
let { width:
|
|
94
|
-
Math.max(B, Math.min(e, B + H -
|
|
95
|
-
Math.max(V, Math.min(t, V + U -
|
|
96
|
-
|
|
97
|
-
|
|
153
|
+
let I = y.parentElement?.getAttribute("data-chart-names"), L = I == null ? v.names : I !== "false", R = 4 * f, z = [
|
|
154
|
+
l[0] + 1.5 * R,
|
|
155
|
+
l[1],
|
|
156
|
+
l[2] - 1.5 * R,
|
|
157
|
+
l[3] - 1.5 * R
|
|
158
|
+
], [B, V, H, U] = z, W = F.map(({ i: e, px: t, py: n, r }) => {
|
|
159
|
+
if (h[e].hasAttribute("data-same")) return [];
|
|
160
|
+
let { width: i, height: a } = c(h[e]), o = i * f, s = a * f, l = s * .1, u = r * .7 + R / 2, d = (e, t) => [
|
|
161
|
+
Math.max(B, Math.min(e, B + H - o)),
|
|
162
|
+
Math.max(V, Math.min(t, V + U - s)) + l,
|
|
163
|
+
o,
|
|
164
|
+
s - 2 * l
|
|
98
165
|
];
|
|
99
166
|
return [
|
|
100
|
-
d(t +
|
|
101
|
-
d(t -
|
|
102
|
-
d(t -
|
|
103
|
-
d(t -
|
|
104
|
-
d(t + u, n - u -
|
|
105
|
-
d(t - u -
|
|
167
|
+
d(t + r + R, n - s / 2),
|
|
168
|
+
d(t - r - R - o, n - s / 2),
|
|
169
|
+
d(t - o / 2, n - r - R - s),
|
|
170
|
+
d(t - o / 2, n + r + R),
|
|
171
|
+
d(t + u, n - u - s),
|
|
172
|
+
d(t - u - o, n - u - s),
|
|
106
173
|
d(t + u, n + u),
|
|
107
|
-
d(t - u -
|
|
174
|
+
d(t - u - o, n + u)
|
|
108
175
|
];
|
|
109
|
-
}), G = L ?
|
|
176
|
+
}), G = L ? t(W, M.map(({ px: e, py: t, r: n }) => [
|
|
110
177
|
e - n,
|
|
111
178
|
t - n,
|
|
112
179
|
2 * n,
|
|
113
180
|
2 * n
|
|
114
181
|
]), z) : F.map(() => null);
|
|
115
|
-
for (let e of
|
|
182
|
+
for (let e of h) e.hidden = !0, e.dataset.missing = "";
|
|
116
183
|
F.forEach((e, t) => {
|
|
117
|
-
let n =
|
|
118
|
-
if (n.hidden = !1, delete n.dataset.missing, n.style.setProperty("--i", String(P.get(e.i))), n.toggleAttribute("data-left-out",
|
|
119
|
-
n.dataset.side =
|
|
120
|
-
let [
|
|
121
|
-
|
|
122
|
-
}),
|
|
123
|
-
let n = null, r = 6 *
|
|
184
|
+
let n = h[e.i], r = G[t];
|
|
185
|
+
if (n.hidden = !1, delete n.dataset.missing, n.style.setProperty("--i", String(P.get(e.i))), n.toggleAttribute("data-left-out", r === null), r === null) return;
|
|
186
|
+
n.dataset.side = S[r];
|
|
187
|
+
let [i, a, , o] = W[t][r];
|
|
188
|
+
p(n, i, a - (c(n).height * f - o) / 2, u, _);
|
|
189
|
+
}), r.rowAt = (e, t) => {
|
|
190
|
+
let n = null, r = 6 * f;
|
|
124
191
|
for (let i of M) {
|
|
125
|
-
let a = Math.max(Math.hypot(i.px - e *
|
|
192
|
+
let a = Math.max(Math.hypot(i.px - e * f, i.py - t * f) - i.r, 0);
|
|
126
193
|
(a < r || a === r && n && i.r < n.r) && (r = a, n = i);
|
|
127
194
|
}
|
|
128
195
|
return n ? n.i : null;
|
|
129
196
|
};
|
|
130
197
|
},
|
|
131
198
|
tooltip(e, t) {
|
|
132
|
-
let { x: n, y: r } =
|
|
199
|
+
let { x: n, y: r } = C(e.series), i = T(e.rows[t], n, r), a = e.rows.flatMap((e, a) => a === t || i !== null && T(e, n, r) === i ? [a] : []), o = a.filter((t) => e.categories[t]?.hasAttribute("data-more"));
|
|
133
200
|
return [...o, ...a.filter((e) => !o.includes(e))].map((t) => ({
|
|
134
201
|
name: e.categories[t]?.textContent ?? "",
|
|
135
202
|
value: ""
|
|
136
203
|
}));
|
|
137
204
|
}
|
|
138
205
|
};
|
|
139
|
-
|
|
140
|
-
export { g as scatter };
|
|
206
|
+
export { E as scatter };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
export { type ChartState, type ChartType, type Config, PLACED_CLASS, PLOT_CLASS, PRINTING_CLASS, QUEUED_CLASS, type Row, SHOWN_CLASS, type Series, type StepPlan, addType, adoptTables, assignKeys, build, defaultConfig, entranceOf, layout, loadSources, prepare, readMarkdownRows, relabel, setShown, stepTo, unbuild };
|
|
1
|
+
import { A as SHOWN_CLASS, C as stepTo, D as PLOT_CLASS, E as PLACED_CLASS, O as PRINTING_CLASS, S as StepPlan, T as Config, b as Row, c as entranceOf, d as addType, f as build, g as unbuild, h as setShown, i as readMarkdownRows, j as defaultConfig, k as QUEUED_CLASS, m as relabel, n as adoptTables, p as layout, r as loadSources, t as assignKeys, u as prepare, v as ChartState, w as AT_ONCE_CLASS, x as Series, y as ChartType } from "./tablechart-shared.mjs";
|
|
2
|
+
export { AT_ONCE_CLASS, type ChartState, type ChartType, type Config, PLACED_CLASS, PLOT_CLASS, PRINTING_CLASS, QUEUED_CLASS, type Row, SHOWN_CLASS, type Series, type StepPlan, addType, adoptTables, assignKeys, build, defaultConfig, entranceOf, layout, loadSources, prepare, readMarkdownRows, relabel, setShown, stepTo, unbuild };
|
package/dist/tablechart-core.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { M as AT_ONCE_CLASS, L as PLACED_CLASS, R as PLOT_CLASS, B as PRINTING_CLASS, H as QUEUED_CLASS, U as SHOWN_CLASS, c as addType, a as adoptTables, h as assignKeys, l as build, G as defaultConfig, n as entranceOf, u as layout, o as loadSources, i as prepare, s as readMarkdownRows, d as relabel, f as setShown, m as stepTo, p as unbuild } from "./tablechart-shared.mjs";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
//#region src/js/config.d.ts
|
|
2
1
|
declare const PLOT_CLASS = "tablechart-plot";
|
|
3
2
|
declare const PLACED_CLASS = "is-placed";
|
|
4
3
|
declare const SHOWN_CLASS = "is-shown";
|
|
5
4
|
declare const PRINTING_CLASS = "is-printing";
|
|
5
|
+
declare const AT_ONCE_CLASS = "is-at-once";
|
|
6
6
|
declare const QUEUED_CLASS = "tablechart-queued";
|
|
7
7
|
interface Config {
|
|
8
8
|
/** Which elements Tablechart turns into charts. */
|
|
@@ -21,6 +21,13 @@ interface Config {
|
|
|
21
21
|
entrance: number;
|
|
22
22
|
/** Where a column's number goes: on the bar, or inside it. A figure overrides it with `data-chart-labels`. */
|
|
23
23
|
labels: "outside" | "inside";
|
|
24
|
+
/**
|
|
25
|
+
* Which values a line or area chart shows: `"auto"`, all if they fit and else the first, last, highest and lowest; `"all"`;
|
|
26
|
+
* `"none"`; or a set, such as `"first last"`. `"auto last"` shows all if they fit, and else the last. A figure overrides it with `data-chart-values`.
|
|
27
|
+
*/
|
|
28
|
+
values: string;
|
|
29
|
+
/** A tick above each name under a line or area chart, at the place of its row. A figure overrides it with `data-chart-ticks`. */
|
|
30
|
+
ticks: boolean;
|
|
24
31
|
/** How a line or area runs between points: `straight`, `step` or `smooth`. A figure overrides it with `data-chart-shape`. */
|
|
25
32
|
shape: "straight" | "step" | "smooth";
|
|
26
33
|
/** Names of several lines in a legend instead of at the end of each line. A figure overrides it with `data-chart-legend`. */
|
|
@@ -37,6 +44,10 @@ interface Config {
|
|
|
37
44
|
tooltipparent: HTMLElement | string | null;
|
|
38
45
|
/** The table under the chart: `"always"`, only in `"print"`, in print when numbers are left out (`"auto"`), or `"never"`. A figure overrides it with `data-chart-table`. */
|
|
39
46
|
table: "never" | "auto" | "print" | "always";
|
|
47
|
+
/** With `auto`, the table is printed only up to this many values, rows times value columns; a longer one prints the summary instead. */
|
|
48
|
+
tablelimit: number;
|
|
49
|
+
/** The summary of a chart, in a `.chart-summary`: `"always"`, only in `"print"`, in print when the table is not (`"auto"`), or `"never"`, for screen readers only. A figure overrides it with `data-chart-summary`. */
|
|
50
|
+
summary: "never" | "auto" | "print" | "always";
|
|
40
51
|
/** The name of the total that a donut without a total row works out, for screen readers. */
|
|
41
52
|
totallabel: string;
|
|
42
53
|
/** Previous and Next buttons under a chart that steps (`data-fragment`). `false` leaves them out, for buttons of your own. */
|
|
@@ -57,8 +68,6 @@ interface Config {
|
|
|
57
68
|
debug?: boolean;
|
|
58
69
|
}
|
|
59
70
|
declare const defaultConfig: Config;
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region src/js/functions/scale.d.ts
|
|
62
71
|
/** A break in the scale: values from `lo` to `hi` get `share` of the length, and the cut is at `gap`. */
|
|
63
72
|
interface Squeeze {
|
|
64
73
|
lo: number;
|
|
@@ -66,8 +75,6 @@ interface Squeeze {
|
|
|
66
75
|
gap: number;
|
|
67
76
|
share: number;
|
|
68
77
|
}
|
|
69
|
-
//#endregion
|
|
70
|
-
//#region src/js/steps.d.ts
|
|
71
78
|
/** The steps of one chart: which step shows each row, column and annotation, and how many steps there are. */
|
|
72
79
|
interface StepPlan {
|
|
73
80
|
rows: {
|
|
@@ -95,8 +102,6 @@ interface StepPlan {
|
|
|
95
102
|
* Says so with a `tablechart:step` event on the figure, unless `quietly`.
|
|
96
103
|
*/
|
|
97
104
|
declare const stepTo: (state: ChartState, step: number, quietly?: boolean) => void;
|
|
98
|
-
//#endregion
|
|
99
|
-
//#region src/js/types.d.ts
|
|
100
105
|
/** How a line or an area runs from one point to the next. */
|
|
101
106
|
type Shape = "straight" | "step" | "smooth";
|
|
102
107
|
/** How a chart builds: each element grows from zero, or the chart is revealed in one movement. */
|
|
@@ -114,6 +119,13 @@ interface Cell {
|
|
|
114
119
|
}
|
|
115
120
|
interface Row extends Cell {
|
|
116
121
|
label: string;
|
|
122
|
+
/** `data-short` on the row's header: the name under the chart, where room is short. The table and the summary have `label`. */
|
|
123
|
+
short: string | null;
|
|
124
|
+
/** `data-value="show"` on the row: its value is always shown on a line. */
|
|
125
|
+
pinned: boolean;
|
|
126
|
+
/** The text of its cell in a column with `data-note`, such as "Share issue", and its translation key. */
|
|
127
|
+
note: string | null;
|
|
128
|
+
noteKey: string | null;
|
|
117
129
|
key: string | null;
|
|
118
130
|
cells: Cell[];
|
|
119
131
|
/** Copied to everything drawn for the row, so one class styles all of it. */
|
|
@@ -132,12 +144,20 @@ interface Series {
|
|
|
132
144
|
line: "dashed" | "dotted" | null;
|
|
133
145
|
/** `data-group` on the header: the cells name a group, such as "Predefined". */
|
|
134
146
|
group: boolean;
|
|
147
|
+
/** `data-chart="line"` on the header, in a chart that takes it: a line over the other marks. */
|
|
148
|
+
chart: "line" | null;
|
|
135
149
|
}
|
|
136
150
|
interface Segment extends Row {
|
|
137
151
|
from: number;
|
|
138
152
|
to: number;
|
|
139
153
|
kind: "bar" | "up" | "down" | "total";
|
|
140
154
|
}
|
|
155
|
+
/** Which values a line shows, from `data-chart-values`: all, none, a set of rows, or all if they fit and else the set. */
|
|
156
|
+
interface ValuePick {
|
|
157
|
+
mode: "auto" | "all" | "set";
|
|
158
|
+
/** `first`, `last`, `highest`, `lowest`, `outliers`. Rows with `data-value="show"` are always in the set. */
|
|
159
|
+
keys: string[];
|
|
160
|
+
}
|
|
141
161
|
/** Scales only, no pixel positions, so an annotation follows the data. */
|
|
142
162
|
interface Geometry {
|
|
143
163
|
rows: Row[];
|
|
@@ -150,6 +170,8 @@ interface Geometry {
|
|
|
150
170
|
frame?: [number, number, number, number];
|
|
151
171
|
/** A chart that knows better which row is pointed at sets this, in screen pixels from the plot's corner. */
|
|
152
172
|
rowAt?: (x: number, y: number) => number | null;
|
|
173
|
+
/** Where the tooltip of a row points, in viewBox units, for a row whose mark may not be drawn, such as a point of a long line. */
|
|
174
|
+
pointOf?: (index: number) => [number, number] | null;
|
|
153
175
|
/** A CSS length set on the figure, such as `--tablechart-marker-size`, in viewBox units. */
|
|
154
176
|
length: (name: string, fallback: string) => number | null;
|
|
155
177
|
barWidth: number;
|
|
@@ -178,6 +200,8 @@ interface Geometry {
|
|
|
178
200
|
insideAlign: "start" | "center" | "end" | null;
|
|
179
201
|
stacked: boolean;
|
|
180
202
|
shape: Shape;
|
|
203
|
+
/** Which values a line or an area shows. */
|
|
204
|
+
pick: ValuePick;
|
|
181
205
|
/** Empty when the chart is not stacked or its kind shows no totals. */
|
|
182
206
|
totals: HTMLElement[];
|
|
183
207
|
svg: SVGSVGElement;
|
|
@@ -185,6 +209,8 @@ interface Geometry {
|
|
|
185
209
|
/** Made by `build`; a chart only places them. */
|
|
186
210
|
values: HTMLElement[];
|
|
187
211
|
series: Series[];
|
|
212
|
+
/** The series this drawing draws: all of them, or in a chart with columns and a line, those of its own kind. */
|
|
213
|
+
own: number[];
|
|
188
214
|
seriesValues: HTMLElement[][];
|
|
189
215
|
/** Empty with one series. */
|
|
190
216
|
names: HTMLElement[];
|
|
@@ -196,6 +222,8 @@ interface Geometry {
|
|
|
196
222
|
checks: Check[];
|
|
197
223
|
/** The labels of annotations placed so far, as left, top, width and height, so the next one finds room. */
|
|
198
224
|
taken: [number, number, number, number][];
|
|
225
|
+
/** Holes in the lines and areas, such as under an open marker: the core leaves them out with a clip, from the start. */
|
|
226
|
+
lineHoles: SVGElement[];
|
|
199
227
|
}
|
|
200
228
|
interface Check {
|
|
201
229
|
label: string;
|
|
@@ -221,6 +249,12 @@ interface ChartType {
|
|
|
221
249
|
columns?: boolean;
|
|
222
250
|
/** An axis across and an axis up, from the first two value columns, with their headers as titles. */
|
|
223
251
|
axes?: boolean;
|
|
252
|
+
/** A series with `data-chart="line"` on its header is a line over the marks, on the same scale. */
|
|
253
|
+
lines?: boolean;
|
|
254
|
+
/** Several series side by side, as groups of bars: their numbers are smaller, so the plot is marked `data-grouped` before anything is measured. */
|
|
255
|
+
groups?: boolean;
|
|
256
|
+
/** False: no numbers on the chart. They stay out of the layout, which costs a lot with many rows. */
|
|
257
|
+
numbers?: false;
|
|
224
258
|
/** Text of its own, made with the rest of the text so a translation script finds it, such as a legend. */
|
|
225
259
|
text?: (input: {
|
|
226
260
|
figure: HTMLElement;
|
|
@@ -247,6 +281,8 @@ interface ChartType {
|
|
|
247
281
|
draw: (geo: Geometry) => void;
|
|
248
282
|
/** The lines of the tooltip of a row. Default: each value with the name of its series, and the total of a stack. */
|
|
249
283
|
tooltip?: (state: ChartState, index: number, config: Config) => TooltipLine[];
|
|
284
|
+
/** Annotations that come with this type, such as `quadrant` with `scatter`; `addType` adds them. */
|
|
285
|
+
annotations?: Record<string, AnnotationType>;
|
|
250
286
|
}
|
|
251
287
|
/** One line of a tooltip, under the name of the row. */
|
|
252
288
|
interface TooltipLine {
|
|
@@ -303,6 +339,8 @@ interface ChartState {
|
|
|
303
339
|
rowAt: ((x: number, y: number) => number | null) | null;
|
|
304
340
|
/** As percentages: left, top, width and height. */
|
|
305
341
|
rowBox: ((index: number) => [number, number, number, number]) | null;
|
|
342
|
+
/** Where the tooltip of a row points, in viewBox units; set by a chart such as a line. */
|
|
343
|
+
pointOf: ((index: number) => [number, number] | null) | null;
|
|
306
344
|
annotations: {
|
|
307
345
|
spec: HTMLElement;
|
|
308
346
|
type: AnnotationType;
|
|
@@ -319,12 +357,8 @@ interface ChartState {
|
|
|
319
357
|
controls: HTMLElement | null;
|
|
320
358
|
checks: Check[];
|
|
321
359
|
}
|
|
322
|
-
//#endregion
|
|
323
|
-
//#region src/js/charts/scatter.d.ts
|
|
324
360
|
/** One marker per row, across by its first value and up by its second; a third value makes it a bubble. */
|
|
325
361
|
declare const scatter: ChartType;
|
|
326
|
-
//#endregion
|
|
327
|
-
//#region src/js/core.d.ts
|
|
328
362
|
/** Adds a chart type for `data-chart="name"`, such as one from `@martinomagnifico/tablechart/additional-types`, before `init()`. */
|
|
329
363
|
declare const addType: (name: string, type: ChartType) => void;
|
|
330
364
|
/** Pass 2: everything a reader will read, before a translation script looks. */
|
|
@@ -335,10 +369,11 @@ declare const layout: (state: ChartState, config: Config) => boolean;
|
|
|
335
369
|
declare const relabel: (state: ChartState, config: Config) => void;
|
|
336
370
|
/** Removes what `build` added, so the chart can be built again. */
|
|
337
371
|
declare const unbuild: (state: ChartState) => void;
|
|
338
|
-
/**
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
372
|
+
/**
|
|
373
|
+
* One class, `is-shown`, starts the whole build. `atOnce` skips it: the chart lands at its end, or back at its start,
|
|
374
|
+
* without transitions, such as a chart in view when the page opens, or one hidden where nobody sees it.
|
|
375
|
+
*/
|
|
376
|
+
declare const setShown: (state: ChartState, shown: boolean, atOnce?: boolean) => void;
|
|
342
377
|
interface TablechartChart {
|
|
343
378
|
figure: HTMLElement;
|
|
344
379
|
/** Lays the chart out again, for example after a script has changed its text. */
|
|
@@ -376,17 +411,12 @@ declare const prepare: (found: HTMLElement[], config: Config) => Promise<HTMLEle
|
|
|
376
411
|
declare const create: (element: HTMLElement, options?: Partial<Config>) => Promise<TablechartChart | null>;
|
|
377
412
|
/** Makes a chart of every figure in `root` that matches the selector, skipping existing charts. */
|
|
378
413
|
declare const init: (options?: Partial<Config>, root?: ParentNode) => Promise<TablechartInstance>;
|
|
379
|
-
//#endregion
|
|
380
|
-
//#region src/js/functions/sources.d.ts
|
|
381
414
|
/** A Markdown table, or a caption with chart attributes, is wrapped in a figure with the caption and annotations beside it. */
|
|
382
415
|
declare const adoptTables: (figures: HTMLElement[]) => HTMLElement[];
|
|
383
416
|
/** `data-chart-src` fills the figure's table with the rows of a JSON file, keeping a header row the author wrote; a file that fails is reported. */
|
|
384
417
|
declare const loadSources: (figures: HTMLElement[]) => Promise<void>;
|
|
385
418
|
/** In a Markdown table, a bold label makes the row a total, and a bold header puts that series in focus. */
|
|
386
419
|
declare const readMarkdownRows: (figures: HTMLElement[]) => void;
|
|
387
|
-
//#endregion
|
|
388
|
-
//#region src/js/functions/read-table.d.ts
|
|
389
420
|
/** Writes translation keys such as `harvest-row1` onto a figure with `data-chart-keys`; a duplicate prefix gets a number. */
|
|
390
421
|
declare const assignKeys: (figures: HTMLElement[], langattribute: string | false) => void;
|
|
391
|
-
|
|
392
|
-
export { defaultConfig as A, stepTo as C, PRINTING_CLASS as D, PLOT_CLASS as E, QUEUED_CLASS as O, StepPlan as S, PLACED_CLASS as T, scatter as _, TablechartChart as a, Row as b, entranceOf as c, addType as d, build as f, unbuild as g, setShown as h, readMarkdownRows as i, SHOWN_CLASS as k, init as l, relabel as m, adoptTables as n, TablechartInstance as o, layout as p, loadSources as r, create as s, assignKeys as t, prepare as u, ChartState as v, Config as w, Series as x, ChartType as y };
|
|
422
|
+
export { SHOWN_CLASS as A, stepTo as C, PLOT_CLASS as D, PLACED_CLASS as E, PRINTING_CLASS as O, StepPlan as S, Config as T, scatter as _, TablechartChart as a, Row as b, entranceOf as c, addType as d, build as f, unbuild as g, setShown as h, readMarkdownRows as i, defaultConfig as j, QUEUED_CLASS as k, init as l, relabel as m, adoptTables as n, TablechartInstance as o, layout as p, loadSources as r, create as s, assignKeys as t, prepare as u, ChartState as v, AT_ONCE_CLASS as w, Series as x, ChartType as y };
|