@martinomagnifico/tablechart 1.0.6 → 1.1.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 +40 -0
- package/README.md +20 -2
- package/dist/tablechart-additional-types.d.mts +5 -0
- package/dist/tablechart-additional-types.js +1 -0
- package/dist/tablechart-additional-types.mjs +140 -0
- package/dist/tablechart-core.d.mts +3 -14
- package/dist/tablechart-core.mjs +3 -1
- package/dist/tablechart-shared.d.mts +93 -94
- package/dist/tablechart-shared.mjs +1279 -1082
- package/dist/tablechart-shared2.d.mts +55 -0
- package/dist/tablechart-shared2.mjs +134 -0
- package/dist/tablechart.css +1 -1
- package/dist/tablechart.d.mts +3 -2
- package/dist/tablechart.js +1 -1
- package/dist/tablechart.mjs +3 -1
- package/package.json +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.1.0] - 2026-10-23
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- A scatter and bubble chart, `data-chart="scatter"`, in the new additional types: `@martinomagnifico/tablechart/additional-types` or `tablechart-additional-types.js`.
|
|
8
|
+
- `addType()`, to add one of the additional types.
|
|
9
|
+
- Axes with numbers on the scatter chart, with a scale of your own (`data-chart-scale`).
|
|
10
|
+
- A value axis (`data-chart-axis`) and gridlines (`data-chart-grid`) on the other types, off by default. With either, the scale ends on a number of the axis, or where `data-chart-scale` says.
|
|
11
|
+
- A reference line annotation, at a value, the mean or the median.
|
|
12
|
+
- `data-chart-animate="false"`, to show one chart from the start, without animation.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- A line chart with three lines or more shows a number above or below each point where there is room. Before, it left all numbers out.
|
|
17
|
+
|
|
18
|
+
### Removed
|
|
19
|
+
|
|
20
|
+
- The old CSS variable names from 1.0.4, and the animate values `up` and `across`.
|
|
21
|
+
- The `hover` option and `data-chart-hover`. Use `tooltip` and `data-chart-tooltip`.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## [1.0.7] - 2026-10-16
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- A `tooltipparent` option. Can by body or any other selector.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- The text of a tooltip has the size of the chart's text on the screen, also when the chart is scaled.
|
|
34
|
+
- A scroll closes a tooltip, like a key. It opens again when the mouse moves.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- After a scroll, a tooltip could show at the top of the window, for a row that had scrolled away.
|
|
39
|
+
- The arrow of a tooltip points at the middle of its row and stops just short of it, at every size. It was a little to the right, and on a large screen it covered the mark.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
3
43
|
## [1.0.6] - 2026-10-16
|
|
4
44
|
|
|
5
45
|
### Changed
|
package/README.md
CHANGED
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
|
|
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
|
-
* **Chart types:** column, bar, line, area, waterfall and donut
|
|
14
|
+
* **Chart types:** column, bar, line, area, waterfall and donut, and scatter as an additional type
|
|
15
15
|
* **The table stays:** it is hidden from sight, but screen readers, search engines and translation scripts still read it. Without JavaScript, the table is all there is.
|
|
16
16
|
* **Real text:** names and numbers are HTML, so they use the font of the page and do not scale with the drawing.
|
|
17
17
|
* **CSS for the looks:** colours, sizes and animation are CSS variables. Light and dark mode follow the page.
|
|
18
|
-
* **Annotations:** badges, brackets, trend arrows and a break in the scale
|
|
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
|
* **Print and PDF:** every chart prints whole, and the table can be shown under a chart that leaves numbers out
|
|
21
21
|
* **Step by step:** show the rows one at a time, with Previous and Next buttons
|
|
@@ -50,6 +50,8 @@ Or with a script tag:
|
|
|
50
50
|
</script>
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
The scatter chart is an additional type, in a script of its own. To use it, see [Additional types](#additional-types).
|
|
54
|
+
|
|
53
55
|
## A chart
|
|
54
56
|
|
|
55
57
|
A chart is a `figure` with `data-chart` and a table in it. The first cell of a row is its name, the other cells are its values. The `figcaption` is the title; text after a `br` is the subtitle.
|
|
@@ -69,6 +71,20 @@ A chart is a `figure` with `data-chart` and a table in it. The first cell of a r
|
|
|
69
71
|
|
|
70
72
|
Use `bar`, `line`, `area`, `waterfall` or `donut` for the other types. With more than one value column, each column is a line, or a bar in each group. Add `data-chart-stack` to stack them.
|
|
71
73
|
|
|
74
|
+
### Additional types
|
|
75
|
+
|
|
76
|
+
The scatter chart is an additional type, in a script of its own. To use it, add it before `init()`:
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
import { addType, init } from "@martinomagnifico/tablechart";
|
|
80
|
+
import { scatter } from "@martinomagnifico/tablechart/additional-types";
|
|
81
|
+
|
|
82
|
+
addType("scatter", scatter);
|
|
83
|
+
init();
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
With a script tag, load `tablechart-additional-types.js` after `tablechart.js`. See [Additional types](https://martinomagnifico.github.io/tablechart/types/additional-types.html).
|
|
87
|
+
|
|
72
88
|
## Options
|
|
73
89
|
|
|
74
90
|
```js
|
|
@@ -79,6 +95,8 @@ init({
|
|
|
79
95
|
controls: true, // Previous and Next buttons on a chart that steps
|
|
80
96
|
tooltip: "auto", // Tooltips: "auto" only when a chart leaves numbers out, true or false
|
|
81
97
|
table: "never", // The table under the chart: "never", "auto" (in print, if numbers are left out), "print" or "always"
|
|
98
|
+
axis: false, // Numbers along the value axis
|
|
99
|
+
grid: false, // Gridlines at the numbers of the axis
|
|
82
100
|
locale: undefined, // Locale for numbers; the language of the page if not set
|
|
83
101
|
});
|
|
84
102
|
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(t){var e=["circle","triangle","square","diamond"],o=["right","left","above","below","right","left","right","left"],n=t=>{const e=t.flatMap((t,e)=>t.group?[]:[e]);return{x:e[0],y:e[1],size:e[2],group:t.findIndex(t=>t.group)}},r=(t,e)=>e<0?[]:[...new Set(t.map(t=>t.cells[e]?.raw??""))],a=(t,e,o)=>t.cells[e]?.missing||t.cells[o]?.missing?null:`${t.cells[e]?.value} ${t.cells[o]?.value}`,s={aspect:.62,categories:"beside",columns:!0,axes:!0,text({figure:o,plot:s,rows:c,series:i,config:l}){const{x:u,y:f,size:h,group:d}=n(i),g=s.querySelector(":scope > .tablechart-categories")?.children??[],p=new Map;c.forEach((t,e)=>{const o=a(t,u,f);o&&(p.get(o)?.push(e)??p.set(o,[e]))});const M=t=>void 0===h?0:Math.abs(c[t].cells[h]?.value??0);for(const t of p.values()){if(t.length<2)continue;const e=t.reduce((t,e)=>M(e)>M(t)?e:t);for(const o of t){const n=g[o];o===e?n?.setAttribute("data-more",String(t.length-1)):n?.setAttribute("data-same","")}}const b=r(c,d);if(b.length<2&&void 0===h)return;const m=document.createElement("div");m.className=t.LEGEND_CLASS,m.setAttribute("aria-hidden","true"),m.inert=!0;const v=Array.from(o.querySelectorAll(`tbody tr > td:nth-of-type(${d+1})`)),x=(e,o)=>{const n=(0,t.htmlEl)(t.NAME_CLASS,m);return n.dataset.place="legend",n.dataset.line="none",n.textContent=e,o&&l.langattribute&&n.setAttribute(l.langattribute,o),n};b.length>1&&b.forEach((t,o)=>{const n=l.langattribute?v.find(e=>e.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!==h&&(x(i[h].name,i[h].key).dataset.marker="size"),o.appendChild(m)},draw(a){const{rows:s,series:c,x:i,y:l,frame:u,unit:f,svg:h,categories:d,seriesValues:g,height:p,config:M,plot:b}=a;if(!i||!u)return;const m=n(c),v=r(s,m.group),x=v.length>1;for(const t of g.flat())t.dataset.place="none";const w=(a.length("--tablechart-marker-size","10px")??10*f)/2,y=(a.length("--tablechart-bubble-max","24px")??24*f)/2,$=t=>void 0===m.size?void 0:t.cells[m.size],S=(0,t.largest)(s.map(t=>Math.abs($(t)?.value??0))),z=s.flatMap((t,e)=>{const o=t.cells[m.x],n=t.cells[m.y];if(!o||!n||o.missing||n.missing)return[];const r=$(t),a=r&&!r.missing&&S>0?Math.max(.6*w,Math.sqrt(Math.abs(r.value)/S)*y):w,s=x?v.indexOf(t.cells[m.group]?.raw??""):-1;return[{i:e,px:i(o.value),py:l(n.value),r:a,g:s}]}),k=Math.min(z.length-1,6);b.style.setProperty("--count",String(k+1));const q=new Map([...z].sort((t,e)=>t.px-e.px||t.i-e.i).map((e,o)=>[e.i,k?(0,t.short)(o*k/(z.length-1)):0])),A=[...z].sort((t,e)=>e.r-t.r||t.i-e.i);for(const o of A){const n=x?e[o.g%e.length]:"circle";h.appendChild((0,t.markerEl)(n,o.px,o.py,o.r,{class:t.POINT_CLASS,"data-row":o.i+1,"data-marker":n,style:`--i:${q.get(o.i)}; ${x?`--n:${o.g}; --palette:var(--tablechart-color-${o.g+1})`:""}`}))}const T=b.parentElement?.getAttribute("data-chart-names"),V=null==T?M.names:"false"!==T,j=4*f,B=[u[0]+1.5*j,u[1],u[2]-1.5*j,u[3]-1.5*j],[C,D,E,F]=B,G=A.map(({i:e,px:o,py:n,r:r})=>{if(d[e].hasAttribute("data-same"))return[];const{width:a,height:s}=(0,t.sizeOf)(d[e]),c=a*f,i=s*f,l=.1*i,u=.7*r+j/2,h=(t,e)=>[Math.max(C,Math.min(t,C+E-c)),Math.max(D,Math.min(e,D+F-i))+l,c,i-2*l];return[h(o+r+j,n-i/2),h(o-r-j-c,n-i/2),h(o-c/2,n-r-j-i),h(o-c/2,n+r+j),h(o+u,n-u-i),h(o-u-c,n-u-i),h(o+u,n+u),h(o-u-c,n+u)]}),H=V?(0,t.avoidCollisions)(G,z.map(({px:t,py:e,r:o})=>[t-o,e-o,2*o,2*o]),B):A.map(()=>null);for(const t of d)t.hidden=!0,t.dataset.missing="";A.forEach((e,n)=>{const r=d[e.i],a=H[n];if(r.hidden=!1,delete r.dataset.missing,r.style.setProperty("--i",String(q.get(e.i))),r.toggleAttribute("data-left-out",null===a),null===a)return;r.dataset.side=o[a];const[s,c,,i]=G[n][a];(0,t.placeAt)(r,s,c-((0,t.sizeOf)(r).height*f-i)/2,t.VIEWBOX_WIDTH,p)}),a.rowAt=(t,e)=>{let o=null,n=6*f;for(const r of z){const a=Math.max(Math.hypot(r.px-t*f,r.py-e*f)-r.r,0);(a<n||a===n&&o&&r.r<o.r)&&(n=a,o=r)}return o?o.i:null}},tooltip(t,e){const{x:o,y:r}=n(t.series),s=a(t.rows[e],o,r),c=t.rows.flatMap((t,n)=>n===e||null!==s&&a(t,o,r)===s?[n]:[]),i=c.filter(e=>t.categories[e]?.hasAttribute("data-more"));return[...i,...c.filter(t=>!i.includes(t))].map(e=>({name:t.categories[e]?.textContent??"",value:""}))}};window.Tablechart.addType("scatter",s)}(Tablechart.kit);
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { B as e, I as t, M as n, Z as r, a as i, d as a, f as o, i as s, p as c, s as l, t as u } from "./tablechart-shared2.mjs";
|
|
2
|
+
//#region src/js/charts/scatter.ts
|
|
3
|
+
var d = [
|
|
4
|
+
"circle",
|
|
5
|
+
"triangle",
|
|
6
|
+
"square",
|
|
7
|
+
"diamond"
|
|
8
|
+
], f = [
|
|
9
|
+
"right",
|
|
10
|
+
"left",
|
|
11
|
+
"above",
|
|
12
|
+
"below",
|
|
13
|
+
"right",
|
|
14
|
+
"left",
|
|
15
|
+
"right",
|
|
16
|
+
"left"
|
|
17
|
+
], p = (e) => {
|
|
18
|
+
let t = e.flatMap((e, t) => e.group ? [] : [t]);
|
|
19
|
+
return {
|
|
20
|
+
x: t[0],
|
|
21
|
+
y: t[1],
|
|
22
|
+
size: t[2],
|
|
23
|
+
group: e.findIndex((e) => e.group)
|
|
24
|
+
};
|
|
25
|
+
}, m = (e, t) => t < 0 ? [] : [...new Set(e.map((e) => e.cells[t]?.raw ?? ""))], h = (e, t, n) => e.cells[t]?.missing || e.cells[n]?.missing ? null : `${e.cells[t]?.value} ${e.cells[n]?.value}`, g = {
|
|
26
|
+
aspect: .62,
|
|
27
|
+
categories: "beside",
|
|
28
|
+
columns: !0,
|
|
29
|
+
axes: !0,
|
|
30
|
+
text({ figure: e, plot: r, rows: i, series: o, config: s }) {
|
|
31
|
+
let { x: c, y: l, size: u, group: f } = p(o), g = r.querySelector(":scope > .tablechart-categories")?.children ?? [], _ = /* @__PURE__ */ new Map();
|
|
32
|
+
i.forEach((e, t) => {
|
|
33
|
+
let n = h(e, c, l);
|
|
34
|
+
n && (_.get(n)?.push(t) ?? _.set(n, [t]));
|
|
35
|
+
});
|
|
36
|
+
let v = (e) => u === void 0 ? 0 : Math.abs(i[e].cells[u]?.value ?? 0);
|
|
37
|
+
for (let e of _.values()) {
|
|
38
|
+
if (e.length < 2) continue;
|
|
39
|
+
let t = e.reduce((e, t) => v(t) > v(e) ? t : e);
|
|
40
|
+
for (let n of e) {
|
|
41
|
+
let r = g[n];
|
|
42
|
+
n === t ? r?.setAttribute("data-more", String(e.length - 1)) : r?.setAttribute("data-same", "");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
let y = m(i, f);
|
|
46
|
+
if (y.length < 2 && u === void 0) return;
|
|
47
|
+
let b = document.createElement("div");
|
|
48
|
+
b.className = n, b.setAttribute("aria-hidden", "true"), b.inert = !0;
|
|
49
|
+
let x = Array.from(e.querySelectorAll(`tbody tr > td:nth-of-type(${f + 1})`)), S = (e, n) => {
|
|
50
|
+
let r = a(t, b);
|
|
51
|
+
return r.dataset.place = "legend", r.dataset.line = "none", r.textContent = e, n && s.langattribute && r.setAttribute(s.langattribute, n), r;
|
|
52
|
+
};
|
|
53
|
+
y.length > 1 && y.forEach((e, t) => {
|
|
54
|
+
let n = s.langattribute ? x.find((t) => t.textContent?.trim() === e)?.getAttribute(s.langattribute) : null, r = S(e, n);
|
|
55
|
+
r.dataset.marker = d[t % d.length], r.style.setProperty("--n", String(t)), r.style.setProperty("--palette", `var(--tablechart-color-${t + 1})`);
|
|
56
|
+
}), u !== void 0 && (S(o[u].name, o[u].key).dataset.marker = "size"), e.appendChild(b);
|
|
57
|
+
},
|
|
58
|
+
draw(t) {
|
|
59
|
+
let { rows: n, series: a, x: h, y: g, frame: _, unit: v, svg: y, categories: b, seriesValues: x, height: S, config: C, plot: w } = t;
|
|
60
|
+
if (!h || !_) return;
|
|
61
|
+
let T = p(a), E = m(n, T.group), D = E.length > 1;
|
|
62
|
+
for (let e of x.flat()) e.dataset.place = "none";
|
|
63
|
+
let O = (t.length("--tablechart-marker-size", "10px") ?? 10 * v) / 2, k = (t.length("--tablechart-bubble-max", "24px") ?? 24 * v) / 2, A = (e) => T.size === void 0 ? void 0 : e.cells[T.size], j = l(n.map((e) => Math.abs(A(e)?.value ?? 0))), M = n.flatMap((e, t) => {
|
|
64
|
+
let n = e.cells[T.x], r = e.cells[T.y];
|
|
65
|
+
if (!n || !r || n.missing || r.missing) return [];
|
|
66
|
+
let i = A(e), a = i && !i.missing && j > 0 ? Math.max(O * .6, Math.sqrt(Math.abs(i.value) / j) * k) : O, o = D ? E.indexOf(e.cells[T.group]?.raw ?? "") : -1;
|
|
67
|
+
return [{
|
|
68
|
+
i: t,
|
|
69
|
+
px: h(n.value),
|
|
70
|
+
py: g(r.value),
|
|
71
|
+
r: a,
|
|
72
|
+
g: o
|
|
73
|
+
}];
|
|
74
|
+
}), N = Math.min(M.length - 1, 6);
|
|
75
|
+
w.style.setProperty("--count", String(N + 1));
|
|
76
|
+
let P = new Map([...M].sort((e, t) => e.px - t.px || e.i - t.i).map((e, t) => [e.i, N ? c(t * N / (M.length - 1)) : 0])), F = [...M].sort((e, t) => t.r - e.r || e.i - t.i);
|
|
77
|
+
for (let t of F) {
|
|
78
|
+
let n = D ? d[t.g % d.length] : "circle";
|
|
79
|
+
y.appendChild(u(n, t.px, t.py, t.r, {
|
|
80
|
+
class: e,
|
|
81
|
+
"data-row": t.i + 1,
|
|
82
|
+
"data-marker": n,
|
|
83
|
+
style: `--i:${P.get(t.i)}; ${D ? `--n:${t.g}; --palette:var(--tablechart-color-${t.g + 1})` : ""}`
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
let I = w.parentElement?.getAttribute("data-chart-names"), L = I == null ? C.names : I !== "false", R = 4 * v, z = [
|
|
87
|
+
_[0] + 1.5 * R,
|
|
88
|
+
_[1],
|
|
89
|
+
_[2] - 1.5 * R,
|
|
90
|
+
_[3] - 1.5 * R
|
|
91
|
+
], [B, V, H, U] = z, W = F.map(({ i: e, px: t, py: n, r }) => {
|
|
92
|
+
if (b[e].hasAttribute("data-same")) return [];
|
|
93
|
+
let { width: i, height: a } = s(b[e]), o = i * v, c = a * v, l = c * .1, u = r * .7 + R / 2, d = (e, t) => [
|
|
94
|
+
Math.max(B, Math.min(e, B + H - o)),
|
|
95
|
+
Math.max(V, Math.min(t, V + U - c)) + l,
|
|
96
|
+
o,
|
|
97
|
+
c - 2 * l
|
|
98
|
+
];
|
|
99
|
+
return [
|
|
100
|
+
d(t + r + R, n - c / 2),
|
|
101
|
+
d(t - r - R - o, n - c / 2),
|
|
102
|
+
d(t - o / 2, n - r - R - c),
|
|
103
|
+
d(t - o / 2, n + r + R),
|
|
104
|
+
d(t + u, n - u - c),
|
|
105
|
+
d(t - u - o, n - u - c),
|
|
106
|
+
d(t + u, n + u),
|
|
107
|
+
d(t - u - o, n + u)
|
|
108
|
+
];
|
|
109
|
+
}), G = L ? i(W, M.map(({ px: e, py: t, r: n }) => [
|
|
110
|
+
e - n,
|
|
111
|
+
t - n,
|
|
112
|
+
2 * n,
|
|
113
|
+
2 * n
|
|
114
|
+
]), z) : F.map(() => null);
|
|
115
|
+
for (let e of b) e.hidden = !0, e.dataset.missing = "";
|
|
116
|
+
F.forEach((e, t) => {
|
|
117
|
+
let n = b[e.i], i = G[t];
|
|
118
|
+
if (n.hidden = !1, delete n.dataset.missing, n.style.setProperty("--i", String(P.get(e.i))), n.toggleAttribute("data-left-out", i === null), i === null) return;
|
|
119
|
+
n.dataset.side = f[i];
|
|
120
|
+
let [a, c, , l] = W[t][i];
|
|
121
|
+
o(n, a, c - (s(n).height * v - l) / 2, r, S);
|
|
122
|
+
}), t.rowAt = (e, t) => {
|
|
123
|
+
let n = null, r = 6 * v;
|
|
124
|
+
for (let i of M) {
|
|
125
|
+
let a = Math.max(Math.hypot(i.px - e * v, i.py - t * v) - i.r, 0);
|
|
126
|
+
(a < r || a === r && n && i.r < n.r) && (r = a, n = i);
|
|
127
|
+
}
|
|
128
|
+
return n ? n.i : null;
|
|
129
|
+
};
|
|
130
|
+
},
|
|
131
|
+
tooltip(e, t) {
|
|
132
|
+
let { x: n, y: r } = p(e.series), i = h(e.rows[t], n, r), a = e.rows.flatMap((e, a) => a === t || i !== null && h(e, n, r) === i ? [a] : []), o = a.filter((t) => e.categories[t]?.hasAttribute("data-more"));
|
|
133
|
+
return [...o, ...a.filter((e) => !o.includes(e))].map((t) => ({
|
|
134
|
+
name: e.categories[t]?.textContent ?? "",
|
|
135
|
+
value: ""
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
//#endregion
|
|
140
|
+
export { g as scatter };
|
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/** Pass 2: everything a reader will read, before a translation script looks. */
|
|
4
|
-
export declare const build: (figure: HTMLElement, config: Config, asKind?: string | null) => ChartState | null;
|
|
5
|
-
/** Pass 3. Needs layout; makes no text, only places it. */
|
|
6
|
-
export declare const layout: (state: ChartState, config: Config) => boolean;
|
|
7
|
-
/** Numbers are reformatted in place, so a language change costs no redraw. */
|
|
8
|
-
export declare const relabel: (state: ChartState, config: Config) => void;
|
|
9
|
-
/** Removes what `build` added, so the chart can be built again. */
|
|
10
|
-
export declare const unbuild: (state: ChartState) => void;
|
|
11
|
-
/** One class, `is-shown`, starts the whole build. */
|
|
12
|
-
export declare const setShown: (state: ChartState, shown: boolean) => void;
|
|
13
|
-
//#endregion
|
|
1
|
+
import { a as StepPlan, c as PLACED_CLASS, d as QUEUED_CLASS, f as SHOWN_CLASS, i as Series, l as PLOT_CLASS, n as ChartType, o as stepTo, p as defaultConfig, r as Row, s as Config, t as ChartState, u as PRINTING_CLASS } from "./tablechart-shared.mjs";
|
|
2
|
+
import { c as build, d as setShown, f as unbuild, i as entranceOf, l as layout, o as prepare, s as addType, u as relabel } from "./tablechart-shared2.mjs";
|
|
14
3
|
//#region src/js/functions/sources.d.ts
|
|
15
4
|
/** A Markdown table, or a caption with chart attributes, is wrapped in a figure with the caption and annotations beside it. */
|
|
16
5
|
export declare const adoptTables: (figures: HTMLElement[]) => HTMLElement[];
|
|
@@ -23,4 +12,4 @@ export declare const readMarkdownRows: (figures: HTMLElement[]) => void;
|
|
|
23
12
|
/** Writes translation keys such as `harvest-row1` onto a figure with `data-chart-keys`; a duplicate prefix gets a number. */
|
|
24
13
|
export declare const assignKeys: (figures: HTMLElement[], langattribute: string | false) => void;
|
|
25
14
|
//#endregion
|
|
26
|
-
export { type ChartState, type Config, PLACED_CLASS, PLOT_CLASS, PRINTING_CLASS, QUEUED_CLASS, type Row, SHOWN_CLASS, type Series, type StepPlan, defaultConfig, entranceOf, prepare, stepTo };
|
|
15
|
+
export { type ChartState, type ChartType, type Config, PLACED_CLASS, PLOT_CLASS, PRINTING_CLASS, QUEUED_CLASS, type Row, SHOWN_CLASS, type Series, type StepPlan, addType, build, defaultConfig, entranceOf, layout, prepare, relabel, setShown, stepTo, unbuild };
|
package/dist/tablechart-core.mjs
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
import { a as e, c as t, d as n, f as r, h as i, i as a, l as o, m as s, n as c, o as l, p as u, s as d, u as f } from "./tablechart-shared.mjs";
|
|
2
|
+
import { H as p, K as m, Q as h, R as g, V as _, z as v } from "./tablechart-shared2.mjs";
|
|
3
|
+
export { g as PLACED_CLASS, v as PLOT_CLASS, _ as PRINTING_CLASS, p as QUEUED_CLASS, m as SHOWN_CLASS, t as addType, e as adoptTables, i as assignKeys, o as build, h as defaultConfig, c as entranceOf, f as layout, l as loadSources, a as prepare, d as readMarkdownRows, n as relabel, r as setShown, s as stepTo, u as unbuild };
|
|
@@ -1,3 +1,63 @@
|
|
|
1
|
+
//#region src/js/config.d.ts
|
|
2
|
+
declare const PLOT_CLASS = "tablechart-plot";
|
|
3
|
+
declare const PLACED_CLASS = "is-placed";
|
|
4
|
+
declare const SHOWN_CLASS = "is-shown";
|
|
5
|
+
declare const PRINTING_CLASS = "is-printing";
|
|
6
|
+
declare const QUEUED_CLASS = "tablechart-queued";
|
|
7
|
+
interface Config {
|
|
8
|
+
/** Which elements Tablechart turns into charts. */
|
|
9
|
+
selector: string;
|
|
10
|
+
/** Height of the plot as a share of its width. */
|
|
11
|
+
aspect: number;
|
|
12
|
+
/** Share of a band that a bar fills. */
|
|
13
|
+
barfill: number;
|
|
14
|
+
/** Share of a donut's radius that the ring itself takes. */
|
|
15
|
+
ringfill: number;
|
|
16
|
+
/** Locale for numbers. Unset, the document's language is used and followed when it changes. */
|
|
17
|
+
locale?: string;
|
|
18
|
+
/** Animate a chart when it builds. `"grow"` grows each element from zero, `"sweep"` reveals the chart in one movement; a figure overrides it with `data-chart-animate`, also with `"false"`. */
|
|
19
|
+
animate: boolean | Motion;
|
|
20
|
+
/** How far an animated parent is in before its chart builds: 0 when it starts moving, 1 when it is in. A figure overrides it with `data-chart-entrance`. */
|
|
21
|
+
entrance: number;
|
|
22
|
+
/** Where a column's number goes: on the bar, or inside it. A figure overrides it with `data-chart-labels`. */
|
|
23
|
+
labels: "outside" | "inside";
|
|
24
|
+
/** How a line or area runs between points: `straight`, `step` or `smooth`. A figure overrides it with `data-chart-shape`. */
|
|
25
|
+
shape: "straight" | "step" | "smooth";
|
|
26
|
+
/** Names of several lines in a legend instead of at the end of each line. A figure overrides it with `data-chart-legend`. */
|
|
27
|
+
legend: boolean;
|
|
28
|
+
/** Numbers along the value axis of a column, bar, line, area or waterfall chart. A figure overrides it with `data-chart-axis`. */
|
|
29
|
+
axis: boolean;
|
|
30
|
+
/** Gridlines across the plot at each number of the axis. A figure overrides it with `data-chart-grid`. */
|
|
31
|
+
grid: boolean;
|
|
32
|
+
/** The name of each marker beside it, on a scatter chart. A figure overrides it with `data-chart-names`. */
|
|
33
|
+
names: boolean;
|
|
34
|
+
/** A tooltip with the values of a row that is pointed at or tapped: `"auto"`, the default, only on a chart that does not show all its numbers; `true` always; `false` never. A figure overrides it with `data-chart-tooltip`. */
|
|
35
|
+
tooltip: boolean | "auto";
|
|
36
|
+
/** Where the tooltip goes in the page: an element or a selector, `body` by default. In a scaled element, such as the slides of a presentation, the tooltip has their scale. */
|
|
37
|
+
tooltipparent: HTMLElement | string | null;
|
|
38
|
+
/** 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
|
+
table: "never" | "auto" | "print" | "always";
|
|
40
|
+
/** The name of the total that a donut without a total row works out, for screen readers. */
|
|
41
|
+
totallabel: string;
|
|
42
|
+
/** Previous and Next buttons under a chart that steps (`data-fragment`). `false` leaves them out, for buttons of your own. */
|
|
43
|
+
controls: boolean;
|
|
44
|
+
/** The text of the Previous button. */
|
|
45
|
+
previouslabel: string;
|
|
46
|
+
/** The text of the Next button. */
|
|
47
|
+
nextlabel: string;
|
|
48
|
+
/** Read by screen readers after the text of each button, so they know it only changes the chart. */
|
|
49
|
+
stephint: string;
|
|
50
|
+
/** How much of a chart must be in view before it builds, from 0 to 1. */
|
|
51
|
+
threshold: number;
|
|
52
|
+
/** Build again each time a chart scrolls back into view, not only the first time. */
|
|
53
|
+
replay: boolean;
|
|
54
|
+
/** The attribute for translation keys, for a translation script. `false` turns keys off. */
|
|
55
|
+
langattribute: string | false;
|
|
56
|
+
/** Show messages in the console for whoever is working on the page. */
|
|
57
|
+
debug?: boolean;
|
|
58
|
+
}
|
|
59
|
+
declare const defaultConfig: Config;
|
|
60
|
+
//#endregion
|
|
1
61
|
//#region src/js/functions/scale.d.ts
|
|
2
62
|
/** A break in the scale: values from `lo` to `hi` get `share` of the length, and the cut is at `gap`. */
|
|
3
63
|
interface Squeeze {
|
|
@@ -70,6 +130,8 @@ interface Series {
|
|
|
70
130
|
/** `data-marker` on the header, such as `square` or `diamond open`. */
|
|
71
131
|
marker: string | null;
|
|
72
132
|
line: "dashed" | "dotted" | null;
|
|
133
|
+
/** `data-group` on the header: the cells name a group, such as "Predefined". */
|
|
134
|
+
group: boolean;
|
|
73
135
|
}
|
|
74
136
|
interface Segment extends Row {
|
|
75
137
|
from: number;
|
|
@@ -82,6 +144,14 @@ interface Geometry {
|
|
|
82
144
|
segments: Segment[];
|
|
83
145
|
cx: (index: number) => number;
|
|
84
146
|
y: (value: number) => number;
|
|
147
|
+
/** Across: on a chart with two axes, and the value scale of a bar chart, set by its drawing. */
|
|
148
|
+
x?: (value: number) => number;
|
|
149
|
+
/** The plot inside the axes, on a chart with axes. */
|
|
150
|
+
frame?: [number, number, number, number];
|
|
151
|
+
/** A chart that knows better which row is pointed at sets this, in screen pixels from the plot's corner. */
|
|
152
|
+
rowAt?: (x: number, y: number) => number | null;
|
|
153
|
+
/** A CSS length set on the figure, such as `--tablechart-marker-size`, in viewBox units. */
|
|
154
|
+
length: (name: string, fallback: string) => number | null;
|
|
85
155
|
barWidth: number;
|
|
86
156
|
barMax: number;
|
|
87
157
|
height: number;
|
|
@@ -99,6 +169,8 @@ interface Geometry {
|
|
|
99
169
|
squeeze: Squeeze | null;
|
|
100
170
|
/** The empty space where the scale jumps, in viewBox units. */
|
|
101
171
|
breakGap: number;
|
|
172
|
+
/** The range of the value axis, on a chart with an axis or gridlines; a chart that makes its own scale reaches it. */
|
|
173
|
+
domain: [number, number] | null;
|
|
102
174
|
/** Where a bar chart is cut across, in viewBox units; set by its drawing. */
|
|
103
175
|
breakX?: number;
|
|
104
176
|
labels: "outside" | "inside";
|
|
@@ -122,6 +194,8 @@ interface Geometry {
|
|
|
122
194
|
config: Config;
|
|
123
195
|
/** Numbers an annotation worked out, against the ones the author wrote. */
|
|
124
196
|
checks: Check[];
|
|
197
|
+
/** The labels of annotations placed so far, as left, top, width and height, so the next one finds room. */
|
|
198
|
+
taken: [number, number, number, number][];
|
|
125
199
|
}
|
|
126
200
|
interface Check {
|
|
127
201
|
label: string;
|
|
@@ -143,6 +217,18 @@ interface ChartType {
|
|
|
143
217
|
swatch?: "box";
|
|
144
218
|
categories?: "under" | "beside";
|
|
145
219
|
series?: boolean;
|
|
220
|
+
/** The value columns are the fields of one mark, such as x and y, rather than series: no names for them. */
|
|
221
|
+
columns?: boolean;
|
|
222
|
+
/** An axis across and an axis up, from the first two value columns, with their headers as titles. */
|
|
223
|
+
axes?: boolean;
|
|
224
|
+
/** Text of its own, made with the rest of the text so a translation script finds it, such as a legend. */
|
|
225
|
+
text?: (input: {
|
|
226
|
+
figure: HTMLElement;
|
|
227
|
+
plot: HTMLElement;
|
|
228
|
+
rows: Row[];
|
|
229
|
+
series: Series[];
|
|
230
|
+
config: Config;
|
|
231
|
+
}) => void;
|
|
146
232
|
/** With several series, always a legend, with a sample of this shape. */
|
|
147
233
|
legend?: "box";
|
|
148
234
|
headroom?: (geo: HeadroomInput) => number;
|
|
@@ -204,6 +290,12 @@ interface ChartState {
|
|
|
204
290
|
names: HTMLElement[];
|
|
205
291
|
categories: HTMLElement[];
|
|
206
292
|
centre: HTMLElement | null;
|
|
293
|
+
/** The axis titles and the place for the numbers along the axes. Without `numbers`, only for gridlines. */
|
|
294
|
+
axes: {
|
|
295
|
+
titles: HTMLElement[];
|
|
296
|
+
ticks: HTMLElement;
|
|
297
|
+
numbers: boolean;
|
|
298
|
+
} | null;
|
|
207
299
|
stacked: boolean;
|
|
208
300
|
totals: HTMLElement[];
|
|
209
301
|
totalCell: HTMLElement | null;
|
|
@@ -228,97 +320,4 @@ interface ChartState {
|
|
|
228
320
|
checks: Check[];
|
|
229
321
|
}
|
|
230
322
|
//#endregion
|
|
231
|
-
|
|
232
|
-
declare const PLOT_CLASS = "tablechart-plot";
|
|
233
|
-
declare const PLACED_CLASS = "is-placed";
|
|
234
|
-
declare const SHOWN_CLASS = "is-shown";
|
|
235
|
-
declare const PRINTING_CLASS = "is-printing";
|
|
236
|
-
declare const QUEUED_CLASS = "tablechart-queued";
|
|
237
|
-
interface Config {
|
|
238
|
-
/** Which elements Tablechart turns into charts. */
|
|
239
|
-
selector: string;
|
|
240
|
-
/** Height of the plot as a share of its width. */
|
|
241
|
-
aspect: number;
|
|
242
|
-
/** Share of a band that a bar fills. */
|
|
243
|
-
barfill: number;
|
|
244
|
-
/** Share of a donut's radius that the ring itself takes. */
|
|
245
|
-
ringfill: number;
|
|
246
|
-
/** Locale for numbers. Unset, the document's language is used and followed when it changes. */
|
|
247
|
-
locale?: string;
|
|
248
|
-
/** Animate a chart when it builds. `"grow"` grows each element from zero, `"sweep"` reveals the chart in one movement; a figure overrides it with `data-chart-animate`. `"up"` and `"across"` are their old names. */
|
|
249
|
-
animate: boolean | Motion | "across" | "up";
|
|
250
|
-
/** How far an animated parent is in before its chart builds: 0 when it starts moving, 1 when it is in. A figure overrides it with `data-chart-entrance`. */
|
|
251
|
-
entrance: number;
|
|
252
|
-
/** Where a column's number goes: on the bar, or inside it. A figure overrides it with `data-chart-labels`. */
|
|
253
|
-
labels: "outside" | "inside";
|
|
254
|
-
/** How a line or area runs between points: `straight`, `step` or `smooth`. A figure overrides it with `data-chart-shape`. */
|
|
255
|
-
shape: "straight" | "step" | "smooth";
|
|
256
|
-
/** Names of several lines in a legend instead of at the end of each line. A figure overrides it with `data-chart-legend`. */
|
|
257
|
-
legend: boolean;
|
|
258
|
-
/** A tooltip with the values of a row that is pointed at or tapped: `"auto"`, the default, only on a chart that does not show all its numbers; `true` always; `false` never. A figure overrides it with `data-chart-tooltip`. */
|
|
259
|
-
tooltip: boolean | "auto";
|
|
260
|
-
/** The old name of `tooltip`, until the next minor version. */
|
|
261
|
-
hover?: boolean;
|
|
262
|
-
/** 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`. */
|
|
263
|
-
table: "never" | "auto" | "print" | "always";
|
|
264
|
-
/** The name of the total that a donut without a total row works out, for screen readers. */
|
|
265
|
-
totallabel: string;
|
|
266
|
-
/** Previous and Next buttons under a chart that steps (`data-fragment`). `false` leaves them out, for buttons of your own. */
|
|
267
|
-
controls: boolean;
|
|
268
|
-
/** The text of the Previous button. */
|
|
269
|
-
previouslabel: string;
|
|
270
|
-
/** The text of the Next button. */
|
|
271
|
-
nextlabel: string;
|
|
272
|
-
/** Read by screen readers after the text of each button, so they know it only changes the chart. */
|
|
273
|
-
stephint: string;
|
|
274
|
-
/** How much of a chart must be in view before it builds, from 0 to 1. */
|
|
275
|
-
threshold: number;
|
|
276
|
-
/** Build again each time a chart scrolls back into view, not only the first time. */
|
|
277
|
-
replay: boolean;
|
|
278
|
-
/** The attribute for translation keys, for a translation script. `false` turns keys off. */
|
|
279
|
-
langattribute: string | false;
|
|
280
|
-
/** Show messages in the console for whoever is working on the page. */
|
|
281
|
-
debug?: boolean;
|
|
282
|
-
}
|
|
283
|
-
declare const defaultConfig: Config;
|
|
284
|
-
//#endregion
|
|
285
|
-
//#region src/js/init.d.ts
|
|
286
|
-
interface TablechartChart {
|
|
287
|
-
figure: HTMLElement;
|
|
288
|
-
/** Lays the chart out again, for example after a script has changed its text. */
|
|
289
|
-
refresh(): void;
|
|
290
|
-
/** Stops watching scroll, size and language. The chart stays as it is. */
|
|
291
|
-
destroy(): void;
|
|
292
|
-
/** On a chart that steps (`data-fragment`): shows one step more. */
|
|
293
|
-
next(): void;
|
|
294
|
-
/** On a chart that steps: shows one step less. */
|
|
295
|
-
previous(): void;
|
|
296
|
-
/** On a chart that steps: shows the chart up to `step`, from 0 to `steps`. */
|
|
297
|
-
stepTo(step: number): void;
|
|
298
|
-
/** How many steps are shown. */
|
|
299
|
-
readonly step: number;
|
|
300
|
-
/** How many steps the chart has; 0 for a chart that does not step. */
|
|
301
|
-
readonly steps: number;
|
|
302
|
-
}
|
|
303
|
-
interface TablechartInstance {
|
|
304
|
-
charts: TablechartChart[];
|
|
305
|
-
/** Lays out every chart again, for example after a script has changed its text. */
|
|
306
|
-
refresh(): void;
|
|
307
|
-
/** Stops watching scroll, size and language. The charts stay as they are. */
|
|
308
|
-
destroy(): void;
|
|
309
|
-
}
|
|
310
|
-
declare global {
|
|
311
|
-
interface HTMLElement {
|
|
312
|
-
tablechart?: TablechartChart;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
/** How far an animated parent is in before the chart builds: the figure's `data-chart-entrance`, or else the option. */
|
|
316
|
-
declare const entranceOf: (figure: HTMLElement, config: Config) => number;
|
|
317
|
-
/** Turns elements into figures with a table and translation keys, all at once, so duplicate keys are found. */
|
|
318
|
-
declare const prepare: (found: HTMLElement[], config: Config) => Promise<HTMLElement[]>;
|
|
319
|
-
/** Makes a chart of one figure; returns the existing chart if there is one, or null without data. */
|
|
320
|
-
declare const create: (element: HTMLElement, options?: Partial<Config>) => Promise<TablechartChart | null>;
|
|
321
|
-
/** Makes a chart of every figure in `root` that matches the selector, skipping existing charts. */
|
|
322
|
-
declare const init: (options?: Partial<Config>, root?: ParentNode) => Promise<TablechartInstance>;
|
|
323
|
-
//#endregion
|
|
324
|
-
export { StepPlan as _, init as a, PLACED_CLASS as c, QUEUED_CLASS as d, SHOWN_CLASS as f, Series as g, Row as h, entranceOf as i, PLOT_CLASS as l, ChartState as m, TablechartInstance as n, prepare as o, defaultConfig as p, create as r, Config as s, TablechartChart as t, PRINTING_CLASS as u, stepTo as v };
|
|
323
|
+
export { StepPlan as a, PLACED_CLASS as c, QUEUED_CLASS as d, SHOWN_CLASS as f, Series as i, PLOT_CLASS as l, ChartType as n, stepTo as o, defaultConfig as p, Row as r, Config as s, ChartState as t, PRINTING_CLASS as u };
|