Skip to content

Commit c76aba1

Browse files
Filmbostock
andauthored
document text (#1381)
* document text * better text * shorter + links * edits --------- Co-authored-by: Mike Bostock <[email protected]>
1 parent bb27526 commit c76aba1

File tree

2 files changed

+209
-17
lines changed

2 files changed

+209
-17
lines changed

src/marks/text.d.ts

Lines changed: 202 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,238 @@ import type {ChannelValue, ChannelValueIntervalSpec, ChannelValueSpec} from "../
22
import type {Interval} from "../interval.js";
33
import type {Data, FrameAnchor, MarkOptions, RenderableMark} from "../mark.js";
44

5-
export type TextAnchor = "start" | "middle" | "end";
6-
7-
export type LineAnchor = "top" | "middle" | "bottom";
8-
9-
export type TextOverflow =
10-
| "clip"
11-
| "ellipsis"
12-
| "clip-start"
13-
| "clip-end"
14-
| "ellipsis-start"
15-
| "ellipsis-middle"
16-
| "ellipsis-end";
17-
5+
/** Options for the text mark. */
186
export interface TextOptions extends MarkOptions {
7+
/**
8+
* The horizontal position channel specifying the text’s anchor point,
9+
* typically bound to the *x* scale.
10+
*/
1911
x?: ChannelValueSpec;
12+
13+
/**
14+
* The vertical position channel specifying the text’s anchor point, typically
15+
* bound to the *y* scale.
16+
*/
2017
y?: ChannelValueSpec;
18+
19+
/**
20+
* The text contents channel, possibly with line breaks (\n, \r\n, or \r). If
21+
* not specified, defaults to the zero-based index [0, 1, 2, …].
22+
*/
2123
text?: ChannelValue;
24+
25+
/**
26+
* The frame anchor specifies defaults for **x** and **y**, along with
27+
* **textAnchor** and **lineAnchor**, based on the plot’s frame; it may be one
28+
* of the four sides (*top*, *right*, *bottom*, *left*), one of the four
29+
* corners (*top-left*, *top-right*, *bottom-right*, *bottom-left*), or the
30+
* *middle* of the frame.
31+
*/
2232
frameAnchor?: FrameAnchor;
23-
textAnchor?: TextAnchor;
24-
lineAnchor?: LineAnchor;
33+
34+
/**
35+
* The [text anchor][1] controls how text is aligned (typically horizontally)
36+
* relative to its anchor point; it is one of *start*, *end*, or *middle*. If
37+
* the frame anchor is *left*, *top-left*, or *bottom-left*, the default text
38+
* anchor is *start*; if the frame anchor is *right*, *top-right*, or
39+
* *bottom-right*, the default is *end*; otherwise it is *middle*.
40+
*
41+
* [1]: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-anchor
42+
*/
43+
textAnchor?: "start" | "middle" | "end";
44+
45+
/**
46+
* The line anchor controls how text is aligned (typically vertically)
47+
* relative to its anchor point; it is one of *top*, *bottom*, or *middle*. If
48+
* the frame anchor is *top*, *top-left*, or *top-right*, the default line
49+
* anchor is *top*; if the frame anchor is *bottom*, *bottom-right*, or
50+
* *bottom-left*, the default is *bottom*; otherwise it is *middle*.
51+
*/
52+
lineAnchor?: "top" | "middle" | "bottom";
53+
54+
/**
55+
* The line height in ems; defaults to 1. The line height affects the
56+
* (typically vertical) separation between adjacent baselines of text, as well
57+
* as the separation between the text and its anchor point.
58+
*/
2559
lineHeight?: number;
60+
61+
/**
62+
* The line width in ems (e.g., 10 for about 20 characters); defaults to
63+
* infinity, disabling wrapping and clipping.
64+
*
65+
* If **textOverflow** is null, lines will be wrapped at the specified length.
66+
* If a line is split at a soft hyphen (\xad), a hyphen (-) will be displayed
67+
* at the end of the line. If **textOverflow** is not null, lines will be
68+
* clipped according to the given strategy.
69+
*/
2670
lineWidth?: number;
27-
textOverflow?: TextOverflow;
71+
72+
/**
73+
* How truncate (or wrap) lines of text longer than the given **lineWidth**;
74+
* one of:
75+
*
76+
* - null (default) - preserve overflowing characters (and wrap if needed)
77+
* - *clip* or *clip-end* - remove characters from the end
78+
* - *clip-start* - remove characters from the start
79+
* - *ellipsis* or *ellipsis-end* - replace characters from the end with an ellipsis (…)
80+
* - *ellipsis-start* - replace characters from the start with an ellipsis (…)
81+
* - *ellipsis-middle* - replace characters from the middle with an ellipsis (…)
82+
*
83+
* If no **title** was specified, if text requires truncation, a title
84+
* containing the non-truncated text will be implicitly added.
85+
*/
86+
textOverflow?:
87+
| null
88+
| "clip"
89+
| "ellipsis"
90+
| "clip-start"
91+
| "clip-end"
92+
| "ellipsis-start"
93+
| "ellipsis-middle"
94+
| "ellipsis-end";
95+
96+
/**
97+
* If true, changes the default **fontFamily** to *monospace*, and uses
98+
* simplified monospaced text metrics calculations.
99+
*/
28100
monospace?: boolean;
101+
102+
/**
103+
* The [font-family][1]; a constant; defaults to the plot’s font family, which
104+
* is typically [*system-ui*][2].
105+
*
106+
* [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/font-family
107+
* [2]: https://drafts.csswg.org/css-fonts-4/#valdef-font-family-system-ui
108+
*/
29109
fontFamily?: string;
110+
111+
/**
112+
* The [font size][1] in pixels; either a constant or a channel; defaults to
113+
* the plot’s font size, which is typically 10. When a number, it is
114+
* interpreted as a constant; otherwise it is interpreted as a channel.
115+
*
116+
* [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/font-size
117+
*/
30118
fontSize?: ChannelValue;
119+
120+
/**
121+
* The [font style][1]; a constant; defaults to the plot’s font style, which
122+
* is typically *normal*.
123+
*
124+
* [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/font-style
125+
*/
31126
fontStyle?: string;
127+
128+
/**
129+
* The [font variant][1]; a constant; if the **text** channel contains numbers
130+
* or dates, defaults to *tabular-nums* to facilitate comparing numbers;
131+
* otherwise defaults to the plot’s font style, which is typically *normal*.
132+
*
133+
* [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant
134+
*/
32135
fontVariant?: string;
136+
137+
/**
138+
* The [font weight][1]; a constant; defaults to the plot’s font weight, which
139+
* is typically *normal*.
140+
*
141+
* [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
142+
*/
33143
fontWeight?: string | number;
144+
145+
/**
146+
* The rotation angle in degrees clockwise; a constant or a channel; defaults
147+
* to 0°. When a number, it is interpreted as a constant; otherwise it is
148+
* interpreted as a channel.
149+
*/
34150
rotate?: ChannelValue;
35151
}
36152

153+
/** Options for the textX mark. */
37154
export interface TextXOptions extends Omit<TextOptions, "y"> {
155+
/**
156+
* The vertical position of the text’s anchor point, typically bound to the
157+
* *y* scale.
158+
*/
38159
y?: ChannelValueIntervalSpec;
160+
161+
/**
162+
* An interval (such as *day* or a number), to transform **y** values to the
163+
* middle of the interval.
164+
*/
39165
interval?: Interval;
40166
}
41167

168+
/** Options for the textY mark. */
42169
export interface TextYOptions extends Omit<TextOptions, "x"> {
170+
/**
171+
* The horizontal position of the text’s anchor point, typically bound to the
172+
* *x* scale.
173+
*/
43174
x?: ChannelValueIntervalSpec;
175+
176+
/**
177+
* An interval (such as *day* or a number), to transform **x** values to the
178+
* middle of the interval.
179+
*/
44180
interval?: Interval;
45181
}
46182

183+
/**
184+
* Returns a new text mark for the given *data* and *options*. The **text**
185+
* channel specifies the textual contents of the mark, which may be preformatted
186+
* with line breaks (\n, \r\n, or \r), or wrapped or clipped using the
187+
* **lineWidth** and **textOverflow** options.
188+
*
189+
* If **text** contains numbers or dates, a default formatter will be applied,
190+
* and the **fontVariant** will default to *tabular-nums* instead of *normal*.
191+
* For more control, consider [*number*.toLocaleString][1],
192+
* [*date*.toLocaleString][2], [d3-format][3], or [d3-time-format][4]. If
193+
* **text** is not specified, it defaults to the identity function for primitive
194+
* data (such as numbers, dates, and strings), and to the zero-based index [0,
195+
* 1, 2, …] for objects (so that something identifying is visible by default).
196+
*
197+
* If either **x** or **y** is not specified, the default is determined by the
198+
* **frameAnchor** option. If none of **x**, **y**, and **frameAnchor** are
199+
* specified, *data* is assumed to be an array of pairs [[*x₀*, *y₀*], [*x₁*,
200+
* *y₁*], [*x₂*, *y₂*], …] such that **x** = [*x₀*, *x₁*, *x₂*, …] and **y** =
201+
* [*y₀*, *y₁*, *y₂*, …].
202+
*
203+
* [1]: https://observablehq.com/@mbostock/number-formatting
204+
* [2]: https://observablehq.com/@mbostock/date-formatting
205+
* [3]: https://github.com/d3/d3-format
206+
* [4]: https://github.com/d3/d3-time-format
207+
*/
47208
export function text(data?: Data, options?: TextOptions): Text;
48209

210+
/**
211+
* Like text, but **x** defaults to the identity function, assuming that *data*
212+
* = [*x₀*, *x₁*, *x₂*, …]. For example to display tick label-like marks at the
213+
* top of the frame:
214+
*
215+
* ```js
216+
* Plot.textX([10, 15, 20, 25, 30], {frameAnchor: "top"})
217+
* ```
218+
*
219+
* If an **interval** is specified, such as *day*, **y** is transformed to the
220+
* middle of the interval.
221+
*/
49222
export function textX(data?: Data, options?: TextXOptions): Text;
50223

224+
/**
225+
* Like text, but **y** defaults to the identity function, assuming that *data*
226+
* = [*y₀*, *y₁*, *y₂*, …]. For example to display tick label-like marks on the
227+
* right of the frame:
228+
*
229+
* ```js
230+
* Plot.textY([10, 15, 20, 25, 30], {frameAnchor: "right"})
231+
* ```
232+
*
233+
* If an **interval** is specified, such as *day*, **x** is transformed to the
234+
* middle of the interval.
235+
*/
51236
export function textY(data?: Data, options?: TextYOptions): Text;
52237

238+
/** The text mark. */
53239
export class Text extends RenderableMark {}

test/plots/text-overflow.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,13 @@ export async function textOverflow() {
4141
"👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩👁️‍🗨️👩‍❤️‍💋‍👩", // composed emoji
4242
"🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿.🧑🏾.👨🏻.👧🏼.👦🏽.🧒🏿" // fitz modifiers
4343
];
44-
const options: Plot.TextOverflow[] = ["clip-start", "clip-end", "ellipsis-start", "ellipsis-middle", "ellipsis-end"];
44+
const options: Plot.TextOptions["textOverflow"][] = [
45+
"clip-start",
46+
"clip-end",
47+
"ellipsis-start",
48+
"ellipsis-middle",
49+
"ellipsis-end"
50+
];
4551
return Plot.plot({
4652
width: 800,
4753
marginLeft: 180,

0 commit comments

Comments
 (0)