@thilakbhat/heatmap-ui 0.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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +471 -0
  3. package/dist/calendar.d.ts +40 -0
  4. package/dist/calendar.d.ts.map +1 -0
  5. package/dist/calendar.js +136 -0
  6. package/dist/calendar.js.map +1 -0
  7. package/dist/colors.d.ts +112 -0
  8. package/dist/colors.d.ts.map +1 -0
  9. package/dist/colors.js +186 -0
  10. package/dist/colors.js.map +1 -0
  11. package/dist/grid.d.ts +26 -0
  12. package/dist/grid.d.ts.map +1 -0
  13. package/dist/grid.js +102 -0
  14. package/dist/grid.js.map +1 -0
  15. package/dist/heatmap.d.ts +4 -0
  16. package/dist/heatmap.d.ts.map +1 -0
  17. package/dist/heatmap.js +134 -0
  18. package/dist/heatmap.js.map +1 -0
  19. package/dist/heatmap3d-patterns.d.ts +19 -0
  20. package/dist/heatmap3d-patterns.d.ts.map +1 -0
  21. package/dist/heatmap3d-patterns.js +57 -0
  22. package/dist/heatmap3d-patterns.js.map +1 -0
  23. package/dist/heatmap3d-scene.d.ts +49 -0
  24. package/dist/heatmap3d-scene.d.ts.map +1 -0
  25. package/dist/heatmap3d-scene.js +104 -0
  26. package/dist/heatmap3d-scene.js.map +1 -0
  27. package/dist/heatmap3d-visuals.d.ts +30 -0
  28. package/dist/heatmap3d-visuals.d.ts.map +1 -0
  29. package/dist/heatmap3d-visuals.js +50 -0
  30. package/dist/heatmap3d-visuals.js.map +1 -0
  31. package/dist/heatmap3d.d.ts +6 -0
  32. package/dist/heatmap3d.d.ts.map +1 -0
  33. package/dist/heatmap3d.js +268 -0
  34. package/dist/heatmap3d.js.map +1 -0
  35. package/dist/index.d.ts +11 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +11 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/projection3d.d.ts +29 -0
  40. package/dist/projection3d.d.ts.map +1 -0
  41. package/dist/projection3d.js +55 -0
  42. package/dist/projection3d.js.map +1 -0
  43. package/dist/scale.d.ts +21 -0
  44. package/dist/scale.d.ts.map +1 -0
  45. package/dist/scale.js +61 -0
  46. package/dist/scale.js.map +1 -0
  47. package/dist/shapes.d.ts +13 -0
  48. package/dist/shapes.d.ts.map +1 -0
  49. package/dist/shapes.js +63 -0
  50. package/dist/shapes.js.map +1 -0
  51. package/dist/static-svg.d.ts +45 -0
  52. package/dist/static-svg.d.ts.map +1 -0
  53. package/dist/static-svg.js +177 -0
  54. package/dist/static-svg.js.map +1 -0
  55. package/dist/types.d.ts +151 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +2 -0
  58. package/dist/types.js.map +1 -0
  59. package/docs/cover.png +0 -0
  60. package/docs/playground-2d.png +0 -0
  61. package/docs/playground-3d.png +0 -0
  62. package/package.json +61 -0
  63. package/src/styles.css +385 -0
