Skip to content

Commit 2ac08e2

Browse files
Filmbostock
andauthored
documentation for the tree mark and the treeLink, treeNode transforms (#1351)
* documentation for the tree mark and the treeLink, treeNode transforms * tweaks * tweaks --------- Co-authored-by: Mike Bostock <mbostock@gmail.com>
1 parent d82fbfb commit 2ac08e2

4 files changed

Lines changed: 196 additions & 0 deletions

File tree

src/marks/tree.d.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,47 @@ import type {TextOptions} from "./text.js";
66

77
// TODO tree channels, e.g., "node:name" | "node:path" | "node:internal"?
88
export interface TreeOptions extends DotOptions, LinkOptions, TextOptions, TreeTransformOptions {
9+
/**
10+
* Whether to represent the node with a dot; defaults to true unless a
11+
* **marker** is specified.
12+
*/
913
dot?: boolean;
14+
/**
15+
* The **stroke** color for the text mark to improve the legibility of labels
16+
* atop other marks by creating a halo effect; defaults to *white*.
17+
*/
1018
textStroke?: MarkOptions["stroke"];
1119
}
1220

21+
/**
22+
* Transforms a tabular dataset into a hierarchy according to the given **path**
23+
* input channel, which typically contains slash-separated strings; then
24+
* executes a tree layout algorithm, by default Reingold–Tilford’s “tidy”
25+
* algorithm, to compute *x* and *y* output channels; these channels can then be
26+
* fed to other marks to construct a node-link diagram.
27+
*
28+
* These options control how the tabular data is organized into a hierarchy:
29+
*
30+
* * **path** - a channel specifying each node’s hierarchy location; defaults to identity
31+
* * **delimiter** - the path separator; defaults to forward slash (/)
32+
*
33+
* These options control how the node-link diagram is laid out:
34+
*
35+
* * **treeLayout** - a tree layout algorithm; defaults to [d3.tree](https://github.com/d3/d3-hierarchy/blob/main/README.md#tree)
36+
* * **treeAnchor** - a tree layout orientation, either *left* or *right*; defaults to *left*
37+
* * **treeSort** - a node comparator, or null to preserve input order
38+
* * **treeSeparation** - a node separation function, or null for uniform separation
39+
*/
1340
export function tree(data?: Data, options?: TreeOptions): CompoundMark;
1441

42+
/**
43+
* Shorthand for Plot.tree using
44+
* [d3.cluster](https://github.com/d3/d3-hierarchy/blob/main/README.md#cluster)
45+
* as the **treeLayout** option, placing leaf nodes of the tree at the same
46+
* depth. Equivalent to:
47+
*
48+
* ```js
49+
* Plot.tree(data, {...options, treeLayout: d3.cluster})
50+
* ```
51+
*/
1552
export function cluster(data?: Data, options?: TreeOptions): CompoundMark;

src/transforms/tree.d.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,107 @@ import type {ChannelValue} from "../channel.js";
22
import type {CompareFunction, Transformed} from "./basic.js";
33

44
export interface TreeTransformOptions {
5+
/**
6+
* The location of each node in the hierarchy; typically slash-separated
7+
* strings, as with UNIX-based file systems or URLs. Defaults to identity,
8+
* assuming the mark’s data are path strings.
9+
*/
510
path?: ChannelValue;
11+
12+
/**
13+
* The path separator, used for inferring the hierarchy from the **path**
14+
* channel; defaults to forward slash (/).
15+
*/
616
delimiter?: string;
17+
18+
/**
19+
* How to orient the tree. If the **treeAnchor** is *left*, the root of the
20+
* tree will be aligned with the left side of the frame; if **treeAnchor** is
21+
* *right*, the root of the tree will be aligned with the right side of the
22+
* frame; use the **insetLeft** and **insetRight** *x* scale options if
23+
* horizontal padding is desired, say to make room for labels.
24+
*/
725
treeAnchor?: "left" | "right";
26+
27+
/**
28+
* How to layout the tree. The default **treeLayout** implements the
29+
* Reingold–Tilford “tidy” algorithm. Use
30+
* [d3.cluster](https://github.com/d3/d3-hierarchy/blob/main/README.md#cluster)
31+
* instead to align leaf nodes; see also Plot.cluster.
32+
*/
833
treeLayout?: () => any;
34+
35+
/**
36+
* How much space to reserve between adjacent nodes in the layout. If the
37+
* **treeSeparation** is not null, it is a function that is passed two nodes
38+
* in the hierarchy and returns the desired (relative) amount of separation;
39+
* see [d3-hierarchy’s
40+
* _tree_.separation](https://github.com/d3/d3-hierarchy/blob/main/README.md#tree_separation)
41+
* for more. By default, non-siblings are at least twice as far apart as
42+
* siblings.
43+
*/
944
treeSeparation?: CompareFunction | null;
45+
46+
/**
47+
* How to order nodes prior to laying them out. If the **treeSort** option is
48+
* not null, it is typically a function that is passed two nodes in the
49+
* hierarchy and compares them, similar to
50+
* [_array_.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort);
51+
* see [d3-hierarchy’s
52+
* _node_.sort](https://github.com/d3/d3-hierarchy/blob/main/README.md#node_sort)
53+
* for more. The **treeSort** option can also be specified as a string, in
54+
* which case it refers either to a named column in data, or if it starts with
55+
* “node:”, a node value such as node:name.
56+
*/
1057
treeSort?: CompareFunction | {node: (node: any) => any} | string | null;
1158
}
1259

60+
/**
61+
* Populates the *x* and *y* channels with the positions for each node, and
62+
* applies a default **frameAnchor** based on the specified **treeAnchor**. This
63+
* transform is intended to be used with dot, text, and other point-based marks.
64+
* This transform is rarely used directly; see the tree mark.
65+
*
66+
* The treeNode transform will derive output columns for any *options* that have
67+
* one of the following named node values:
68+
*
69+
* * *node:name* - the node’s name (the last part of its path)
70+
* * *node:path* - the node’s full, normalized, slash-separated path
71+
* * *node:internal* - true if the node is internal, or false for leaves
72+
* * *node:depth* - the distance from the node to the root
73+
* * *node:height* - the distance from the node to its deepest descendant
74+
*
75+
* In addition, if any option value is specified as an object with a **node**
76+
* method, a derived output column will be generated by invoking the **node**
77+
* method for each node in the tree.
78+
*/
1379
export function treeNode<T>(options?: T & TreeTransformOptions): Transformed<T>;
1480

81+
/**
82+
* Populates the *x1*, *y1*, *x2*, and *y2* channels, and applies the following
83+
* defaults: **curve** is *bump-x*, **stroke** is #555, **strokeWidth** is 1.5,
84+
* and **strokeOpacity** is 0.5. This transform is intended to be used with
85+
* link, arrow, and other two-point-based marks. This transform is rarely used
86+
* directly; see the tree mark.
87+
*
88+
* The treeLink transform will derive output columns for any *options* that have
89+
* one of the following named link values:
90+
*
91+
* * *node:name* - the child node’s name (the last part of its path)
92+
* * *node:path* - the child node’s full, normalized, slash-separated path
93+
* * *node:internal* - true if the child node is internal, or false for leaves
94+
* * *node:depth* - the distance from the child node to the root
95+
* * *node:height* - the distance from the child node to its deepest descendant
96+
* * *parent:name* - the parent node’s name (the last part of its path)
97+
* * *parent:path* - the parent node’s full, normalized, slash-separated path
98+
* * *parent:depth* - the distance from the parent node to the root
99+
* * *parent:height* - the distance from the parent node to its deepest descendant
100+
*
101+
* In addition, if any option value is specified as an object with a **node**
102+
* method, a derived output column will be generated by invoking the **node**
103+
* method for each child node in the tree; likewise if any option value is
104+
* specified as an object with a **link** method, a derived output column will
105+
* be generated by invoking the **link** method for each link in the tree, being
106+
* passed two node arguments, the child and the parent.
107+
*/
15108
export function treeLink<T>(options?: T & TreeTransformOptions): Transformed<T>;

test/output/greekGodsExplicit.svg

Lines changed: 45 additions & 0 deletions
Loading

test/plots/greek-gods.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,24 @@ Chaos Tartarus`
1818
marks: [Plot.tree(gods)]
1919
});
2020
}
21+
22+
export async function greekGodsExplicit() {
23+
const gods = `Chaos Gaia Mountains
24+
Chaos Gaia Pontus
25+
Chaos Gaia Uranus
26+
Chaos Eros
27+
Chaos Erebus
28+
Chaos Tartarus`.split("\n");
29+
return Plot.plot({
30+
axis: null,
31+
insetLeft: 10,
32+
insetTop: 20,
33+
insetBottom: 20,
34+
insetRight: 120,
35+
marks: [
36+
Plot.link(gods, Plot.treeLink({stroke: "node:internal", delimiter: " "})),
37+
Plot.dot(gods, Plot.treeNode({fill: "node:internal", delimiter: " "})),
38+
Plot.text(gods, Plot.treeNode({text: "node:name", stroke: "white", fill: "currentColor", dx: 6, delimiter: " "}))
39+
]
40+
});
41+
}

0 commit comments

Comments
 (0)