diff --git a/docs/marks/tree.md b/docs/marks/tree.md index 7ea61bbce2..be67690ce5 100644 --- a/docs/marks/tree.md +++ b/docs/marks/tree.md @@ -32,7 +32,7 @@ function indent() { # Tree mark -The **tree mark** produces tree diagrams using the [tree transform](../transforms/tree.md). It is a [composite mark](../features/marks.md#marks-marks), consisting of a [link](./link.md) to render links from parent to child, an optional [dot](./dot.md) for nodes, and a [text](./text.md) for node labels. The link mark uses the [treeLink transform](../transforms/tree.md#treelink-options), while the dot and text marks use the [treeNode transform](../transforms/tree.md#treenode-options). +The **tree mark** produces tree diagrams using the [tree transform](../transforms/tree.md). It is a [composite mark](../features/marks.md#marks-marks), consisting of a [link](./link.md) to render links from parent to child, an optional [dot](./dot.md) for nodes, and one or two [text](./text.md) for node labels. The link mark uses the [treeLink transform](../transforms/tree.md#treelink-options), while the dot and text marks use the [treeNode transform](../transforms/tree.md#treenode-options). For example, here is a little family tree of Greek gods. @@ -41,7 +41,8 @@ For example, here is a little family tree of Greek gods. Plot.plot({ axis: null, height: 100, - margin: 20, + margin: 10, + marginLeft: 35, marginRight: 120, marks: [ Plot.tree(gods, {textStroke: "var(--vp-c-bg)"}) @@ -63,6 +64,7 @@ As a more complete example, here is a visualization of a software package hierar Plot.plot({ axis: null, margin: 10, + marginLeft: 30, marginRight: 160, width: 688, height: 1800, @@ -80,6 +82,7 @@ The **treeLayout** option specifies the layout algorithm. The tree mark uses the Plot.plot({ axis: null, margin: 10, + marginLeft: 30, marginRight: 160, width: 688, height: 2400, @@ -148,11 +151,19 @@ The following options are supported: * **title** - the text and dot title; defaults to *node:path* * **text** - the text label; defaults to *node:name* * **textStroke** - the text stroke; defaults to *white* -* **dx** - the text horizontal offset; defaults to 6 if left-anchored, or -6 if right-anchored +* **textLayout** - the text anchoring layout +* **dx** - the text horizontal offset; defaults to 6 * **dy** - the text vertical offset; defaults to 0 Any additional *options* are passed through to the constituent link, dot, and text marks and their corresponding treeLink or treeNode transform. +The **textLayout** option controls how text labels are anchored to the node. Two layouts are supported: + +* *mirrored* - leaf-node labels are left-anchored, and non-leaf nodes right-anchored +* *normal* - all labels are left-anchored + +If the **treeLayout** is d3.tree or d3.cluster, the **textLayout** defaults to *mirrored*; otherwise it defaults to *normal*. + ## tree(*data*, *options*) ```js @@ -167,4 +178,4 @@ Returns a new tree mark with the given *data* and *options*. Plot.cluster(flare, {path: "name", delimiter: "."}) ``` -Like [tree](#tree-data-options), except sets the **treeLayout** option to [d3.cluster](https://github.com/d3/d3-hierarchy/blob/main/README.md#cluster), aligning leaf nodes. +Like [tree](#tree-data-options), except sets the **treeLayout** option to [d3.cluster](https://github.com/d3/d3-hierarchy/blob/main/README.md#cluster), aligning leaf nodes, and defaults the **textLayout** option to *mirrored*. diff --git a/docs/transforms/tree.md b/docs/transforms/tree.md index 8c573c0dd0..3212e2eab5 100644 --- a/docs/transforms/tree.md +++ b/docs/transforms/tree.md @@ -88,6 +88,7 @@ The treeNode transform will derive output columns for any *options* that have on * *node:name* - the node’s name (the last part of its path) * *node:path* - the node’s full, normalized, slash-separated path * *node:internal* - true if the node is internal, or false for leaves +* *node:external* - true if the node is a leaf, or false for internal nodes * *node:depth* - the distance from the node to the root * *node:height* - the distance from the node to its deepest descendant @@ -102,6 +103,7 @@ The treeLink transform will likewise derive output columns for any *options* tha * *node:name* - the child node’s name (the last part of its path) * *node:path* - the child node’s full, normalized, slash-separated path * *node:internal* - true if the child node is internal, or false for leaves +* *node:external* - true if the child node is a leaf, or false for internal nodes * *node:depth* - the distance from the child node to the root * *node:height* - the distance from the child node to its deepest descendant * *parent:name* - the parent node’s name (the last part of its path) diff --git a/src/marks/tree.d.ts b/src/marks/tree.d.ts index 7798218484..de24023add 100644 --- a/src/marks/tree.d.ts +++ b/src/marks/tree.d.ts @@ -4,7 +4,7 @@ import type {DotOptions} from "./dot.js"; import type {LinkOptions} from "./link.js"; import type {TextOptions} from "./text.js"; -// TODO tree channels, e.g., "node:name" | "node:path" | "node:internal"? +// TODO tree channels, e.g., "node:name" | "node:path" | "node:internal" | "node:external"? /** Options for the compound tree mark. */ export interface TreeOptions extends DotOptions, LinkOptions, TextOptions, TreeTransformOptions { @@ -19,6 +19,14 @@ export interface TreeOptions extends DotOptions, LinkOptions, TextOptions, TreeT * atop other marks by creating a halo effect; defaults to *white*. */ textStroke?: MarkOptions["stroke"]; + + /** + * Layout for node labels: if *mirrored*, leaf-node labels are left-anchored, + * and non-leaf nodes right-anchored (with a -dx offset). If *normal*, all + * labels are left-anchored. Defaults to *mirrored* unless a **treeLayout** + * has been specified. + */ + textLayout?: "mirrored" | "normal"; } /** @@ -40,7 +48,7 @@ export function tree(data?: Data, options?: TreeOptions): CompoundMark; * option, placing leaf nodes of the tree at the same depth. Equivalent to: * * ```js - * Plot.tree(data, {...options, treeLayout: d3.cluster}) + * Plot.tree(data, {...options, treeLayout: d3.cluster, textLayout: "mirrored"}) * ``` * * [1]: https://github.com/d3/d3-hierarchy/blob/main/README.md#cluster diff --git a/src/marks/tree.js b/src/marks/tree.js index ebc6bf02e1..4345f08de4 100644 --- a/src/marks/tree.js +++ b/src/marks/tree.js @@ -1,10 +1,11 @@ -import {cluster as Cluster} from "d3"; -import {isNoneish} from "../options.js"; +import {cluster as Cluster, tree as Tree} from "d3"; import {marks} from "../mark.js"; +import {isNoneish} from "../options.js"; import {maybeTreeAnchor, treeLink, treeNode} from "../transforms/tree.js"; import {dot} from "./dot.js"; import {link} from "./link.js"; import {text} from "./text.js"; +import {keyword} from "../options.js"; export function tree( data, @@ -27,14 +28,38 @@ export function tree( title = "node:path", dx, dy, + textAnchor, + treeLayout = Tree, + textLayout = treeLayout === Tree || treeLayout === Cluster ? "mirrored" : "normal", ...options } = {} ) { if (dx === undefined) dx = maybeTreeAnchor(options.treeAnchor).dx; + if (textAnchor !== undefined) throw new Error("textAnchor is not a configurable tree option"); + textLayout = keyword(textLayout, "textLayout", ["mirrored", "normal"]); + + function treeText(textOptions) { + return text( + data, + treeNode({ + treeLayout, + text: textText, + fill: fill === undefined ? "currentColor" : fill, + stroke: textStroke, + dx, + dy, + title, + ...textOptions, + ...options + }) + ); + } + return marks( link( data, treeLink({ + treeLayout, markerStart, markerEnd, stroke: stroke !== undefined ? stroke : fill === undefined ? "node:internal" : fill, @@ -48,20 +73,16 @@ export function tree( ...options }) ), - dotDot ? dot(data, treeNode({fill: fill === undefined ? "node:internal" : fill, title, ...options})) : null, + dotDot + ? dot(data, treeNode({treeLayout, fill: fill === undefined ? "node:internal" : fill, title, ...options})) + : null, textText != null - ? text( - data, - treeNode({ - text: textText, - fill: fill === undefined ? "currentColor" : fill, - stroke: textStroke, - dx, - dy, - title, - ...options - }) - ) + ? textLayout === "mirrored" + ? [ + treeText({textAnchor: "start", treeFilter: "node:external"}), + treeText({textAnchor: "end", treeFilter: "node:internal", dx: -dx}) + ] + : treeText() : null ); } diff --git a/src/transforms/tree.d.ts b/src/transforms/tree.d.ts index 3b704fd074..d7bda93b06 100644 --- a/src/transforms/tree.d.ts +++ b/src/transforms/tree.d.ts @@ -75,6 +75,7 @@ export interface TreeTransformOptions { * * *node:name* - the node’s name (the last part of its path) * * *node:path* - the node’s full, normalized, slash-separated path * * *node:internal* - true if the node is internal, or false for leaves + * * *node:external* - true if the node is a leaf, or false for internal nodes * * *node:depth* - the distance from the node to the root * * *node:height* - the distance from the node to its deepest descendant * @@ -97,6 +98,7 @@ export function treeNode(options?: T & TreeTransformOptions): Transformed; * * *node:name* - the child node’s name (the last part of its path) * * *node:path* - the child node’s full, normalized, slash-separated path * * *node:internal* - true if the child node is internal, or false for leaves + * * *node:external* - true if the child node is a leaf, or false for external nodes * * *node:depth* - the distance from the child node to the root * * *node:height* - the distance from the child node to its deepest descendant * * *parent:name* - the parent node’s name (the last part of its path) diff --git a/src/transforms/tree.js b/src/transforms/tree.js index 9ff9871ba1..44d42cf474 100644 --- a/src/transforms/tree.js +++ b/src/transforms/tree.js @@ -11,10 +11,12 @@ export function treeNode({ treeSort, treeSeparation, treeAnchor, + treeFilter, ...options } = {}) { treeAnchor = maybeTreeAnchor(treeAnchor); treeSort = maybeTreeSort(treeSort); + if (treeFilter != null) treeFilter = maybeNodeValue(treeFilter); if (frameAnchor === undefined) frameAnchor = treeAnchor.frameAnchor; const normalize = normalizer(delimiter); const outputs = treeOutputs(options, maybeNodeValue); @@ -42,6 +44,7 @@ export function treeNode({ if (treeSort != null) root.sort(treeSort); layout(root); for (const node of root.descendants()) { + if (treeFilter != null && !treeFilter(node)) continue; treeFacet.push(++treeIndex); treeData[treeIndex] = node.data; treeAnchor.position(node, treeIndex, X, Y); @@ -66,10 +69,12 @@ export function treeLink({ treeSort, treeSeparation, treeAnchor, + treeFilter, ...options } = {}) { treeAnchor = maybeTreeAnchor(treeAnchor); treeSort = maybeTreeSort(treeSort); + if (treeFilter != null) treeFilter = maybeLinkValue(treeFilter); options = {curve, stroke, strokeWidth, strokeOpacity, ...options}; const normalize = normalizer(delimiter); const outputs = treeOutputs(options, maybeLinkValue); @@ -102,6 +107,7 @@ export function treeLink({ if (treeSort != null) root.sort(treeSort); layout(root); for (const {source, target} of root.links()) { + if (treeFilter != null && !treeFilter(target, source)) continue; treeFacet.push(++treeIndex); treeData[treeIndex] = target.data; treeAnchor.position(source, treeIndex, X1, Y1); @@ -194,6 +200,8 @@ function maybeNodeValue(value) { return nodePath; case "node:internal": return nodeInternal; + case "node:external": + return nodeExternal; case "node:depth": return nodeDepth; case "node:height": @@ -222,6 +230,8 @@ function maybeLinkValue(value) { return nodePath; case "node:internal": return nodeInternal; + case "node:external": + return nodeExternal; case "node:depth": return nodeDepth; case "node:height": @@ -250,6 +260,10 @@ function nodeInternal(node) { return !!node.children; } +function nodeExternal(node) { + return !node.children; +} + function parentValue(evaluate) { return (child, parent) => (parent == null ? undefined : evaluate(parent)); } diff --git a/test/output/flareCluster.svg b/test/output/flareCluster.svg index 6e54354e41..cdfa34d8b7 100644 --- a/test/output/flareCluster.svg +++ b/test/output/flareCluster.svg @@ -14,276 +14,276 @@ } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - /flare - /flare/analytics - /flare/animate - /flare/data - /flare/display - /flare/flex - /flare/physics - /flare/query - /flare/scale - /flare/util - /flare/vis - /flare/analytics/cluster - /flare/analytics/graph - /flare/analytics/optimization + /flare + /flare/analytics + /flare/animate + /flare/data + /flare/display + /flare/flex + /flare/physics + /flare/query + /flare/scale + /flare/util + /flare/vis + /flare/analytics/cluster + /flare/analytics/graph + /flare/analytics/optimization /flare/animate/Easing /flare/animate/FunctionSequence - /flare/animate/interpolate + /flare/animate/interpolate /flare/animate/ISchedulable /flare/animate/Parallel /flare/animate/Pause @@ -293,7 +293,7 @@ /flare/animate/Transitioner /flare/animate/TransitionEvent /flare/animate/Tween - /flare/data/converters + /flare/data/converters /flare/data/DataField /flare/data/DataSchema /flare/data/DataSet @@ -331,7 +331,7 @@ /flare/query/Literal /flare/query/Match /flare/query/Maximum - /flare/query/methods + /flare/query/methods /flare/query/Minimum /flare/query/Not /flare/query/Or @@ -358,25 +358,25 @@ /flare/util/Displays /flare/util/Filter /flare/util/Geometry - /flare/util/heap + /flare/util/heap /flare/util/IEvaluable /flare/util/IPredicate /flare/util/IValueProxy - /flare/util/math + /flare/util/math /flare/util/Maths /flare/util/Orientation - /flare/util/palette + /flare/util/palette /flare/util/Property /flare/util/Shapes /flare/util/Sort /flare/util/Stats /flare/util/Strings - /flare/vis/axis - /flare/vis/controls - /flare/vis/data - /flare/vis/events - /flare/vis/legend - /flare/vis/operator + /flare/vis/axis + /flare/vis/controls + /flare/vis/data + /flare/vis/events + /flare/vis/legend + /flare/vis/operator /flare/vis/Visualization /flare/analytics/cluster/AgglomerativeCluster /flare/analytics/cluster/CommunityStructure @@ -464,7 +464,7 @@ /flare/vis/data/DataSprite /flare/vis/data/EdgeSprite /flare/vis/data/NodeSprite - /flare/vis/data/render + /flare/vis/data/render /flare/vis/data/ScaleBinding /flare/vis/data/Tree /flare/vis/data/TreeBuilder @@ -475,12 +475,12 @@ /flare/vis/legend/Legend /flare/vis/legend/LegendItem /flare/vis/legend/LegendRange - /flare/vis/operator/distortion - /flare/vis/operator/encoder - /flare/vis/operator/filter + /flare/vis/operator/distortion + /flare/vis/operator/encoder + /flare/vis/operator/filter /flare/vis/operator/IOperator - /flare/vis/operator/label - /flare/vis/operator/layout + /flare/vis/operator/label + /flare/vis/operator/layout /flare/vis/operator/Operator /flare/vis/operator/OperatorList /flare/vis/operator/OperatorSequence @@ -521,23 +521,8 @@ /flare/vis/operator/layout/TreeMapLayout - flare/flare - analytics/flare/analytics - animate/flare/animate - data/flare/data - display/flare/display - flex/flare/flex - physics/flare/physics - query/flare/query - scale/flare/scale - util/flare/util - vis/flare/vis - cluster/flare/analytics/cluster - graph/flare/analytics/graph - optimization/flare/analytics/optimization Easing/flare/animate/Easing FunctionSequence/flare/animate/FunctionSequence - interpolate/flare/animate/interpolate ISchedulable/flare/animate/ISchedulable Parallel/flare/animate/Parallel Pause/flare/animate/Pause @@ -547,7 +532,6 @@ Transitioner/flare/animate/Transitioner TransitionEvent/flare/animate/TransitionEvent Tween/flare/animate/Tween - converters/flare/data/converters DataField/flare/data/DataField DataSchema/flare/data/DataSchema DataSet/flare/data/DataSet @@ -585,7 +569,6 @@ Literal/flare/query/Literal Match/flare/query/Match Maximum/flare/query/Maximum - methods/flare/query/methods Minimum/flare/query/Minimum Not/flare/query/Not Or/flare/query/Or @@ -612,25 +595,16 @@ Displays/flare/util/Displays Filter/flare/util/Filter Geometry/flare/util/Geometry - heap/flare/util/heap IEvaluable/flare/util/IEvaluable IPredicate/flare/util/IPredicate IValueProxy/flare/util/IValueProxy - math/flare/util/math Maths/flare/util/Maths Orientation/flare/util/Orientation - palette/flare/util/palette Property/flare/util/Property Shapes/flare/util/Shapes Sort/flare/util/Sort Stats/flare/util/Stats Strings/flare/util/Strings - axis/flare/vis/axis - controls/flare/vis/controls - data/flare/vis/data - events/flare/vis/events - legend/flare/vis/legend - operator/flare/vis/operator Visualization/flare/vis/Visualization AgglomerativeCluster/flare/analytics/cluster/AgglomerativeCluster CommunityStructure/flare/analytics/cluster/CommunityStructure @@ -718,7 +692,6 @@ DataSprite/flare/vis/data/DataSprite EdgeSprite/flare/vis/data/EdgeSprite NodeSprite/flare/vis/data/NodeSprite - render/flare/vis/data/render ScaleBinding/flare/vis/data/ScaleBinding Tree/flare/vis/data/Tree TreeBuilder/flare/vis/data/TreeBuilder @@ -729,12 +702,7 @@ Legend/flare/vis/legend/Legend LegendItem/flare/vis/legend/LegendItem LegendRange/flare/vis/legend/LegendRange - distortion/flare/vis/operator/distortion - encoder/flare/vis/operator/encoder - filter/flare/vis/operator/filter IOperator/flare/vis/operator/IOperator - label/flare/vis/operator/label - layout/flare/vis/operator/layout Operator/flare/vis/operator/Operator OperatorList/flare/vis/operator/OperatorList OperatorSequence/flare/vis/operator/OperatorSequence @@ -774,4 +742,38 @@ StackedAreaLayout/flare/vis/operator/layout/StackedAreaLayout TreeMapLayout/flare/vis/operator/layout/TreeMapLayout + + flare/flare + analytics/flare/analytics + animate/flare/animate + data/flare/data + display/flare/display + flex/flare/flex + physics/flare/physics + query/flare/query + scale/flare/scale + util/flare/util + vis/flare/vis + cluster/flare/analytics/cluster + graph/flare/analytics/graph + optimization/flare/analytics/optimization + interpolate/flare/animate/interpolate + converters/flare/data/converters + methods/flare/query/methods + heap/flare/util/heap + math/flare/util/math + palette/flare/util/palette + axis/flare/vis/axis + controls/flare/vis/controls + data/flare/vis/data + events/flare/vis/events + legend/flare/vis/legend + operator/flare/vis/operator + render/flare/vis/data/render + distortion/flare/vis/operator/distortion + encoder/flare/vis/operator/encoder + filter/flare/vis/operator/filter + label/flare/vis/operator/label + layout/flare/vis/operator/layout + \ No newline at end of file diff --git a/test/output/flareTree.svg b/test/output/flareTree.svg index 2d9271f72a..691f0bb2d8 100644 --- a/test/output/flareTree.svg +++ b/test/output/flareTree.svg @@ -17,481 +17,449 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - flare/flare - analytics/flare/analytics - animate/flare/animate - data/flare/data - display/flare/display - flex/flare/flex - physics/flare/physics - query/flare/query - scale/flare/scale - util/flare/util - vis/flare/vis - cluster/flare/analytics/cluster - graph/flare/analytics/graph - optimization/flare/analytics/optimization - Easing/flare/animate/Easing - FunctionSequence/flare/animate/FunctionSequence - interpolate/flare/animate/interpolate - ISchedulable/flare/animate/ISchedulable - Parallel/flare/animate/Parallel - Pause/flare/animate/Pause - Scheduler/flare/animate/Scheduler - Sequence/flare/animate/Sequence - Transition/flare/animate/Transition - Transitioner/flare/animate/Transitioner - TransitionEvent/flare/animate/TransitionEvent - Tween/flare/animate/Tween - converters/flare/data/converters - DataField/flare/data/DataField - DataSchema/flare/data/DataSchema - DataSet/flare/data/DataSet - DataSource/flare/data/DataSource - DataTable/flare/data/DataTable - DataUtil/flare/data/DataUtil - DirtySprite/flare/display/DirtySprite - LineSprite/flare/display/LineSprite - RectSprite/flare/display/RectSprite - TextSprite/flare/display/TextSprite - FlareVis/flare/flex/FlareVis - DragForce/flare/physics/DragForce - GravityForce/flare/physics/GravityForce - IForce/flare/physics/IForce - NBodyForce/flare/physics/NBodyForce - Particle/flare/physics/Particle - Simulation/flare/physics/Simulation - Spring/flare/physics/Spring - SpringForce/flare/physics/SpringForce - AggregateExpression/flare/query/AggregateExpression - And/flare/query/And - Arithmetic/flare/query/Arithmetic - Average/flare/query/Average - BinaryExpression/flare/query/BinaryExpression - Comparison/flare/query/Comparison - CompositeExpression/flare/query/CompositeExpression - Count/flare/query/Count - DateUtil/flare/query/DateUtil - Distinct/flare/query/Distinct - Expression/flare/query/Expression - ExpressionIterator/flare/query/ExpressionIterator - Fn/flare/query/Fn - If/flare/query/If - IsA/flare/query/IsA - Literal/flare/query/Literal - Match/flare/query/Match - Maximum/flare/query/Maximum - methods/flare/query/methods - Minimum/flare/query/Minimum - Not/flare/query/Not - Or/flare/query/Or - Query/flare/query/Query - Range/flare/query/Range - StringUtil/flare/query/StringUtil - Sum/flare/query/Sum - Variable/flare/query/Variable - Variance/flare/query/Variance - Xor/flare/query/Xor - IScaleMap/flare/scale/IScaleMap - LinearScale/flare/scale/LinearScale - LogScale/flare/scale/LogScale - OrdinalScale/flare/scale/OrdinalScale - QuantileScale/flare/scale/QuantileScale - QuantitativeScale/flare/scale/QuantitativeScale - RootScale/flare/scale/RootScale - Scale/flare/scale/Scale - ScaleType/flare/scale/ScaleType - TimeScale/flare/scale/TimeScale - Arrays/flare/util/Arrays - Colors/flare/util/Colors - Dates/flare/util/Dates - Displays/flare/util/Displays - Filter/flare/util/Filter - Geometry/flare/util/Geometry - heap/flare/util/heap - IEvaluable/flare/util/IEvaluable - IPredicate/flare/util/IPredicate - IValueProxy/flare/util/IValueProxy - math/flare/util/math - Maths/flare/util/Maths - Orientation/flare/util/Orientation - palette/flare/util/palette - Property/flare/util/Property - Shapes/flare/util/Shapes - Sort/flare/util/Sort - Stats/flare/util/Stats - Strings/flare/util/Strings - axis/flare/vis/axis - controls/flare/vis/controls - data/flare/vis/data - events/flare/vis/events - legend/flare/vis/legend - operator/flare/vis/operator - Visualization/flare/vis/Visualization - AgglomerativeCluster/flare/analytics/cluster/AgglomerativeCluster - CommunityStructure/flare/analytics/cluster/CommunityStructure - HierarchicalCluster/flare/analytics/cluster/HierarchicalCluster - MergeEdge/flare/analytics/cluster/MergeEdge - BetweennessCentrality/flare/analytics/graph/BetweennessCentrality - LinkDistance/flare/analytics/graph/LinkDistance - MaxFlowMinCut/flare/analytics/graph/MaxFlowMinCut - ShortestPaths/flare/analytics/graph/ShortestPaths - SpanningTree/flare/analytics/graph/SpanningTree - AspectRatioBanker/flare/analytics/optimization/AspectRatioBanker - ArrayInterpolator/flare/animate/interpolate/ArrayInterpolator - ColorInterpolator/flare/animate/interpolate/ColorInterpolator - DateInterpolator/flare/animate/interpolate/DateInterpolator - Interpolator/flare/animate/interpolate/Interpolator - MatrixInterpolator/flare/animate/interpolate/MatrixInterpolator - NumberInterpolator/flare/animate/interpolate/NumberInterpolator - ObjectInterpolator/flare/animate/interpolate/ObjectInterpolator - PointInterpolator/flare/animate/interpolate/PointInterpolator - RectangleInterpolator/flare/animate/interpolate/RectangleInterpolator - Converters/flare/data/converters/Converters - DelimitedTextConverter/flare/data/converters/DelimitedTextConverter - GraphMLConverter/flare/data/converters/GraphMLConverter - IDataConverter/flare/data/converters/IDataConverter - JSONConverter/flare/data/converters/JSONConverter - add/flare/query/methods/add - and/flare/query/methods/and - average/flare/query/methods/average - count/flare/query/methods/count - distinct/flare/query/methods/distinct - div/flare/query/methods/div - eq/flare/query/methods/eq - fn/flare/query/methods/fn - gt/flare/query/methods/gt - gte/flare/query/methods/gte - iff/flare/query/methods/iff - isa/flare/query/methods/isa - lt/flare/query/methods/lt - lte/flare/query/methods/lte - max/flare/query/methods/max - min/flare/query/methods/min - mod/flare/query/methods/mod - mul/flare/query/methods/mul - neq/flare/query/methods/neq - not/flare/query/methods/not - or/flare/query/methods/or - orderby/flare/query/methods/orderby - range/flare/query/methods/range - select/flare/query/methods/select - stddev/flare/query/methods/stddev - sub/flare/query/methods/sub - sum/flare/query/methods/sum - update/flare/query/methods/update - variance/flare/query/methods/variance - where/flare/query/methods/where - xor/flare/query/methods/xor - _/flare/query/methods/_ - FibonacciHeap/flare/util/heap/FibonacciHeap - HeapNode/flare/util/heap/HeapNode - DenseMatrix/flare/util/math/DenseMatrix - IMatrix/flare/util/math/IMatrix - SparseMatrix/flare/util/math/SparseMatrix - ColorPalette/flare/util/palette/ColorPalette - Palette/flare/util/palette/Palette - ShapePalette/flare/util/palette/ShapePalette - SizePalette/flare/util/palette/SizePalette - Axes/flare/vis/axis/Axes - Axis/flare/vis/axis/Axis - AxisGridLine/flare/vis/axis/AxisGridLine - AxisLabel/flare/vis/axis/AxisLabel - CartesianAxes/flare/vis/axis/CartesianAxes - AnchorControl/flare/vis/controls/AnchorControl - ClickControl/flare/vis/controls/ClickControl - Control/flare/vis/controls/Control - ControlList/flare/vis/controls/ControlList - DragControl/flare/vis/controls/DragControl - ExpandControl/flare/vis/controls/ExpandControl - HoverControl/flare/vis/controls/HoverControl - IControl/flare/vis/controls/IControl - PanZoomControl/flare/vis/controls/PanZoomControl - SelectionControl/flare/vis/controls/SelectionControl - TooltipControl/flare/vis/controls/TooltipControl - Data/flare/vis/data/Data - DataList/flare/vis/data/DataList - DataSprite/flare/vis/data/DataSprite - EdgeSprite/flare/vis/data/EdgeSprite - NodeSprite/flare/vis/data/NodeSprite - render/flare/vis/data/render - ScaleBinding/flare/vis/data/ScaleBinding - Tree/flare/vis/data/Tree - TreeBuilder/flare/vis/data/TreeBuilder - DataEvent/flare/vis/events/DataEvent - SelectionEvent/flare/vis/events/SelectionEvent - TooltipEvent/flare/vis/events/TooltipEvent - VisualizationEvent/flare/vis/events/VisualizationEvent - Legend/flare/vis/legend/Legend - LegendItem/flare/vis/legend/LegendItem - LegendRange/flare/vis/legend/LegendRange - distortion/flare/vis/operator/distortion - encoder/flare/vis/operator/encoder - filter/flare/vis/operator/filter - IOperator/flare/vis/operator/IOperator - label/flare/vis/operator/label - layout/flare/vis/operator/layout - Operator/flare/vis/operator/Operator - OperatorList/flare/vis/operator/OperatorList - OperatorSequence/flare/vis/operator/OperatorSequence - OperatorSwitch/flare/vis/operator/OperatorSwitch - SortOperator/flare/vis/operator/SortOperator + Easing/flare/animate/Easing + FunctionSequence/flare/animate/FunctionSequence + ISchedulable/flare/animate/ISchedulable + Parallel/flare/animate/Parallel + Pause/flare/animate/Pause + Scheduler/flare/animate/Scheduler + Sequence/flare/animate/Sequence + Transition/flare/animate/Transition + Transitioner/flare/animate/Transitioner + TransitionEvent/flare/animate/TransitionEvent + Tween/flare/animate/Tween + DataField/flare/data/DataField + DataSchema/flare/data/DataSchema + DataSet/flare/data/DataSet + DataSource/flare/data/DataSource + DataTable/flare/data/DataTable + DataUtil/flare/data/DataUtil + DirtySprite/flare/display/DirtySprite + LineSprite/flare/display/LineSprite + RectSprite/flare/display/RectSprite + TextSprite/flare/display/TextSprite + FlareVis/flare/flex/FlareVis + DragForce/flare/physics/DragForce + GravityForce/flare/physics/GravityForce + IForce/flare/physics/IForce + NBodyForce/flare/physics/NBodyForce + Particle/flare/physics/Particle + Simulation/flare/physics/Simulation + Spring/flare/physics/Spring + SpringForce/flare/physics/SpringForce + AggregateExpression/flare/query/AggregateExpression + And/flare/query/And + Arithmetic/flare/query/Arithmetic + Average/flare/query/Average + BinaryExpression/flare/query/BinaryExpression + Comparison/flare/query/Comparison + CompositeExpression/flare/query/CompositeExpression + Count/flare/query/Count + DateUtil/flare/query/DateUtil + Distinct/flare/query/Distinct + Expression/flare/query/Expression + ExpressionIterator/flare/query/ExpressionIterator + Fn/flare/query/Fn + If/flare/query/If + IsA/flare/query/IsA + Literal/flare/query/Literal + Match/flare/query/Match + Maximum/flare/query/Maximum + Minimum/flare/query/Minimum + Not/flare/query/Not + Or/flare/query/Or + Query/flare/query/Query + Range/flare/query/Range + StringUtil/flare/query/StringUtil + Sum/flare/query/Sum + Variable/flare/query/Variable + Variance/flare/query/Variance + Xor/flare/query/Xor + IScaleMap/flare/scale/IScaleMap + LinearScale/flare/scale/LinearScale + LogScale/flare/scale/LogScale + OrdinalScale/flare/scale/OrdinalScale + QuantileScale/flare/scale/QuantileScale + QuantitativeScale/flare/scale/QuantitativeScale + RootScale/flare/scale/RootScale + Scale/flare/scale/Scale + ScaleType/flare/scale/ScaleType + TimeScale/flare/scale/TimeScale + Arrays/flare/util/Arrays + Colors/flare/util/Colors + Dates/flare/util/Dates + Displays/flare/util/Displays + Filter/flare/util/Filter + Geometry/flare/util/Geometry + IEvaluable/flare/util/IEvaluable + IPredicate/flare/util/IPredicate + IValueProxy/flare/util/IValueProxy + Maths/flare/util/Maths + Orientation/flare/util/Orientation + Property/flare/util/Property + Shapes/flare/util/Shapes + Sort/flare/util/Sort + Stats/flare/util/Stats + Strings/flare/util/Strings + Visualization/flare/vis/Visualization + AgglomerativeCluster/flare/analytics/cluster/AgglomerativeCluster + CommunityStructure/flare/analytics/cluster/CommunityStructure + HierarchicalCluster/flare/analytics/cluster/HierarchicalCluster + MergeEdge/flare/analytics/cluster/MergeEdge + BetweennessCentrality/flare/analytics/graph/BetweennessCentrality + LinkDistance/flare/analytics/graph/LinkDistance + MaxFlowMinCut/flare/analytics/graph/MaxFlowMinCut + ShortestPaths/flare/analytics/graph/ShortestPaths + SpanningTree/flare/analytics/graph/SpanningTree + AspectRatioBanker/flare/analytics/optimization/AspectRatioBanker + ArrayInterpolator/flare/animate/interpolate/ArrayInterpolator + ColorInterpolator/flare/animate/interpolate/ColorInterpolator + DateInterpolator/flare/animate/interpolate/DateInterpolator + Interpolator/flare/animate/interpolate/Interpolator + MatrixInterpolator/flare/animate/interpolate/MatrixInterpolator + NumberInterpolator/flare/animate/interpolate/NumberInterpolator + ObjectInterpolator/flare/animate/interpolate/ObjectInterpolator + PointInterpolator/flare/animate/interpolate/PointInterpolator + RectangleInterpolator/flare/animate/interpolate/RectangleInterpolator + Converters/flare/data/converters/Converters + DelimitedTextConverter/flare/data/converters/DelimitedTextConverter + GraphMLConverter/flare/data/converters/GraphMLConverter + IDataConverter/flare/data/converters/IDataConverter + JSONConverter/flare/data/converters/JSONConverter + add/flare/query/methods/add + and/flare/query/methods/and + average/flare/query/methods/average + count/flare/query/methods/count + distinct/flare/query/methods/distinct + div/flare/query/methods/div + eq/flare/query/methods/eq + fn/flare/query/methods/fn + gt/flare/query/methods/gt + gte/flare/query/methods/gte + iff/flare/query/methods/iff + isa/flare/query/methods/isa + lt/flare/query/methods/lt + lte/flare/query/methods/lte + max/flare/query/methods/max + min/flare/query/methods/min + mod/flare/query/methods/mod + mul/flare/query/methods/mul + neq/flare/query/methods/neq + not/flare/query/methods/not + or/flare/query/methods/or + orderby/flare/query/methods/orderby + range/flare/query/methods/range + select/flare/query/methods/select + stddev/flare/query/methods/stddev + sub/flare/query/methods/sub + sum/flare/query/methods/sum + update/flare/query/methods/update + variance/flare/query/methods/variance + where/flare/query/methods/where + xor/flare/query/methods/xor + _/flare/query/methods/_ + FibonacciHeap/flare/util/heap/FibonacciHeap + HeapNode/flare/util/heap/HeapNode + DenseMatrix/flare/util/math/DenseMatrix + IMatrix/flare/util/math/IMatrix + SparseMatrix/flare/util/math/SparseMatrix + ColorPalette/flare/util/palette/ColorPalette + Palette/flare/util/palette/Palette + ShapePalette/flare/util/palette/ShapePalette + SizePalette/flare/util/palette/SizePalette + Axes/flare/vis/axis/Axes + Axis/flare/vis/axis/Axis + AxisGridLine/flare/vis/axis/AxisGridLine + AxisLabel/flare/vis/axis/AxisLabel + CartesianAxes/flare/vis/axis/CartesianAxes + AnchorControl/flare/vis/controls/AnchorControl + ClickControl/flare/vis/controls/ClickControl + Control/flare/vis/controls/Control + ControlList/flare/vis/controls/ControlList + DragControl/flare/vis/controls/DragControl + ExpandControl/flare/vis/controls/ExpandControl + HoverControl/flare/vis/controls/HoverControl + IControl/flare/vis/controls/IControl + PanZoomControl/flare/vis/controls/PanZoomControl + SelectionControl/flare/vis/controls/SelectionControl + TooltipControl/flare/vis/controls/TooltipControl + Data/flare/vis/data/Data + DataList/flare/vis/data/DataList + DataSprite/flare/vis/data/DataSprite + EdgeSprite/flare/vis/data/EdgeSprite + NodeSprite/flare/vis/data/NodeSprite + ScaleBinding/flare/vis/data/ScaleBinding + Tree/flare/vis/data/Tree + TreeBuilder/flare/vis/data/TreeBuilder + DataEvent/flare/vis/events/DataEvent + SelectionEvent/flare/vis/events/SelectionEvent + TooltipEvent/flare/vis/events/TooltipEvent + VisualizationEvent/flare/vis/events/VisualizationEvent + Legend/flare/vis/legend/Legend + LegendItem/flare/vis/legend/LegendItem + LegendRange/flare/vis/legend/LegendRange + IOperator/flare/vis/operator/IOperator + Operator/flare/vis/operator/Operator + OperatorList/flare/vis/operator/OperatorList + OperatorSequence/flare/vis/operator/OperatorSequence + OperatorSwitch/flare/vis/operator/OperatorSwitch + SortOperator/flare/vis/operator/SortOperator ArrowType/flare/vis/data/render/ArrowType EdgeRenderer/flare/vis/data/render/EdgeRenderer IRenderer/flare/vis/data/render/IRenderer @@ -526,4 +494,38 @@ StackedAreaLayout/flare/vis/operator/layout/StackedAreaLayout TreeMapLayout/flare/vis/operator/layout/TreeMapLayout + + flare/flare + analytics/flare/analytics + animate/flare/animate + data/flare/data + display/flare/display + flex/flare/flex + physics/flare/physics + query/flare/query + scale/flare/scale + util/flare/util + vis/flare/vis + cluster/flare/analytics/cluster + graph/flare/analytics/graph + optimization/flare/analytics/optimization + interpolate/flare/animate/interpolate + converters/flare/data/converters + methods/flare/query/methods + heap/flare/util/heap + math/flare/util/math + palette/flare/util/palette + axis/flare/vis/axis + controls/flare/vis/controls + data/flare/vis/data + events/flare/vis/events + legend/flare/vis/legend + operator/flare/vis/operator + render/flare/vis/data/render + distortion/flare/vis/operator/distortion + encoder/flare/vis/operator/encoder + filter/flare/vis/operator/filter + label/flare/vis/operator/label + layout/flare/vis/operator/layout + \ No newline at end of file diff --git a/test/output/greekGods.svg b/test/output/greekGods.svg index 8e88e87ec0..656be67932 100644 --- a/test/output/greekGods.svg +++ b/test/output/greekGods.svg @@ -14,32 +14,34 @@ } - - - - - - - + + + + + + + - /Chaos - /Chaos/Eros - /Chaos/Erebus - /Chaos/Tartarus - /Chaos/Gaia + /Chaos + /Chaos/Eros + /Chaos/Erebus + /Chaos/Tartarus + /Chaos/Gaia /Chaos/Gaia/Mountains /Chaos/Gaia/Pontus /Chaos/Gaia/Uranus - Chaos/Chaos - Eros/Chaos/Eros - Erebus/Chaos/Erebus - Tartarus/Chaos/Tartarus - Gaia/Chaos/Gaia + Eros/Chaos/Eros + Erebus/Chaos/Erebus + Tartarus/Chaos/Tartarus Mountains/Chaos/Gaia/Mountains Pontus/Chaos/Gaia/Pontus Uranus/Chaos/Gaia/Uranus + + Chaos/Chaos + Gaia/Chaos/Gaia + \ No newline at end of file diff --git a/test/plots/flare-cluster.ts b/test/plots/flare-cluster.ts index 0020403e7e..778a2a29f4 100644 --- a/test/plots/flare-cluster.ts +++ b/test/plots/flare-cluster.ts @@ -6,6 +6,7 @@ export async function flareCluster() { return Plot.plot({ axis: null, inset: 10, + insetLeft: 30, insetRight: 120, height: 2400, marks: Plot.cluster(flare, {path: "name", delimiter: "."}) diff --git a/test/plots/flare-tree.ts b/test/plots/flare-tree.ts index 510e8a6101..77e1a2228b 100644 --- a/test/plots/flare-tree.ts +++ b/test/plots/flare-tree.ts @@ -6,6 +6,7 @@ export async function flareTree() { return Plot.plot({ axis: null, inset: 10, + insetLeft: 30, insetRight: 120, height: 1800, marks: Plot.tree(flare, {markerEnd: "arrow", path: "name", delimiter: "."}) diff --git a/test/plots/greek-gods.ts b/test/plots/greek-gods.ts index ab53de312d..0e4136afd8 100644 --- a/test/plots/greek-gods.ts +++ b/test/plots/greek-gods.ts @@ -11,7 +11,7 @@ Chaos Tartarus` .map((d) => d.replace(/\s+/g, "/")); return Plot.plot({ axis: null, - insetLeft: 10, + insetLeft: 35, insetTop: 20, insetBottom: 20, insetRight: 120,