From e93c9fed687a404b73109d5dfceb1f499333b621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Mon, 3 Jul 2023 13:08:44 +0200 Subject: [PATCH 1/5] the text mark supports a clip: "box" option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit assuming that channels x1, x2, y1, y2 are specified. An alternative would be to create a "textbox" mark which would combine a rect and a text; it would probably allow more nice things, like anchoring the text to the left of the box… --- src/marks/text.js | 36 ++++++++++++++++++++++++++++++++++++ src/style.js | 6 +++++- 2 files changed, 41 insertions(+), 1 deletion(-) 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/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 From aef7795aaabb7a7da452dab91ff145a990e75ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Mon, 3 Jul 2023 13:09:35 +0200 Subject: [PATCH 2/5] extend the treemap to return a [rect, text] combination --- src/marks/treemap.d.ts | 7 +++--- src/marks/treemap.js | 49 +++++++++++++++++++++++++++++++++++++-- src/transforms/treemap.js | 4 +++- 3 files changed, 54 insertions(+), 6 deletions(-) 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/transforms/treemap.js b/src/transforms/treemap.js index baeb3422cd..35f00233c8 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 {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)); From 32512b2e86322a61442c3f0f14bccf55b40a673f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Mon, 3 Jul 2023 13:09:44 +0200 Subject: [PATCH 3/5] support node:branch --- src/transforms/tree.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) 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; } From 0fe14b081b5ab2dccd8c1779d1f00d192e77ee45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Mon, 3 Jul 2023 13:09:51 +0200 Subject: [PATCH 4/5] examples --- test/output/flareTreemap.svg | 660 ++++++++++++++++++---------- test/output/flareTreemapText.svg | 722 +++++++++++++++++++++++++++++++ test/plots/flare-treemap.ts | 18 +- 3 files changed, 1179 insertions(+), 221 deletions(-) create mode 100644 test/output/flareTreemapText.svg 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/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..8ff57ac406 100644 --- a/test/plots/flare-treemap.ts +++ b/test/plots/flare-treemap.ts @@ -9,7 +9,23 @@ 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 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] }) ] }); From 2d48d50eb6dff34374cfa9a172e779b4665bdf87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Mon, 3 Jul 2023 15:01:17 +0200 Subject: [PATCH 5/5] make treemap areas comparable across facets --- src/transforms/treemap.js | 20 +- test/output/flareTreemapFacet.svg | 908 ++++++++++++++++++++++++++++++ test/plots/flare-treemap.ts | 18 + 3 files changed, 945 insertions(+), 1 deletion(-) create mode 100644 test/output/flareTreemapFacet.svg diff --git a/src/transforms/treemap.js b/src/transforms/treemap.js index 35f00233c8..226a1be306 100644 --- a/src/transforms/treemap.js +++ b/src/transforms/treemap.js @@ -1,4 +1,4 @@ -import {stratify, treemap, treemapBinary} from "d3"; +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"; @@ -43,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()) { @@ -61,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/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 @@ + + + + + not vis + + + vis + + + + + 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 + + + + + AgglomerativeCluster + + CommunityStructure + + HierarchicalCluster + + MergeEdge + + 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 + + IForce + + NBodyForce + + Particle + + Simulation + + Spring + + SpringForce + + AggregateExpression + + And + + Arithmetic + + Average + + BinaryExpression + + Comparison + + CompositeExpression + + Count + + DateUtil + + Distinct + + Expression + + ExpressionIterator + + Fn + + If + + IsA + + Literal + + Match + + 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 + + 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 + + + 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 8ff57ac406..d1a2f45319 100644 --- a/test/plots/flare-treemap.ts +++ b/test/plots/flare-treemap.ts @@ -16,6 +16,24 @@ export async function flareTreemap() { }); } +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({