@martinomagnifico/tablechart 1.1.0 → 1.1.1

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 CHANGED
@@ -1,24 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.1.1] - 2026-10-23
4
+
5
+ ### Changed
6
+
7
+ - Columns and bars now grow in 0.8s with an ease-in-out, and overlap more to avoid stutter.
8
+ - Numbers now fade in as one group to avoid Safari issues.
9
+ - Gaps in lines and gridlines now switch on instead of fading.
10
+ - The mask under an annotation label is now set when the chart has built, not during the build.
11
+
12
+ ### Fixed
13
+
14
+ - A value of zero no longer shows a sliver of a column or bar under the axis.
15
+
16
+
17
+
3
18
  ## [1.1.0] - 2026-10-23
4
19
 
5
20
  ### Added
6
21
 
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.
22
+ - Scatter and bubble charts: `data-chart="scatter"`. The first additional type, in `@martinomagnifico/tablechart/additional-types` or `tablechart-additional-types.js`. It is in a script of its own, so a page without a scatter chart does not load it.
23
+ - `addType()`, to add an additional type.
24
+ - A value axis with `data-chart-axis`, and gridlines with `data-chart-grid`. Off by default, because the numbers on the bars already show the values. A scatter chart always has its axes.
25
+ - `data-chart-scale` for a scale of your own, such as 0 to 100%. On a scatter chart also `-x` and `-y`.
26
+ - Reference lines: `data-annotation="reference"`, at a value, the mean or the median. For a target, or the mean and median of a histogram.
27
+ - `data-chart-animate="false"`, for a chart that should just be there, without waiting to scroll into view.
28
+ - `--tablechart-axis-text-color` and `--tablechart-name-color`, so the numbers on an axis can be lighter or darker than the names.
13
29
 
14
30
  ### Changed
15
31
 
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.
32
+ - A line chart with three lines or more now shows its numbers where there is room, above or below the point. Before, they were all left out, so you only saw them in the tooltip.
17
33
 
18
34
  ### Removed
