insomni-plot 0.1.0-alpha.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/LICENSE.md +674 -0
- package/README.md +81 -0
- package/dist/core.d.mts +340 -0
- package/dist/core.mjs +1047 -0
- package/dist/index.d.mts +3426 -0
- package/dist/index.mjs +12762 -0
- package/dist/interactions-DEFL_F4E.mjs +5395 -0
- package/dist/range-presets-CzECsu3V.d.mts +1523 -0
- package/package.json +34 -0
- package/src/annotations.d.ts +121 -0
- package/src/annotations.ts +438 -0
- package/src/axis.d.ts +184 -0
- package/src/axis.test.ts +131 -0
- package/src/axis.ts +765 -0
- package/src/colorbar.d.ts +69 -0
- package/src/colorbar.ts +294 -0
- package/src/colors.d.ts +57 -0
- package/src/colors.test.ts +28 -0
- package/src/colors.ts +486 -0
- package/src/core.ts +299 -0
- package/src/format.d.ts +54 -0
- package/src/format.ts +138 -0
- package/src/grammar/accessibility.d.ts +147 -0
- package/src/grammar/accessibility.test.ts +199 -0
- package/src/grammar/accessibility.ts +443 -0
- package/src/grammar/aes.d.ts +35 -0
- package/src/grammar/aes.test.ts +75 -0
- package/src/grammar/aes.ts +120 -0
- package/src/grammar/annotations.d.ts +86 -0
- package/src/grammar/annotations.test.ts +68 -0
- package/src/grammar/annotations.ts +336 -0
- package/src/grammar/attach-brush.d.ts +44 -0
- package/src/grammar/attach-brush.test.ts +214 -0
- package/src/grammar/attach-brush.ts +111 -0
- package/src/grammar/attach-presets.d.ts +33 -0
- package/src/grammar/attach-presets.test.ts +106 -0
- package/src/grammar/attach-presets.ts +215 -0
- package/src/grammar/chart.d.ts +952 -0
- package/src/grammar/chart.test.ts +118 -0
- package/src/grammar/chart.ts +1172 -0
- package/src/grammar/color-utils.d.ts +29 -0
- package/src/grammar/color-utils.test.ts +53 -0
- package/src/grammar/color-utils.ts +66 -0
- package/src/grammar/constants.d.ts +45 -0
- package/src/grammar/constants.ts +61 -0
- package/src/grammar/coord.d.ts +183 -0
- package/src/grammar/coord.test.ts +355 -0
- package/src/grammar/coord.ts +619 -0
- package/src/grammar/data/pivot.d.ts +57 -0
- package/src/grammar/data/pivot.ts +107 -0
- package/src/grammar/emphasis-driver.d.ts +69 -0
- package/src/grammar/emphasis-driver.test.ts +199 -0
- package/src/grammar/emphasis-driver.ts +205 -0
- package/src/grammar/equality.d.ts +3 -0
- package/src/grammar/equality.ts +40 -0
- package/src/grammar/facet.d.ts +63 -0
- package/src/grammar/facet.test.ts +60 -0
- package/src/grammar/facet.ts +175 -0
- package/src/grammar/geoms/_categorical.d.ts +94 -0
- package/src/grammar/geoms/_categorical.ts +0 -0
- package/src/grammar/geoms/_distribution.d.ts +52 -0
- package/src/grammar/geoms/_distribution.ts +125 -0
- package/src/grammar/geoms/_mark.d.ts +69 -0
- package/src/grammar/geoms/_mark.ts +136 -0
- package/src/grammar/geoms/_shape.d.ts +41 -0
- package/src/grammar/geoms/_shape.ts +74 -0
- package/src/grammar/geoms/aggregate.d.ts +95 -0
- package/src/grammar/geoms/aggregate.test.ts +554 -0
- package/src/grammar/geoms/aggregate.ts +840 -0
- package/src/grammar/geoms/area.d.ts +32 -0
- package/src/grammar/geoms/area.test.ts +165 -0
- package/src/grammar/geoms/area.ts +578 -0
- package/src/grammar/geoms/band.d.ts +27 -0
- package/src/grammar/geoms/band.test.ts +57 -0
- package/src/grammar/geoms/band.ts +126 -0
- package/src/grammar/geoms/bar.d.ts +56 -0
- package/src/grammar/geoms/bar.test.ts +367 -0
- package/src/grammar/geoms/bar.ts +1054 -0
- package/src/grammar/geoms/boxplot.d.ts +129 -0
- package/src/grammar/geoms/boxplot.test.ts +299 -0
- package/src/grammar/geoms/boxplot.ts +834 -0
- package/src/grammar/geoms/connected-scatter.d.ts +27 -0
- package/src/grammar/geoms/connected-scatter.test.ts +157 -0
- package/src/grammar/geoms/connected-scatter.ts +63 -0
- package/src/grammar/geoms/emphasis.d.ts +76 -0
- package/src/grammar/geoms/emphasis.test.ts +135 -0
- package/src/grammar/geoms/emphasis.ts +162 -0
- package/src/grammar/geoms/histogram.d.ts +75 -0
- package/src/grammar/geoms/histogram.test.ts +262 -0
- package/src/grammar/geoms/histogram.ts +740 -0
- package/src/grammar/geoms/index.d.ts +20 -0
- package/src/grammar/geoms/index.ts +77 -0
- package/src/grammar/geoms/interval.d.ts +31 -0
- package/src/grammar/geoms/interval.test.ts +154 -0
- package/src/grammar/geoms/interval.ts +342 -0
- package/src/grammar/geoms/line.d.ts +38 -0
- package/src/grammar/geoms/line.test.ts +247 -0
- package/src/grammar/geoms/line.ts +659 -0
- package/src/grammar/geoms/point.d.ts +57 -0
- package/src/grammar/geoms/point.test.ts +163 -0
- package/src/grammar/geoms/point.ts +545 -0
- package/src/grammar/geoms/polar.test.ts +216 -0
- package/src/grammar/geoms/ribbon.d.ts +21 -0
- package/src/grammar/geoms/ribbon.test.ts +170 -0
- package/src/grammar/geoms/ribbon.ts +87 -0
- package/src/grammar/geoms/ridgeline.d.ts +89 -0
- package/src/grammar/geoms/ridgeline.test.ts +247 -0
- package/src/grammar/geoms/ridgeline.ts +1164 -0
- package/src/grammar/geoms/rolling.d.ts +43 -0
- package/src/grammar/geoms/rolling.test.ts +217 -0
- package/src/grammar/geoms/rolling.ts +387 -0
- package/src/grammar/geoms/rug.d.ts +28 -0
- package/src/grammar/geoms/rug.test.ts +126 -0
- package/src/grammar/geoms/rug.ts +214 -0
- package/src/grammar/geoms/rule.d.ts +23 -0
- package/src/grammar/geoms/rule.test.ts +69 -0
- package/src/grammar/geoms/rule.ts +212 -0
- package/src/grammar/geoms/smooth.d.ts +54 -0
- package/src/grammar/geoms/smooth.test.ts +78 -0
- package/src/grammar/geoms/smooth.ts +337 -0
- package/src/grammar/geoms/text.d.ts +29 -0
- package/src/grammar/geoms/text.test.ts +64 -0
- package/src/grammar/geoms/text.ts +234 -0
- package/src/grammar/geoms/tile.d.ts +61 -0
- package/src/grammar/geoms/tile.test.ts +157 -0
- package/src/grammar/geoms/tile.ts +621 -0
- package/src/grammar/geoms/types.d.ts +319 -0
- package/src/grammar/geoms/types.ts +362 -0
- package/src/grammar/geoms/violin.d.ts +85 -0
- package/src/grammar/geoms/violin.test.ts +187 -0
- package/src/grammar/geoms/violin.ts +672 -0
- package/src/grammar/index.d.ts +22 -0
- package/src/grammar/index.ts +269 -0
- package/src/grammar/interactions/_disposable.d.ts +5 -0
- package/src/grammar/interactions/_disposable.ts +23 -0
- package/src/grammar/interactions/_z.d.ts +4 -0
- package/src/grammar/interactions/_z.ts +16 -0
- package/src/grammar/interactions/brush-selection.test.ts +262 -0
- package/src/grammar/interactions/brush.d.ts +63 -0
- package/src/grammar/interactions/brush.test.ts +483 -0
- package/src/grammar/interactions/brush.ts +452 -0
- package/src/grammar/interactions/crosshair.d.ts +19 -0
- package/src/grammar/interactions/crosshair.test.ts +127 -0
- package/src/grammar/interactions/crosshair.ts +76 -0
- package/src/grammar/interactions/hit-layer.d.ts +64 -0
- package/src/grammar/interactions/hit-layer.ts +246 -0
- package/src/grammar/interactions/legend.d.ts +19 -0
- package/src/grammar/interactions/legend.ts +101 -0
- package/src/grammar/interactions/menu.d.ts +93 -0
- package/src/grammar/interactions/menu.test.ts +373 -0
- package/src/grammar/interactions/menu.ts +342 -0
- package/src/grammar/interactions/selection.d.ts +25 -0
- package/src/grammar/interactions/selection.test.ts +289 -0
- package/src/grammar/interactions/selection.ts +142 -0
- package/src/grammar/interactions/series-readout.d.ts +91 -0
- package/src/grammar/interactions/series-readout.test.ts +668 -0
- package/src/grammar/interactions/series-readout.ts +422 -0
- package/src/grammar/interactions/series-snap.d.ts +70 -0
- package/src/grammar/interactions/series-snap.test.ts +214 -0
- package/src/grammar/interactions/series-snap.ts +218 -0
- package/src/grammar/interactions/tooltip-axis.test.ts +176 -0
- package/src/grammar/interactions/tooltip-touch.browser.test.ts +49 -0
- package/src/grammar/interactions/tooltip-touch.test.ts +161 -0
- package/src/grammar/interactions/tooltip.d.ts +140 -0
- package/src/grammar/interactions/tooltip.test.ts +406 -0
- package/src/grammar/interactions/tooltip.ts +622 -0
- package/src/grammar/interactions/transitions.d.ts +34 -0
- package/src/grammar/interactions/transitions.test.ts +172 -0
- package/src/grammar/interactions/transitions.ts +160 -0
- package/src/grammar/layout.d.ts +68 -0
- package/src/grammar/layout.ts +186 -0
- package/src/grammar/legend-merge.test.ts +332 -0
- package/src/grammar/mount.d.ts +78 -0
- package/src/grammar/mount.test.ts +479 -0
- package/src/grammar/mount.ts +2112 -0
- package/src/grammar/palettes.d.ts +54 -0
- package/src/grammar/palettes.test.ts +80 -0
- package/src/grammar/palettes.ts +167 -0
- package/src/grammar/pan-zoom.test.ts +398 -0
- package/src/grammar/phylo.d.ts +65 -0
- package/src/grammar/phylo.test.ts +59 -0
- package/src/grammar/phylo.ts +112 -0
- package/src/grammar/pipeline.auto-ticks.test.ts +40 -0
- package/src/grammar/pipeline.d.ts +158 -0
- package/src/grammar/pipeline.test.ts +463 -0
- package/src/grammar/pipeline.ts +1233 -0
- package/src/grammar/profiling.d.ts +8 -0
- package/src/grammar/profiling.ts +24 -0
- package/src/grammar/scales.d.ts +188 -0
- package/src/grammar/scales.test.ts +181 -0
- package/src/grammar/scales.ts +800 -0
- package/src/grammar/svg.d.ts +3 -0
- package/src/grammar/svg.ts +39 -0
- package/src/grammar/theme.d.ts +261 -0
- package/src/grammar/theme.test.ts +105 -0
- package/src/grammar/theme.ts +490 -0
- package/src/heatmap/cpu.ts +109 -0
- package/src/heatmap/gpu.ts +565 -0
- package/src/heatmap/types.ts +177 -0
- package/src/heatmap.browser.test.ts +308 -0
- package/src/heatmap.test.ts +320 -0
- package/src/heatmap.ts +123 -0
- package/src/index.d.ts +1 -0
- package/src/index.ts +8 -0
- package/src/interactions.d.ts +48 -0
- package/src/interactions.test.ts +226 -0
- package/src/interactions.ts +394 -0
- package/src/layout/box.d.ts +48 -0
- package/src/layout/box.test.ts +107 -0
- package/src/layout/box.ts +143 -0
- package/src/legend.d.ts +115 -0
- package/src/legend.ts +422 -0
- package/src/marks/curve.d.ts +43 -0
- package/src/marks/curve.ts +244 -0
- package/src/marks/stack.d.ts +53 -0
- package/src/marks/stack.ts +184 -0
- package/src/marks.d.ts +273 -0
- package/src/marks.test.ts +541 -0
- package/src/marks.ts +1292 -0
- package/src/navigator.test.ts +174 -0
- package/src/navigator.ts +393 -0
- package/src/range-presets.d.ts +113 -0
- package/src/range-presets.test.ts +345 -0
- package/src/range-presets.ts +349 -0
- package/src/scales.d.ts +98 -0
- package/src/scales.test.ts +103 -0
- package/src/scales.ts +695 -0
- package/src/stats/index.d.ts +200 -0
- package/src/stats/index.test.ts +349 -0
- package/src/stats/index.ts +740 -0
- package/src/stats/regression.d.ts +38 -0
- package/src/stats/regression.test.ts +56 -0
- package/src/stats/regression.ts +396 -0
- package/src/stats/rolling-window.d.ts +55 -0
- package/src/stats/rolling-window.test.ts +237 -0
- package/src/stats/rolling-window.ts +256 -0
- package/src/test-setup.ts +19 -0
- package/src/viewport/axis-state.d.ts +72 -0
- package/src/viewport/axis-state.ts +476 -0
- package/src/viewport.d.ts +170 -0
- package/src/viewport.test.ts +363 -0
- package/src/viewport.ts +510 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Color } from "insomni";
|
|
2
|
+
import { type CategoricalPalette } from "../colors.ts";
|
|
3
|
+
import type { ColorScale } from "./scales.ts";
|
|
4
|
+
import type { Theme, ThemeAccentKey } from "./theme.ts";
|
|
5
|
+
/** Multiply a color's alpha by `a`. Preserves rgb. */
|
|
6
|
+
export declare function alphaize(c: Color, a: number): Color;
|
|
7
|
+
/** Override a color's alpha to `a`. */
|
|
8
|
+
export declare function withAlpha(c: Color, a: number): Color;
|
|
9
|
+
/**
|
|
10
|
+
* Accent-key shorthand used by chart-level marks (`band`, `rule`, `interval`,
|
|
11
|
+
* `ribbon`). Literal {@link Color} values bypass theme resolution; accent
|
|
12
|
+
* keys resolve through `theme.accents`.
|
|
13
|
+
*/
|
|
14
|
+
export type ColorOrAccent = Color | ThemeAccentKey;
|
|
15
|
+
export declare function isColor(v: unknown): v is Color;
|
|
16
|
+
export declare function isAccentKey(v: unknown): v is ThemeAccentKey;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a `Color | ThemeAccentKey | undefined` against the theme's accent
|
|
19
|
+
* palette. Returns `undefined` when the input is undefined; throws on an
|
|
20
|
+
* unknown string so typos surface at construction rather than rendering as
|
|
21
|
+
* silent transparent black.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveAccent(value: ColorOrAccent | undefined, theme: Theme): Color | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve a per-series color function: prefer the chart-provided color scale
|
|
26
|
+
* (so auto-legend swatches stay in sync), otherwise fall back to a fresh
|
|
27
|
+
* categorical palette keyed on `fallbackKeys`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function seriesColor(scale: ColorScale | undefined, palette: CategoricalPalette, fallbackKeys: readonly string[]): (key: string) => Color;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { rgba } from "insomni";
|
|
2
|
+
import { describe, expect, test } from "vite-plus/test";
|
|
3
|
+
|
|
4
|
+
import { isAccentKey, isColor, resolveAccent } from "./color-utils.ts";
|
|
5
|
+
import { theme, themeDefault } from "./theme.ts";
|
|
6
|
+
|
|
7
|
+
describe("resolveAccent", () => {
|
|
8
|
+
test("returns undefined for undefined input", () => {
|
|
9
|
+
expect(resolveAccent(undefined, themeDefault)).toBeUndefined();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("passes through literal Color values", () => {
|
|
13
|
+
const c = rgba(0.1, 0.2, 0.3, 1);
|
|
14
|
+
expect(resolveAccent(c, themeDefault)).toBe(c);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("resolves each accent key against theme.accents", () => {
|
|
18
|
+
expect(resolveAccent("positive", themeDefault)).toBe(themeDefault.accents.positive);
|
|
19
|
+
expect(resolveAccent("negative", themeDefault)).toBe(themeDefault.accents.negative);
|
|
20
|
+
expect(resolveAccent("warn", themeDefault)).toBe(themeDefault.accents.warn);
|
|
21
|
+
expect(resolveAccent("info", themeDefault)).toBe(themeDefault.accents.info);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("picks up theme overrides", () => {
|
|
25
|
+
const customWarn = rgba(0.5, 0.5, 0.5, 1);
|
|
26
|
+
const t = theme({ accents: { warn: customWarn } });
|
|
27
|
+
// `theme()` deep-merges, so the resolved value is a structural copy, not
|
|
28
|
+
// the same reference as `customWarn`.
|
|
29
|
+
expect(resolveAccent("warn", t)).toEqual(customWarn);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("throws on unknown string", () => {
|
|
33
|
+
expect(() => resolveAccent("good" as never, themeDefault)).toThrow(/unknown accent key/);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe("isColor / isAccentKey", () => {
|
|
38
|
+
test("isColor distinguishes Color from accent string", () => {
|
|
39
|
+
expect(isColor(rgba(0, 0, 0, 1))).toBe(true);
|
|
40
|
+
expect(isColor("positive")).toBe(false);
|
|
41
|
+
expect(isColor(undefined)).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("isAccentKey only matches the four known keys", () => {
|
|
45
|
+
expect(isAccentKey("positive")).toBe(true);
|
|
46
|
+
expect(isAccentKey("negative")).toBe(true);
|
|
47
|
+
expect(isAccentKey("warn")).toBe(true);
|
|
48
|
+
expect(isAccentKey("info")).toBe(true);
|
|
49
|
+
expect(isAccentKey("good")).toBe(false);
|
|
50
|
+
expect(isAccentKey("")).toBe(false);
|
|
51
|
+
expect(isAccentKey(rgba(0, 0, 0, 1))).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { Color } from "insomni";
|
|
2
|
+
import { colorScale, type CategoricalPalette } from "../colors.ts";
|
|
3
|
+
import type { ColorScale } from "./scales.ts";
|
|
4
|
+
import type { Theme, ThemeAccentKey } from "./theme.ts";
|
|
5
|
+
|
|
6
|
+
/** Multiply a color's alpha by `a`. Preserves rgb. */
|
|
7
|
+
export function alphaize(c: Color, a: number): Color {
|
|
8
|
+
return { r: c.r, g: c.g, b: c.b, a: (c.a ?? 1) * a };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Override a color's alpha to `a`. */
|
|
12
|
+
export function withAlpha(c: Color, a: number): Color {
|
|
13
|
+
return { r: c.r, g: c.g, b: c.b, a };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Accent-key shorthand used by chart-level marks (`band`, `rule`, `interval`,
|
|
18
|
+
* `ribbon`). Literal {@link Color} values bypass theme resolution; accent
|
|
19
|
+
* keys resolve through `theme.accents`.
|
|
20
|
+
*/
|
|
21
|
+
export type ColorOrAccent = Color | ThemeAccentKey;
|
|
22
|
+
|
|
23
|
+
export function isColor(v: unknown): v is Color {
|
|
24
|
+
return (
|
|
25
|
+
typeof v === "object" &&
|
|
26
|
+
v !== null &&
|
|
27
|
+
typeof (v as { r?: unknown }).r === "number" &&
|
|
28
|
+
typeof (v as { g?: unknown }).g === "number" &&
|
|
29
|
+
typeof (v as { b?: unknown }).b === "number"
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const ACCENT_KEYS: ReadonlySet<ThemeAccentKey> = new Set(["positive", "negative", "warn", "info"]);
|
|
34
|
+
|
|
35
|
+
export function isAccentKey(v: unknown): v is ThemeAccentKey {
|
|
36
|
+
return typeof v === "string" && ACCENT_KEYS.has(v as ThemeAccentKey);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Resolve a `Color | ThemeAccentKey | undefined` against the theme's accent
|
|
41
|
+
* palette. Returns `undefined` when the input is undefined; throws on an
|
|
42
|
+
* unknown string so typos surface at construction rather than rendering as
|
|
43
|
+
* silent transparent black.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveAccent(value: ColorOrAccent | undefined, theme: Theme): Color | undefined {
|
|
46
|
+
if (value === undefined) return undefined;
|
|
47
|
+
if (isColor(value)) return value;
|
|
48
|
+
if (isAccentKey(value)) return theme.accents[value];
|
|
49
|
+
throw new Error(
|
|
50
|
+
`resolveAccent: unknown accent key "${String(value)}" — expected positive | negative | warn | info, or a Color.`,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Resolve a per-series color function: prefer the chart-provided color scale
|
|
56
|
+
* (so auto-legend swatches stay in sync), otherwise fall back to a fresh
|
|
57
|
+
* categorical palette keyed on `fallbackKeys`.
|
|
58
|
+
*/
|
|
59
|
+
export function seriesColor(
|
|
60
|
+
scale: ColorScale | undefined,
|
|
61
|
+
palette: CategoricalPalette,
|
|
62
|
+
fallbackKeys: readonly string[],
|
|
63
|
+
): (key: string) => Color {
|
|
64
|
+
if (scale) return (key: string) => scale.fn(key);
|
|
65
|
+
return colorScale(palette, fallbackKeys);
|
|
66
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { DataPanBoundsOptions } from "../viewport.ts";
|
|
2
|
+
export declare const DEFAULT_CHART_WIDTH = 800;
|
|
3
|
+
export declare const DEFAULT_CHART_HEIGHT = 500;
|
|
4
|
+
export declare const DEFAULT_PADDING = 16;
|
|
5
|
+
export declare const DEFAULT_TICK_COUNT = 5;
|
|
6
|
+
export declare const DEFAULT_ATLAS_SIZE = 1024;
|
|
7
|
+
/** Default pan-bounds when panZoom is enabled without explicit bounds. */
|
|
8
|
+
export declare const DEFAULT_PAN_BOUNDS: DataPanBoundsOptions;
|
|
9
|
+
/** Half-padding fraction applied around the visible-Y extent when yFit is enabled. */
|
|
10
|
+
export declare const DEFAULT_Y_FIT_PADDING = 0.05;
|
|
11
|
+
/** Confidence-interval level used by aggregate/smooth when none is supplied. */
|
|
12
|
+
export declare const DEFAULT_CI_LEVEL = 0.95;
|
|
13
|
+
/** Default secondary-glyph scale relative to the base point in overlay geoms. */
|
|
14
|
+
export declare const DEFAULT_OVERLAY_SCALE = 0.6;
|
|
15
|
+
/** Facet layout defaults: gap between panels and strip dimensions. */
|
|
16
|
+
export declare const DEFAULT_FACET_GAP = 12;
|
|
17
|
+
export declare const DEFAULT_FACET_STRIP_HEIGHT = 22;
|
|
18
|
+
export declare const DEFAULT_FACET_STRIP_FONT_SIZE = 11;
|
|
19
|
+
/**
|
|
20
|
+
* Per-bucket sample-count threshold below which boxplot/violin geoms switch
|
|
21
|
+
* from the summary mark to drawing each raw point. Keeps tiny groups from
|
|
22
|
+
* showing a misleading shape built from <10 samples.
|
|
23
|
+
*/
|
|
24
|
+
export declare const DEFAULT_POINTS_THRESHOLD = 10;
|
|
25
|
+
/**
|
|
26
|
+
* Default ridgeline ridge overlap as a multiple of one row's cell size.
|
|
27
|
+
* `2.5` lets each ridge rise 2.5 cells above its baseline before the next
|
|
28
|
+
* ridge sits on top.
|
|
29
|
+
*/
|
|
30
|
+
export declare const DEFAULT_OVERLAP = 2.5;
|
|
31
|
+
/** Pixel gaps between layout regions inside `computeLayout`. */
|
|
32
|
+
export declare const LAYOUT_GAP: {
|
|
33
|
+
/** Gap above the plot frame after title/legend reservation. */
|
|
34
|
+
readonly topReservation: 16;
|
|
35
|
+
/** Right margin inside the outer frame. */
|
|
36
|
+
readonly plotRight: 4;
|
|
37
|
+
/** Pixels between axis edge and plot frame. */
|
|
38
|
+
readonly axisToPlot: 4;
|
|
39
|
+
/** Pixels between title block and legend (when both present). */
|
|
40
|
+
readonly titleToLegend: 4;
|
|
41
|
+
/** Pixels between title and subtitle within title block. */
|
|
42
|
+
readonly subtitleGap: 8;
|
|
43
|
+
/** Pixels reserved below legend before plot frame. */
|
|
44
|
+
readonly legendToPlot: 12;
|
|
45
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Grammar-layer constants
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Sizes and spacings used by the chart pipeline that are NOT theme-able. Theme
|
|
5
|
+
// covers visual appearance (fonts, colors, alphas); this file covers structural
|
|
6
|
+
// layout numbers and pipeline defaults.
|
|
7
|
+
|
|
8
|
+
import type { DataPanBoundsOptions } from "../viewport.ts";
|
|
9
|
+
|
|
10
|
+
export const DEFAULT_CHART_WIDTH = 800;
|
|
11
|
+
export const DEFAULT_CHART_HEIGHT = 500;
|
|
12
|
+
export const DEFAULT_PADDING = 16;
|
|
13
|
+
export const DEFAULT_TICK_COUNT = 5;
|
|
14
|
+
export const DEFAULT_ATLAS_SIZE = 1024;
|
|
15
|
+
|
|
16
|
+
/** Default pan-bounds when panZoom is enabled without explicit bounds. */
|
|
17
|
+
export const DEFAULT_PAN_BOUNDS: DataPanBoundsOptions = { overshoot: 0.1 };
|
|
18
|
+
|
|
19
|
+
/** Half-padding fraction applied around the visible-Y extent when yFit is enabled. */
|
|
20
|
+
export const DEFAULT_Y_FIT_PADDING = 0.05;
|
|
21
|
+
|
|
22
|
+
/** Confidence-interval level used by aggregate/smooth when none is supplied. */
|
|
23
|
+
export const DEFAULT_CI_LEVEL = 0.95;
|
|
24
|
+
|
|
25
|
+
/** Default secondary-glyph scale relative to the base point in overlay geoms. */
|
|
26
|
+
export const DEFAULT_OVERLAY_SCALE = 0.6;
|
|
27
|
+
|
|
28
|
+
/** Facet layout defaults: gap between panels and strip dimensions. */
|
|
29
|
+
export const DEFAULT_FACET_GAP = 12;
|
|
30
|
+
export const DEFAULT_FACET_STRIP_HEIGHT = 22;
|
|
31
|
+
export const DEFAULT_FACET_STRIP_FONT_SIZE = 11;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Per-bucket sample-count threshold below which boxplot/violin geoms switch
|
|
35
|
+
* from the summary mark to drawing each raw point. Keeps tiny groups from
|
|
36
|
+
* showing a misleading shape built from <10 samples.
|
|
37
|
+
*/
|
|
38
|
+
export const DEFAULT_POINTS_THRESHOLD = 10;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Default ridgeline ridge overlap as a multiple of one row's cell size.
|
|
42
|
+
* `2.5` lets each ridge rise 2.5 cells above its baseline before the next
|
|
43
|
+
* ridge sits on top.
|
|
44
|
+
*/
|
|
45
|
+
export const DEFAULT_OVERLAP = 2.5;
|
|
46
|
+
|
|
47
|
+
/** Pixel gaps between layout regions inside `computeLayout`. */
|
|
48
|
+
export const LAYOUT_GAP = {
|
|
49
|
+
/** Gap above the plot frame after title/legend reservation. */
|
|
50
|
+
topReservation: 16,
|
|
51
|
+
/** Right margin inside the outer frame. */
|
|
52
|
+
plotRight: 4,
|
|
53
|
+
/** Pixels between axis edge and plot frame. */
|
|
54
|
+
axisToPlot: 4,
|
|
55
|
+
/** Pixels between title block and legend (when both present). */
|
|
56
|
+
titleToLegend: 4,
|
|
57
|
+
/** Pixels between title and subtitle within title block. */
|
|
58
|
+
subtitleGap: 8,
|
|
59
|
+
/** Pixels reserved below legend before plot frame. */
|
|
60
|
+
legendToPlot: 12,
|
|
61
|
+
} as const;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { type GlyphAtlas, type Layer } from "insomni";
|
|
2
|
+
import { type AxisOptions } from "../axis.ts";
|
|
3
|
+
import type { ScaleBundle } from "./geoms/types.ts";
|
|
4
|
+
export interface Point {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Inputs to `Coord.renderAxes`. The pipeline owns scale construction and
|
|
10
|
+
* layout; the coord owns axis dispatch (Cartesian → bottom + left; polar →
|
|
11
|
+
* angular ring + radial spokes).
|
|
12
|
+
*/
|
|
13
|
+
export interface CoordAxesArgs {
|
|
14
|
+
axisLayer: Layer;
|
|
15
|
+
scales: ScaleBundle;
|
|
16
|
+
/** Inner plot frame — coords project relative to this. */
|
|
17
|
+
plotFrame: import("insomni").Frame;
|
|
18
|
+
/** True when the chart actually has a column on this channel. Skipped axes are not drawn. */
|
|
19
|
+
hasX: boolean;
|
|
20
|
+
hasY: boolean;
|
|
21
|
+
xAxisOptions: AxisOptions<unknown>;
|
|
22
|
+
yAxisOptions: AxisOptions<unknown>;
|
|
23
|
+
atlas: GlyphAtlas | undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Inputs to `Coord.handlePan`. The mount / interactions layer passes a pointer
|
|
27
|
+
* delta in plot-frame pixels plus the active plot frame and a viewport handle
|
|
28
|
+
* the coord can use to mutate scale state. Cartesian delegates the whole
|
|
29
|
+
* thing to `viewport.panBy(dx, dy)`; polar decomposes into tangential
|
|
30
|
+
* (rotate `startAngle`) and radial (translate radius domain via the viewport).
|
|
31
|
+
*/
|
|
32
|
+
export interface CoordPanArgs {
|
|
33
|
+
dx: number;
|
|
34
|
+
dy: number;
|
|
35
|
+
/** Plot frame in absolute layer-pixel space (x, y are screen-space origin). */
|
|
36
|
+
plotFrame: import("insomni").Frame;
|
|
37
|
+
/** Viewport handle for scale-domain mutations. */
|
|
38
|
+
viewport: CoordViewportHandle;
|
|
39
|
+
}
|
|
40
|
+
export interface CoordZoomArgs {
|
|
41
|
+
/**
|
|
42
|
+
* Multiplicative zoom factor — `> 1` zooms in, `< 1` zooms out. May be a
|
|
43
|
+
* scalar (both axes) or a `{ x?, y? }` per-axis form (matches
|
|
44
|
+
* `viewport.zoomAt` and the masking that `bindDataViewport` performs).
|
|
45
|
+
*/
|
|
46
|
+
factor: number | {
|
|
47
|
+
x?: number;
|
|
48
|
+
y?: number;
|
|
49
|
+
};
|
|
50
|
+
/** Cursor position in absolute layer-pixel space (matches `viewport.zoomAt`). */
|
|
51
|
+
cx: number;
|
|
52
|
+
cy: number;
|
|
53
|
+
plotFrame: import("insomni").Frame;
|
|
54
|
+
viewport: CoordViewportHandle;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Minimal facade over `DataViewport` so the coord can mutate scale state
|
|
58
|
+
* without depending on the full viewport surface. The two methods polar
|
|
59
|
+
* uses (`panBy`, `zoomAt`) match `DataViewport` semantics 1:1; Cartesian's
|
|
60
|
+
* implementation forwards through them so behavior is byte-identical to the
|
|
61
|
+
* pre-`handlePan` path.
|
|
62
|
+
*/
|
|
63
|
+
export interface CoordViewportHandle {
|
|
64
|
+
panBy(dxPx: number, dyPx: number): void;
|
|
65
|
+
zoomAt(anchorSx: number, anchorSy: number, factor: number | {
|
|
66
|
+
x?: number;
|
|
67
|
+
y?: number;
|
|
68
|
+
}): void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A coordinate system. Polar / cartesian today; future room for log-polar /
|
|
72
|
+
* geographic projections behind the same interface.
|
|
73
|
+
*/
|
|
74
|
+
export interface Coord {
|
|
75
|
+
readonly kind: "cartesian" | "polar";
|
|
76
|
+
/**
|
|
77
|
+
* Bind the coord to a specific plot frame for the upcoming render.
|
|
78
|
+
* Polar's `project` / `segment` / `renderAxes` need the plot-frame
|
|
79
|
+
* dimensions and centre to compute (cx, cy) and the default outerRadius.
|
|
80
|
+
* Called by the pipeline once per panel (faceted) or once per chart
|
|
81
|
+
* (unfaceted) before any `project` / `renderAxes` call. Cartesian no-ops.
|
|
82
|
+
*/
|
|
83
|
+
bindFrame(plotFrame: import("insomni").Frame): void;
|
|
84
|
+
/**
|
|
85
|
+
* Map a single point from plot-frame pixel space (0..plotFrame.width on x,
|
|
86
|
+
* 0..plotFrame.height on y — i.e. the raw output of `xScale.fn` / `yScale.fn`)
|
|
87
|
+
* to layer-pixel space (still relative to the plot frame's origin —
|
|
88
|
+
* `plot.topLeft` offsets are applied later by each geom).
|
|
89
|
+
*
|
|
90
|
+
* Cartesian: identity. Polar: (θ, r) → (cx + r·cosθ, cy + r·sinθ).
|
|
91
|
+
*/
|
|
92
|
+
project(p: Point): Point;
|
|
93
|
+
/**
|
|
94
|
+
* Tessellate a polyline segment between two points in plot-frame pixel
|
|
95
|
+
* space. Returns the projected pixel points (including both endpoints).
|
|
96
|
+
* Cartesian returns `[project(p1), project(p2)]`; polar returns ~N points
|
|
97
|
+
* along the arc.
|
|
98
|
+
*/
|
|
99
|
+
segment(p1: Point, p2: Point): Point[];
|
|
100
|
+
/**
|
|
101
|
+
* Render axes into `args.axisLayer`. Cartesian draws bottom (x) + left (y);
|
|
102
|
+
* polar draws an angular ring (spokes) + radial concentric circles.
|
|
103
|
+
*/
|
|
104
|
+
renderAxes(args: CoordAxesArgs): void;
|
|
105
|
+
/**
|
|
106
|
+
* Inverse of `project`, for hit-testing / tooltips. Cartesian is the
|
|
107
|
+
* identity within the plot frame. Polar inverts (θ, r) and returns `null`
|
|
108
|
+
* when the projected point is outside `[innerRadius, outerRadius]`.
|
|
109
|
+
*/
|
|
110
|
+
unproject(p: Point): Point | null;
|
|
111
|
+
/**
|
|
112
|
+
* Translate a pointer pan delta into scale-domain mutations.
|
|
113
|
+
* Cartesian forwards to `viewport.panBy(dx, dy)` — byte-identical to the
|
|
114
|
+
* pre-coord path. Polar decomposes the delta relative to the plot centre
|
|
115
|
+
* into tangential (rotate `startAngle`) and radial (translate the radius
|
|
116
|
+
* scale via `viewport.panBy(0, radial_dy)`) components.
|
|
117
|
+
*/
|
|
118
|
+
handlePan(args: CoordPanArgs): void;
|
|
119
|
+
/**
|
|
120
|
+
* Translate a zoom factor + anchor into scale-domain mutations.
|
|
121
|
+
* Cartesian forwards to `viewport.zoomAt(cx, cy, factor)`. Polar scales the
|
|
122
|
+
* radius domain around the cursor's data-space radius; angle scale
|
|
123
|
+
* unchanged.
|
|
124
|
+
*/
|
|
125
|
+
handleZoom(args: CoordZoomArgs): void;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Default coord — identity projection, current axis behavior. Plot's existing
|
|
129
|
+
* pipeline behaves exactly as it did before the `Coord` interface was added
|
|
130
|
+
* when this is in use.
|
|
131
|
+
*/
|
|
132
|
+
export declare function coordCartesian(): Coord;
|
|
133
|
+
export interface CoordPolarOptions {
|
|
134
|
+
/** Angle (radians) where the angular axis starts. Default `-π/2` (top). */
|
|
135
|
+
startAngle?: number;
|
|
136
|
+
/** Angle where the angular axis ends. Default `startAngle + 2π` (full circle). */
|
|
137
|
+
endAngle?: number;
|
|
138
|
+
/**
|
|
139
|
+
* Convenience for non-full-circle layouts: the gap (in radians) between
|
|
140
|
+
* `startAngle` and `endAngle`. `openAngle: 0` ↔ full circle;
|
|
141
|
+
* `openAngle: π/4` ↔ fan with a 45° gap at the start. Ignored when
|
|
142
|
+
* `endAngle` is provided.
|
|
143
|
+
*/
|
|
144
|
+
openAngle?: number;
|
|
145
|
+
/** `1` (default, CCW) or `-1` (CW). */
|
|
146
|
+
direction?: 1 | -1;
|
|
147
|
+
/** Inner radius in pixels. Default `0`. */
|
|
148
|
+
innerRadius?: number;
|
|
149
|
+
/**
|
|
150
|
+
* Outer radius in pixels. Default `min(plotFrame.width, plotFrame.height) / 2`
|
|
151
|
+
* — resolved lazily on `bindFrame`.
|
|
152
|
+
*/
|
|
153
|
+
outerRadius?: number;
|
|
154
|
+
/** Which channel maps to θ. Default `'y'` (gheatmap/circular-tree convention). */
|
|
155
|
+
angleChannel?: "x" | "y";
|
|
156
|
+
/** Angular tessellation step (radians) for `segment` and circular axes. Default ~1°. */
|
|
157
|
+
quality?: number;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Polar projection. See {@link CoordPolarOptions}.
|
|
161
|
+
*
|
|
162
|
+
* Each call returns a fresh stateful coord so the same `coordPolar({...})`
|
|
163
|
+
* expression can be reused safely. `bindFrame` mutates the centre and the
|
|
164
|
+
* default `outerRadius`.
|
|
165
|
+
*/
|
|
166
|
+
export declare function coordPolar(opts?: CoordPolarOptions): Coord;
|
|
167
|
+
/**
|
|
168
|
+
* Convenience polar coord: full circle, root at centre. Equivalent to
|
|
169
|
+
* `coordPolar({ openAngle: 0, innerRadius: 0 })`.
|
|
170
|
+
*/
|
|
171
|
+
export declare function coordRadial(opts?: Omit<CoordPolarOptions, "openAngle" | "innerRadius">): Coord;
|
|
172
|
+
/**
|
|
173
|
+
* Pin a coord to one plot frame (faceted panels). The facet loop mutates a
|
|
174
|
+
* SINGLE shared stateful coord via `bindFrame(panel.frame)` per panel; that's
|
|
175
|
+
* fine for the synchronous mark-push path (compiled right after the bind), but
|
|
176
|
+
* a geom's `hoverDecoration` closure captures `ctx.coord` and runs LATER (at
|
|
177
|
+
* hover, from the mount) — by then the shared coord is bound to the LAST
|
|
178
|
+
* panel's frame, so a polar halo would project against the wrong centre. This
|
|
179
|
+
* wrapper re-binds the underlying coord to THIS panel's frame before every
|
|
180
|
+
* frame-dependent delegate, so each panel's closures see a panel-stable
|
|
181
|
+
* projection. Cartesian's `bindFrame` is a no-op so this is zero-cost there.
|
|
182
|
+
*/
|
|
183
|
+
export declare function frameBoundCoord(coord: Coord, frame: import("insomni").Frame): Coord;
|