@data-profile/fingerprint 0.0.0-stage → 0.3.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 +33 -0
- package/LICENSE +21 -0
- package/README.md +345 -2
- package/dist/chunk-y8jc1j2x.js +447 -0
- package/dist/chunk-y8jc1j2x.js.map +15 -0
- package/dist/index.d.ts +247 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +10 -0
- package/dist/react/index.d.ts +300 -0
- package/dist/react/index.js +643 -0
- package/dist/react/index.js.map +14 -0
- package/dist/styles.css +117 -0
- package/package.json +75 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@data-profile/fingerprint`: the layout, as plain data, with no React. Lay items out
|
|
3
|
+
* with `layoutFingerprint`, derive a form with `formFromItems`, describe it with `describeLayout`.
|
|
4
|
+
* The data types and encoding come from `@data-profile/core`.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
* @module fingerprint
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { Category } from '@data-profile/core';
|
|
11
|
+
import type { Channel } from '@data-profile/core';
|
|
12
|
+
import { DEFAULT_PALETTE } from '@data-profile/core';
|
|
13
|
+
import type { Dimension } from '@data-profile/core';
|
|
14
|
+
import type { Encoding } from '@data-profile/core';
|
|
15
|
+
import { DataError as FingerprintDataError } from '@data-profile/core';
|
|
16
|
+
import type { Item } from '@data-profile/core';
|
|
17
|
+
import type { LegendEntry } from '@data-profile/core';
|
|
18
|
+
import type { LegendGroup } from '@data-profile/core';
|
|
19
|
+
import type { Mark } from '@data-profile/core';
|
|
20
|
+
import { markOpacity } from '@data-profile/core';
|
|
21
|
+
import type { Profile } from '@data-profile/core';
|
|
22
|
+
import { UNKNOWN_CATEGORY_ID } from '@data-profile/core';
|
|
23
|
+
import { UNKNOWN_COLOR } from '@data-profile/core';
|
|
24
|
+
|
|
25
|
+
export { DEFAULT_PALETTE }
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A plain-language summary of what a layout shows, for a screen reader or a caption: the total, the
|
|
29
|
+
* largest categories of the arranging dimension with their counts, which dimension each visual
|
|
30
|
+
* property shows when they differ, and how many items each mark stands for. Every number in it is
|
|
31
|
+
* one the legends also show. Core's `describeProfile`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function describeLayout(layout: FingerprintLayout, unit?: string): string;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* A note pinned to the fingerprint, such as "Mostly fiction". The consumer writes the words; the
|
|
37
|
+
* canvas points a leader at a real mark of the named categories.
|
|
38
|
+
*/
|
|
39
|
+
export declare interface FingerprintAnnotation {
|
|
40
|
+
/** Unique among the annotations. */
|
|
41
|
+
id: string;
|
|
42
|
+
/** Categories the note is about. Hidden when none has a mark. */
|
|
43
|
+
categoryIds: readonly string[];
|
|
44
|
+
/** The dimension those categories belong to. Defaults to the arranging dimension. */
|
|
45
|
+
dimensionId?: string;
|
|
46
|
+
/** The note's headline. */
|
|
47
|
+
title: string;
|
|
48
|
+
/** A sentence under it. */
|
|
49
|
+
body?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** One category of a dimension. Core's `Category`. */
|
|
53
|
+
export declare type FingerprintCategory = Category;
|
|
54
|
+
|
|
55
|
+
/** The visual properties a dimension can drive. `arrange` orders marks along the ridges. Core's `Channel`. */
|
|
56
|
+
export declare type FingerprintChannel = Channel;
|
|
57
|
+
|
|
58
|
+
export { FingerprintDataError }
|
|
59
|
+
|
|
60
|
+
/** One way of grouping the items. Category order is the order marks are laid out in. Core's `Dimension`. */
|
|
61
|
+
export declare type FingerprintDimension = Dimension;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Which dimension drives which visual property, by dimension id. `arrange` orders marks along the
|
|
65
|
+
* ridges. Core's `Encoding`.
|
|
66
|
+
*/
|
|
67
|
+
export declare type FingerprintEncoding = Encoding;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The print's form: its pattern and where its singular points sit. Every number is a small,
|
|
71
|
+
* bounded nudge, so any form still reads as a fingertip. (A mark's *shape* is something else: an
|
|
72
|
+
* encoding.)
|
|
73
|
+
*/
|
|
74
|
+
export declare interface FingerprintForm {
|
|
75
|
+
/** Loop, whorl or arch. */
|
|
76
|
+
pattern: RidgePattern;
|
|
77
|
+
/** Which way a loop opens, or a whorl twists. */
|
|
78
|
+
hand: -1 | 1;
|
|
79
|
+
/** -1 to 1: moves the core left or right of centre. */
|
|
80
|
+
coreX: number;
|
|
81
|
+
/** -1 to 1: moves the core up or down. */
|
|
82
|
+
coreY: number;
|
|
83
|
+
/** 0 to 1: how far the deltas sit from the core; wider reads looser. */
|
|
84
|
+
spread: number;
|
|
85
|
+
/** Degrees, -10 to 10: the whole pattern's lean. */
|
|
86
|
+
tilt: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The fingerprint's data contract. The data types are `@data-profile/core`'s, under the names this
|
|
91
|
+
* package has always used; the rest is the fingerprint's own geometry.
|
|
92
|
+
*/
|
|
93
|
+
/** One thing in the collection, drawn as one mark (below the mark cap). Core's `Item`. */
|
|
94
|
+
export declare type FingerprintItem = Item;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* What `layoutFingerprint` returns: everything a renderer needs, in a fixed frame. Core's `Profile`
|
|
98
|
+
* with its marks placed as `nodes`, and the ridges they sit on.
|
|
99
|
+
*/
|
|
100
|
+
export declare interface FingerprintLayout extends Omit<Profile, "marks"> {
|
|
101
|
+
/** The fixed coordinate frame's width; resizing scales it, never changes it. */
|
|
102
|
+
width: number;
|
|
103
|
+
/** The fixed coordinate frame's height. */
|
|
104
|
+
height: number;
|
|
105
|
+
/** The marks, laid along the ridges from the core outwards. */
|
|
106
|
+
nodes: FingerprintNode[];
|
|
107
|
+
/** The ridges marks sit on, core outwards, as polylines of `[x, y]` points, for renderers that draw them. */
|
|
108
|
+
ridges: (readonly [x: number, y: number])[][];
|
|
109
|
+
/** The form actually drawn, every field resolved. */
|
|
110
|
+
form: FingerprintForm;
|
|
111
|
+
/** Centre-to-centre distance between neighbouring ridges. */
|
|
112
|
+
ridgeSpacing: number;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** One category in a legend, with how its marks are drawn and how many items it holds. Core's `LegendEntry`. */
|
|
116
|
+
export declare type FingerprintLegendEntry = LegendEntry;
|
|
117
|
+
|
|
118
|
+
/** One dimension's legend, and which visual properties that dimension drives. Core's `LegendGroup`. */
|
|
119
|
+
export declare type FingerprintLegendGroup = LegendGroup;
|
|
120
|
+
|
|
121
|
+
/** A laid-out mark: core's `Mark`, placed in the layout's fixed coordinate frame. */
|
|
122
|
+
export declare interface FingerprintNode extends Mark {
|
|
123
|
+
/** Centre, in the layout's frame. */
|
|
124
|
+
x: number;
|
|
125
|
+
/** Centre, in the layout's frame. */
|
|
126
|
+
y: number;
|
|
127
|
+
/** Degrees, the ridge's direction at this mark. */
|
|
128
|
+
rotation: number;
|
|
129
|
+
/** Diameter of the mark's footprint. Area is proportional to weight. */
|
|
130
|
+
size: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* A shape that is the collection's own: derived only from the data, so the same collection always
|
|
135
|
+
* draws the same fingerprint, and it changes slowly as the collection grows. It is a signature,
|
|
136
|
+
* not a chart; say so beside it. The mapping, which a caption can state:
|
|
137
|
+
*
|
|
138
|
+
* - **Pattern.** An arch while there are fewer than 12 items; then a loop when one category of the
|
|
139
|
+
* first dimension holds 40% or more of the items (a focused collection); otherwise a whorl.
|
|
140
|
+
* - **Core across, and loop direction.** Where the second dimension's values sit, on average, in its
|
|
141
|
+
* category order: earlier categories pull the core left, later ones right.
|
|
142
|
+
* - **Core height.** The same for the third dimension.
|
|
143
|
+
* - **Spread.** The share of all categories that have at least one item: broader reads looser.
|
|
144
|
+
* - **Tilt.** From the seed only, so two equal collections still differ slightly.
|
|
145
|
+
*/
|
|
146
|
+
export declare function formFromItems(items: readonly FingerprintItem[], dimensions: readonly FingerprintDimension[], seed?: string): FingerprintForm;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Lays the items out along fingerprint ridges.
|
|
150
|
+
*
|
|
151
|
+
* `encoding` says which dimension arranges the marks and which drive colour, shape and lightness
|
|
152
|
+
* (see `FingerprintEncoding`); left out, the first dimension does all but lightness. Items are
|
|
153
|
+
* sorted by the arranging dimension's category order, then by each other encoded dimension's,
|
|
154
|
+
* then by id, and laid along the ridges from the core outwards, so categories form runs. Mark
|
|
155
|
+
* **area** is proportional to weight; positions only arrange.
|
|
156
|
+
*
|
|
157
|
+
* A pure function of its input: the same items, dimensions, encoding and options give the same
|
|
158
|
+
* layout whatever order the items arrive in and whatever size it is drawn at. The ridges come from
|
|
159
|
+
* `form` (see `formFromItems`). The items array is treated as immutable: work is cached against it.
|
|
160
|
+
*
|
|
161
|
+
* Above `maxMarks` items, consecutive items that agree on **every** encoded dimension share a mark
|
|
162
|
+
* (`itemsPerMark` > 1), so a mark never misrepresents any item in it. Nothing is sampled away.
|
|
163
|
+
*/
|
|
164
|
+
export declare function layoutFingerprint(input: LayoutInput): FingerprintLayout;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* `layoutFingerprint`'s one argument. The items array is treated as immutable: work is cached
|
|
168
|
+
* against it, so pass a new array when the collection changes.
|
|
169
|
+
*/
|
|
170
|
+
export declare interface LayoutInput extends LayoutOptions {
|
|
171
|
+
/** One per mark (below the cap). Unique ids. */
|
|
172
|
+
items: readonly FingerprintItem[];
|
|
173
|
+
/** Every dimension the items carry values for; the encoding picks among them. */
|
|
174
|
+
dimensions: readonly FingerprintDimension[];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Everything `layoutFingerprint` takes besides the data. */
|
|
178
|
+
export declare interface LayoutOptions {
|
|
179
|
+
/** Which dimension drives what. Defaults to the first dimension arranging, colouring and shaping. */
|
|
180
|
+
encoding?: FingerprintEncoding;
|
|
181
|
+
/** Seeds any form field not given, and nothing else. Same seed, same picture. */
|
|
182
|
+
seed?: string;
|
|
183
|
+
/** Overrides the print's form. `formFromItems` derives one from the data. */
|
|
184
|
+
form?: Partial<FingerprintForm>;
|
|
185
|
+
/**
|
|
186
|
+
* Above this many items, marks stand for several items each. Defaults to 600, the most marks a
|
|
187
|
+
* canvas glides smoothly (see `FingerprintCanvas`'s `motion`); raise it for denser prints. A
|
|
188
|
+
* layout can exceed it slightly, since every combination of encoded categories needs a mark.
|
|
189
|
+
*/
|
|
190
|
+
maxMarks?: number;
|
|
191
|
+
/** Ridges never sit further apart than the frame's half-width divided by this. Defaults to 6. */
|
|
192
|
+
minRidges?: number;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export { markOpacity }
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Where each callout goes. Its anchor is a real mark of the categories it names, so the leader
|
|
199
|
+
* never points at empty paper; the label sits in the gutter on the anchor's side, as level with it
|
|
200
|
+
* as the other labels allow. Annotations whose categories have no marks are left out.
|
|
201
|
+
*/
|
|
202
|
+
export declare function placeCallouts(layout: FingerprintLayout, annotations: readonly FingerprintAnnotation[]): PlacedCallout[];
|
|
203
|
+
|
|
204
|
+
/** Where `placeCallouts` puts one annotation, in the layout's frame. */
|
|
205
|
+
export declare interface PlacedCallout {
|
|
206
|
+
/** The annotation placed. */
|
|
207
|
+
annotation: FingerprintAnnotation;
|
|
208
|
+
/** The mark the leader points at: the named categories' mark nearest their centre. */
|
|
209
|
+
anchor: {
|
|
210
|
+
x: number;
|
|
211
|
+
y: number;
|
|
212
|
+
};
|
|
213
|
+
/** Which gutter the label sits in: the side of the print its anchor is on. */
|
|
214
|
+
side: "left" | "right";
|
|
215
|
+
/** Top of the label, in layout units. */
|
|
216
|
+
labelY: number;
|
|
217
|
+
/** 1-based, in reading order: left side top to bottom, then right. */
|
|
218
|
+
number: number;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** The three classes every fingerprint falls into. */
|
|
222
|
+
export declare type RidgePattern = "loop" | "whorl" | "arch";
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* How the ridges behind the marks are drawn. `auto` shows them while a collection is too small for
|
|
226
|
+
* its marks alone to read as a fingerprint, fading out as it fills.
|
|
227
|
+
*/
|
|
228
|
+
export declare interface RidgeStyle {
|
|
229
|
+
/** `auto` (the default), `always` or `never`. */
|
|
230
|
+
show?: "auto" | "always" | "never";
|
|
231
|
+
/** `auto`: full opacity at or below this many items. Defaults to 60. */
|
|
232
|
+
fadeFrom?: number;
|
|
233
|
+
/** `auto`: gone at or above this many items. Defaults to 160. */
|
|
234
|
+
fadeTo?: number;
|
|
235
|
+
/** Opacity at full strength. Defaults to 0.22. */
|
|
236
|
+
opacity?: number;
|
|
237
|
+
/** Any CSS colour. Defaults to `currentColor`. */
|
|
238
|
+
color?: string;
|
|
239
|
+
/** Stroke width as a share of the ridge spacing. Defaults to 0.12. */
|
|
240
|
+
width?: number;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export { UNKNOWN_CATEGORY_ID }
|
|
244
|
+
|
|
245
|
+
export { UNKNOWN_COLOR }
|
|
246
|
+
|
|
247
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataError,
|
|
3
|
+
UNKNOWN_CATEGORY_ID,
|
|
4
|
+
describeLayout,
|
|
5
|
+
formFromItems,
|
|
6
|
+
layoutFingerprint,
|
|
7
|
+
placeCallouts
|
|
8
|
+
} from "./chunk-y8jc1j2x.js";
|
|
9
|
+
|
|
10
|
+
// temp/src/index.ts
|
|
11
|
+
import { DEFAULT_PALETTE, UNKNOWN_COLOR, markOpacity } from "@data-profile/core";
|
|
12
|
+
export {
|
|
13
|
+
placeCallouts,
|
|
14
|
+
markOpacity,
|
|
15
|
+
layoutFingerprint,
|
|
16
|
+
formFromItems,
|
|
17
|
+
describeLayout,
|
|
18
|
+
UNKNOWN_COLOR,
|
|
19
|
+
UNKNOWN_CATEGORY_ID,
|
|
20
|
+
DataError as FingerprintDataError,
|
|
21
|
+
DEFAULT_PALETTE
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
//# debugId=044A7D70804C965764756E2164756E21
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../temp/src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * `@data-profile/fingerprint`: the layout, as plain data, with no React. Lay items out\n * with `layoutFingerprint`, derive a form with `formFromItems`, describe it with `describeLayout`.\n * The data types and encoding come from `@data-profile/core`.\n *\n * @packageDocumentation\n * @module fingerprint\n */\nexport { layoutFingerprint, FingerprintDataError, UNKNOWN_CATEGORY_ID } from \"./layout\";\nexport { DEFAULT_PALETTE, UNKNOWN_COLOR, markOpacity } from \"@data-profile/core\";\nexport { formFromItems } from \"./form\";\nexport { placeCallouts, type PlacedCallout } from \"./callouts\";\nexport { describeLayout } from \"./describe\";\nexport type {\n FingerprintAnnotation,\n FingerprintCategory,\n FingerprintChannel,\n FingerprintDimension,\n FingerprintEncoding,\n FingerprintForm,\n FingerprintItem,\n FingerprintLayout,\n FingerprintLegendEntry,\n FingerprintLegendGroup,\n FingerprintNode,\n LayoutInput,\n LayoutOptions,\n RidgePattern,\n RidgeStyle,\n} from \"./types\";\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;;;;;;AASA;",
|
|
8
|
+
"debugId": "044A7D70804C965764756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@data-profile/fingerprint/react`: the canvas, legends, list and view switch, the
|
|
3
|
+
* `useFingerprint` hook that wires them together, and the built-in renderers.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
* @module fingerprint/react
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { FingerprintAnnotation } from '@data-profile/fingerprint';
|
|
10
|
+
import { FingerprintDataError } from '@data-profile/fingerprint';
|
|
11
|
+
import type { FingerprintDimension } from '@data-profile/fingerprint';
|
|
12
|
+
import type { FingerprintEncoding } from '@data-profile/fingerprint';
|
|
13
|
+
import type { FingerprintForm } from '@data-profile/fingerprint';
|
|
14
|
+
import type { FingerprintItem } from '@data-profile/fingerprint';
|
|
15
|
+
import type { FingerprintLayout } from '@data-profile/fingerprint';
|
|
16
|
+
import type { FingerprintLegendGroup } from '@data-profile/fingerprint';
|
|
17
|
+
import type { FingerprintNode } from '@data-profile/fingerprint';
|
|
18
|
+
import { JSX } from 'react';
|
|
19
|
+
import { markOpacity } from '@data-profile/core';
|
|
20
|
+
import type { ReactNode } from 'react';
|
|
21
|
+
import type { RidgeStyle } from '@data-profile/fingerprint';
|
|
22
|
+
|
|
23
|
+
/** Every mark a dot, shape ignored. Only for when shape must carry nothing. */
|
|
24
|
+
export declare const dotsRenderer: FingerprintRenderer;
|
|
25
|
+
|
|
26
|
+
/** Where callouts go. */
|
|
27
|
+
export declare interface FingerprintCallouts {
|
|
28
|
+
/** `auto` (the default) puts them beside the print when there is room and numbered below it when not. */
|
|
29
|
+
placement?: "auto" | "beside" | "below";
|
|
30
|
+
/** Below this container width, `auto` puts callouts below. Defaults to 640 px. */
|
|
31
|
+
breakpoint?: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The fingerprint itself: ridges, one mark per laid-out node drawn by `renderer`, and optional
|
|
36
|
+
* callouts. Marks move to their new places when the layout's view changes (instantly under reduced
|
|
37
|
+
* motion), and marks outside a selection dim. Both are CSS: a selection re-renders no marks. The SVG is one image to assistive technology, named and described by `title` and
|
|
38
|
+
* `description`; choosing a category is done from the legend or list, which are keyboard
|
|
39
|
+
* reachable, and also by pointer on a mark.
|
|
40
|
+
*/
|
|
41
|
+
export declare function FingerprintCanvas({ layout, title, description, renderer, ridges, selected, onSelect, annotations, callouts, unit, motion, className, }: FingerprintCanvasProps): JSX.Element;
|
|
42
|
+
|
|
43
|
+
/** Props for `FingerprintCanvas`, ready to spread; add a `title`. */
|
|
44
|
+
export declare interface FingerprintCanvasBinding {
|
|
45
|
+
/** The current view's layout. */
|
|
46
|
+
layout: FingerprintLayout;
|
|
47
|
+
/** `describeLayout`'s summary of it, or the data error's message. */
|
|
48
|
+
description: string;
|
|
49
|
+
/** The current selection. */
|
|
50
|
+
selected: FingerprintSelection | null;
|
|
51
|
+
/** Updates the selection. */
|
|
52
|
+
onSelect: (selection: FingerprintSelection | null) => void;
|
|
53
|
+
/** What one item is. */
|
|
54
|
+
unit: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Props of `FingerprintCanvas`. `useFingerprint`'s `canvasProps` supplies most of them. */
|
|
58
|
+
export declare interface FingerprintCanvasProps {
|
|
59
|
+
/** What to draw: from `useFingerprint` (`canvasProps`) or `layoutFingerprint`. */
|
|
60
|
+
layout: FingerprintLayout;
|
|
61
|
+
/** The drawing's accessible name. */
|
|
62
|
+
title: string;
|
|
63
|
+
/** What it shows, in words (`describeLayout` writes one). */
|
|
64
|
+
description: string;
|
|
65
|
+
/** Draws each mark. Defaults to `shapesRenderer`. */
|
|
66
|
+
renderer?: FingerprintRenderer;
|
|
67
|
+
/** How the ridges behind the marks are drawn. Defaults to `{ show: "auto" }`. */
|
|
68
|
+
ridges?: RidgeStyle;
|
|
69
|
+
/** Marks in this category of this dimension are highlighted, the rest dimmed. */
|
|
70
|
+
selected?: FingerprintSelection | null;
|
|
71
|
+
/**
|
|
72
|
+
* Called when a mark is clicked, with its category in the arranging dimension, or null when that
|
|
73
|
+
* is already the selection.
|
|
74
|
+
*/
|
|
75
|
+
onSelect?: (selection: FingerprintSelection | null) => void;
|
|
76
|
+
/** Notes pinned to the print, each with a leader to a mark of the categories it names. */
|
|
77
|
+
annotations?: readonly FingerprintAnnotation[];
|
|
78
|
+
/** Where the annotations go. See `FingerprintCallouts`. */
|
|
79
|
+
callouts?: FingerprintCallouts;
|
|
80
|
+
/** Names what one item is, for the selection announcement. Defaults to "items". */
|
|
81
|
+
unit?: string;
|
|
82
|
+
/** How marks move when the view changes. See `FingerprintMotion`. */
|
|
83
|
+
motion?: FingerprintMotion;
|
|
84
|
+
/** Extra class on the canvas's wrapper. */
|
|
85
|
+
className?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Props for `FingerprintLegend` or `FingerprintList`, for one legend group, ready to spread. */
|
|
89
|
+
export declare interface FingerprintGroupBinding {
|
|
90
|
+
/** The legend group. */
|
|
91
|
+
group: FingerprintLegendGroup;
|
|
92
|
+
/** The current selection. */
|
|
93
|
+
selected: FingerprintSelection | null;
|
|
94
|
+
/** Updates the selection. */
|
|
95
|
+
onSelect: (selection: FingerprintSelection | null) => void;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* One dimension's categories, each drawn as a mark of it would be in the properties this dimension
|
|
100
|
+
* drives (a colour swatch for colour, a neutral shape for shape, a fading tone for lightness), and
|
|
101
|
+
* each a toggle that selects it in the canvas. Render one per `layout.legends` group: the legends
|
|
102
|
+
* are how a keyboard reaches a category, and what names it.
|
|
103
|
+
*/
|
|
104
|
+
export declare function FingerprintLegend({ group, renderer, selected, onSelect, heading, counts, hideEmpty, className, }: FingerprintLegendProps): JSX.Element;
|
|
105
|
+
|
|
106
|
+
/** Props of `FingerprintLegend`. `useFingerprint`'s `legendProps(group)` supplies most of them. */
|
|
107
|
+
export declare interface FingerprintLegendProps {
|
|
108
|
+
/** One dimension's legend, from `layout.legends`. */
|
|
109
|
+
group: FingerprintLegendGroup;
|
|
110
|
+
/** The current selection, from `useFingerprint`. */
|
|
111
|
+
selected?: FingerprintSelection | null;
|
|
112
|
+
/** Called with a category of this group, or null to clear; makes each entry a toggle. */
|
|
113
|
+
onSelect?: (selection: FingerprintSelection | null) => void;
|
|
114
|
+
/** Extra class on the outer element. */
|
|
115
|
+
className?: string;
|
|
116
|
+
/** Draws each entry's swatch; use the canvas's renderer so they match. Defaults to `shapesRenderer`. */
|
|
117
|
+
renderer?: FingerprintRenderer;
|
|
118
|
+
/** Show the dimension's label above its entries. Defaults to true. */
|
|
119
|
+
heading?: boolean;
|
|
120
|
+
/** Show each category's count. Defaults to true. */
|
|
121
|
+
counts?: boolean;
|
|
122
|
+
/** Leave out categories with no items. Defaults to false. */
|
|
123
|
+
hideEmpty?: boolean;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* One dimension as a table: every category with its exact count and share. Render one per
|
|
128
|
+
* `layout.legends` group: together they are the accessible equivalent of the drawing, and the place
|
|
129
|
+
* a callout's claim can be checked.
|
|
130
|
+
*/
|
|
131
|
+
export declare function FingerprintList({ group, unit, linkLabel, selected, onSelect, className, }: FingerprintListProps): JSX.Element;
|
|
132
|
+
|
|
133
|
+
/** Props of `FingerprintList`. `useFingerprint`'s `listProps(group)` supplies most of them. */
|
|
134
|
+
export declare interface FingerprintListProps {
|
|
135
|
+
/** One dimension's legend, from `layout.legends`. */
|
|
136
|
+
group: FingerprintLegendGroup;
|
|
137
|
+
/** The current selection, from `useFingerprint`. */
|
|
138
|
+
selected?: FingerprintSelection | null;
|
|
139
|
+
/** Called with a category of this group, or null to clear; makes each entry a toggle. */
|
|
140
|
+
onSelect?: (selection: FingerprintSelection | null) => void;
|
|
141
|
+
/** Extra class on the outer element. */
|
|
142
|
+
className?: string;
|
|
143
|
+
/** What one item is, e.g. "sets". Defaults to "items". */
|
|
144
|
+
unit?: string;
|
|
145
|
+
/** Text for each category's link, when it has an `href`. Defaults to "Explore". */
|
|
146
|
+
linkLabel?: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** What a renderer's `mark` receives. */
|
|
150
|
+
export declare interface FingerprintMarkProps {
|
|
151
|
+
/** Carries the resolved `color`, `shape` (null when unknown) and `lightness` (null when full strength). */
|
|
152
|
+
node: FingerprintNode;
|
|
153
|
+
/** Prefix for any ids the renderer's `defs` declared, unique to this drawing. */
|
|
154
|
+
idPrefix: string;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* How marks move when the view changes. SVG animates only so many marks smoothly, so above each
|
|
159
|
+
* limit the change is instant instead of stuttering. Under `prefers-reduced-motion` nothing moves.
|
|
160
|
+
*/
|
|
161
|
+
export declare interface FingerprintMotion {
|
|
162
|
+
/**
|
|
163
|
+
* Marks glide to their new places while there are at most this many. Defaults to 800: about what
|
|
164
|
+
* SVG animates smoothly enough (43-50 fps in Chrome); 1,500 gliding marks fell to 16-27 fps. It
|
|
165
|
+
* sits above the default mark cap of 600 because a layout can exceed its cap slightly.
|
|
166
|
+
*/
|
|
167
|
+
glide?: number;
|
|
168
|
+
/**
|
|
169
|
+
* Colours, fills and lightness fade while there are at most this many marks. Defaults to 400:
|
|
170
|
+
* fades on top of a glide cost a third of the frame rate at 600 marks, and nothing at 400.
|
|
171
|
+
*/
|
|
172
|
+
fade?: number;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Draws marks. `mark` draws one mark centred on the origin, `node.size` across, with the ridge
|
|
177
|
+
* running along the x axis: the canvas positions and rotates it, so a renderer never changes
|
|
178
|
+
* layout, counts or selection. It should honour `node.color`, `node.shape` and `node.lightness`
|
|
179
|
+
* (see `markOpacity`), since those carry data. `defs` runs once per drawing. Marks are memoised and
|
|
180
|
+
* selection is drawn by the canvas (dimming the rest), so `mark` must depend on its props alone.
|
|
181
|
+
* The canvas transitions the fill, fill-opacity and stroke of each mark's top-level elements.
|
|
182
|
+
*/
|
|
183
|
+
export declare interface FingerprintRenderer {
|
|
184
|
+
/** A name for debugging and for telling renderers apart. */
|
|
185
|
+
name: string;
|
|
186
|
+
/** Shared SVG definitions (gradients, patterns, symbols), rendered once per drawing. */
|
|
187
|
+
defs?: (props: {
|
|
188
|
+
idPrefix: string;
|
|
189
|
+
legends: readonly FingerprintLegendGroup[];
|
|
190
|
+
}) => ReactNode;
|
|
191
|
+
/** Draws one mark. */
|
|
192
|
+
mark: (props: FingerprintMarkProps) => ReactNode;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** A category of one dimension: what a legend entry or a mark selects. */
|
|
196
|
+
export declare interface FingerprintSelection {
|
|
197
|
+
/** The dimension the category belongs to. */
|
|
198
|
+
dimensionId: string;
|
|
199
|
+
/** The category's id, or `UNKNOWN_CATEGORY_ID`. */
|
|
200
|
+
categoryId: string;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** What `useFingerprint` returns. */
|
|
204
|
+
export declare interface FingerprintState {
|
|
205
|
+
/** The current view's layout; empty while `error` is set. */
|
|
206
|
+
layout: FingerprintLayout;
|
|
207
|
+
/** A plain-language summary of the layout, for the canvas's description. */
|
|
208
|
+
description: string;
|
|
209
|
+
/** Invalid data (duplicate ids, lightness on an unordered dimension, …), or null. */
|
|
210
|
+
error: FingerprintDataError | null;
|
|
211
|
+
/** The views, as given or one per dimension. */
|
|
212
|
+
views: readonly FingerprintView[];
|
|
213
|
+
/** The active view. */
|
|
214
|
+
view: FingerprintView | undefined;
|
|
215
|
+
/** The active view's id. */
|
|
216
|
+
viewId: string;
|
|
217
|
+
/** Switches view and clears the selection. */
|
|
218
|
+
setViewId: (viewId: string) => void;
|
|
219
|
+
/** The selected category of a dimension, or null. */
|
|
220
|
+
selected: FingerprintSelection | null;
|
|
221
|
+
/** Selects a category of a dimension, or clears with null. */
|
|
222
|
+
setSelected: (selection: FingerprintSelection | null) => void;
|
|
223
|
+
/** Spread onto `FingerprintCanvas`, with a `title`. */
|
|
224
|
+
canvasProps: FingerprintCanvasBinding;
|
|
225
|
+
/** Spread onto a `FingerprintLegend` for one group. */
|
|
226
|
+
legendProps: (group: FingerprintLegendGroup) => FingerprintGroupBinding;
|
|
227
|
+
/** Spread onto a `FingerprintList` for one group, with `unit` included. */
|
|
228
|
+
listProps: (group: FingerprintLegendGroup) => FingerprintGroupBinding & {
|
|
229
|
+
unit: string;
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** A named way of looking at the items: which dimension drives which visual property. */
|
|
234
|
+
export declare interface FingerprintView {
|
|
235
|
+
/** Unique among the views. */
|
|
236
|
+
id: string;
|
|
237
|
+
/** The switch's button text. */
|
|
238
|
+
label: string;
|
|
239
|
+
/** Which dimension drives what in this view. */
|
|
240
|
+
encoding: FingerprintEncoding;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** One pressed button per view. */
|
|
244
|
+
export declare function FingerprintViewSwitch({ views, value, onChange, label, className, }: FingerprintViewSwitchProps): JSX.Element;
|
|
245
|
+
|
|
246
|
+
/** Props of `FingerprintViewSwitch`. */
|
|
247
|
+
export declare interface FingerprintViewSwitchProps {
|
|
248
|
+
/** The views, in button order. */
|
|
249
|
+
views: readonly FingerprintView[];
|
|
250
|
+
/** The active view's id. */
|
|
251
|
+
value: string;
|
|
252
|
+
/** Called with a view's id when its button is pressed. */
|
|
253
|
+
onChange: (viewId: string) => void;
|
|
254
|
+
/** The group's accessible name. Defaults to "View". */
|
|
255
|
+
label?: string;
|
|
256
|
+
/** Extra class on the group. */
|
|
257
|
+
className?: string;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export { markOpacity }
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* The default: five shapes (circle, rounded square, triangle, diamond, hexagon) by `node.shape`, a
|
|
264
|
+
* ring in the mark's colour when its shape category is unknown, and lightness as opacity.
|
|
265
|
+
*/
|
|
266
|
+
export declare const shapesRenderer: FingerprintRenderer;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* The state a fingerprint needs: the active view, the selected category, the layout for both, and
|
|
270
|
+
* prop bundles that wire them to the components. The form is derived from all the items and
|
|
271
|
+
* dimensions, never the active view, so the ridges hold still and only the marks move when the
|
|
272
|
+
* view changes. Changing view clears the selection. Invalid data comes back as `error` with an
|
|
273
|
+
* empty layout, rather than throwing out of render.
|
|
274
|
+
*/
|
|
275
|
+
export declare function useFingerprint({ items, dimensions, views: given, initialViewId, form, seed, maxMarks, unit, }: UseFingerprintOptions): FingerprintState;
|
|
276
|
+
|
|
277
|
+
/** What `useFingerprint` takes. */
|
|
278
|
+
export declare interface UseFingerprintOptions {
|
|
279
|
+
/** One per mark (below the cap), unique ids. Treated as immutable: pass a new array to change it. */
|
|
280
|
+
items: readonly FingerprintItem[];
|
|
281
|
+
/** Every dimension the items carry values for. */
|
|
282
|
+
dimensions: readonly FingerprintDimension[];
|
|
283
|
+
/**
|
|
284
|
+
* The ways of looking, in switcher order. Defaults to one view per dimension, each driving
|
|
285
|
+
* colour, shape and arrangement from that dimension alone.
|
|
286
|
+
*/
|
|
287
|
+
views?: readonly FingerprintView[];
|
|
288
|
+
/** The view shown first. Defaults to the first. */
|
|
289
|
+
initialViewId?: string;
|
|
290
|
+
/** Overrides fields of the form `formFromItems` derives from the data. */
|
|
291
|
+
form?: Partial<FingerprintForm>;
|
|
292
|
+
/** Seeds the form's free fields. Same seed, same picture. Defaults to "fingerprint". */
|
|
293
|
+
seed?: string;
|
|
294
|
+
/** Above this many items, marks stand for several. Defaults to 600. */
|
|
295
|
+
maxMarks?: number;
|
|
296
|
+
/** What one item is, for the description and announcements. Defaults to "items". */
|
|
297
|
+
unit?: string;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export { }
|