@thl-ui/charts 0.1.0 → 0.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/dist/index.d.ts CHANGED
@@ -22,6 +22,12 @@ export declare const chartColors: string[];
22
22
  export declare const colorAt: (i: number, s?: {
23
23
  color?: string;
24
24
  }) => string;
25
+ /**
26
+ * Which x-axis labels to draw so they do not overlap: every `step`-th label, starting at 0.
27
+ * Width per label is estimated from the longest label (11px axis text ≈ 6.5px per character + 8px gap).
28
+ * Data points are unaffected; only the axis text is thinned.
29
+ */
30
+ export declare function labelStep(labels: string[], plotWidth: number, charWidth?: number, gap?: number): number;
25
31
  /** "Nice" axis ticks. */
26
32
  export declare function niceTicks(min: number, max: number, count?: number): number[];
27
33
  /** Smooth path through points (monotone-ish cardinal spline). */
package/dist/index.js CHANGED
@@ -8,6 +8,19 @@ export const chartColors = [
8
8
  'var(--thl-color-inverse)',
9
9
  ];
10
10
  export const colorAt = (i, s) => s?.color ?? chartColors[i % chartColors.length];
11
+ /**
12
+ * Which x-axis labels to draw so they do not overlap: every `step`-th label, starting at 0.
13
+ * Width per label is estimated from the longest label (11px axis text ≈ 6.5px per character + 8px gap).
14
+ * Data points are unaffected; only the axis text is thinned.
15
+ */
16
+ export function labelStep(labels, plotWidth, charWidth = 6.5, gap = 8) {
17
+ if (labels.length < 2)
18
+ return 1;
19
+ const longest = Math.max(...labels.map((l) => String(l).length));
20
+ const need = longest * charWidth + gap;
21
+ const slot = plotWidth / labels.length;
22
+ return Math.max(1, Math.ceil(need / Math.max(1, slot)));
23
+ }
11
24
  /** "Nice" axis ticks. */
12
25
  export function niceTicks(min, max, count = 5) {
13
26
  if (min === max) {
@@ -41,6 +54,11 @@ export function smoothPath(pts, tension = 0.2) {
41
54
  }
42
55
  return d;
43
56
  }
57
+ /** Labels with the ones that would overlap blanked out (positions stay, so indexes still match the data). */
58
+ const thin = (labels, plotWidth) => {
59
+ const step = labelStep(labels, plotWidth);
60
+ return labels.map((l, i) => (i % step === 0 ? l : ''));
61
+ };
44
62
  const linePath = (pts) => pts.map((p, i) => `${i ? 'L' : 'M'}${p[0]},${p[1]}`).join(' ');
45
63
  /** Line / area chart. */
46
64
  export function lineChart(series, labels, box, o = {}) {
@@ -56,7 +74,7 @@ export function lineChart(series, labels, box, o = {}) {
56
74
  height: box.height,
57
75
  plot: { x: f.x0, y: f.y0, width: f.w, height: f.h },
58
76
  yTicks: ticks.map((value) => ({ value, y: Number(sy(value).toFixed(2)) })),
59
- xLabels: labels.map((label, i) => ({ label, x: Number(sx(i).toFixed(2)) })),
77
+ xLabels: thin(labels, f.w).map((label, i) => ({ label, x: Number(sx(i).toFixed(2)) })),
60
78
  series: series.map((s, si) => {
61
79
  const pts = s.data.map((v, i) => [Number(sx(i).toFixed(2)), Number(sy(v).toFixed(2))]);
62
80
  const line = o.smooth ? smoothPath(pts) : linePath(pts);
@@ -101,7 +119,7 @@ export function barChart(series, labels, box, o = {}) {
101
119
  height: box.height,
102
120
  plot: { x: f.x0, y: f.y0, width: f.w, height: f.h },
103
121
  yTicks: ticks.map((value) => ({ value, y: sy(value) })),
104
- xLabels: labels.map((label, i) => ({ label, x: f.x0 + i * band + band / 2 })),
122
+ xLabels: thin(labels, f.w).map((label, i) => ({ label, x: f.x0 + i * band + band / 2 })),
105
123
  bars: bars.map((b) => ({ ...b, x: +b.x.toFixed(2), y: +b.y.toFixed(2), width: +b.width.toFixed(2), height: +Math.max(0, b.height).toFixed(2) })),
106
124
  };
107
125
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thl-ui/charts",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "thl-ui charts: dependency-free SVG geometry for line, bar, pie and sparkline charts.",
5
5
  "keywords": [
6
6
  "thl-ui",