@@ -0,0 +1,112 @@
1
+ import type { Heatmap3DFace, Heatmap3DThemeName } from "./types.js";
2
+ /**
3
+ * Ramp derivation.
4
+ *
5
+ * Passing an explicit `colors` array is always an option, but most callers
6
+ * have one brand colour and want a ladder from it. Deriving the ramp keeps
7
+ * the palest band tied to the surface behind it, which is why `ground`
8
+ * matters: fading toward white on a dark card washes the low end out.
9
+ */
10
+ export type RampOptions = {
11
+ levels?: number;
12
+ /** The surface the cells sit on. Pale bands fade toward this. */
13
+ ground?: string;
14
+ /** What the darkest band leans into. Defaults to black on light grounds. */
15
+ peak?: string;
16
+ };
17
+ type Rgb = {
18
+ r: number;
19
+ g: number;
20
+ b: number;
21
+ };
22
+ export type Heatmap3DThemePreset = {
23
+ colors: readonly string[];
24
+ emptyColor: string;
25
+ floor: string;
26
+ floorEdge: string;
27
+ grid: string;
28
+ ink: string;
29
+ window: string;
30
+ };
31
+ /**
32
+ * Small, concrete presets keep the 3D component usable without a token
33
+ * system. The colour ramps stay in hex because that is the public notation of
34
+ * this package and can be copied straight into a static SVG.
35
+ *
36
+ * `color` is the neutral default. It carries no opinion past a starting ramp,
37
+ * so whatever `colors` you pass is what you see. The other three decide
38
+ * colour for you, `seasonal` and `rainbow` per column, which is the reason to
39
+ * reach for them; leave `colors` unset when you do.
40
+ */
41
+ export declare const HEATMAP_3D_THEMES: {
42
+ readonly color: {
43
+ readonly colors: readonly ["#9be9a8", "#40c463", "#30a14e", "#216e39"];
44
+ readonly emptyColor: "#e5e9e7";
45
+ readonly floor: "#f0f1f3";
46
+ readonly floorEdge: "#d9dde2";
47
+ readonly grid: "#d9dde2";
48
+ readonly ink: "#7b838e";
49
+ readonly window: "#f7fff5";
50
+ };
51
+ readonly night: {
52
+ readonly colors: readonly ["#b8d4ff", "#78a8f5", "#4e7fe0", "#2f56b7"];
53
+ readonly emptyColor: "#343a43";
54
+ readonly floor: "#24272d";
55
+ readonly floorEdge: "#353a43";
56
+ readonly grid: "#3d424b";
57
+ readonly ink: "#a6afbc";
58
+ readonly window: "#ffd786";
59
+ };
60
+ readonly seasonal: {
61
+ readonly colors: readonly ["#f8e8f1", "#f3b6d2", "#d779ac", "#9d4d80"];
62
+ readonly emptyColor: "#eeeae5";
63
+ readonly floor: "#f0f1f3";
64
+ readonly floorEdge: "#d9dde2";
65
+ readonly grid: "#d9dde2";
66
+ readonly ink: "#7b838e";
67
+ readonly window: "#fffaf0";
68
+ };
69
+ readonly rainbow: {
70
+ readonly colors: readonly ["#e85d75", "#e7b84b", "#45b97c", "#547de8"];
71
+ readonly emptyColor: "#e8eaf0";
72
+ readonly floor: "#f0f1f3";
73
+ readonly floorEdge: "#d9dde2";
74
+ readonly grid: "#d9dde2";
75
+ readonly ink: "#687080";
76
+ readonly window: "#fff8dd";
77
+ };
78
+ };
79
+ export declare function parseHex(value: string): Rgb | null;
80
+ export declare function mix(from: Rgb, to: Rgb, weight: number): Rgb;
81
+ /** Mix two hexadecimal colours while retaining the package's hex notation. */
82
+ export declare function mixHex(from: string, to: string, weight: number): string;
83
+ export declare function resolve3DTheme(theme?: Heatmap3DThemeName): Heatmap3DThemePreset;
84
+ export declare function resolve3DColors({ theme, colors, column, columns, levels, }: {
85
+ theme?: Heatmap3DThemeName;
86
+ colors?: readonly string[];
87
+ column?: number;
88
+ columns?: number;
89
+ levels?: number;
90
+ }): string[];
91
+ /**
92
+ * Concrete face fills are useful to both the React and string renderers. The
93
+ * top is lifted toward white; visible sides lean toward black, with a gentler
94
+ * treatment for the bright night preset.
95
+ */
96
+ export declare function resolve3DFaceColor({ color, face, theme, cell, level, faceColor, }: {
97
+ color: string;
98
+ face: Heatmap3DFace;
99
+ theme?: Heatmap3DThemeName;
100
+ cell: import("./types.js").ResolvedCell;
101
+ level: number;
102
+ faceColor?: import("./types.js").Heatmap3DFaceColor;
103
+ }): string;
104
+ /** Relative luminance, for deciding whether a ground reads as light or dark. */
105
+ export declare function luminance(color: string): number;
106
+ /**
107
+ * A ramp from one base colour, palest first. Returns `[base]` when the colour
108
+ * cannot be parsed, so a bad value degrades to a flat ramp rather than throwing.
109
+ */
110
+ export declare function deriveRamp(base: string, options?: RampOptions): string[];
111
+ export {};
112
+ //# sourceMappingURL=colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEpE;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,GAAG,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/C,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCuC,CAAC;AAStE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI,CAelD;AASD,wBAAgB,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,CAG3D;AAED,8EAA8E;AAC9E,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKvE;AA0BD,wBAAgB,cAAc,CAAC,KAAK,GAAE,kBAA4B,GAAG,oBAAoB,CAExF;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAe,EACf,MAAM,EACN,MAAU,EACV,OAAW,EACX,MAAU,GACX,EAAE;IACD,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,EAAE,CAmBX;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,IAAI,EACJ,KAAe,EACf,IAAI,EACJ,KAAK,EACL,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,OAAO,YAAY,EAAE,YAAY,CAAC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,YAAY,EAAE,kBAAkB,CAAC;CACrD,GAAG,MAAM,CAMT;AAED,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ/C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,MAAM,EAAE,CAqB5E"}
package/dist/colors.js ADDED
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Small, concrete presets keep the 3D component usable without a token
3
+ * system. The colour ramps stay in hex because that is the public notation of
4
+ * this package and can be copied straight into a static SVG.
5
+ *
6
+ * `color` is the neutral default. It carries no opinion past a starting ramp,
7
+ * so whatever `colors` you pass is what you see. The other three decide
8
+ * colour for you, `seasonal` and `rainbow` per column, which is the reason to
9
+ * reach for them; leave `colors` unset when you do.
10
+ */
11
+ export const HEATMAP_3D_THEMES = {
12
+ color: {
13
+ colors: ["#9be9a8", "#40c463", "#30a14e", "#216e39"],
14
+ emptyColor: "#e5e9e7",
15
+ floor: "#f0f1f3",
16
+ floorEdge: "#d9dde2",
17
+ grid: "#d9dde2",
18
+ ink: "#7b838e",
19
+ window: "#f7fff5",
20
+ },
21
+ night: {
22
+ colors: ["#b8d4ff", "#78a8f5", "#4e7fe0", "#2f56b7"],
23
+ emptyColor: "#343a43",
24
+ floor: "#24272d",
25
+ floorEdge: "#353a43",
26
+ grid: "#3d424b",
27
+ ink: "#a6afbc",
28
+ window: "#ffd786",
29
+ },
30
+ seasonal: {
31
+ colors: ["#f8e8f1", "#f3b6d2", "#d779ac", "#9d4d80"],
32
+ emptyColor: "#eeeae5",
33
+ floor: "#f0f1f3",
34
+ floorEdge: "#d9dde2",
35
+ grid: "#d9dde2",
36
+ ink: "#7b838e",
37
+ window: "#fffaf0",
38
+ },
39
+ rainbow: {
40
+ colors: ["#e85d75", "#e7b84b", "#45b97c", "#547de8"],
41
+ emptyColor: "#e8eaf0",
42
+ floor: "#f0f1f3",
43
+ floorEdge: "#d9dde2",
44
+ grid: "#d9dde2",
45
+ ink: "#687080",
46
+ window: "#fff8dd",
47
+ },
48
+ };
49
+ const SEASONAL_RAMPS = [
50
+ ["#f8e8f1", "#f3b6d2", "#d779ac", "#9d4d80"], // spring
51
+ ["#e8f6df", "#a9da8d", "#56b35d", "#227a3a"], // summer
52
+ ["#fff1d5", "#f5c26b", "#e68532", "#b2471e"], // autumn
53
+ ["#eef2f5", "#b9c6d5", "#7b8ca4", "#4d5b73"], // winter
54
+ ];
55
+ export function parseHex(value) {
56
+ const normalized = value.trim().replace(/^#/, "");
57
+ const expanded = normalized.length === 3
58
+ ? normalized
59
+ .split("")
60
+ .map((character) => character + character)
61
+ .join("")
62
+ : normalized;
63
+ if (!/^[0-9a-f]{6}$/i.test(expanded))
64
+ return null;
65
+ return {
66
+ r: Number.parseInt(expanded.slice(0, 2), 16),
67
+ g: Number.parseInt(expanded.slice(2, 4), 16),
68
+ b: Number.parseInt(expanded.slice(4, 6), 16),
69
+ };
70
+ }
71
+ function toHex({ r, g, b }) {
72
+ return ("#" +
73
+ [r, g, b].map((channel) => Math.round(channel).toString(16).padStart(2, "0")).join(""));
74
+ }
75
+ export function mix(from, to, weight) {
76
+ const blend = (a, b) => a + (b - a) * weight;
77
+ return { r: blend(from.r, to.r), g: blend(from.g, to.g), b: blend(from.b, to.b) };
78
+ }
79
+ /** Mix two hexadecimal colours while retaining the package's hex notation. */
80
+ export function mixHex(from, to, weight) {
81
+ const fromRgb = parseHex(from);
82
+ const toRgb = parseHex(to);
83
+ if (!fromRgb || !toRgb)
84
+ return from;
85
+ return toHex(mix(fromRgb, toRgb, Math.min(1, Math.max(0, weight))));
86
+ }
87
+ function resampleRamp(stops, levels) {
88
+ if (stops.length === 0)
89
+ return [];
90
+ if (stops.length === 1)
91
+ return Array.from({ length: Math.max(1, levels) }, () => stops[0]);
92
+ if (levels <= 1)
93
+ return [stops[stops.length - 1]];
94
+ if (levels === stops.length)
95
+ return [...stops];
96
+ return Array.from({ length: levels }, (_, index) => {
97
+ const position = (index / (levels - 1)) * (stops.length - 1);
98
+ const lower = Math.min(stops.length - 2, Math.floor(position));
99
+ const weight = position - lower;
100
+ return mixHex(stops[lower], stops[lower + 1], weight);
101
+ });
102
+ }
103
+ function hslToHex(hue, saturation, lightness) {
104
+ const h = ((hue % 360) + 360) % 360 / 60;
105
+ const s = Math.min(1, Math.max(0, saturation));
106
+ const l = Math.min(1, Math.max(0, lightness));
107
+ const chroma = (1 - Math.abs(2 * l - 1)) * s;
108
+ const x = chroma * (1 - Math.abs(h % 2 - 1));
109
+ const match = l - chroma / 2;
110
+ const channels = h < 1 ? [chroma, x, 0] : h < 2 ? [x, chroma, 0] : h < 3 ? [0, chroma, x] : h < 4 ? [0, x, chroma] : h < 5 ? [x, 0, chroma] : [chroma, 0, x];
111
+ return toHex({ r: (channels[0] + match) * 255, g: (channels[1] + match) * 255, b: (channels[2] + match) * 255 });
112
+ }
113
+ export function resolve3DTheme(theme = "color") {
114
+ return HEATMAP_3D_THEMES[theme];
115
+ }
116
+ export function resolve3DColors({ theme = "color", colors, column = 0, columns = 1, levels = 4, }) {
117
+ const count = Math.max(1, Math.floor(levels));
118
+ if (colors && colors.length > 0)
119
+ return resampleRamp(colors, count);
120
+ if (theme === "seasonal") {
121
+ const normalized = Math.min(1, Math.max(0, column / Math.max(1, columns - 1)));
122
+ const position = normalized * (SEASONAL_RAMPS.length - 1);
123
+ const lower = Math.min(SEASONAL_RAMPS.length - 2, Math.floor(position));
124
+ const weight = position - lower;
125
+ const blended = SEASONAL_RAMPS[lower].map((color, index) => mixHex(color, SEASONAL_RAMPS[lower + 1][index], weight));
126
+ return resampleRamp(blended, count);
127
+ }
128
+ if (theme === "rainbow") {
129
+ const progress = column / Math.max(1, columns);
130
+ return Array.from({ length: count }, (_, index) => {
131
+ const levelProgress = count === 1 ? 0.5 : index / (count - 1);
132
+ return hslToHex(progress * 360 + levelProgress * 28, 0.72, 0.38 + levelProgress * 0.25);
133
+ });
134
+ }
135
+ return resampleRamp(resolve3DTheme(theme).colors, count);
136
+ }
137
+ /**
138
+ * Concrete face fills are useful to both the React and string renderers. The
139
+ * top is lifted toward white; visible sides lean toward black, with a gentler
140
+ * treatment for the bright night preset.
141
+ */
142
+ export function resolve3DFaceColor({ color, face, theme = "color", cell, level, faceColor, }) {
143
+ const custom = faceColor?.({ cell, face, color, level, theme });
144
+ if (custom)
145
+ return custom;
146
+ return face === "top"
147
+ ? mixHex(color, "#ffffff", theme === "night" ? 0.1 : 0.07)
148
+ : mixHex(color, "#071b19", theme === "night" ? 0.16 : 0.2);
149
+ }
150
+ /** Relative luminance, for deciding whether a ground reads as light or dark. */
151
+ export function luminance(color) {
152
+ const rgb = parseHex(color);
153
+ if (!rgb)
154
+ return 1;
155
+ const channel = (value) => {
156
+ const v = value / 255;
157
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
158
+ };
159
+ return 0.2126 * channel(rgb.r) + 0.7152 * channel(rgb.g) + 0.0722 * channel(rgb.b);
160
+ }
161
+ /**
162
+ * A ramp from one base colour, palest first. Returns `[base]` when the colour
163
+ * cannot be parsed, so a bad value degrades to a flat ramp rather than throwing.
164
+ */
165
+ export function deriveRamp(base, options = {}) {
166
+ const { levels = 4, ground = "#ffffff" } = options;
167
+ const baseRgb = parseHex(base);
168
+ const groundRgb = parseHex(ground) ?? { r: 255, g: 255, b: 255 };
169
+ if (!baseRgb)
170
+ return [base];
171
+ // On a dark ground the top band brightens rather than darkens, otherwise the
172
+ // strongest cells disappear into the background.
173
+ const groundIsDark = luminance(ground) < 0.2;
174
+ const peakRgb = parseHex(options.peak ?? "") ??
175
+ (groundIsDark ? { r: 255, g: 255, b: 255 } : { r: 0, g: 0, b: 0 });
176
+ return Array.from({ length: levels }, (_, index) => {
177
+ const position = levels === 1 ? 1 : index / (levels - 1);
178
+ // The last band leans slightly past the base toward the peak; the rest
179
+ // fade back toward the ground.
180
+ if (position >= 1)
181
+ return toHex(mix(baseRgb, peakRgb, 0.1));
182
+ const towardGround = 0.8 * (1 - position);
183
+ return toHex(mix(baseRgb, groundRgb, towardGround));
184
+ });
185
+ }
186
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"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"}
package/dist/grid.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import type { HeatmapCell, HeatmapScale, HeatmapValues, ResolvedCell } from "./types.js";
2
+ /**
3
+ * Both input shapes collapse to one sparse map keyed by "row:column".
4
+ *
5
+ * A slot absent from the map has no data; a slot present with value 0 was
6
+ * measured and found empty. Keeping those apart is the whole point — every
7
+ * library that conflates them draws a gap in your records as a day off.
8
+ */
9
+ export declare function normalizeValues(values: HeatmapValues | undefined): Map<string, HeatmapCell>;
10
+ export declare function resolveThresholds(activeValues: readonly number[], scale: HeatmapScale, levels: number, explicit?: readonly number[]): number[];
11
+ /** Every slot in the grid, shaded, in row-major order. */
12
+ export declare function buildCells({ rows, columns, values, scale, levels, thresholds: explicitThresholds, isSlotHidden, }: {
13
+ rows: number;
14
+ columns: number;
15
+ values: HeatmapValues | undefined;
16
+ scale: HeatmapScale;
17
+ levels: number;
18
+ thresholds?: readonly number[];
19
+ isSlotHidden?: (row: number, column: number) => boolean;
20
+ }): {
21
+ cells: ResolvedCell[];
22
+ thresholds: number[];
23
+ total: number;
24
+ unknownCount: number;
25
+ };
26
+ //# sourceMappingURL=grid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,WAAW,EAEX,YAAY,EACZ,aAAa,EACb,YAAY,EACb,MAAM,YAAY,CAAC;AAMpB;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CA0B3F;AAED,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,GAC3B,MAAM,EAAE,CAiBV;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,OAAO,EACP,MAAM,EACN,KAAK,EACL,MAAM,EACN,UAAU,EAAE,kBAAkB,EAC9B,YAAY,GACb,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;CACzD,GAAG;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAsCvF"}
package/dist/grid.js ADDED
@@ -0,0 +1,102 @@
1
+ import { levelForValue, linearThresholds, logThresholds, quantileThresholds, } from "./scale.js";
2
+ function isMatrix(values) {
3
+ return Array.isArray(values[0]) || values.length === 0;
4
+ }
5
+ /**
6
+ * Both input shapes collapse to one sparse map keyed by "row:column".
7
+ *
8
+ * A slot absent from the map has no data; a slot present with value 0 was
9
+ * measured and found empty. Keeping those apart is the whole point — every
10
+ * library that conflates them draws a gap in your records as a day off.
11
+ */
12
+ export function normalizeValues(values) {
13
+ const cells = new Map();
14
+ if (!values || values.length === 0)
15
+ return cells;
16
+ if (isMatrix(values)) {
17
+ values.forEach((rowValues, row) => {
18
+ (rowValues ?? []).forEach((value, column) => {
19
+ if (value === null || value === undefined || !Number.isFinite(value))
20
+ return;
21
+ cells.set(row + ":" + column, { row, column, value, known: true });
22
+ });
23
+ });
24
+ return cells;
25
+ }
26
+ values.forEach((cell) => {
27
+ if (!cell || !Number.isInteger(cell.row) || !Number.isInteger(cell.column))
28
+ return;
29
+ const value = Number.isFinite(cell.value) ? cell.value : 0;
30
+ cells.set(cell.row + ":" + cell.column, {
31
+ row: cell.row,
32
+ column: cell.column,
33
+ value,
34
+ known: cell.known !== false,
35
+ meta: cell.meta,
36
+ });
37
+ });
38
+ return cells;
39
+ }
40
+ export function resolveThresholds(activeValues, scale, levels, explicit) {
41
+ if (explicit && explicit.length > 0)
42
+ return [...explicit];
43
+ if (typeof scale === "function") {
44
+ // A custom scale maps a value straight onto 0..1; turn that into a ladder.
45
+ const maximum = activeValues.reduce((largest, v) => (v > largest ? v : largest), 0);
46
+ if (maximum <= 0)
47
+ return [];
48
+ return Array.from({ length: levels }, (_, index) => {
49
+ const target = (index + 1) / levels;
50
+ // Find the smallest value whose scaled position reaches this band.
51
+ const sorted = [...activeValues].sort((a, b) => a - b);
52
+ const hit = sorted.find((value) => scale(value, activeValues) >= target);
53
+ return hit ?? maximum;
54
+ });
55
+ }
56
+ if (scale === "linear")
57
+ return linearThresholds(activeValues, levels);
58
+ if (scale === "log")
59
+ return logThresholds(activeValues, levels);
60
+ return quantileThresholds(activeValues, levels);
61
+ }
62
+ /** Every slot in the grid, shaded, in row-major order. */
63
+ export function buildCells({ rows, columns, values, scale, levels, thresholds: explicitThresholds, isSlotHidden, }) {
64
+ const known = normalizeValues(values);
65
+ const activeValues = [];
66
+ for (let row = 0; row < rows; row += 1) {
67
+ for (let column = 0; column < columns; column += 1) {
68
+ if (isSlotHidden?.(row, column))
69
+ continue;
70
+ const cell = known.get(row + ":" + column);
71
+ if (cell && cell.known !== false && cell.value > 0)
72
+ activeValues.push(cell.value);
73
+ }
74
+ }
75
+ const thresholds = resolveThresholds(activeValues, scale, levels, explicitThresholds);
76
+ const cells = [];
77
+ let total = 0;
78
+ let unknownCount = 0;
79
+ for (let row = 0; row < rows; row += 1) {
80
+ for (let column = 0; column < columns; column += 1) {
81
+ if (isSlotHidden?.(row, column))
82
+ continue;
83
+ const cell = known.get(row + ":" + column);
84
+ const isKnown = Boolean(cell) && cell.known !== false;
85
+ const value = isKnown ? cell.value : 0;
86
+ if (isKnown)
87
+ total += value;
88
+ else
89
+ unknownCount += 1;
90
+ cells.push({
91
+ row,
92
+ column,
93
+ value,
94
+ known: isKnown,
95
+ level: isKnown ? levelForValue(value, thresholds, levels) : 0,
96
+ meta: cell?.meta,
97
+ });
98
+ }
99
+ }
100
+ return { cells, thresholds, total, unknownCount };
101
+ }
102
+ //# sourceMappingURL=grid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid.js","sourceRoot":"","sources":["../src/grid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { HeatmapProps } from "./types.js";
2
+ export declare function Heatmap({ rows, columns, values, scale, levels: levelsProp, thresholds: thresholdsProp, shape, encode, cellSize, gap, radius, colors, emptyColor, unknownOpacity, minScale, rowLabels, columnLabels, tooltip, cellContent, cellLabel, onCellClick, isSlotHidden, showLegend, legendLabels, ariaLabel, className, style, ...rest }: HeatmapProps): import("react").JSX.Element;
3
+ export default Heatmap;
4
+ //# sourceMappingURL=heatmap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heatmap.d.ts","sourceRoot":"","sources":["../src/heatmap.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,YAAY,CAAC;AAO7D,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,OAAO,EACP,MAAM,EACN,KAAgB,EAChB,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,cAAc,EAC1B,KAAiB,EACjB,MAAgB,EAChB,QAAa,EACb,GAAO,EACP,MAAM,EACN,MAAuB,EACvB,UAA0B,EAC1B,cAAoB,EACpB,QAAe,EACf,SAAS,EACT,YAAY,EACZ,OAAO,EACP,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,EACZ,UAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,YAAY,+BA6Hd;AAqND,eAAe,OAAO,CAAC"}
@@ -0,0 +1,134 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect, useId, useMemo, useRef, useState } from "react";
4
+ import { luminance, parseHex } from "./colors.js";
5
+ import { buildCells } from "./grid.js";
6
+ import { fillStyle, rowOffset, rowSpacing, shapeStyle } from "./shapes.js";
7
+ /** GitHub's light ramp, as a neutral default rather than a statement. */
8
+ const DEFAULT_COLORS = ["#9be9a8", "#40c463", "#30a14e", "#216e39"];
9
+ const DEFAULT_EMPTY = "#ebedf0";
10
+ const TOOLTIP_DELAY = 300;
11
+ export function Heatmap({ rows, columns, values, scale = "linear", levels: levelsProp, thresholds: thresholdsProp, shape = "rounded", encode = "color", cellSize = 13, gap = 3, radius, colors = DEFAULT_COLORS, emptyColor = DEFAULT_EMPTY, unknownOpacity = 0.5, minScale = 0.35, rowLabels, columnLabels, tooltip, cellContent, cellLabel, onCellClick, isSlotHidden, showLegend = false, legendLabels, ariaLabel, className, style, ...rest }) {
12
+ const levels = levelsProp ?? colors.length ?? 4;
13
+ const { cells, total, unknownCount } = useMemo(() => buildCells({
14
+ rows,
15
+ columns,
16
+ values,
17
+ scale,
18
+ levels,
19
+ thresholds: thresholdsProp,
20
+ isSlotHidden,
21
+ }), [rows, columns, values, scale, levels, thresholdsProp, isSlotHidden]);
22
+ const columnWidth = cellSize + gap;
23
+ const rowHeight = rowSpacing(shape, cellSize, gap);
24
+ // Hexagon rows are offset by half a column, so the grid is that much wider.
25
+ const overhang = shape === "hexagon" && rows > 1 ? columnWidth / 2 : 0;
26
+ const width = columns * columnWidth - gap + overhang;
27
+ const height = (rows - 1) * rowHeight + cellSize;
28
+ const label = ariaLabel ??
29
+ "Heatmap, " + rows + " by " + columns +
30
+ (unknownCount > 0 ? ", " + unknownCount + " slots with no data" : "");
31
+ return (_jsxs("div", { className: ["heatmap", className].filter(Boolean).join(" "), role: "group", "aria-label": label, "data-total": total, style: style, ...rest, children: [_jsxs("div", { className: "heatmap__body", children: [columnLabels && columnLabels.length > 0 ? (_jsx("div", { className: "heatmap__column-labels", style: { height: 16, width }, children: columnLabels.map((entry, index) => (_jsx("span", { className: "heatmap__column-label", style: { left: entry.column * columnWidth + cellSize / 2 }, children: entry.text }, index))) })) : null, rowLabels && rowLabels.length > 0 ? (_jsx("div", { className: "heatmap__row-labels", style: { height, gridAutoRows: rowHeight }, children: rowLabels.map((text, index) => (_jsx("span", { className: "heatmap__row-label", style: { top: index * rowHeight, height: cellSize }, children: text }, index))) })) : null, _jsx("div", { className: "heatmap__grid", style: { width, height }, children: cells.map((cell) => (_jsx(HeatmapCellView, { cell: cell, left: cell.column * columnWidth + rowOffset(shape, cell.row, columnWidth), top: cell.row * rowHeight, size: cellSize, shape: shape, encode: encode, levels: levels, radius: radius, colors: colors, emptyColor: emptyColor, unknownOpacity: unknownOpacity, minScale: minScale, tooltip: tooltip, cellContent: cellContent, cellLabel: cellLabel, onCellClick: onCellClick, nearLeftEdge: cell.column === 0, nearRightEdge: cell.column === columns - 1 }, cell.row + ":" + cell.column))) })] }), showLegend ? (_jsxs("div", { className: "heatmap__legend", children: [_jsx("span", { children: legendLabels?.less ?? "less" }), _jsx(LegendSwatch, { color: emptyColor, shape: shape, size: cellSize, radius: radius }), colors.map((color, index) => (_jsx(LegendSwatch, { color: color, shape: shape, size: cellSize, radius: radius }, color + index))), _jsx("span", { children: legendLabels?.more ?? "more" }), unknownCount > 0 ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "heatmap__legend-unknown", children: legendLabels?.unknown ?? "no data" }), _jsx(LegendSwatch, { color: emptyColor, shape: shape, size: cellSize, radius: radius, opacity: unknownOpacity })] })) : null] })) : null] }));
32
+ }
33
+ function HeatmapCellView({ cell, left, top, size, shape, encode, levels, radius, colors, emptyColor, unknownOpacity, minScale, tooltip, cellContent, cellLabel, onCellClick, nearLeftEdge, nearRightEdge, }) {
34
+ const tooltipId = useId();
35
+ const timer = useRef(null);
36
+ const [open, setOpen] = useState(false);
37
+ useEffect(() => () => {
38
+ if (timer.current !== null)
39
+ window.clearTimeout(timer.current);
40
+ }, []);
41
+ const content = tooltip ? tooltip(cell) : null;
42
+ const visualContent = cellContent ? cellContent(cell) : null;
43
+ const hasVisualContent = visualContent !== null &&
44
+ visualContent !== undefined &&
45
+ visualContent !== false &&
46
+ visualContent !== true &&
47
+ visualContent !== "";
48
+ const name = cellLabel ? cellLabel(cell) : undefined;
49
+ const interactive = Boolean(content || name || onCellClick);
50
+ const show = () => {
51
+ if (!content)
52
+ return;
53
+ if (timer.current !== null)
54
+ window.clearTimeout(timer.current);
55
+ timer.current = window.setTimeout(() => {
56
+ setOpen(true);
57
+ timer.current = null;
58
+ }, TOOLTIP_DELAY);
59
+ };
60
+ const hide = () => {
61
+ if (timer.current !== null)
62
+ window.clearTimeout(timer.current);
63
+ timer.current = null;
64
+ setOpen(false);
65
+ };
66
+ // "size" carries intensity through geometry so it survives in greyscale.
67
+ const usesSize = encode === "size" || encode === "both";
68
+ const usesColor = encode === "color" || encode === "both";
69
+ const intensity = levels > 0 ? cell.level / levels : 0;
70
+ const scaleFactor = usesSize && cell.level > 0 ? minScale + (1 - minScale) * intensity : 1;
71
+ const color = !cell.known
72
+ ? emptyColor
73
+ : cell.level === 0
74
+ ? emptyColor
75
+ : usesColor
76
+ ? colors[Math.min(colors.length - 1, cell.level - 1)]
77
+ : colors[colors.length - 1];
78
+ // `bar` derives its own height from the level, so the box size must not be
79
+ // written afterwards — an explicit `height: undefined` would clobber it.
80
+ const box = shape === "bar"
81
+ ? { width: size }
82
+ : { width: Math.round(size * scaleFactor), height: Math.round(size * scaleFactor) };
83
+ const fill = {
84
+ ...shapeStyle(shape, radius),
85
+ ...box,
86
+ ...fillStyle(shape, cell.level, levels, color, size),
87
+ };
88
+ const contentText = typeof visualContent === "string" || typeof visualContent === "number"
89
+ ? String(visualContent)
90
+ : "";
91
+ const contentStyle = {
92
+ // Hex ramps can choose a readable ink automatically. CSS variables and
93
+ // other non-hex colours fall back to the inherited colour, and a custom
94
+ // node can still set its own.
95
+ ...(parseHex(color)
96
+ ? { color: luminance(color) > 0.18 ? "#171614" : "#ffffff" }
97
+ : {}),
98
+ ...(contentText
99
+ ? {
100
+ fontSize: Math.max(6, Math.min(11, size * 0.68 - Math.max(0, contentText.length - 2) * 1.1)),
101
+ }
102
+ : {}),
103
+ };
104
+ return (_jsxs("div", { className: "heatmap__cell-slot", style: { left, top, width: size, height: size }, "data-known": cell.known ? "true" : "false", "data-level": cell.level, tabIndex: interactive ? 0 : undefined, role: onCellClick ? "button" : undefined, "aria-label": name, "aria-describedby": open ? tooltipId : undefined, onPointerEnter: show, onPointerLeave: hide, onFocus: show, onBlur: hide, onClick: onCellClick ? () => onCellClick(cell) : undefined, onKeyDown: onCellClick
105
+ ? (event) => {
106
+ if (event.key === "Enter" || event.key === " ") {
107
+ event.preventDefault();
108
+ onCellClick(cell);
109
+ }
110
+ }
111
+ : undefined, children: [_jsx("div", { className: "heatmap__cell", style: { ...fill, opacity: cell.known ? 1 : unknownOpacity }, children: hasVisualContent ? (_jsx("span", { className: "heatmap__cell-content", "aria-hidden": "true", style: contentStyle, children: visualContent })) : null }), open && content ? (_jsx("div", { id: tooltipId, className: "heatmap__tooltip", role: "tooltip", "data-align": nearLeftEdge ? "start" : nearRightEdge ? "end" : "center", children: content })) : null] }));
112
+ }
113
+ /*
114
+ * The legend is a key, not data, so its swatches read a step below the cells
115
+ * they describe. The step is proportional, and clamped so a swatch can never
116
+ * outgrow its own cell however small the grid gets.
117
+ */
118
+ function legendSwatchSize(size) {
119
+ const target = Math.min(Math.round(size * 0.8), 12);
120
+ return Math.max(1, Math.min(target, size - 1));
121
+ }
122
+ function LegendSwatch({ color, shape, size, radius, opacity = 1, }) {
123
+ const swatch = legendSwatchSize(size);
124
+ return (_jsx("span", { className: "heatmap__legend-swatch", "aria-hidden": "true", style: {
125
+ ...shapeStyle(shape, radius),
126
+ width: swatch,
127
+ height: swatch,
128
+ background: shape === "ring" ? "transparent" : color,
129
+ border: shape === "ring" ? "2px solid " + color : undefined,
130
+ opacity,
131
+ } }));
132
+ }
133
+ export default Heatmap;
134
+ //# sourceMappingURL=heatmap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heatmap.js","sourceRoot":"","sources":["../src/heatmap.tsx"],"names":[],"mappings":"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"}