19
35
 
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`.
36
+ - The old CSS variable names from 1.0.4, and `up` and `across` for `animate`. Deprecated since 1.0.4.
37
+ - `hover` and `data-chart-hover`. Use `tooltip` and `data-chart-tooltip`. Deprecated since 1.0.5, when tooltips replaced the numbers that appeared on hover.
22
38
 
23
39
 
24
40
 
@@ -1,5 +1,2 @@
1
- import { n as ChartType } from "./tablechart-shared.mjs";
2
- //#region src/js/charts/scatter.d.ts
3
- /** One marker per row, across by its first value and up by its second; a third value makes it a bubble. */
4
- export declare const scatter: ChartType;
5
- //#endregion
1
+ import { _ as scatter } from "./tablechart-shared.mjs";
2
+ export { scatter };
@@ -1,4 +1,4 @@
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";
1
+ import { C as e, D as t, S as n, _ as r, b as i, g as a, j as o, v as s, w as c, x as l, y as u } from "./tablechart-shared.mjs";
2
2
  //#region src/js/charts/scatter.ts
3
3
  var d = [
4
4
  "circle",
@@ -27,13 +27,13 @@ var d = [
27
27
  categories: "beside",
28
28
  columns: !0,
29
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);
30
+ text({ figure: t, plot: n, rows: r, series: a, config: o }) {
31
+ let { x: s, y: l, size: u, group: f } = p(a), g = n.querySelector(":scope > .tablechart-categories")?.children ?? [], _ = /* @__PURE__ */ new Map();
32
+ r.forEach((e, t) => {
33
+ let n = h(e, s, l);
34
34
  n && (_.get(n)?.push(t) ?? _.set(n, [t]));
35
35
  });
36
- let v = (e) => u === void 0 ? 0 : Math.abs(i[e].cells[u]?.value ?? 0);
36
+ let v = (e) => u === void 0 ? 0 : Math.abs(r[e].cells[u]?.value ?? 0);
37
37
  for (let e of _.values()) {
38
38
  if (e.length < 2) continue;
39
39
  let t = e.reduce((e, t) => v(t) > v(e) ? t : e);
@@ -42,25 +42,25 @@ var d = [
42
42
  n === t ? r?.setAttribute("data-more", String(e.length - 1)) : r?.setAttribute("data-same", "");
43
43
  }
44
44
  }
45
- let y = m(i, f);
45
+ let y = m(r, f);
46
46
  if (y.length < 2 && u === void 0) return;
47
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;
48
+ b.className = e, b.setAttribute("aria-hidden", "true"), b.inert = !0;
49
+ let x = Array.from(t.querySelectorAll(`tbody tr > td:nth-of-type(${f + 1})`)), S = (e, t) => {
50
+ let n = i(c, b);
51
+ return n.dataset.place = "legend", n.dataset.line = "none", n.textContent = e, t && o.langattribute && n.setAttribute(o.langattribute, t), n;
52
52
  };
53
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);
54
+ let n = o.langattribute ? x.find((t) => t.textContent?.trim() === e)?.getAttribute(o.langattribute) : null, r = S(e, n);
55
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);
56
+ }), u !== void 0 && (S(a[u].name, a[u].key).dataset.marker = "size"), t.appendChild(b);
57
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;
58
+ draw(e) {
59
+ let { rows: i, series: c, x: h, y: g, frame: _, unit: v, svg: y, categories: b, seriesValues: x, height: S, config: C, plot: w } = e;
60
60
  if (!h || !_) return;
61
- let T = p(a), E = m(n, T.group), D = E.length > 1;
61
+ let T = p(c), E = m(i, T.group), D = E.length > 1;
62
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) => {
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
64
  let n = e.cells[T.x], r = e.cells[T.y];
65
65
  if (!n || !r || n.missing || r.missing) return [];
66
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;
@@ -73,14 +73,14 @@ var d = [
73
73
  }];
74
74
  }), N = Math.min(M.length - 1, 6);
75
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,
76
+ let P = new Map([...M].sort((e, t) => e.px - t.px || e.i - t.i).map((e, t) => [e.i, N ? n(t * N / (M.length - 1)) : 0])), F = [...M].sort((e, t) => t.r - e.r || e.i - t.i);
77
+ for (let e of F) {
78
+ let n = D ? d[e.g % d.length] : "circle";
79
+ y.appendChild(a(n, e.px, e.py, e.r, {
80
+ class: t,
81
+ "data-row": e.i + 1,
82
82
  "data-marker": n,
83
- style: `--i:${P.get(t.i)}; ${D ? `--n:${t.g}; --palette:var(--tablechart-color-${t.g + 1})` : ""}`
83
+ style: `--i:${P.get(e.i)}; ${D ? `--n:${e.g}; --palette:var(--tablechart-color-${e.g + 1})` : ""}`
84
84
  }));
85
85
  }
86
86
  let I = w.parentElement?.getAttribute("data-chart-names"), L = I == null ? C.names : I !== "false", R = 4 * v, z = [
@@ -88,25 +88,25 @@ var d = [
88
88
  _[1],
89
89
  _[2] - 1.5 * R,
90
90
  _[3] - 1.5 * R
91
- ], [B, V, H, U] = z, W = F.map(({ i: e, px: t, py: n, r }) => {
91
+ ], [B, V, H, U] = z, W = F.map(({ i: e, px: t, py: n, r: i }) => {
92
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)),
93
+ let { width: a, height: o } = r(b[e]), s = a * v, c = o * v, l = c * .1, u = i * .7 + R / 2, d = (e, t) => [
94
+ Math.max(B, Math.min(e, B + H - s)),
95
95
  Math.max(V, Math.min(t, V + U - c)) + l,
96
- o,
96
+ s,
97
97
  c - 2 * l
98
98
  ];
99
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),
100
+ d(t + i + R, n - c / 2),
101
+ d(t - i - R - s, n - c / 2),
102
+ d(t - s / 2, n - i - R - c),
103
+ d(t - s / 2, n + i + R),
104
104
  d(t + u, n - u - c),
105
- d(t - u - o, n - u - c),
105
+ d(t - u - s, n - u - c),
106
106
  d(t + u, n + u),
107
- d(t - u - o, n + u)
107
+ d(t - u - s, n + u)
108
108
  ];
109
- }), G = L ? i(W, M.map(({ px: e, py: t, r: n }) => [
109
+ }), G = L ? s(W, M.map(({ px: e, py: t, r: n }) => [
110
110
  e - n,
111
111
  t - n,
112
112
  2 * n,
@@ -117,9 +117,9 @@ var d = [
117
117
  let n = b[e.i], i = G[t];
118
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
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) => {
120
+ let [a, s, , c] = W[t][i];
121
+ l(n, a, s - (r(n).height * v - c) / 2, o, S);
122
+ }), e.rowAt = (e, t) => {
123
123
  let n = null, r = 6 * v;
124
124
  for (let i of M) {
125
125
  let a = Math.max(Math.hypot(i.px - e * v, i.py - t * v) - i.r, 0);
@@ -1,15 +1,2 @@
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";
3
- //#region src/js/functions/sources.d.ts
4
- /** A Markdown table, or a caption with chart attributes, is wrapped in a figure with the caption and annotations beside it. */
5
- export declare const adoptTables: (figures: HTMLElement[]) => HTMLElement[];
6
- /** `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. */
7
- export declare const loadSources: (figures: HTMLElement[]) => Promise<void>;
8
- /** In a Markdown table, a bold label makes the row a total, and a bold header puts that series in focus. */
9
- export declare const readMarkdownRows: (figures: HTMLElement[]) => void;
10
- //#endregion
11
- //#region src/js/functions/read-table.d.ts
12
- /** Writes translation keys such as `harvest-row1` onto a figure with `data-chart-keys`; a duplicate prefix gets a number. */
13
- export declare const assignKeys: (figures: HTMLElement[], langattribute: string | false) => void;
14
- //#endregion
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 };
1
+ import { A as defaultConfig, C as stepTo, D as PRINTING_CLASS, E as PLOT_CLASS, O as QUEUED_CLASS, S as StepPlan, T as PLACED_CLASS, b as Row, c as entranceOf, d as addType, f as build, g as unbuild, h as setShown, i as readMarkdownRows, k as SHOWN_CLASS, m as relabel, n as adoptTables, p as layout, r as loadSources, t as assignKeys, u as prepare, v as ChartState, w as Config, x as Series, y as ChartType } from "./tablechart-shared.mjs";
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,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
+ export { T as PLACED_CLASS, E as PLOT_CLASS, O as PRINTING_CLASS, k as QUEUED_CLASS, A as SHOWN_CLASS, c as addType, a as adoptTables, h as assignKeys, l as build, M 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";
@@ -320,4 +320,73 @@ interface ChartState {
320
320
  checks: Check[];
321
321
  }
322
322
  //#endregion
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 };
323
+ //#region src/js/charts/scatter.d.ts
324
+ /** One marker per row, across by its first value and up by its second; a third value makes it a bubble. */
325
+ declare const scatter: ChartType;
326
+ //#endregion
327
+ //#region src/js/core.d.ts
328
+ /** Adds a chart type for `data-chart="name"`, such as one from `@martinomagnifico/tablechart/additional-types`, before `init()`. */
329
+ declare const addType: (name: string, type: ChartType) => void;
330
+ /** Pass 2: everything a reader will read, before a translation script looks. */
331
+ declare const build: (figure: HTMLElement, config: Config, asKind?: string | null) => ChartState | null;
332
+ /** Pass 3. Needs layout; makes no text, only places it. */
333
+ declare const layout: (state: ChartState, config: Config) => boolean;
334
+ /** Numbers are reformatted in place, so a language change costs no redraw. */
335
+ declare const relabel: (state: ChartState, config: Config) => void;
336
+ /** Removes what `build` added, so the chart can be built again. */
337
+ declare const unbuild: (state: ChartState) => void;
338
+ /** One class, `is-shown`, starts the whole build. */
339
+ declare const setShown: (state: ChartState, shown: boolean) => void;
340
+ //#endregion
341
+ //#region src/js/init.d.ts
342
+ interface TablechartChart {
343
+ figure: HTMLElement;
344
+ /** Lays the chart out again, for example after a script has changed its text. */
345
+ refresh(): void;
346
+ /** Stops watching scroll, size and language. The chart stays as it is. */
347
+ destroy(): void;
348
+ /** On a chart that steps (`data-fragment`): shows one step more. */
349
+ next(): void;
350
+ /** On a chart that steps: shows one step less. */
351
+ previous(): void;
352
+ /** On a chart that steps: shows the chart up to `step`, from 0 to `steps`. */
353
+ stepTo(step: number): void;
354
+ /** How many steps are shown. */
355
+ readonly step: number;
356
+ /** How many steps the chart has; 0 for a chart that does not step. */
357
+ readonly steps: number;
358
+ }
359
+ interface TablechartInstance {
360
+ charts: TablechartChart[];
361
+ /** Lays out every chart again, for example after a script has changed its text. */
362
+ refresh(): void;
363
+ /** Stops watching scroll, size and language. The charts stay as they are. */
364
+ destroy(): void;
365
+ }
366
+ declare global {
367
+ interface HTMLElement {
368
+ tablechart?: TablechartChart;
369
+ }
370
+ }
371
+ /** How far an animated parent is in before the chart builds: the figure's `data-chart-entrance`, or else the option. */
372
+ declare const entranceOf: (figure: HTMLElement, config: Config) => number;
373
+ /** Turns elements into figures with a table and translation keys, all at once, so duplicate keys are found. */
374
+ declare const prepare: (found: HTMLElement[], config: Config) => Promise<HTMLElement[]>;
375
+ /** Makes a chart of one figure; returns the existing chart if there is one, or null without data. */
376
+ declare const create: (element: HTMLElement, options?: Partial<Config>) => Promise<TablechartChart | null>;
377
+ /** Makes a chart of every figure in `root` that matches the selector, skipping existing charts. */
378
+ declare const init: (options?: Partial<Config>, root?: ParentNode) => Promise<TablechartInstance>;
379
+ //#endregion
380
+ //#region src/js/functions/sources.d.ts
381
+ /** A Markdown table, or a caption with chart attributes, is wrapped in a figure with the caption and annotations beside it. */
382
+ declare const adoptTables: (figures: HTMLElement[]) => HTMLElement[];
383
+ /** `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
+ declare const loadSources: (figures: HTMLElement[]) => Promise<void>;
385
+ /** In a Markdown table, a bold label makes the row a total, and a bold header puts that series in focus. */
386
+ declare const readMarkdownRows: (figures: HTMLElement[]) => void;
387
+ //#endregion
388
+ //#region src/js/functions/read-table.d.ts
389
+ /** Writes translation keys such as `harvest-row1` onto a figure with `data-chart-keys`; a duplicate prefix gets a number. */
390
+ declare const assignKeys: (figures: HTMLElement[], langattribute: string | false) => void;
391
+ //#endregion
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 };