diff --git a/src/marks/text.js b/src/marks/text.js
index c7feb36bfe..10f4096b8c 100644
--- a/src/marks/text.js
+++ b/src/marks/text.js
@@ -43,6 +43,10 @@ export class Text extends Mark {
const {
x,
y,
+ x1,
+ x2,
+ y1,
+ y2,
text = isIterable(data) && isTextual(data) ? identity : indexOf,
frameAnchor,
textAnchor = /right$/i.test(frameAnchor) ? "end" : /left$/i.test(frameAnchor) ? "start" : "middle",
@@ -65,6 +69,10 @@ export class Text extends Mark {
{
x: {value: x, scale: "x", optional: true},
y: {value: y, scale: "y", optional: true},
+ x1: {value: x1, scale: "x", optional: true},
+ y1: {value: y1, scale: "y", optional: true},
+ x2: {value: x2, scale: "x", optional: true},
+ y2: {value: y2, scale: "y", optional: true},
fontSize: {value: vfontSize, optional: true},
rotate: {value: numberChannel(vrotate), optional: true},
text: {value: text, filter: nonempty, optional: true}
@@ -94,6 +102,12 @@ export class Text extends Mark {
const {x: X, y: Y, rotate: R, text: T, title: TL, fontSize: FS} = channels;
const {rotate} = this;
const [cx, cy] = applyFrameAnchor(this, dimensions);
+ let clipBox = (s) => s;
+ if (this.clip === "box") {
+ if (!channels.x1 || !channels.y1 || !channels.x2 || !channels.y2)
+ throw new Error("box clipping requires x1, y1, x2, and y2 channels.");
+ clipBox = (selection) => applyClip(selection, channels, 2); // TODO configurable clipInset
+ }
return create("svg:g", context)
.call(applyIndirectStyles, this, dimensions, context)
.call(applyIndirectTextStyles, this, T, dimensions)
@@ -114,11 +128,33 @@ export class Text extends Mark {
)
.call(applyAttr, "font-size", FS && ((i) => FS[i]))
.call(applyChannelStyles, this, channels)
+ .call(clipBox)
)
.node();
}
}
+function applyClip(selection, {x1: X1, x2: X2, y1: Y1, y2: Y2}, clipInset) {
+ return selection.each(function (i) {
+ const g = this.ownerDocument.createElementNS(namespaces.svg, "svg");
+ const x = Math.min(X1[i], X2[i]) + clipInset;
+ const y = Math.min(Y1[i], Y2[i]) + clipInset;
+ const w = Math.abs(X1[i] - X2[i]) - 2 * clipInset;
+ const h = Math.abs(Y1[i] - Y2[i]) - 2 * clipInset;
+ if (w <= 0 || h <= 0) {
+ this.parentElement.removeChild(this);
+ } else {
+ g.setAttribute("viewBox", `${x} ${y} ${w} ${h}`);
+ g.setAttribute("x", `${x}`);
+ g.setAttribute("y", `${y}`);
+ g.setAttribute("width", `${w}`);
+ g.setAttribute("height", `${h}`);
+ this.replaceWith(g);
+ g.appendChild(this);
+ }
+ });
+}
+
export function maybeTextOverflow(textOverflow) {
return textOverflow == null
? null
diff --git a/src/marks/treemap.d.ts b/src/marks/treemap.d.ts
index b27630665b..bbc3a5b973 100644
--- a/src/marks/treemap.d.ts
+++ b/src/marks/treemap.d.ts
@@ -1,11 +1,12 @@
import {ChannelValue} from "../channel.js";
-import {Data} from "../mark.js";
+import {Markish, Data} from "../mark.js";
import {TreeTransformOptions} from "../transforms/tree.js";
-import {Rect, RectOptions} from "./rect.js";
+import {RectOptions} from "./rect.js";
// TODO tree channels, e.g., "node:name" | "node:path" | "node:internal"?
export interface TreemapOptions extends RectOptions, TreeTransformOptions {
+ text?: ChannelValue;
value?: ChannelValue;
}
-export function treemap(data?: Data, options?: TreemapOptions): Rect;
+export function treemap(data?: Data, options?: TreemapOptions): Markish;
diff --git a/src/marks/treemap.js b/src/marks/treemap.js
index d023f699a8..68dbab1b9d 100644
--- a/src/marks/treemap.js
+++ b/src/marks/treemap.js
@@ -1,10 +1,55 @@
import {treemapNode} from "../transforms/treemap.js";
+import {marks} from "../mark.js";
import {rect} from "./rect.js";
+import {text as textMark} from "./text.js";
/** @jsdoc treemap */
export function treemap(
data,
- {inset = 0.5, insetTop = inset, insetRight = inset, insetBottom = inset, insetLeft = inset, ...options} = {}
+ {
+ inset = 0.5,
+ insetTop = inset,
+ insetRight = inset,
+ insetBottom = inset,
+ insetLeft = inset,
+ text = "node:name",
+ clip = "box",
+ value,
+ title = value != null ? "node:title" : "node:name",
+ ...options
+ } = {}
) {
- return rect(data, treemapNode({insetTop, insetRight, insetBottom, insetLeft, ...options}));
+ const r = rect(
+ data,
+ treemapNode({
+ value,
+ insetTop,
+ insetRight,
+ insetBottom,
+ insetLeft,
+ title,
+ ...options
+ })
+ );
+ return text == null
+ ? r
+ : marks([
+ r,
+ textMark(
+ data,
+ treemapNode({
+ value,
+ insetTop,
+ insetRight,
+ insetBottom,
+ insetLeft,
+ text,
+ clip,
+ ...options,
+ fill: "currentColor",
+ pointerEvents: "none",
+ tip: false
+ })
+ )
+ ]);
}
diff --git a/src/style.js b/src/style.js
index b3e046cc91..c94cc15119 100644
--- a/src/style.js
+++ b/src/style.js
@@ -311,7 +311,7 @@ export function* groupIndex(I, position, mark, channels) {
export function maybeClip(clip) {
if (clip === true) clip = "frame";
else if (clip === false) clip = null;
- return maybeKeyword(clip, "clip", ["frame", "sphere"]);
+ return maybeKeyword(clip, "clip", ["frame", "sphere", "box"]);
}
// Note: may mutate selection.node!
@@ -351,6 +351,10 @@ function applyClip(selection, mark, dimensions, context) {
.attr("d", geoPath(projection)({type: "Sphere"}));
break;
}
+ case "box": {
+ // TODO, see text
+ // console.warn({selection, mark, dimensions, context});
+ }
}
// Here we’re careful to apply the ARIA attributes to the outer G element when
// clipping is applied, and to apply the ARIA attributes before any other
diff --git a/src/transforms/tree.js b/src/transforms/tree.js
index c8e39c87bf..778316d0cd 100644
--- a/src/transforms/tree.js
+++ b/src/transforms/tree.js
@@ -198,6 +198,8 @@ export function maybeNodeValue(value) {
return nodeName;
case "node:path":
return nodePath;
+ case "node:branch":
+ return nodeBranch;
case "node:internal":
return nodeInternal;
case "node:external":
@@ -206,6 +208,10 @@ export function maybeNodeValue(value) {
return nodeDepth;
case "node:height":
return nodeHeight;
+ case "node:size":
+ return nodeSize;
+ case "node:title":
+ return nodeTitle;
}
throw new Error(`invalid node value: ${value}`);
}
@@ -244,6 +250,14 @@ function nodePath(node) {
return node.id;
}
+function nodeAncestor(node, i) {
+ return nameof(node.ancestors().at(i)?.id ?? "");
+}
+
+function nodeBranch(node) {
+ return nodeAncestor(node, -2);
+}
+
function nodeName(node) {
return nameof(node.id);
}
@@ -256,6 +270,14 @@ function nodeHeight(node) {
return node.height;
}
+function nodeSize(node) {
+ return node.size;
+}
+
+function nodeTitle(node) {
+ return `${nameof(node.id)}\n${node.data.size}`;
+}
+
function nodeInternal(node) {
return !!node.children;
}
diff --git a/src/transforms/treemap.js b/src/transforms/treemap.js
index baeb3422cd..226a1be306 100644
--- a/src/transforms/treemap.js
+++ b/src/transforms/treemap.js
@@ -1,5 +1,5 @@
-import {stratify, treemap, treemapBinary} from "d3";
-import {column, identity, valueof} from "../options.js";
+import {max, stratify, treemap, treemapBinary} from "d3";
+import {column, identity, mid, valueof} from "../options.js";
import {basic} from "./basic.js";
import {maybeNodeValue, maybeTreeSort, normalizer} from "./tree.js";
import {output_evaluate, output_setValues, output_values, treeOutputs} from "./tree.js";
@@ -28,6 +28,8 @@ export function treemapNode(options = {}) {
y1: Y1,
x2: X2,
y2: Y2,
+ x: mid(X1, X2),
+ y: mid(Y1, Y2),
frameAnchor,
...basic(remainingOptions, (data, facets) => {
const P = normalize(valueof(data, path));
@@ -41,11 +43,13 @@ export function treemapNode(options = {}) {
const rootof = stratify().path((i) => P[i]);
const layout = treemap().tile(treeTile);
for (const o of outputs) o[output_values] = o[output_setValues]([]);
+ const sums = [];
for (const facet of facets) {
const treeFacet = [];
const root = rootof(facet.filter((i) => P[i] != null)).each((node) => (node.data = data[node.data]));
if (value) root.sum(value);
else root.count();
+ sums.push(root.value);
if (treeSort != null) root.sort(treeSort);
layout(root);
for (const node of root.leaves()) {
@@ -59,6 +63,22 @@ export function treemapNode(options = {}) {
}
treeFacets.push(treeFacet);
}
+ // normalize facets
+ if (facets.length > 1) {
+ const m = max(sums);
+ for (let i = 0; i < facets.length; ++i) {
+ const r = Math.sqrt(sums[i] / m);
+ if (r < 1) {
+ for (const j of treeFacets[i]) {
+ X1[j] = 0.5 + r * (X1[j] - 0.5); // centered
+ X2[j] = 0.5 + r * (X2[j] - 0.5);
+ Y1[j] = 0.5 + r * (Y1[j] - 0.5);
+ Y2[j] = 0.5 + r * (Y2[j] - 0.5);
+ }
+ }
+ }
+ }
+
return {data: treeData, facets: treeFacets};
}),
...Object.fromEntries(outputs)
diff --git a/test/output/flareTreemap.svg b/test/output/flareTreemap.svg
index 806d411f51..33380572ba 100644
--- a/test/output/flareTreemap.svg
+++ b/test/output/flareTreemap.svg
@@ -66,225 +66,445 @@
1.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ AgglomerativeCluster
+ 3938
+ CommunityStructure
+ 3812
+ HierarchicalCluster
+ 6714
+ MergeEdge
+ 743
+ BetweennessCentrality
+ 3534
+ LinkDistance
+ 5731
+ MaxFlowMinCut
+ 7840
+ ShortestPaths
+ 5914
+ SpanningTree
+ 3416
+ AspectRatioBanker
+ 7074
+ Easing
+ 17010
+ FunctionSequence
+ 5842
+ ArrayInterpolator
+ 1983
+ ColorInterpolator
+ 2047
+ DateInterpolator
+ 1375
+ Interpolator
+ 8746
+ MatrixInterpolator
+ 2202
+ NumberInterpolator
+ 1382
+ ObjectInterpolator
+ 1629
+ PointInterpolator
+ 1675
+ RectangleInterpolator
+ 2042
+ ISchedulable
+ 1041
+ Parallel
+ 5176
+ Pause
+ 449
+ Scheduler
+ 5593
+ Sequence
+ 5534
+ Transition
+ 9201
+ Transitioner
+ 19975
+ TransitionEvent
+ 1116
+ Tween
+ 6006
+ Converters
+ 721
+ DelimitedTextConverter
+ 4294
+ GraphMLConverter
+ 9800
+ IDataConverter
+ 1314
+ JSONConverter
+ 2220
+ DataField
+ 1759
+ DataSchema
+ 2165
+ DataSet
+ 586
+ DataSource
+ 3331
+ DataTable
+ 772
+ DataUtil
+ 3322
+ DirtySprite
+ 8833
+ LineSprite
+ 1732
+ RectSprite
+ 3623
+ TextSprite
+ 10066
+ FlareVis
+ 4116
+ DragForce
+ 1082
+ GravityForce
+ 1336
+ IForce
+ 319
+ NBodyForce
+ 10498
+ Particle
+ 2822
+ Simulation
+ 9983
+ Spring
+ 2213
+ SpringForce
+ 1681
+ AggregateExpression
+ 1616
+ And
+ 1027
+ Arithmetic
+ 3891
+ Average
+ 891
+ BinaryExpression
+ 2893
+ Comparison
+ 5103
+ CompositeExpression
+ 3677
+ Count
+ 781
+ DateUtil
+ 4141
+ Distinct
+ 933
+ Expression
+ 5130
+ ExpressionIterator
+ 3617
+ Fn
+ 3240
+ If
+ 2732
+ IsA
+ 2039
+ Literal
+ 1214
+ Match
+ 3748
+ Maximum
+ 843
+ add
+ 593
+ and
+ 330
+ average
+ 287
+ count
+ 277
+ distinct
+ 292
+ div
+ 595
+ eq
+ 594
+ fn
+ 460
+ gt
+ 603
+ gte
+ 625
+ iff
+ 748
+ isa
+ 461
+ lt
+ 597
+ lte
+ 619
+ max
+ 283
+ min
+ 283
+ mod
+ 591
+ mul
+ 603
+ neq
+ 599
+ not
+ 386
+ or
+ 323
+ orderby
+ 307
+ range
+ 772
+ select
+ 296
+ stddev
+ 363
+ sub
+ 600
+ sum
+ 280
+ update
+ 307
+ variance
+ 335
+ where
+ 299
+ xor
+ 354
+ _
+ 264
+ Minimum
+ 843
+ Not
+ 1554
+ Or
+ 970
+ Query
+ 13896
+ Range
+ 1594
+ StringUtil
+ 4130
+ Sum
+ 791
+ Variable
+ 1124
+ Variance
+ 1876
+ Xor
+ 1101
+ IScaleMap
+ 2105
+ LinearScale
+ 1316
+ LogScale
+ 3151
+ OrdinalScale
+ 3770
+ QuantileScale
+ 2435
+ QuantitativeScale
+ 4839
+ RootScale
+ 1756
+ Scale
+ 4268
+ ScaleType
+ 1821
+ TimeScale
+ 5833
+ Arrays
+ 8258
+ Colors
+ 10001
+ Dates
+ 8217
+ Displays
+ 12555
+ Filter
+ 2324
+ Geometry
+ 10993
+ FibonacciHeap
+ 9354
+ HeapNode
+ 1233
+ IEvaluable
+ 335
+ IPredicate
+ 383
+ IValueProxy
+ 874
+ DenseMatrix
+ 3165
+ IMatrix
+ 2815
+ SparseMatrix
+ 3366
+ Maths
+ 17705
+ Orientation
+ 1486
+ ColorPalette
+ 6367
+ Palette
+ 1229
+ ShapePalette
+ 2059
+ SizePalette
+ 2291
+ Property
+ 5559
+ Shapes
+ 19118
+ Sort
+ 6887
+ Stats
+ 6557
+ Strings
+ 22026
+ Axes
+ 1302
+ Axis
+ 24593
+ AxisGridLine
+ 652
+ AxisLabel
+ 636
+ CartesianAxes
+ 6703
+ AnchorControl
+ 2138
+ ClickControl
+ 3824
+ Control
+ 1353
+ ControlList
+ 4665
+ DragControl
+ 2649
+ ExpandControl
+ 2832
+ HoverControl
+ 4896
+ IControl
+ 763
+ PanZoomControl
+ 5222
+ SelectionControl
+ 7862
+ TooltipControl
+ 8435
+ Data
+ 20544
+ DataList
+ 19788
+ DataSprite
+ 10349
+ EdgeSprite
+ 3301
+ NodeSprite
+ 19382
+ ArrowType
+ 698
+ EdgeRenderer
+ 5569
+ IRenderer
+ 353
+ ShapeRenderer
+ 2247
+ ScaleBinding
+ 11275
+ Tree
+ 7147
+ TreeBuilder
+ 9930
+ DataEvent
+ 2313
+ SelectionEvent
+ 1880
+ TooltipEvent
+ 1701
+ VisualizationEvent
+ 1117
+ Legend
+ 20859
+ LegendItem
+ 4614
+ LegendRange
+ 10530
+ BifocalDistortion
+ 4461
+ Distortion
+ 6314
+ FisheyeDistortion
+ 3444
+ ColorEncoder
+ 3179
+ Encoder
+ 4060
+ PropertyEncoder
+ 4138
+ ShapeEncoder
+ 1690
+ SizeEncoder
+ 1830
+ FisheyeTreeFilter
+ 5219
+ GraphDistanceFilter
+ 3165
+ VisibilityFilter
+ 3509
+ IOperator
+ 1286
+ Labeler
+ 9956
+ RadialLabeler
+ 3899
+ StackedAreaLabeler
+ 3202
+ AxisLayout
+ 6725
+ BundledEdgeRouter
+ 3727
+ CircleLayout
+ 9317
+ CirclePackingLayout
+ 12003
+ DendrogramLayout
+ 4853
+ ForceDirectedLayout
+ 8411
+ IcicleTreeLayout
+ 4864
+ IndentedTreeLayout
+ 3174
+ Layout
+ 7881
+ NodeLinkTreeLayout
+ 12870
+ PieLayout
+ 2728
+ RadialTreeLayout
+ 12348
+ RandomLayout
+ 870
+ StackedAreaLayout
+ 9121
+ TreeMapLayout
+ 9191
+ Operator
+ 2490
+ OperatorList
+ 5248
+ OperatorSequence
+ 4190
+ OperatorSwitch
+ 2581
+ SortOperator
+ 2023
+ Visualization
+ 16540
\ No newline at end of file
diff --git a/test/output/flareTreemapFacet.svg b/test/output/flareTreemapFacet.svg
new file mode 100644
index 0000000000..d42ed10a9a
--- /dev/null
+++ b/test/output/flareTreemapFacet.svg
@@ -0,0 +1,908 @@
+
\ No newline at end of file
diff --git a/test/output/flareTreemapText.svg b/test/output/flareTreemapText.svg
new file mode 100644
index 0000000000..bcd21958bd
--- /dev/null
+++ b/test/output/flareTreemapText.svg
@@ -0,0 +1,722 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0.0
+ 0.1
+ 0.2
+ 0.3
+ 0.4
+ 0.5
+ 0.6
+ 0.7
+ 0.8
+ 0.9
+ 1.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0.0
+ 0.1
+ 0.2
+ 0.3
+ 0.4
+ 0.5
+ 0.6
+ 0.7
+ 0.8
+ 0.9
+ 1.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AgglomerativeCluster
+
+ CommunityStructure
+
+ HierarchicalCluster
+
+ BetweennessCentrality
+
+ LinkDistance
+
+ MaxFlowMinCut
+
+ ShortestPaths
+
+ SpanningTree
+
+ AspectRatioBanker
+
+ Easing
+
+ FunctionSequence
+
+ ArrayInterpolator
+
+ ColorInterpolator
+
+ DateInterpolator
+
+ Interpolator
+
+ MatrixInterpolator
+
+ NumberInterpolator
+
+ ObjectInterpolator
+
+ PointInterpolator
+
+ RectangleInterpolator
+
+ ISchedulable
+
+ Parallel
+
+ Scheduler
+
+ Sequence
+
+ Transition
+
+ Transitioner
+
+ TransitionEvent
+
+ Tween
+
+ Converters
+
+ DelimitedTextConverter
+
+ GraphMLConverter
+
+ IDataConverter
+
+ JSONConverter
+
+ DataField
+
+ DataSchema
+
+ DataSet
+
+ DataSource
+
+ DataTable
+
+ DataUtil
+
+ DirtySprite
+
+ LineSprite
+
+ RectSprite
+
+ TextSprite
+
+ FlareVis
+
+ DragForce
+
+ GravityForce
+
+ NBodyForce
+
+ Particle
+
+ Simulation
+
+ Spring
+
+ SpringForce
+
+ AggregateExpression
+
+ And
+
+ Arithmetic
+
+ Average
+
+ BinaryExpression
+
+ Comparison
+
+ CompositeExpression
+
+ Count
+
+ DateUtil
+
+ Distinct
+
+ Expression
+
+ ExpressionIterator
+
+ Fn
+
+ If
+
+ IsA
+
+ Literal
+
+ Match
+
+ Maximum
+
+ add
+
+ and
+
+ average
+
+ count
+
+ distinct
+
+ div
+
+ eq
+
+ fn
+
+ gt
+
+ gte
+
+ iff
+
+ isa
+
+ lt
+
+ lte
+
+ max
+
+ min
+
+ mod
+
+ mul
+
+ neq
+
+ not
+
+ or
+
+ orderby
+
+ range
+
+ select
+
+ stddev
+
+ sub
+
+ sum
+
+ update
+
+ variance
+
+ where
+
+ xor
+
+ Minimum
+
+ Not
+
+ Or
+
+ Query
+
+ Range
+
+ StringUtil
+
+ Sum
+
+ Variable
+
+ Variance
+
+ Xor
+
+ IScaleMap
+
+ LinearScale
+
+ LogScale
+
+ OrdinalScale
+
+ QuantileScale
+
+ QuantitativeScale
+
+ RootScale
+
+ Scale
+
+ ScaleType
+
+ TimeScale
+
+ Arrays
+
+ Colors
+
+ Dates
+
+ Displays
+
+ Filter
+
+ Geometry
+
+ FibonacciHeap
+
+ HeapNode
+
+ IPredicate
+
+ IValueProxy
+
+ DenseMatrix
+
+ IMatrix
+
+ SparseMatrix
+
+ Maths
+
+ Orientation
+
+ ColorPalette
+
+ Palette
+
+ ShapePalette
+
+ SizePalette
+
+ Property
+
+ Shapes
+
+ Sort
+
+ Stats
+
+ Strings
+
+ Axes
+
+ Axis
+
+ AxisGridLine
+
+ AxisLabel
+
+ CartesianAxes
+
+ AnchorControl
+
+ ClickControl
+
+ Control
+
+ ControlList
+
+ DragControl
+
+ ExpandControl
+
+ HoverControl
+
+ IControl
+
+ PanZoomControl
+
+ SelectionControl
+
+ TooltipControl
+
+ Data
+
+ DataList
+
+ DataSprite
+
+ EdgeSprite
+
+ NodeSprite
+
+ ArrowType
+
+ EdgeRenderer
+
+ IRenderer
+
+ ShapeRenderer
+
+ ScaleBinding
+
+ Tree
+
+ TreeBuilder
+
+ DataEvent
+
+ SelectionEvent
+
+ TooltipEvent
+
+ VisualizationEvent
+
+ Legend
+
+ LegendItem
+
+ LegendRange
+
+ BifocalDistortion
+
+ Distortion
+
+ FisheyeDistortion
+
+ ColorEncoder
+
+ Encoder
+
+ PropertyEncoder
+
+ ShapeEncoder
+
+ SizeEncoder
+
+ FisheyeTreeFilter
+
+ GraphDistanceFilter
+
+ VisibilityFilter
+
+ IOperator
+
+ Labeler
+
+ RadialLabeler
+
+ StackedAreaLabeler
+
+ AxisLayout
+
+ BundledEdgeRouter
+
+ CircleLayout
+
+ CirclePackingLayout
+
+ DendrogramLayout
+
+ ForceDirectedLayout
+
+ IcicleTreeLayout
+
+ IndentedTreeLayout
+
+ Layout
+
+ NodeLinkTreeLayout
+
+ PieLayout
+
+ RadialTreeLayout
+
+ RandomLayout
+
+ StackedAreaLayout
+
+ TreeMapLayout
+
+ Operator
+
+ OperatorList
+
+ OperatorSequence
+
+ OperatorSwitch
+
+ SortOperator
+
+ Visualization
+
+
+
\ No newline at end of file
diff --git a/test/plots/flare-treemap.ts b/test/plots/flare-treemap.ts
index 5a2e46c4b4..d1a2f45319 100644
--- a/test/plots/flare-treemap.ts
+++ b/test/plots/flare-treemap.ts
@@ -9,7 +9,41 @@ export async function flareTreemap() {
path: "name",
delimiter: ".",
value: "size",
- fill: {node: (d) => d.ancestors().reverse()[1].id} as any // TODO
+ text: null,
+ fill: "node:branch"
+ })
+ ]
+ });
+}
+
+export async function flareTreemapFacet() {
+ const flare = await d3.csv("data/flare.csv", d3.autoType);
+ return Plot.plot({
+ fx: {axis: "bottom"},
+ axis: null,
+ marks: [
+ Plot.treemap(flare, {
+ fx: (d) => (d.name.split(".")[1] === "vis" ? "vis" : "not vis"),
+ path: "name",
+ delimiter: ".",
+ value: "size",
+ fill: (d) => d.name.split(".")[1]
+ }),
+ Plot.frame()
+ ]
+ });
+}
+
+export async function flareTreemapText() {
+ const flare = await d3.csv("data/flare.csv", d3.autoType);
+ return Plot.plot({
+ marks: [
+ Plot.treemap(flare, {
+ path: "name",
+ delimiter: ".",
+ value: "size",
+ tip: true,
+ fill: (d) => d.name.split(".")[1]
})
]
});