@unovis/ts 1.6.2-pre.7 → 1.7.0-Phoenix.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/sankey/config.d.ts +8 -0
- package/components/sankey/config.js +1 -1
- package/components/sankey/config.js.map +1 -1
- package/components/sankey/index.d.ts +29 -0
- package/components/sankey/index.js +70 -0
- package/components/sankey/index.js.map +1 -1
- package/components/sankey/modules/link.js +16 -3
- package/components/sankey/modules/link.js.map +1 -1
- package/components/sankey/types.d.ts +2 -0
- package/components/sankey/types.js.map +1 -1
- package/components/treemap/config.d.ts +17 -10
- package/components/treemap/config.js +2 -1
- package/components/treemap/config.js.map +1 -1
- package/components/treemap/index.d.ts +0 -2
- package/components/treemap/index.js +78 -91
- package/components/treemap/index.js.map +1 -1
- package/components/treemap/style.d.ts +3 -8
- package/components/treemap/style.js +10 -15
- package/components/treemap/style.js.map +1 -1
- package/index.js +1 -1
- package/package.json +1 -1
- package/utils/color.d.ts +1 -0
- package/utils/color.js +7 -1
- package/utils/color.js.map +1 -1
- package/utils/index.js +1 -1
|
@@ -20,6 +20,14 @@ export interface SankeyConfigInterface<N extends SankeyInputNode, L extends Sank
|
|
|
20
20
|
highlightDelay?: number;
|
|
21
21
|
/** Sankey algorithm iterations. Default: `32` */
|
|
22
22
|
iterations?: number;
|
|
23
|
+
/** Enable node collapse functionality. When enabled, clicking on nodes will toggle their collapse state. Default: `false` */
|
|
24
|
+
enableNodeCollapse?: boolean;
|
|
25
|
+
/** Node collapse animation duration, ms. Default: `300` */
|
|
26
|
+
collapseAnimationDuration?: number;
|
|
27
|
+
/** Field name in the node data that indicates if a node should be pre-collapsed.
|
|
28
|
+
* For example, if set to "disabled", nodes with `disabled: true` will start collapsed.
|
|
29
|
+
* Default: `undefined` */
|
|
30
|
+
disabledField?: string;
|
|
23
31
|
/** Sankey node sorting function. Default: `undefined`.
|
|
24
32
|
* Node sorting is applied to nodes in one layer (column). Layer by layer.
|
|
25
33
|
* Options: `undefined` - the order is determined by the layout;
|
|
@@ -5,7 +5,7 @@ import { Position } from '../../types/position.js';
|
|
|
5
5
|
import { SankeyExitTransitionType, SankeyEnterTransitionType, SankeyNodeAlign, SankeySubLabelPlacement } from './types.js';
|
|
6
6
|
|
|
7
7
|
// Config
|
|
8
|
-
const SankeyDefaultConfig = (Object.assign(Object.assign({}, ComponentDefaultConfig), { heightNormalizationCoeff: 1 / 16, exitTransitionType: SankeyExitTransitionType.Default, enterTransitionType: SankeyEnterTransitionType.Default, id: (d, i) => { var _a; return (_a = d._id) !== null && _a !== void 0 ? _a : `${i}`; }, highlightSubtreeOnHover: false, highlightDuration: 300, highlightDelay: 1000, iterations: 32, nodeSort: undefined, nodeWidth: 25, nodeAlign: SankeyNodeAlign.Justify, nodeHorizontalSpacing: 150, nodeMinHeight: 20, nodeMaxHeight: 100, nodePadding: 2, nodeColor: (d) => d.color, nodeFixedValue: (d) => d.fixedValue, showSingleNode: true, nodeCursor: undefined, nodeIcon: undefined, nodeIconColor: undefined, label: (d) => d.label, labelPosition: Position.Auto, labelVerticalAlign: VerticalAlign.Middle, labelBackground: false, labelTextSeparator: [' ', '-'], labelFit: FitMode.Trim, labelTrimMode: TrimMode.Middle, labelForceWordBreak: true, labelFontSize: undefined, labelCursor: undefined, labelColor: undefined, labelMaxWidth: 70, labelExpandTrimmedOnHover: true, labelVisibility: undefined, subLabel: undefined, subLabelFontSize: undefined, subLabelColor: undefined, subLabelPlacement: SankeySubLabelPlacement.Below, subLabelToLabelInlineWidthRatio: 0.4, linkValue: (d) => d.value, linkColor: (d) => d.color, linkCursor: undefined,
|
|
8
|
+
const SankeyDefaultConfig = (Object.assign(Object.assign({}, ComponentDefaultConfig), { heightNormalizationCoeff: 1 / 16, exitTransitionType: SankeyExitTransitionType.Default, enterTransitionType: SankeyEnterTransitionType.Default, id: (d, i) => { var _a; return (_a = d._id) !== null && _a !== void 0 ? _a : `${i}`; }, highlightSubtreeOnHover: false, highlightDuration: 300, highlightDelay: 1000, iterations: 32, enableNodeCollapse: false, collapseAnimationDuration: 300, disabledField: undefined, nodeSort: undefined, nodeWidth: 25, nodeAlign: SankeyNodeAlign.Justify, nodeHorizontalSpacing: 150, nodeMinHeight: 20, nodeMaxHeight: 100, nodePadding: 2, nodeColor: (d) => d.color, nodeFixedValue: (d) => d.fixedValue, showSingleNode: true, nodeCursor: undefined, nodeIcon: undefined, nodeIconColor: undefined, label: (d) => d.label, labelPosition: Position.Auto, labelVerticalAlign: VerticalAlign.Middle, labelBackground: false, labelTextSeparator: [' ', '-'], labelFit: FitMode.Trim, labelTrimMode: TrimMode.Middle, labelForceWordBreak: true, labelFontSize: undefined, labelCursor: undefined, labelColor: undefined, labelMaxWidth: 70, labelExpandTrimmedOnHover: true, labelVisibility: undefined, subLabel: undefined, subLabelFontSize: undefined, subLabelColor: undefined, subLabelPlacement: SankeySubLabelPlacement.Below, subLabelToLabelInlineWidthRatio: 0.4, linkValue: (d) => d.value, linkColor: (d) => d.color, linkCursor: undefined,
|
|
9
9
|
// https://stackoverflow.com/a/21648197/2040291
|
|
10
10
|
init: function () {
|
|
11
11
|
this.linkSort =
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../../../src/components/sankey/config.ts"],"sourcesContent":["// Config\nimport { ComponentConfigInterface, ComponentDefaultConfig } from 'core/component/config'\n\n// Utils\nimport { getNumber } from 'utils/data'\n\n// Types\nimport { ColorAccessor, GenericAccessor, NumericAccessor, StringAccessor } from 'types/accessor'\nimport { TrimMode, VerticalAlign, FitMode } from 'types/text'\nimport { Position } from 'types/position'\nimport {\n SankeyInputLink,\n SankeyInputNode,\n SankeyNodeAlign,\n SankeySubLabelPlacement,\n SankeyExitTransitionType,\n SankeyEnterTransitionType,\n SankeyLink,\n SankeyNode,\n} from './types'\n\nexport interface SankeyConfigInterface<N extends SankeyInputNode, L extends SankeyInputLink> extends ComponentConfigInterface {\n // General\n /** Node / Link id accessor function. Used for mapping of data updates to corresponding SVG objects. Default: `(d, i) => d.id ?? i.toString()` */\n id?: (d: SankeyInputNode | SankeyInputLink, i: number, ...any: unknown[]) => string;\n /** Coefficient to scale the height of the diagram when the amount of links is low: `C * links.length`, clamped to `[height / 2, height]`. Default: `1/16` */\n heightNormalizationCoeff?: number;\n /** Type of animation on removing nodes. Default: `ExitTransitionType.Default` */\n exitTransitionType?: SankeyExitTransitionType;\n /** Type of animation on creating nodes. Default: `EnterTransitionType.Default` */\n enterTransitionType?: SankeyEnterTransitionType;\n /** Highlight the corresponding subtree on node / link hover. Default: `false` */\n highlightSubtreeOnHover?: boolean;\n /** Highlight animation duration, ms. Default: `400` */\n highlightDuration?: number;\n /** Highlight delay, ms. Default: `1000` */\n highlightDelay?: number;\n /** Sankey algorithm iterations. Default: `32` */\n iterations?: number;\n\n // Sorting\n /** Sankey node sorting function. Default: `undefined`.\n * Node sorting is applied to nodes in one layer (column). Layer by layer.\n * Options: `undefined` - the order is determined by the layout;\n * `null` - the order is fixed by the input;\n * sort function - the order is determined by the function.\n */\n nodeSort?: ((node1: SankeyNode<N, L>, node2: SankeyNode<N, L>) => number) | null | undefined;\n /** Sankey link sorting function. Default: `(link2, link1) => link1.value - link2.value`.\n * Link sorting is applied to the source (exiting) links within one node.\n * Options: `undefined` - the order is determined by the layout;\n * `null` - the order is fixed by the input;\n * sort function - the order is determined by the function.\n */\n linkSort?: ((link1: SankeyLink<N, L>, link2: SankeyLink<N, L>) => number) | null | undefined;\n\n // Nodes\n /** Sankey node width in pixels */\n nodeWidth?: number;\n /** Sankey node alignment method */\n nodeAlign?: SankeyNodeAlign;\n /** Horizontal space between the nodes. Extended Sizing property only. Default: `150` */\n nodeHorizontalSpacing?: number;\n /** Minimum node height. Extended Sizing property only. Default: `20` */\n nodeMinHeight?: number;\n /** Maximum node height. Extended Sizing property only. Default: `100` */\n nodeMaxHeight?: number;\n /** Sankey vertical separation between nodes in pixels. Default: `2` */\n nodePadding?: number;\n /** Display the graph when data has just one element */\n showSingleNode?: boolean;\n /** Node cursor on hover. Default: `undefined` */\n nodeCursor?: StringAccessor<SankeyNode<N, L>>;\n /** Node icon accessor function or value. Default: `undefined` */\n nodeIcon?: StringAccessor<SankeyNode<N, L>>;\n /** Node color accessor function or value. Default: `undefined` */\n nodeColor?: ColorAccessor<SankeyNode<N, L>>;\n /** Node `fixedValue` accessor function or constant. It defines the node value that will be used to calculate\n * the height of the nodes by d3-sankey (by default the height will be based on aggregated `linkValue`).\n * Default: `n => n.fixedValue`\n */\n nodeFixedValue?: NumericAccessor<N>;\n /** Icon color accessor function or value. Default: `undefined` */\n nodeIconColor?: ColorAccessor<SankeyNode<N, L>>;\n\n // Links\n /** Link color accessor function or value. Default: `l => l.color` */\n linkColor?: StringAccessor<SankeyLink<N, L>>;\n /** Link flow accessor function or value. Default: `l => l.value` */\n linkValue?: NumericAccessor<L>;\n /** Link cursor on hover. Default: `undefined` */\n linkCursor?: StringAccessor<SankeyLink<N, L>>;\n\n // Labels\n /** Node label accessor function or value. Default: `n => n.label` */\n label?: StringAccessor<SankeyNode<N, L>>;\n /** Node sub-label accessor function or value. Default: `undefined` */\n subLabel?: StringAccessor<SankeyNode<N, L>>;\n /** Label position relative to the Node. Default: `Position.AUTO` */\n labelPosition?: GenericAccessor<Position.Auto | Position.Left | Position.Right | string, SankeyNode<N, L>>;\n /** Label vertical alignment */\n labelVerticalAlign?: VerticalAlign | string;\n /** Label background */\n labelBackground?: boolean;\n /** Label fit mode (wrap or trim). Default: `FitMode.TRIM` **/\n labelFit?: FitMode;\n /** Maximum label with in pixels. Default: `70` */\n labelMaxWidth?: number;\n /** Expand trimmed label on hover. Default: `true` */\n labelExpandTrimmedOnHover?: boolean;\n /** Label trimming mode. Default: `TrimMode.Middle` */\n labelTrimMode?: TrimMode;\n /** Label font size in pixels. If not provided, the value of CSS variable `--vis-sankey-node-label-font-size` will be used. Default: `undefined` */\n labelFontSize?: number;\n /** Label text separators for wrapping. Default: `[' ', '-']` */\n labelTextSeparator?: string[];\n /** Force break words to fit long labels. Default: `true` */\n labelForceWordBreak?: boolean;\n /** Label color. Default: `undefined` */\n labelColor?: ColorAccessor<SankeyNode<N, L>>;\n /** Label cursor on hover. Default: `undefined` */\n labelCursor?: StringAccessor<SankeyNode<N, L>>;\n /** Custom function to set the label visibility. Default: `undefined` */\n labelVisibility?: ((d: SankeyNode<N, L>, bbox: { x: number; y: number; width: number; height: number }, hovered: boolean) => boolean) | undefined;\n /** Sub-label font size in pixels. If not provided, the value of CSS variable `--vis-sankey-node-sublabel-font-size` will be used. Default: `undefined` */\n subLabelFontSize?: number;\n /** Sub-label color. Default: `undefined` */\n subLabelColor?: ColorAccessor<SankeyNode<N, L>>;\n /** Sub-label position. Default: `SankeySubLabelPlacement.Below` */\n subLabelPlacement?: SankeySubLabelPlacement | string;\n /**\n * Sub-label to label width ratio when `subLabelPlacement` is set to `SankeySubLabelPlacement.Inline`\n * Default: `0.4`, which means that 40% of `labelMaxWidth` will be given to sub-label, and 60% to the main label.\n */\n subLabelToLabelInlineWidthRatio?: number;\n}\n\nexport const SankeyDefaultConfig: SankeyConfigInterface<SankeyInputNode, SankeyInputLink> = ({\n ...ComponentDefaultConfig,\n heightNormalizationCoeff: 1 / 16,\n exitTransitionType: SankeyExitTransitionType.Default,\n enterTransitionType: SankeyEnterTransitionType.Default,\n id: (d: SankeyInputNode, i: number) => (d as { _id: string })._id ?? `${i}`,\n highlightSubtreeOnHover: false,\n highlightDuration: 300,\n highlightDelay: 1000,\n iterations: 32,\n nodeSort: undefined,\n nodeWidth: 25,\n nodeAlign: SankeyNodeAlign.Justify,\n nodeHorizontalSpacing: 150,\n nodeMinHeight: 20,\n nodeMaxHeight: 100,\n nodePadding: 2,\n nodeColor: (d: SankeyInputNode) => (d as { color: string }).color,\n nodeFixedValue: (d: SankeyInputNode) => (d as { fixedValue: number }).fixedValue,\n showSingleNode: true,\n nodeCursor: undefined,\n nodeIcon: undefined,\n nodeIconColor: undefined,\n label: (d: SankeyInputNode) => (d as { label: string }).label,\n labelPosition: Position.Auto,\n labelVerticalAlign: VerticalAlign.Middle,\n labelBackground: false,\n labelTextSeparator: [' ', '-'],\n labelFit: FitMode.Trim,\n labelTrimMode: TrimMode.Middle,\n labelForceWordBreak: true,\n labelFontSize: undefined,\n labelCursor: undefined,\n labelColor: undefined,\n labelMaxWidth: 70,\n labelExpandTrimmedOnHover: true,\n labelVisibility: undefined,\n subLabel: undefined,\n subLabelFontSize: undefined,\n subLabelColor: undefined,\n subLabelPlacement: SankeySubLabelPlacement.Below,\n subLabelToLabelInlineWidthRatio: 0.4,\n linkValue: (d: SankeyInputNode) => (d as { value: number }).value,\n linkColor: (d: SankeyInputNode) => (d as { color: string }).color,\n linkCursor: undefined,\n\n // https://stackoverflow.com/a/21648197/2040291\n init: function () {\n (this as SankeyConfigInterface<SankeyInputNode, SankeyInputLink>).linkSort =\n (link2, link1) => getNumber(link1, this.linkValue) - getNumber(link2, this.linkValue)\n delete this.init\n return this\n },\n}).init()\n\n"],"names":[],"mappings":";;;;;;AAAA;AAyIa,MAAA,mBAAmB,GAA4D,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EACvF,sBAAsB,CAAA,EAAA,EACzB,wBAAwB,EAAE,CAAC,GAAG,EAAE,EAChC,kBAAkB,EAAE,wBAAwB,CAAC,OAAO,EACpD,mBAAmB,EAAE,yBAAyB,CAAC,OAAO,EACtD,EAAE,EAAE,CAAC,CAAkB,EAAE,CAAS,KAAK,EAAA,IAAA,EAAA,CAAA,CAAA,OAAA,CAAC,EAAA,GAAA,CAAqB,CAAC,GAAG,MAAI,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAA,CAAA,EAAG,CAAC,CAAA,CAAE,CAAA,EAAA,EAC3E,uBAAuB,EAAE,KAAK,EAC9B,iBAAiB,EAAE,GAAG,EACtB,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,EAAE,EACd,QAAQ,EAAE,SAAS,EACnB,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,eAAe,CAAC,OAAO,EAClC,qBAAqB,EAAE,GAAG,EAC1B,aAAa,EAAE,EAAE,EACjB,aAAa,EAAE,GAAG,EAClB,WAAW,EAAE,CAAC,EACd,SAAS,EAAE,CAAC,CAAkB,KAAM,CAAuB,CAAC,KAAK,EACjE,cAAc,EAAE,CAAC,CAAkB,KAAM,CAA4B,CAAC,UAAU,EAChF,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,SAAS,EACrB,QAAQ,EAAE,SAAS,EACnB,aAAa,EAAE,SAAS,EACxB,KAAK,EAAE,CAAC,CAAkB,KAAM,CAAuB,CAAC,KAAK,EAC7D,aAAa,EAAE,QAAQ,CAAC,IAAI,EAC5B,kBAAkB,EAAE,aAAa,CAAC,MAAM,EACxC,eAAe,EAAE,KAAK,EACtB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAC9B,QAAQ,EAAE,OAAO,CAAC,IAAI,EACtB,aAAa,EAAE,QAAQ,CAAC,MAAM,EAC9B,mBAAmB,EAAE,IAAI,EACzB,aAAa,EAAE,SAAS,EACxB,WAAW,EAAE,SAAS,EACtB,UAAU,EAAE,SAAS,EACrB,aAAa,EAAE,EAAE,EACjB,yBAAyB,EAAE,IAAI,EAC/B,eAAe,EAAE,SAAS,EAC1B,QAAQ,EAAE,SAAS,EACnB,gBAAgB,EAAE,SAAS,EAC3B,aAAa,EAAE,SAAS,EACxB,iBAAiB,EAAE,uBAAuB,CAAC,KAAK,EAChD,+BAA+B,EAAE,GAAG,EACpC,SAAS,EAAE,CAAC,CAAkB,KAAM,CAAuB,CAAC,KAAK,EACjE,SAAS,EAAE,CAAC,CAAkB,KAAM,CAAuB,CAAC,KAAK,EACjE,UAAU,EAAE,SAAS;;AAGrB,IAAA,IAAI,EAAE,YAAA;AACH,QAAA,IAAgE,CAAC,QAAQ;YACxE,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QACvF,OAAO,IAAI,CAAC,IAAI,CAAA;AAChB,QAAA,OAAO,IAAI,CAAA;AACb,KAAC,EACD,CAAA,EAAC,IAAI;;;;"}
|
|
1
|
+
{"version":3,"file":"config.js","sources":["../../../src/components/sankey/config.ts"],"sourcesContent":["// Config\nimport { ComponentConfigInterface, ComponentDefaultConfig } from 'core/component/config'\n\n// Utils\nimport { getNumber } from 'utils/data'\n\n// Types\nimport { ColorAccessor, GenericAccessor, NumericAccessor, StringAccessor } from 'types/accessor'\nimport { TrimMode, VerticalAlign, FitMode } from 'types/text'\nimport { Position } from 'types/position'\nimport {\n SankeyInputLink,\n SankeyInputNode,\n SankeyNodeAlign,\n SankeySubLabelPlacement,\n SankeyExitTransitionType,\n SankeyEnterTransitionType,\n SankeyLink,\n SankeyNode,\n} from './types'\n\nexport interface SankeyConfigInterface<N extends SankeyInputNode, L extends SankeyInputLink> extends ComponentConfigInterface {\n // General\n /** Node / Link id accessor function. Used for mapping of data updates to corresponding SVG objects. Default: `(d, i) => d.id ?? i.toString()` */\n id?: (d: SankeyInputNode | SankeyInputLink, i: number, ...any: unknown[]) => string;\n /** Coefficient to scale the height of the diagram when the amount of links is low: `C * links.length`, clamped to `[height / 2, height]`. Default: `1/16` */\n heightNormalizationCoeff?: number;\n /** Type of animation on removing nodes. Default: `ExitTransitionType.Default` */\n exitTransitionType?: SankeyExitTransitionType;\n /** Type of animation on creating nodes. Default: `EnterTransitionType.Default` */\n enterTransitionType?: SankeyEnterTransitionType;\n /** Highlight the corresponding subtree on node / link hover. Default: `false` */\n highlightSubtreeOnHover?: boolean;\n /** Highlight animation duration, ms. Default: `400` */\n highlightDuration?: number;\n /** Highlight delay, ms. Default: `1000` */\n highlightDelay?: number;\n /** Sankey algorithm iterations. Default: `32` */\n iterations?: number;\n\n // Collapse/Expand\n /** Enable node collapse functionality. When enabled, clicking on nodes will toggle their collapse state. Default: `false` */\n enableNodeCollapse?: boolean;\n /** Node collapse animation duration, ms. Default: `300` */\n collapseAnimationDuration?: number;\n /** Field name in the node data that indicates if a node should be pre-collapsed.\n * For example, if set to \"disabled\", nodes with `disabled: true` will start collapsed.\n * Default: `undefined` */\n disabledField?: string;\n\n // Sorting\n /** Sankey node sorting function. Default: `undefined`.\n * Node sorting is applied to nodes in one layer (column). Layer by layer.\n * Options: `undefined` - the order is determined by the layout;\n * `null` - the order is fixed by the input;\n * sort function - the order is determined by the function.\n */\n nodeSort?: ((node1: SankeyNode<N, L>, node2: SankeyNode<N, L>) => number) | null | undefined;\n /** Sankey link sorting function. Default: `(link2, link1) => link1.value - link2.value`.\n * Link sorting is applied to the source (exiting) links within one node.\n * Options: `undefined` - the order is determined by the layout;\n * `null` - the order is fixed by the input;\n * sort function - the order is determined by the function.\n */\n linkSort?: ((link1: SankeyLink<N, L>, link2: SankeyLink<N, L>) => number) | null | undefined;\n\n // Nodes\n /** Sankey node width in pixels */\n nodeWidth?: number;\n /** Sankey node alignment method */\n nodeAlign?: SankeyNodeAlign;\n /** Horizontal space between the nodes. Extended Sizing property only. Default: `150` */\n nodeHorizontalSpacing?: number;\n /** Minimum node height. Extended Sizing property only. Default: `20` */\n nodeMinHeight?: number;\n /** Maximum node height. Extended Sizing property only. Default: `100` */\n nodeMaxHeight?: number;\n /** Sankey vertical separation between nodes in pixels. Default: `2` */\n nodePadding?: number;\n /** Display the graph when data has just one element */\n showSingleNode?: boolean;\n /** Node cursor on hover. Default: `undefined` */\n nodeCursor?: StringAccessor<SankeyNode<N, L>>;\n /** Node icon accessor function or value. Default: `undefined` */\n nodeIcon?: StringAccessor<SankeyNode<N, L>>;\n /** Node color accessor function or value. Default: `undefined` */\n nodeColor?: ColorAccessor<SankeyNode<N, L>>;\n /** Node `fixedValue` accessor function or constant. It defines the node value that will be used to calculate\n * the height of the nodes by d3-sankey (by default the height will be based on aggregated `linkValue`).\n * Default: `n => n.fixedValue`\n */\n nodeFixedValue?: NumericAccessor<N>;\n /** Icon color accessor function or value. Default: `undefined` */\n nodeIconColor?: ColorAccessor<SankeyNode<N, L>>;\n\n // Links\n /** Link color accessor function or value. Default: `l => l.color` */\n linkColor?: StringAccessor<SankeyLink<N, L>>;\n /** Link flow accessor function or value. Default: `l => l.value` */\n linkValue?: NumericAccessor<L>;\n /** Link cursor on hover. Default: `undefined` */\n linkCursor?: StringAccessor<SankeyLink<N, L>>;\n\n // Labels\n /** Node label accessor function or value. Default: `n => n.label` */\n label?: StringAccessor<SankeyNode<N, L>>;\n /** Node sub-label accessor function or value. Default: `undefined` */\n subLabel?: StringAccessor<SankeyNode<N, L>>;\n /** Label position relative to the Node. Default: `Position.AUTO` */\n labelPosition?: GenericAccessor<Position.Auto | Position.Left | Position.Right | string, SankeyNode<N, L>>;\n /** Label vertical alignment */\n labelVerticalAlign?: VerticalAlign | string;\n /** Label background */\n labelBackground?: boolean;\n /** Label fit mode (wrap or trim). Default: `FitMode.TRIM` **/\n labelFit?: FitMode;\n /** Maximum label with in pixels. Default: `70` */\n labelMaxWidth?: number;\n /** Expand trimmed label on hover. Default: `true` */\n labelExpandTrimmedOnHover?: boolean;\n /** Label trimming mode. Default: `TrimMode.Middle` */\n labelTrimMode?: TrimMode;\n /** Label font size in pixels. If not provided, the value of CSS variable `--vis-sankey-node-label-font-size` will be used. Default: `undefined` */\n labelFontSize?: number;\n /** Label text separators for wrapping. Default: `[' ', '-']` */\n labelTextSeparator?: string[];\n /** Force break words to fit long labels. Default: `true` */\n labelForceWordBreak?: boolean;\n /** Label color. Default: `undefined` */\n labelColor?: ColorAccessor<SankeyNode<N, L>>;\n /** Label cursor on hover. Default: `undefined` */\n labelCursor?: StringAccessor<SankeyNode<N, L>>;\n /** Custom function to set the label visibility. Default: `undefined` */\n labelVisibility?: ((d: SankeyNode<N, L>, bbox: { x: number; y: number; width: number; height: number }, hovered: boolean) => boolean) | undefined;\n /** Sub-label font size in pixels. If not provided, the value of CSS variable `--vis-sankey-node-sublabel-font-size` will be used. Default: `undefined` */\n subLabelFontSize?: number;\n /** Sub-label color. Default: `undefined` */\n subLabelColor?: ColorAccessor<SankeyNode<N, L>>;\n /** Sub-label position. Default: `SankeySubLabelPlacement.Below` */\n subLabelPlacement?: SankeySubLabelPlacement | string;\n /**\n * Sub-label to label width ratio when `subLabelPlacement` is set to `SankeySubLabelPlacement.Inline`\n * Default: `0.4`, which means that 40% of `labelMaxWidth` will be given to sub-label, and 60% to the main label.\n */\n subLabelToLabelInlineWidthRatio?: number;\n}\n\nexport const SankeyDefaultConfig: SankeyConfigInterface<SankeyInputNode, SankeyInputLink> = ({\n ...ComponentDefaultConfig,\n heightNormalizationCoeff: 1 / 16,\n exitTransitionType: SankeyExitTransitionType.Default,\n enterTransitionType: SankeyEnterTransitionType.Default,\n id: (d: SankeyInputNode, i: number) => (d as { _id: string })._id ?? `${i}`,\n highlightSubtreeOnHover: false,\n highlightDuration: 300,\n highlightDelay: 1000,\n iterations: 32,\n enableNodeCollapse: false,\n collapseAnimationDuration: 300,\n disabledField: undefined,\n nodeSort: undefined,\n nodeWidth: 25,\n nodeAlign: SankeyNodeAlign.Justify,\n nodeHorizontalSpacing: 150,\n nodeMinHeight: 20,\n nodeMaxHeight: 100,\n nodePadding: 2,\n nodeColor: (d: SankeyInputNode) => (d as { color: string }).color,\n nodeFixedValue: (d: SankeyInputNode) => (d as { fixedValue: number }).fixedValue,\n showSingleNode: true,\n nodeCursor: undefined,\n nodeIcon: undefined,\n nodeIconColor: undefined,\n label: (d: SankeyInputNode) => (d as { label: string }).label,\n labelPosition: Position.Auto,\n labelVerticalAlign: VerticalAlign.Middle,\n labelBackground: false,\n labelTextSeparator: [' ', '-'],\n labelFit: FitMode.Trim,\n labelTrimMode: TrimMode.Middle,\n labelForceWordBreak: true,\n labelFontSize: undefined,\n labelCursor: undefined,\n labelColor: undefined,\n labelMaxWidth: 70,\n labelExpandTrimmedOnHover: true,\n labelVisibility: undefined,\n subLabel: undefined,\n subLabelFontSize: undefined,\n subLabelColor: undefined,\n subLabelPlacement: SankeySubLabelPlacement.Below,\n subLabelToLabelInlineWidthRatio: 0.4,\n linkValue: (d: SankeyInputNode) => (d as { value: number }).value,\n linkColor: (d: SankeyInputNode) => (d as { color: string }).color,\n linkCursor: undefined,\n\n // https://stackoverflow.com/a/21648197/2040291\n init: function () {\n (this as SankeyConfigInterface<SankeyInputNode, SankeyInputLink>).linkSort =\n (link2, link1) => getNumber(link1, this.linkValue) - getNumber(link2, this.linkValue)\n delete this.init\n return this\n },\n}).init()\n\n"],"names":[],"mappings":";;;;;;AAAA;AAmJO,MAAM,mBAAmB,GAA4D,CACvF,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,sBAAsB,CACzB,EAAA,EAAA,wBAAwB,EAAE,CAAC,GAAG,EAAE,EAChC,kBAAkB,EAAE,wBAAwB,CAAC,OAAO,EACpD,mBAAmB,EAAE,yBAAyB,CAAC,OAAO,EACtD,EAAE,EAAE,CAAC,CAAkB,EAAE,CAAS,KAAK,EAAA,IAAA,EAAA,CAAA,CAAA,OAAA,CAAC,EAAA,GAAA,CAAqB,CAAC,GAAG,MAAI,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAA,CAAA,EAAG,CAAC,CAAA,CAAE,CAAA,EAAA,EAC3E,uBAAuB,EAAE,KAAK,EAC9B,iBAAiB,EAAE,GAAG,EACtB,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,EAAE,EACd,kBAAkB,EAAE,KAAK,EACzB,yBAAyB,EAAE,GAAG,EAC9B,aAAa,EAAE,SAAS,EACxB,QAAQ,EAAE,SAAS,EACnB,SAAS,EAAE,EAAE,EACb,SAAS,EAAE,eAAe,CAAC,OAAO,EAClC,qBAAqB,EAAE,GAAG,EAC1B,aAAa,EAAE,EAAE,EACjB,aAAa,EAAE,GAAG,EAClB,WAAW,EAAE,CAAC,EACd,SAAS,EAAE,CAAC,CAAkB,KAAM,CAAuB,CAAC,KAAK,EACjE,cAAc,EAAE,CAAC,CAAkB,KAAM,CAA4B,CAAC,UAAU,EAChF,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,SAAS,EACrB,QAAQ,EAAE,SAAS,EACnB,aAAa,EAAE,SAAS,EACxB,KAAK,EAAE,CAAC,CAAkB,KAAM,CAAuB,CAAC,KAAK,EAC7D,aAAa,EAAE,QAAQ,CAAC,IAAI,EAC5B,kBAAkB,EAAE,aAAa,CAAC,MAAM,EACxC,eAAe,EAAE,KAAK,EACtB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,EAC9B,QAAQ,EAAE,OAAO,CAAC,IAAI,EACtB,aAAa,EAAE,QAAQ,CAAC,MAAM,EAC9B,mBAAmB,EAAE,IAAI,EACzB,aAAa,EAAE,SAAS,EACxB,WAAW,EAAE,SAAS,EACtB,UAAU,EAAE,SAAS,EACrB,aAAa,EAAE,EAAE,EACjB,yBAAyB,EAAE,IAAI,EAC/B,eAAe,EAAE,SAAS,EAC1B,QAAQ,EAAE,SAAS,EACnB,gBAAgB,EAAE,SAAS,EAC3B,aAAa,EAAE,SAAS,EACxB,iBAAiB,EAAE,uBAAuB,CAAC,KAAK,EAChD,+BAA+B,EAAE,GAAG,EACpC,SAAS,EAAE,CAAC,CAAkB,KAAM,CAAuB,CAAC,KAAK,EACjE,SAAS,EAAE,CAAC,CAAkB,KAAM,CAAuB,CAAC,KAAK,EACjE,UAAU,EAAE,SAAS;;AAGrB,IAAA,IAAI,EAAE,YAAA;AACH,QAAA,IAAgE,CAAC,QAAQ;YACxE,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QACvF,OAAO,IAAI,CAAC,IAAI,CAAA;AAChB,QAAA,OAAO,IAAI,CAAA;AACb,KAAC,EACD,CAAA,EAAC,IAAI;;;;"}
|
|
@@ -26,9 +26,15 @@ export declare class Sankey<N extends SankeyInputNode, L extends SankeyInputLink
|
|
|
26
26
|
[x: string]: {
|
|
27
27
|
mouseenter: (d: SankeyNode<N, L>, event: MouseEvent) => void;
|
|
28
28
|
mouseleave: (d: SankeyNode<N, L>, event: MouseEvent) => void;
|
|
29
|
+
click?: undefined;
|
|
30
|
+
} | {
|
|
31
|
+
mouseenter: (d: SankeyNode<N, L>) => void;
|
|
32
|
+
mouseleave: (d: SankeyNode<N, L>) => void;
|
|
33
|
+
click: (d: SankeyNode<N, L>, event: MouseEvent) => void;
|
|
29
34
|
} | {
|
|
30
35
|
mouseenter: (d: SankeyLink<N, L>, event: MouseEvent) => void;
|
|
31
36
|
mouseleave: (d: SankeyLink<N, L>, event: MouseEvent) => void;
|
|
37
|
+
click?: undefined;
|
|
32
38
|
};
|
|
33
39
|
};
|
|
34
40
|
constructor(config?: SankeyConfigInterface<N, L>);
|
|
@@ -50,11 +56,34 @@ export declare class Sankey<N extends SankeyInputNode, L extends SankeyInputLink
|
|
|
50
56
|
highlightSubtree(node: SankeyNode<N, L>): void;
|
|
51
57
|
recursiveSetSubtreeState(node: SankeyNode<N, L>, linksKey: 'sourceLinks' | 'targetLinks', nodeKey: 'source' | 'target', key: string, value: unknown): void;
|
|
52
58
|
disableHighlight(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Collapses a node by hiding only the links directly connected to it.
|
|
61
|
+
* All other nodes (including children and descendants) remain visible in their original positions.
|
|
62
|
+
* Only the immediate incoming and outgoing links of the collapsed node are hidden.
|
|
63
|
+
*/
|
|
64
|
+
collapseNode(node: SankeyNode<N, L>): void;
|
|
65
|
+
/**
|
|
66
|
+
* Expands a previously collapsed node by showing its directly connected links.
|
|
67
|
+
*/
|
|
68
|
+
expandNode(node: SankeyNode<N, L>): void;
|
|
69
|
+
/**
|
|
70
|
+
* Toggles the collapse state of a node.
|
|
71
|
+
*
|
|
72
|
+
* @param node The node to toggle
|
|
73
|
+
*/
|
|
74
|
+
toggleNodeCollapse(node: SankeyNode<N, L>): void;
|
|
53
75
|
private _hasLinks;
|
|
76
|
+
/**
|
|
77
|
+
* Applies initial collapse state to nodes based on the disabledField configuration.
|
|
78
|
+
* If disabledField is set (e.g., "disabled"), nodes with that field set to true
|
|
79
|
+
* will be pre-collapsed when the component loads.
|
|
80
|
+
*/
|
|
81
|
+
private _applyInitialCollapseState;
|
|
54
82
|
private _onNodeMouseOver;
|
|
55
83
|
private _onNodeMouseOut;
|
|
56
84
|
private _onNodeRectMouseOver;
|
|
57
85
|
private _onNodeRectMouseOut;
|
|
58
86
|
private _onLinkMouseOver;
|
|
59
87
|
private _onLinkMouseOut;
|
|
88
|
+
private _onNodeClick;
|
|
60
89
|
}
|
|
@@ -38,6 +38,7 @@ class Sankey extends ComponentCore {
|
|
|
38
38
|
[Sankey.selectors.node]: {
|
|
39
39
|
mouseenter: this._onNodeRectMouseOver.bind(this),
|
|
40
40
|
mouseleave: this._onNodeRectMouseOut.bind(this),
|
|
41
|
+
click: this._onNodeClick.bind(this),
|
|
41
42
|
},
|
|
42
43
|
[Sankey.selectors.link]: {
|
|
43
44
|
mouseenter: this._onLinkMouseOver.bind(this),
|
|
@@ -80,12 +81,16 @@ class Sankey extends ComponentCore {
|
|
|
80
81
|
}
|
|
81
82
|
setData(data) {
|
|
82
83
|
super.setData(data);
|
|
84
|
+
// Pre-collapse nodes based on disabledField
|
|
85
|
+
this._applyInitialCollapseState();
|
|
83
86
|
// Pre-calculate component size for Sizing.EXTEND
|
|
84
87
|
if ((this.sizing !== Sizing.Fit) || !this._hasLinks())
|
|
85
88
|
this._preCalculateComponentSize();
|
|
86
89
|
}
|
|
87
90
|
setConfig(config) {
|
|
88
91
|
super.setConfig(config);
|
|
92
|
+
// Apply initial collapse state if disabledField is set
|
|
93
|
+
this._applyInitialCollapseState();
|
|
89
94
|
// Pre-calculate component size for Sizing.EXTEND
|
|
90
95
|
if ((this.sizing !== Sizing.Fit) || !this._hasLinks())
|
|
91
96
|
this._preCalculateComponentSize();
|
|
@@ -274,10 +279,69 @@ class Sankey extends ComponentCore {
|
|
|
274
279
|
this._render(config.highlightDuration);
|
|
275
280
|
}
|
|
276
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* Collapses a node by hiding only the links directly connected to it.
|
|
284
|
+
* All other nodes (including children and descendants) remain visible in their original positions.
|
|
285
|
+
* Only the immediate incoming and outgoing links of the collapsed node are hidden.
|
|
286
|
+
*/
|
|
287
|
+
collapseNode(node) {
|
|
288
|
+
const { config } = this;
|
|
289
|
+
// Clear any active highlights before collapsing
|
|
290
|
+
this.disableHighlight();
|
|
291
|
+
node._state = node._state || {};
|
|
292
|
+
node._state.collapsed = true;
|
|
293
|
+
this._render(config.collapseAnimationDuration);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Expands a previously collapsed node by showing its directly connected links.
|
|
297
|
+
*/
|
|
298
|
+
expandNode(node) {
|
|
299
|
+
const { config } = this;
|
|
300
|
+
// Clear any active highlights before expanding
|
|
301
|
+
this.disableHighlight();
|
|
302
|
+
node._state = node._state || {};
|
|
303
|
+
node._state.collapsed = false;
|
|
304
|
+
this._render(config.collapseAnimationDuration);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Toggles the collapse state of a node.
|
|
308
|
+
*
|
|
309
|
+
* @param node The node to toggle
|
|
310
|
+
*/
|
|
311
|
+
toggleNodeCollapse(node) {
|
|
312
|
+
var _a;
|
|
313
|
+
if ((_a = node._state) === null || _a === void 0 ? void 0 : _a.collapsed) {
|
|
314
|
+
this.expandNode(node);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
this.collapseNode(node);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
277
320
|
_hasLinks() {
|
|
278
321
|
const { datamodel } = this;
|
|
279
322
|
return datamodel.links.length > 0;
|
|
280
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* Applies initial collapse state to nodes based on the disabledField configuration.
|
|
326
|
+
* If disabledField is set (e.g., "disabled"), nodes with that field set to true
|
|
327
|
+
* will be pre-collapsed when the component loads.
|
|
328
|
+
*/
|
|
329
|
+
_applyInitialCollapseState() {
|
|
330
|
+
const { config, datamodel } = this;
|
|
331
|
+
if (!config.disabledField)
|
|
332
|
+
return;
|
|
333
|
+
// Check each node for the disabled field and set initial collapse state
|
|
334
|
+
for (const node of datamodel.nodes) {
|
|
335
|
+
const inputData = node;
|
|
336
|
+
const isDisabled = inputData && typeof inputData === 'object' &&
|
|
337
|
+
config.disabledField in inputData &&
|
|
338
|
+
inputData[config.disabledField] === true;
|
|
339
|
+
if (isDisabled) {
|
|
340
|
+
node._state = node._state || {};
|
|
341
|
+
node._state.collapsed = true;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
281
345
|
_onNodeMouseOver(d, event) {
|
|
282
346
|
onNodeMouseOver(d, select(event.currentTarget), this.config, this._width);
|
|
283
347
|
}
|
|
@@ -300,6 +364,12 @@ class Sankey extends ComponentCore {
|
|
|
300
364
|
_onLinkMouseOut(d, event) {
|
|
301
365
|
this.disableHighlight();
|
|
302
366
|
}
|
|
367
|
+
_onNodeClick(d, event) {
|
|
368
|
+
const { config } = this;
|
|
369
|
+
if (config.enableNodeCollapse) {
|
|
370
|
+
this.toggleNodeCollapse(d);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
303
373
|
}
|
|
304
374
|
Sankey.selectors = style;
|
|
305
375
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/sankey/index.ts"],"sourcesContent":["import { select, Selection } from 'd3-selection'\nimport { sankey, SankeyGraph } from 'd3-sankey'\nimport { extent, max, sum } from 'd3-array'\nimport { scaleLinear } from 'd3-scale'\n\n// Core\nimport { ComponentCore } from 'core/component'\nimport { GraphDataModel } from 'data-models/graph'\n\n// Types\nimport { ExtendedSizeComponent, Sizing } from 'types/component'\nimport { Position } from 'types/position'\nimport { Spacing } from 'types/spacing'\nimport { VerticalAlign } from 'types/text'\n\n// Utils\nimport { smartTransition } from 'utils/d3'\nimport { getNumber, getString, groupBy, isNumber } from 'utils/data'\nimport { getCSSVariableValueInPixels } from 'utils/misc'\n\n// Config\nimport { SankeyDefaultConfig, SankeyConfigInterface } from './config'\n\n// Styles\nimport * as s from './style'\n\n// Local Types\nimport { SankeyInputLink, SankeyInputNode, SankeyLayout, SankeyLink, SankeyNode } from './types'\n\n// Modules\nimport { createLinks, removeLinks, updateLinks } from './modules/link'\nimport { createNodes, onNodeMouseOut, onNodeMouseOver, removeNodes, updateNodes } from './modules/node'\nimport { getLabelOrientation, requiredLabelSpace } from './modules/label'\n\nexport class Sankey<\n N extends SankeyInputNode,\n L extends SankeyInputLink,\n> extends ComponentCore<\n {nodes: N[]; links?: L[]},\n SankeyConfigInterface<N, L>\n > implements ExtendedSizeComponent {\n static selectors = s\n protected _defaultConfig = SankeyDefaultConfig as SankeyConfigInterface<N, L>\n public config: SankeyConfigInterface<N, L> = this._defaultConfig\n datamodel: GraphDataModel<N, L, SankeyNode<N, L>, SankeyLink<N, L>> = new GraphDataModel()\n private _extendedWidth: number | undefined = undefined\n private _extendedHeight: number | undefined = undefined\n private _extendedHeightIncreased: number | undefined = undefined\n private _linksGroup: Selection<SVGGElement, unknown, SVGGElement, unknown>\n private _nodesGroup: Selection<SVGGElement, unknown, SVGGElement, unknown>\n private _backgroundRect: Selection<SVGRectElement, unknown, SVGGElement, unknown>\n private _sankey = sankey<SankeyGraph<N, L>, SankeyNode<N, L>, SankeyLink<N, L>>()\n private _highlightTimeoutId: ReturnType<typeof setTimeout> | null = null\n private _highlightActive = false\n events = {\n [Sankey.selectors.nodeGroup]: {\n mouseenter: this._onNodeMouseOver.bind(this),\n mouseleave: this._onNodeMouseOut.bind(this),\n },\n [Sankey.selectors.node]: {\n mouseenter: this._onNodeRectMouseOver.bind(this),\n mouseleave: this._onNodeRectMouseOut.bind(this),\n },\n [Sankey.selectors.link]: {\n mouseenter: this._onLinkMouseOver.bind(this),\n mouseleave: this._onLinkMouseOut.bind(this),\n },\n }\n\n constructor (config?: SankeyConfigInterface<N, L>) {\n super()\n if (config) this.setConfig(config)\n this._backgroundRect = this.g.append('rect').attr('class', s.background)\n this._linksGroup = this.g.append('g').attr('class', s.links)\n this._nodesGroup = this.g.append('g').attr('class', s.nodes)\n }\n\n get bleed (): Spacing {\n const { config, datamodel: { nodes, links } } = this\n const labelFontSize = config.labelFontSize ?? getCSSVariableValueInPixels('var(--vis-sankey-label-font-size)', this.element)\n const labelSize = requiredLabelSpace(config.labelMaxWidth, labelFontSize)\n\n let left = 0\n let right = 0\n\n // We pre-calculate sankey layout to get information about node labels placement and calculate bleed properly\n // Potentially it can be a performance bottleneck for large layouts, but generally rendering of such layouts is much more computationally heavy\n if (nodes.length) {\n const sankeyProbeSize = 1000\n this._populateLinkAndNodeValues()\n this._sankey.size([sankeyProbeSize, sankeyProbeSize])\n this._sankey({ nodes, links })\n const maxDepth = max(nodes, d => d.depth)\n const zeroDepthNodes = nodes.filter(d => d.depth === 0)\n const maxDepthNodes = nodes.filter(d => d.depth === maxDepth)\n\n left = zeroDepthNodes.some(d => getLabelOrientation(d, sankeyProbeSize, config.labelPosition) === Position.Left) ? labelSize.width : 0\n right = maxDepthNodes.some(d => getLabelOrientation(d, sankeyProbeSize, config.labelPosition) === Position.Right) ? labelSize.width : 0\n }\n\n const top = config.labelVerticalAlign === VerticalAlign.Top ? 0\n : config.labelVerticalAlign === VerticalAlign.Bottom ? labelSize.height\n : labelSize.height / 2\n\n const bottom = config.labelVerticalAlign === VerticalAlign.Top ? labelSize.height\n : config.labelVerticalAlign === VerticalAlign.Bottom ? 0\n : labelSize.height / 2\n\n return { top, bottom, left, right }\n }\n\n setData (data: { nodes: N[]; links?: L[] }): void {\n super.setData(data)\n\n // Pre-calculate component size for Sizing.EXTEND\n if ((this.sizing !== Sizing.Fit) || !this._hasLinks()) this._preCalculateComponentSize()\n }\n\n setConfig (config: SankeyConfigInterface<N, L>): void {\n super.setConfig(config)\n\n // Pre-calculate component size for Sizing.EXTEND\n if ((this.sizing !== Sizing.Fit) || !this._hasLinks()) this._preCalculateComponentSize()\n\n // Using \"as any\" because typings are not full (\"@types/d3-sankey\": \"^0.11.2\")\n const nodeId = ((d: SankeyInputNode, i: number) => getString(d, this.config.id, i)) as any;\n (this._sankey as any).linkSort(this.config.linkSort)\n this._sankey\n .nodeId(nodeId)\n .nodeWidth(this.config.nodeWidth)\n .nodePadding(this.config.nodePadding)\n .nodeAlign(SankeyLayout[this.config.nodeAlign])\n .nodeSort(this.config.nodeSort)\n .iterations(this.config.iterations)\n }\n\n _render (customDuration?: number): void {\n const { config, bleed, datamodel: { nodes, links } } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n if (\n (nodes.length === 0) ||\n (nodes.length === 1 && links.length > 0) ||\n (nodes.length === 1 && !config.showSingleNode) ||\n (nodes.length > 1 && links.length === 0)\n ) {\n this._linksGroup.selectAll<SVGGElement, SankeyLink<N, L>>(`.${s.link}`).call(removeLinks, duration)\n this._nodesGroup.selectAll<SVGGElement, SankeyNode<N, L>>(`.${s.nodeGroup}`).call(removeNodes, config, duration)\n }\n\n // Prepare Layout\n this._prepareLayout()\n\n // Links\n smartTransition(this._linksGroup, duration).attr('transform', `translate(${bleed.left},${bleed.top})`)\n const linkSelection = this._linksGroup.selectAll<SVGGElement, SankeyLink<N, L>>(`.${s.link}`)\n .data(links, (d, i) => config.id(d, i) ?? i)\n const linkSelectionEnter = linkSelection.enter().append('g').attr('class', s.link)\n linkSelectionEnter.call(createLinks)\n linkSelection.merge(linkSelectionEnter).call(updateLinks, config, duration)\n linkSelection.exit<SankeyLink<N, L>>().call(removeLinks)\n\n // Nodes\n smartTransition(this._nodesGroup, duration).attr('transform', `translate(${bleed.left},${bleed.top})`)\n\n const nodeSelection = this._nodesGroup.selectAll<SVGGElement, SankeyNode<N, L>>(`.${s.nodeGroup}`)\n .data(nodes, (d, i) => config.id(d, i) ?? i)\n const nodeSelectionEnter = nodeSelection.enter().append('g').attr('class', s.nodeGroup)\n nodeSelectionEnter.call(createNodes, this.config, this._width, bleed)\n nodeSelection.merge(nodeSelectionEnter).call(updateNodes, config, this._width, bleed, this._hasLinks(), duration)\n nodeSelection.exit<SankeyNode<N, L>>()\n .attr('class', s.nodeExit)\n .call(removeNodes, config, duration)\n\n // Background\n this._backgroundRect\n .attr('width', this.getWidth())\n .attr('height', this.getHeight())\n .attr('opacity', 0)\n }\n\n private _populateLinkAndNodeValues (): void {\n const { config, datamodel } = this\n\n const nodes = datamodel.nodes\n const links = datamodel.links\n\n // For d3-sankey each link must be an object with the `value` property\n links.forEach((link, i) => {\n link.value = getNumber(link, d => getNumber(d, config.linkValue, i))\n })\n\n // Populating node.fixedValue for d3-sankey\n nodes.forEach((node, i) => {\n node.fixedValue = getNumber(node, config.nodeFixedValue, i)\n })\n }\n\n private _preCalculateComponentSize (): void {\n const { bleed, config, datamodel } = this\n const nodes = datamodel.nodes\n\n\n if (nodes.length) {\n this._populateLinkAndNodeValues()\n this._sankey(datamodel)\n }\n\n const scaleExtent = extent(nodes, d => d.value || undefined)\n const scaleRange = [config.nodeMinHeight, config.nodeMaxHeight]\n const scale = scaleLinear().domain(scaleExtent).range(scaleRange).clamp(true)\n nodes.forEach(n => { n._state.precalculatedHeight = scale(n.value) || config.nodeMinHeight })\n\n const groupedByColumn: { [key: string]: SankeyNode<N, L>[] } = groupBy(nodes, d => d.layer)\n const values = Object.values(groupedByColumn)\n .map((group) =>\n sum(group.map(n => n._state.precalculatedHeight + config.nodePadding)) - config.nodePadding\n )\n\n const height = max(values) || config.nodeMinHeight\n this._extendedHeight = height + bleed.top + bleed.bottom\n this._extendedWidth = Math.max(0, (config.nodeWidth + config.nodeHorizontalSpacing) * Object.keys(groupedByColumn).length - config.nodeHorizontalSpacing + bleed.left + bleed.right)\n }\n\n private _prepareLayout (): void {\n const { config, bleed, datamodel } = this\n const isExtendedSize = this.sizing === Sizing.Extend\n const sankeyHeight = this.sizing === Sizing.Fit ? this._height : this._extendedHeight\n const sankeyWidth = this.sizing === Sizing.Fit ? this._width : this._extendedWidth\n this._sankey\n .size([\n Math.max(sankeyWidth - bleed.left - bleed.right, 0),\n Math.max(sankeyHeight - bleed.top - bleed.bottom, 0),\n ])\n\n const nodes = datamodel.nodes\n const links = datamodel.links\n\n // If there are no links we manually calculate the visualization layout\n if (!this._hasLinks()) {\n let y = 0\n const nodesTotalHeight = sum(nodes, n => n._state.precalculatedHeight || 1)\n for (const node of nodes) {\n const sankeyHeight = this.getHeight() - bleed.top - bleed.bottom\n const nodeHeight = node._state.precalculatedHeight || 1\n const h = isExtendedSize ? nodeHeight : (sankeyHeight - config.nodePadding * (nodes.length - 1)) * nodeHeight / nodesTotalHeight\n\n node.width = Math.max(10, config.nodeWidth)\n node.x0 = 0\n node.x1 = node.width\n node.y0 = y\n node.y1 = y + Math.max(1, h)\n node.layer = 0\n\n y = node.y1 + config.nodePadding\n }\n\n this._extendedHeightIncreased = undefined\n return\n }\n\n // Calculate sankey\n this._populateLinkAndNodeValues()\n this._sankey({ nodes, links })\n\n // Setting minimum node height\n // Default: 1px\n // Extended size nodes that have no links: config.nodeMinHeight\n for (const node of nodes) {\n const singleExtendedSize = isExtendedSize && !node.sourceLinks?.length && !node.targetLinks?.length\n const h = Math.max(singleExtendedSize ? config.nodeMinHeight : 1, node.y1 - node.y0)\n const y = (node.y0 + node.y1) / 2\n node.y0 = y - h / 2\n node.y1 = y + h / 2\n }\n\n if (isExtendedSize) {\n const height = max(nodes, d => d.y1)\n this._extendedHeightIncreased = height + bleed.top + bleed.bottom\n }\n }\n\n getWidth (): number {\n return this.sizing === Sizing.Fit ? this._width : (this._extendedWidth || 0)\n }\n\n getHeight (): number {\n return this.sizing === Sizing.Fit ? this._height : Math.max(this._extendedHeightIncreased || 0, this._extendedHeight || 0)\n }\n\n getLayoutWidth (): number {\n return this.sizing === Sizing.Fit ? this._width : this._extendedWidth\n }\n\n getLayoutHeight (): number {\n return this.sizing === Sizing.Fit ? this._height : (this._extendedHeightIncreased || this._extendedHeight)\n }\n\n getColumnCenters (): number[] {\n const { datamodel } = this\n const nodes = datamodel.nodes as SankeyNode<N, L>[]\n const centers = nodes.reduce((pos, node) => {\n const idx = node.layer\n if (!isFinite(pos[idx])) {\n pos[idx] = (node.x0 + node.x1) / 2\n }\n return pos\n }, [])\n\n return centers\n }\n\n highlightSubtree (node: SankeyNode<N, L>): void {\n const { config, datamodel } = this\n\n clearTimeout(this._highlightTimeoutId)\n this._highlightTimeoutId = setTimeout(() => {\n for (const n of datamodel.nodes) n._state.greyout = true\n for (const l of datamodel.links) l._state.greyout = true\n\n this.recursiveSetSubtreeState(node, 'sourceLinks', 'target', 'greyout', false)\n this.recursiveSetSubtreeState(node, 'targetLinks', 'source', 'greyout', false)\n this._render(config.highlightDuration)\n this._highlightActive = true\n }, config.highlightDelay)\n }\n\n recursiveSetSubtreeState (\n node: SankeyNode<N, L>,\n linksKey: 'sourceLinks' | 'targetLinks',\n nodeKey: 'source' | 'target',\n key: string,\n value: unknown\n ): void {\n node._state[key] = value\n\n for (const l of node[linksKey]) {\n l._state[key] = value\n this.recursiveSetSubtreeState(l[nodeKey] as SankeyNode<N, L>, linksKey, nodeKey, key, value)\n }\n }\n\n disableHighlight (): void {\n const { config, datamodel } = this\n\n clearTimeout(this._highlightTimeoutId)\n if (this._highlightActive) {\n this._highlightActive = false\n\n for (const n of datamodel.nodes) n._state.greyout = false\n for (const l of datamodel.links) l._state.greyout = false\n this._render(config.highlightDuration)\n }\n }\n\n private _hasLinks (): boolean {\n const { datamodel } = this\n return datamodel.links.length > 0\n }\n\n private _onNodeMouseOver (d: SankeyNode<N, L>, event: MouseEvent): void {\n onNodeMouseOver(d, select(event.currentTarget as SVGGElement), this.config, this._width)\n }\n\n private _onNodeMouseOut (d: SankeyNode<N, L>, event: MouseEvent): void {\n onNodeMouseOut(d, select(event.currentTarget as SVGGElement), this.config, this._width)\n }\n\n private _onNodeRectMouseOver (d: SankeyNode<N, L>): void {\n const { config } = this\n if (config.highlightSubtreeOnHover) this.highlightSubtree(d)\n }\n\n private _onNodeRectMouseOut (d: SankeyNode<N, L>): void {\n this.disableHighlight()\n }\n\n private _onLinkMouseOver (d: SankeyLink<N, L>, event: MouseEvent): void {\n const { config } = this\n\n if (config.highlightSubtreeOnHover) this.highlightSubtree(d.target as SankeyNode<N, L>)\n }\n\n private _onLinkMouseOut (d: SankeyLink<N, L>, event: MouseEvent): void {\n this.disableHighlight()\n }\n}\n"],"names":["s.background","s.links","s.nodes","s.link","s.nodeGroup","s.nodeExit","s"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/sankey/index.ts"],"sourcesContent":["import { select, Selection } from 'd3-selection'\nimport { sankey, SankeyGraph } from 'd3-sankey'\nimport { extent, max, sum } from 'd3-array'\nimport { scaleLinear } from 'd3-scale'\n\n// Core\nimport { ComponentCore } from 'core/component'\nimport { GraphDataModel } from 'data-models/graph'\n\n// Types\nimport { ExtendedSizeComponent, Sizing } from 'types/component'\nimport { Position } from 'types/position'\nimport { Spacing } from 'types/spacing'\nimport { VerticalAlign } from 'types/text'\n\n// Utils\nimport { smartTransition } from 'utils/d3'\nimport { getNumber, getString, groupBy, isNumber } from 'utils/data'\nimport { getCSSVariableValueInPixels } from 'utils/misc'\n\n// Config\nimport { SankeyDefaultConfig, SankeyConfigInterface } from './config'\n\n// Styles\nimport * as s from './style'\n\n// Local Types\nimport { SankeyInputLink, SankeyInputNode, SankeyLayout, SankeyLink, SankeyNode } from './types'\n\n// Modules\nimport { createLinks, removeLinks, updateLinks } from './modules/link'\nimport { createNodes, onNodeMouseOut, onNodeMouseOver, removeNodes, updateNodes } from './modules/node'\nimport { getLabelOrientation, requiredLabelSpace } from './modules/label'\n\nexport class Sankey<\n N extends SankeyInputNode,\n L extends SankeyInputLink,\n> extends ComponentCore<\n {nodes: N[]; links?: L[]},\n SankeyConfigInterface<N, L>\n > implements ExtendedSizeComponent {\n static selectors = s\n protected _defaultConfig = SankeyDefaultConfig as SankeyConfigInterface<N, L>\n public config: SankeyConfigInterface<N, L> = this._defaultConfig\n datamodel: GraphDataModel<N, L, SankeyNode<N, L>, SankeyLink<N, L>> = new GraphDataModel()\n private _extendedWidth: number | undefined = undefined\n private _extendedHeight: number | undefined = undefined\n private _extendedHeightIncreased: number | undefined = undefined\n private _linksGroup: Selection<SVGGElement, unknown, SVGGElement, unknown>\n private _nodesGroup: Selection<SVGGElement, unknown, SVGGElement, unknown>\n private _backgroundRect: Selection<SVGRectElement, unknown, SVGGElement, unknown>\n private _sankey = sankey<SankeyGraph<N, L>, SankeyNode<N, L>, SankeyLink<N, L>>()\n private _highlightTimeoutId: ReturnType<typeof setTimeout> | null = null\n private _highlightActive = false\n events = {\n [Sankey.selectors.nodeGroup]: {\n mouseenter: this._onNodeMouseOver.bind(this),\n mouseleave: this._onNodeMouseOut.bind(this),\n },\n [Sankey.selectors.node]: {\n mouseenter: this._onNodeRectMouseOver.bind(this),\n mouseleave: this._onNodeRectMouseOut.bind(this),\n click: this._onNodeClick.bind(this),\n },\n [Sankey.selectors.link]: {\n mouseenter: this._onLinkMouseOver.bind(this),\n mouseleave: this._onLinkMouseOut.bind(this),\n },\n }\n\n constructor (config?: SankeyConfigInterface<N, L>) {\n super()\n if (config) this.setConfig(config)\n this._backgroundRect = this.g.append('rect').attr('class', s.background)\n this._linksGroup = this.g.append('g').attr('class', s.links)\n this._nodesGroup = this.g.append('g').attr('class', s.nodes)\n }\n\n get bleed (): Spacing {\n const { config, datamodel: { nodes, links } } = this\n const labelFontSize = config.labelFontSize ?? getCSSVariableValueInPixels('var(--vis-sankey-label-font-size)', this.element)\n const labelSize = requiredLabelSpace(config.labelMaxWidth, labelFontSize)\n\n let left = 0\n let right = 0\n\n // We pre-calculate sankey layout to get information about node labels placement and calculate bleed properly\n // Potentially it can be a performance bottleneck for large layouts, but generally rendering of such layouts is much more computationally heavy\n if (nodes.length) {\n const sankeyProbeSize = 1000\n this._populateLinkAndNodeValues()\n this._sankey.size([sankeyProbeSize, sankeyProbeSize])\n this._sankey({ nodes, links })\n const maxDepth = max(nodes, d => d.depth)\n const zeroDepthNodes = nodes.filter(d => d.depth === 0)\n const maxDepthNodes = nodes.filter(d => d.depth === maxDepth)\n\n left = zeroDepthNodes.some(d => getLabelOrientation(d, sankeyProbeSize, config.labelPosition) === Position.Left) ? labelSize.width : 0\n right = maxDepthNodes.some(d => getLabelOrientation(d, sankeyProbeSize, config.labelPosition) === Position.Right) ? labelSize.width : 0\n }\n\n const top = config.labelVerticalAlign === VerticalAlign.Top ? 0\n : config.labelVerticalAlign === VerticalAlign.Bottom ? labelSize.height\n : labelSize.height / 2\n\n const bottom = config.labelVerticalAlign === VerticalAlign.Top ? labelSize.height\n : config.labelVerticalAlign === VerticalAlign.Bottom ? 0\n : labelSize.height / 2\n\n return { top, bottom, left, right }\n }\n\n setData (data: { nodes: N[]; links?: L[] }): void {\n super.setData(data)\n\n // Pre-collapse nodes based on disabledField\n this._applyInitialCollapseState()\n\n // Pre-calculate component size for Sizing.EXTEND\n if ((this.sizing !== Sizing.Fit) || !this._hasLinks()) this._preCalculateComponentSize()\n }\n\n setConfig (config: SankeyConfigInterface<N, L>): void {\n super.setConfig(config)\n\n // Apply initial collapse state if disabledField is set\n this._applyInitialCollapseState()\n\n // Pre-calculate component size for Sizing.EXTEND\n if ((this.sizing !== Sizing.Fit) || !this._hasLinks()) this._preCalculateComponentSize()\n\n // Using \"as any\" because typings are not full (\"@types/d3-sankey\": \"^0.11.2\")\n const nodeId = ((d: SankeyInputNode, i: number) => getString(d, this.config.id, i)) as any;\n (this._sankey as any).linkSort(this.config.linkSort)\n this._sankey\n .nodeId(nodeId)\n .nodeWidth(this.config.nodeWidth)\n .nodePadding(this.config.nodePadding)\n .nodeAlign(SankeyLayout[this.config.nodeAlign])\n .nodeSort(this.config.nodeSort)\n .iterations(this.config.iterations)\n }\n\n _render (customDuration?: number): void {\n const { config, bleed, datamodel: { nodes, links } } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n if (\n (nodes.length === 0) ||\n (nodes.length === 1 && links.length > 0) ||\n (nodes.length === 1 && !config.showSingleNode) ||\n (nodes.length > 1 && links.length === 0)\n ) {\n this._linksGroup.selectAll<SVGGElement, SankeyLink<N, L>>(`.${s.link}`).call(removeLinks, duration)\n this._nodesGroup.selectAll<SVGGElement, SankeyNode<N, L>>(`.${s.nodeGroup}`).call(removeNodes, config, duration)\n }\n\n // Prepare Layout\n this._prepareLayout()\n\n // Links\n smartTransition(this._linksGroup, duration).attr('transform', `translate(${bleed.left},${bleed.top})`)\n const linkSelection = this._linksGroup.selectAll<SVGGElement, SankeyLink<N, L>>(`.${s.link}`)\n .data(links, (d, i) => config.id(d, i) ?? i)\n const linkSelectionEnter = linkSelection.enter().append('g').attr('class', s.link)\n linkSelectionEnter.call(createLinks)\n linkSelection.merge(linkSelectionEnter).call(updateLinks, config, duration)\n linkSelection.exit<SankeyLink<N, L>>().call(removeLinks)\n\n // Nodes\n smartTransition(this._nodesGroup, duration).attr('transform', `translate(${bleed.left},${bleed.top})`)\n\n const nodeSelection = this._nodesGroup.selectAll<SVGGElement, SankeyNode<N, L>>(`.${s.nodeGroup}`)\n .data(nodes, (d, i) => config.id(d, i) ?? i)\n const nodeSelectionEnter = nodeSelection.enter().append('g').attr('class', s.nodeGroup)\n nodeSelectionEnter.call(createNodes, this.config, this._width, bleed)\n nodeSelection.merge(nodeSelectionEnter).call(updateNodes, config, this._width, bleed, this._hasLinks(), duration)\n nodeSelection.exit<SankeyNode<N, L>>()\n .attr('class', s.nodeExit)\n .call(removeNodes, config, duration)\n\n // Background\n this._backgroundRect\n .attr('width', this.getWidth())\n .attr('height', this.getHeight())\n .attr('opacity', 0)\n }\n\n private _populateLinkAndNodeValues (): void {\n const { config, datamodel } = this\n\n const nodes = datamodel.nodes\n const links = datamodel.links\n\n // For d3-sankey each link must be an object with the `value` property\n links.forEach((link, i) => {\n link.value = getNumber(link, d => getNumber(d, config.linkValue, i))\n })\n\n // Populating node.fixedValue for d3-sankey\n nodes.forEach((node, i) => {\n node.fixedValue = getNumber(node, config.nodeFixedValue, i)\n })\n }\n\n private _preCalculateComponentSize (): void {\n const { bleed, config, datamodel } = this\n const nodes = datamodel.nodes\n\n\n if (nodes.length) {\n this._populateLinkAndNodeValues()\n this._sankey(datamodel)\n }\n\n const scaleExtent = extent(nodes, d => d.value || undefined)\n const scaleRange = [config.nodeMinHeight, config.nodeMaxHeight]\n const scale = scaleLinear().domain(scaleExtent).range(scaleRange).clamp(true)\n nodes.forEach(n => { n._state.precalculatedHeight = scale(n.value) || config.nodeMinHeight })\n\n const groupedByColumn: { [key: string]: SankeyNode<N, L>[] } = groupBy(nodes, d => d.layer)\n const values = Object.values(groupedByColumn)\n .map((group) =>\n sum(group.map(n => n._state.precalculatedHeight + config.nodePadding)) - config.nodePadding\n )\n\n const height = max(values) || config.nodeMinHeight\n this._extendedHeight = height + bleed.top + bleed.bottom\n this._extendedWidth = Math.max(0, (config.nodeWidth + config.nodeHorizontalSpacing) * Object.keys(groupedByColumn).length - config.nodeHorizontalSpacing + bleed.left + bleed.right)\n }\n\n private _prepareLayout (): void {\n const { config, bleed, datamodel } = this\n const isExtendedSize = this.sizing === Sizing.Extend\n const sankeyHeight = this.sizing === Sizing.Fit ? this._height : this._extendedHeight\n const sankeyWidth = this.sizing === Sizing.Fit ? this._width : this._extendedWidth\n this._sankey\n .size([\n Math.max(sankeyWidth - bleed.left - bleed.right, 0),\n Math.max(sankeyHeight - bleed.top - bleed.bottom, 0),\n ])\n\n const nodes = datamodel.nodes\n const links = datamodel.links\n\n // If there are no links we manually calculate the visualization layout\n if (!this._hasLinks()) {\n let y = 0\n const nodesTotalHeight = sum(nodes, n => n._state.precalculatedHeight || 1)\n for (const node of nodes) {\n const sankeyHeight = this.getHeight() - bleed.top - bleed.bottom\n const nodeHeight = node._state.precalculatedHeight || 1\n const h = isExtendedSize ? nodeHeight : (sankeyHeight - config.nodePadding * (nodes.length - 1)) * nodeHeight / nodesTotalHeight\n\n node.width = Math.max(10, config.nodeWidth)\n node.x0 = 0\n node.x1 = node.width\n node.y0 = y\n node.y1 = y + Math.max(1, h)\n node.layer = 0\n\n y = node.y1 + config.nodePadding\n }\n\n this._extendedHeightIncreased = undefined\n return\n }\n\n // Calculate sankey\n this._populateLinkAndNodeValues()\n this._sankey({ nodes, links })\n\n // Setting minimum node height\n // Default: 1px\n // Extended size nodes that have no links: config.nodeMinHeight\n for (const node of nodes) {\n const singleExtendedSize = isExtendedSize && !node.sourceLinks?.length && !node.targetLinks?.length\n const h = Math.max(singleExtendedSize ? config.nodeMinHeight : 1, node.y1 - node.y0)\n const y = (node.y0 + node.y1) / 2\n node.y0 = y - h / 2\n node.y1 = y + h / 2\n }\n\n if (isExtendedSize) {\n const height = max(nodes, d => d.y1)\n this._extendedHeightIncreased = height + bleed.top + bleed.bottom\n }\n }\n\n getWidth (): number {\n return this.sizing === Sizing.Fit ? this._width : (this._extendedWidth || 0)\n }\n\n getHeight (): number {\n return this.sizing === Sizing.Fit ? this._height : Math.max(this._extendedHeightIncreased || 0, this._extendedHeight || 0)\n }\n\n getLayoutWidth (): number {\n return this.sizing === Sizing.Fit ? this._width : this._extendedWidth\n }\n\n getLayoutHeight (): number {\n return this.sizing === Sizing.Fit ? this._height : (this._extendedHeightIncreased || this._extendedHeight)\n }\n\n getColumnCenters (): number[] {\n const { datamodel } = this\n const nodes = datamodel.nodes as SankeyNode<N, L>[]\n const centers = nodes.reduce((pos, node) => {\n const idx = node.layer\n if (!isFinite(pos[idx])) {\n pos[idx] = (node.x0 + node.x1) / 2\n }\n return pos\n }, [])\n\n return centers\n }\n\n highlightSubtree (node: SankeyNode<N, L>): void {\n const { config, datamodel } = this\n\n clearTimeout(this._highlightTimeoutId)\n this._highlightTimeoutId = setTimeout(() => {\n for (const n of datamodel.nodes) n._state.greyout = true\n for (const l of datamodel.links) l._state.greyout = true\n\n this.recursiveSetSubtreeState(node, 'sourceLinks', 'target', 'greyout', false)\n this.recursiveSetSubtreeState(node, 'targetLinks', 'source', 'greyout', false)\n this._render(config.highlightDuration)\n this._highlightActive = true\n }, config.highlightDelay)\n }\n\n recursiveSetSubtreeState (\n node: SankeyNode<N, L>,\n linksKey: 'sourceLinks' | 'targetLinks',\n nodeKey: 'source' | 'target',\n key: string,\n value: unknown\n ): void {\n node._state[key] = value\n\n for (const l of node[linksKey]) {\n l._state[key] = value\n this.recursiveSetSubtreeState(l[nodeKey] as SankeyNode<N, L>, linksKey, nodeKey, key, value)\n }\n }\n\n disableHighlight (): void {\n const { config, datamodel } = this\n\n clearTimeout(this._highlightTimeoutId)\n if (this._highlightActive) {\n this._highlightActive = false\n\n for (const n of datamodel.nodes) n._state.greyout = false\n for (const l of datamodel.links) l._state.greyout = false\n this._render(config.highlightDuration)\n }\n }\n\n /**\n * Collapses a node by hiding only the links directly connected to it.\n * All other nodes (including children and descendants) remain visible in their original positions.\n * Only the immediate incoming and outgoing links of the collapsed node are hidden.\n */\n collapseNode (node: SankeyNode<N, L>): void {\n const { config } = this\n\n // Clear any active highlights before collapsing\n this.disableHighlight()\n\n node._state = node._state || {}\n node._state.collapsed = true\n this._render(config.collapseAnimationDuration)\n }\n\n /**\n * Expands a previously collapsed node by showing its directly connected links.\n */\n expandNode (node: SankeyNode<N, L>): void {\n const { config } = this\n\n // Clear any active highlights before expanding\n this.disableHighlight()\n\n node._state = node._state || {}\n node._state.collapsed = false\n this._render(config.collapseAnimationDuration)\n }\n\n /**\n * Toggles the collapse state of a node.\n *\n * @param node The node to toggle\n */\n toggleNodeCollapse (node: SankeyNode<N, L>): void {\n if (node._state?.collapsed) {\n this.expandNode(node)\n } else {\n this.collapseNode(node)\n }\n }\n\n private _hasLinks (): boolean {\n const { datamodel } = this\n return datamodel.links.length > 0\n }\n\n /**\n * Applies initial collapse state to nodes based on the disabledField configuration.\n * If disabledField is set (e.g., \"disabled\"), nodes with that field set to true\n * will be pre-collapsed when the component loads.\n */\n private _applyInitialCollapseState (): void {\n const { config, datamodel } = this\n\n if (!config.disabledField) return\n\n // Check each node for the disabled field and set initial collapse state\n for (const node of datamodel.nodes) {\n const inputData = node as unknown as N\n const isDisabled = inputData && typeof inputData === 'object' &&\n config.disabledField in inputData &&\n (inputData as any)[config.disabledField] === true\n\n if (isDisabled) {\n node._state = node._state || {}\n node._state.collapsed = true\n }\n }\n }\n\n private _onNodeMouseOver (d: SankeyNode<N, L>, event: MouseEvent): void {\n onNodeMouseOver(d, select(event.currentTarget as SVGGElement), this.config, this._width)\n }\n\n private _onNodeMouseOut (d: SankeyNode<N, L>, event: MouseEvent): void {\n onNodeMouseOut(d, select(event.currentTarget as SVGGElement), this.config, this._width)\n }\n\n private _onNodeRectMouseOver (d: SankeyNode<N, L>): void {\n const { config } = this\n if (config.highlightSubtreeOnHover) this.highlightSubtree(d)\n }\n\n private _onNodeRectMouseOut (d: SankeyNode<N, L>): void {\n this.disableHighlight()\n }\n\n private _onLinkMouseOver (d: SankeyLink<N, L>, event: MouseEvent): void {\n const { config } = this\n\n if (config.highlightSubtreeOnHover) this.highlightSubtree(d.target as SankeyNode<N, L>)\n }\n\n private _onLinkMouseOut (d: SankeyLink<N, L>, event: MouseEvent): void {\n this.disableHighlight()\n }\n\n private _onNodeClick (d: SankeyNode<N, L>, event: MouseEvent): void {\n const { config } = this\n if (config.enableNodeCollapse) {\n this.toggleNodeCollapse(d)\n }\n }\n}\n"],"names":["s.background","s.links","s.nodes","s.link","s.nodeGroup","s.nodeExit","s"],"mappings":"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"}
|
|
@@ -42,9 +42,21 @@ function createLinks(sel) {
|
|
|
42
42
|
}
|
|
43
43
|
function updateLinks(sel, config, duration) {
|
|
44
44
|
smartTransition(sel, duration)
|
|
45
|
-
.style('opacity', (d) =>
|
|
45
|
+
.style('opacity', (d) => {
|
|
46
|
+
var _a, _b, _c;
|
|
47
|
+
// Hide links if either connected node is collapsed
|
|
48
|
+
if (((_a = d.source._state) === null || _a === void 0 ? void 0 : _a.collapsed) || ((_b = d.target._state) === null || _b === void 0 ? void 0 : _b.collapsed))
|
|
49
|
+
return 0;
|
|
50
|
+
// Apply greyout effect
|
|
51
|
+
return ((_c = d._state) === null || _c === void 0 ? void 0 : _c.greyout) ? 0.2 : 1;
|
|
52
|
+
});
|
|
46
53
|
const linkSelection = sel.select(`.${linkPath$1}`)
|
|
47
|
-
.style('cursor', (d) => getString(d, config.linkCursor))
|
|
54
|
+
.style('cursor', (d) => getString(d, config.linkCursor))
|
|
55
|
+
.style('pointer-events', (d) => {
|
|
56
|
+
var _a, _b;
|
|
57
|
+
// Disable pointer events for collapsed links to prevent hover interference
|
|
58
|
+
return (((_a = d.source._state) === null || _a === void 0 ? void 0 : _a.collapsed) || ((_b = d.target._state) === null || _b === void 0 ? void 0 : _b.collapsed)) ? 'none' : null;
|
|
59
|
+
});
|
|
48
60
|
const selectionTransition = smartTransition(linkSelection, duration)
|
|
49
61
|
.style('fill', (link) => getColor(link, config.linkColor));
|
|
50
62
|
if (duration) {
|
|
@@ -94,7 +106,8 @@ function updateLinks(sel, config, duration) {
|
|
|
94
106
|
y1: d.y1,
|
|
95
107
|
width: Math.max(10, d.width),
|
|
96
108
|
}))
|
|
97
|
-
.style('cursor', d => getString(d, config.linkCursor))
|
|
109
|
+
.style('cursor', d => getString(d, config.linkCursor))
|
|
110
|
+
.style('pointer-events', (d) => { var _a, _b; return (((_a = d.source._state) === null || _a === void 0 ? void 0 : _a.collapsed) || ((_b = d.target._state) === null || _b === void 0 ? void 0 : _b.collapsed)) ? 'none' : null; });
|
|
98
111
|
}
|
|
99
112
|
function removeLinks(sel) {
|
|
100
113
|
sel.remove();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.js","sources":["../../../../src/components/sankey/modules/link.ts"],"sourcesContent":["import { Selection } from 'd3-selection'\nimport { Transition } from 'd3-transition'\nimport { interpolateNumber } from 'd3-interpolate'\n\n// Utils\nimport { getColor } from 'utils/color'\nimport { getString } from 'utils/data'\nimport { smartTransition } from 'utils/d3'\n\n// Local Types\nimport { SankeyInputLink, SankeyInputNode, SankeyLink } from '../types'\n\n// Config\nimport { SankeyConfigInterface } from '../config'\n\n// Styles\nimport * as s from '../style'\n\nexport type LinkPathOptions = {\n x0: number;\n x1: number;\n y0: number;\n y1: number;\n width: number;\n}\n\nexport function linkPath ({ x0, x1, y0, y1, width }: LinkPathOptions): string {\n const top0 = y0 - width / 2\n const top1 = y1 - width / 2\n const bottom0 = y0 + width / 2\n const bottom1 = y1 + width / 2\n const centerX = (x0 + x1) / 2\n\n return `\n M ${x0}, ${top0}\n\n C ${centerX}, ${top0}\n ${centerX}, ${top1}\n ${x1}, ${top1}\n\n L ${x1}, ${bottom1}\n\n C ${centerX}, ${bottom1}\n ${centerX}, ${bottom0}\n ${x0}, ${bottom0}\n z\n `\n}\n\nexport type LinkAnimState = { x0: number; x1: number; y0: number; y1: number; width: number }\n\nexport interface LinkElement extends SVGPathElement {\n _animState?: LinkAnimState;\n}\n\nexport function createLinks<N extends SankeyInputNode, L extends SankeyInputLink> (\n sel: Selection<SVGGElement, SankeyLink<N, L>, SVGGElement, unknown>\n): void {\n sel.append('path').attr('class', s.linkPath)\n .attr('d', (d: SankeyLink<N, L>, i: number, el: ArrayLike<LinkElement>) => {\n el[i]._animState = {\n x0: d.source.x1,\n x1: d.target.x0,\n y0: d.y0,\n y1: d.y1,\n width: Math.max(1, d.width),\n }\n return linkPath(el[i]._animState)\n })\n sel.append('path').attr('class', s.linkSelectionHelper)\n sel.style('opacity', 0)\n}\n\nexport function updateLinks<N extends SankeyInputNode, L extends SankeyInputLink> (\n sel: Selection<SVGGElement, SankeyLink<N, L>, SVGGElement, unknown>,\n config: SankeyConfigInterface<N, L>,\n duration: number\n): void {\n smartTransition(sel, duration)\n .style('opacity', (d: SankeyLink<N, L>) => d._state.greyout ? 0.2 : 1)\n\n const linkSelection = sel.select<SVGPathElement>(`.${s.linkPath}`)\n .style('cursor', (d: SankeyLink<N, L>) => getString(d, config.linkCursor))\n\n const selectionTransition = smartTransition(linkSelection, duration)\n .style('fill', (link: SankeyLink<N, L>) => getColor(link, config.linkColor))\n\n if (duration) {\n (selectionTransition as Transition<SVGPathElement, SankeyLink<N, L>, SVGGElement, unknown>)\n .attrTween('d', (d: SankeyLink<N, L>, i: number, el: ArrayLike<LinkElement>) => {\n const previous = el[i]._animState\n const next = {\n x0: d.source.x1,\n x1: d.target.x0,\n y0: d.y0,\n y1: d.y1,\n width: Math.max(1, d.width),\n }\n const interpolator = {\n x0: interpolateNumber(previous.x0, next.x0),\n x1: interpolateNumber(previous.x1, next.x1),\n y0: interpolateNumber(previous.y0, next.y0),\n y1: interpolateNumber(previous.y1, next.y1),\n width: interpolateNumber(previous.width, next.width),\n }\n el[i]._animState = next\n\n return function (t: number) {\n return linkPath({\n x0: interpolator.x0(t),\n x1: interpolator.x1(t),\n y0: interpolator.y0(t),\n y1: interpolator.y1(t),\n width: interpolator.width(t),\n })\n }\n })\n } else {\n linkSelection.attr('d', (d: SankeyLink<N, L>) => linkPath({\n x0: d.source.x1,\n x1: d.target.x0,\n y0: d.y0,\n y1: d.y1,\n width: Math.max(1, d.width),\n }))\n }\n\n sel.select(`.${s.linkSelectionHelper}`)\n .attr('d', (d: SankeyLink<N, L>) => linkPath({\n x0: d.source.x1,\n x1: d.target.x0,\n y0: d.y0,\n y1: d.y1,\n width: Math.max(10, d.width),\n }))\n .style('cursor', d => getString(d, config.linkCursor))\n}\n\nexport function removeLinks<N extends SankeyInputNode, L extends SankeyInputLink> (\n sel: Selection<SVGGElement, SankeyLink<N, L>, SVGGElement, unknown>\n): void {\n sel.remove()\n}\n"],"names":["s.linkPath","s.linkSelectionHelper"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"link.js","sources":["../../../../src/components/sankey/modules/link.ts"],"sourcesContent":["import { Selection } from 'd3-selection'\nimport { Transition } from 'd3-transition'\nimport { interpolateNumber } from 'd3-interpolate'\n\n// Utils\nimport { getColor } from 'utils/color'\nimport { getString } from 'utils/data'\nimport { smartTransition } from 'utils/d3'\n\n// Local Types\nimport { SankeyInputLink, SankeyInputNode, SankeyLink } from '../types'\n\n// Config\nimport { SankeyConfigInterface } from '../config'\n\n// Styles\nimport * as s from '../style'\n\nexport type LinkPathOptions = {\n x0: number;\n x1: number;\n y0: number;\n y1: number;\n width: number;\n}\n\nexport function linkPath ({ x0, x1, y0, y1, width }: LinkPathOptions): string {\n const top0 = y0 - width / 2\n const top1 = y1 - width / 2\n const bottom0 = y0 + width / 2\n const bottom1 = y1 + width / 2\n const centerX = (x0 + x1) / 2\n\n return `\n M ${x0}, ${top0}\n\n C ${centerX}, ${top0}\n ${centerX}, ${top1}\n ${x1}, ${top1}\n\n L ${x1}, ${bottom1}\n\n C ${centerX}, ${bottom1}\n ${centerX}, ${bottom0}\n ${x0}, ${bottom0}\n z\n `\n}\n\nexport type LinkAnimState = { x0: number; x1: number; y0: number; y1: number; width: number }\n\nexport interface LinkElement extends SVGPathElement {\n _animState?: LinkAnimState;\n}\n\nexport function createLinks<N extends SankeyInputNode, L extends SankeyInputLink> (\n sel: Selection<SVGGElement, SankeyLink<N, L>, SVGGElement, unknown>\n): void {\n sel.append('path').attr('class', s.linkPath)\n .attr('d', (d: SankeyLink<N, L>, i: number, el: ArrayLike<LinkElement>) => {\n el[i]._animState = {\n x0: d.source.x1,\n x1: d.target.x0,\n y0: d.y0,\n y1: d.y1,\n width: Math.max(1, d.width),\n }\n return linkPath(el[i]._animState)\n })\n sel.append('path').attr('class', s.linkSelectionHelper)\n sel.style('opacity', 0)\n}\n\nexport function updateLinks<N extends SankeyInputNode, L extends SankeyInputLink> (\n sel: Selection<SVGGElement, SankeyLink<N, L>, SVGGElement, unknown>,\n config: SankeyConfigInterface<N, L>,\n duration: number\n): void {\n smartTransition(sel, duration)\n .style('opacity', (d: SankeyLink<N, L>) => {\n // Hide links if either connected node is collapsed\n if (d.source._state?.collapsed || d.target._state?.collapsed) return 0\n // Apply greyout effect\n return d._state?.greyout ? 0.2 : 1\n })\n\n const linkSelection = sel.select<SVGPathElement>(`.${s.linkPath}`)\n .style('cursor', (d: SankeyLink<N, L>) => getString(d, config.linkCursor))\n .style('pointer-events', (d: SankeyLink<N, L>) => {\n // Disable pointer events for collapsed links to prevent hover interference\n return (d.source._state?.collapsed || d.target._state?.collapsed) ? 'none' : null\n })\n\n const selectionTransition = smartTransition(linkSelection, duration)\n .style('fill', (link: SankeyLink<N, L>) => getColor(link, config.linkColor))\n\n if (duration) {\n (selectionTransition as Transition<SVGPathElement, SankeyLink<N, L>, SVGGElement, unknown>)\n .attrTween('d', (d: SankeyLink<N, L>, i: number, el: ArrayLike<LinkElement>) => {\n const previous = el[i]._animState\n const next = {\n x0: d.source.x1,\n x1: d.target.x0,\n y0: d.y0,\n y1: d.y1,\n width: Math.max(1, d.width),\n }\n const interpolator = {\n x0: interpolateNumber(previous.x0, next.x0),\n x1: interpolateNumber(previous.x1, next.x1),\n y0: interpolateNumber(previous.y0, next.y0),\n y1: interpolateNumber(previous.y1, next.y1),\n width: interpolateNumber(previous.width, next.width),\n }\n el[i]._animState = next\n\n return function (t: number) {\n return linkPath({\n x0: interpolator.x0(t),\n x1: interpolator.x1(t),\n y0: interpolator.y0(t),\n y1: interpolator.y1(t),\n width: interpolator.width(t),\n })\n }\n })\n } else {\n linkSelection.attr('d', (d: SankeyLink<N, L>) => linkPath({\n x0: d.source.x1,\n x1: d.target.x0,\n y0: d.y0,\n y1: d.y1,\n width: Math.max(1, d.width),\n }))\n }\n\n sel.select(`.${s.linkSelectionHelper}`)\n .attr('d', (d: SankeyLink<N, L>) => linkPath({\n x0: d.source.x1,\n x1: d.target.x0,\n y0: d.y0,\n y1: d.y1,\n width: Math.max(10, d.width),\n }))\n .style('cursor', d => getString(d, config.linkCursor))\n .style('pointer-events', (d: SankeyLink<N, L>) => (d.source._state?.collapsed || d.target._state?.collapsed) ? 'none' : null)\n}\n\nexport function removeLinks<N extends SankeyInputNode, L extends SankeyInputLink> (\n sel: Selection<SVGGElement, SankeyLink<N, L>, SVGGElement, unknown>\n): void {\n sel.remove()\n}\n"],"names":["s.linkPath","s.linkSelectionHelper"],"mappings":"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"}
|
|
@@ -37,6 +37,8 @@ export declare type SankeyNode<N extends SankeyInputNode, L extends SankeyInputL
|
|
|
37
37
|
_state?: {
|
|
38
38
|
greyout?: boolean;
|
|
39
39
|
precalculatedHeight?: number;
|
|
40
|
+
/** Whether this node is collapsed (hides all connected links) */
|
|
41
|
+
collapsed?: boolean;
|
|
40
42
|
};
|
|
41
43
|
};
|
|
42
44
|
export declare type SankeyLink<N extends SankeyInputNode, L extends SankeyInputLink> = GraphLinkCore<N, L> & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../src/components/sankey/types.ts"],"sourcesContent":["/* eslint-disable no-use-before-define */\nimport { sankeyLeft, sankeyRight, sankeyCenter, sankeyJustify } from 'd3-sankey'\nimport { GraphInputLink, GraphLinkCore, GraphNodeCore } from 'types/graph'\nimport { GraphInputNode } from '../../types'\n\nexport type SankeyInputNode = GraphInputNode\n\nexport type SankeyInputLink = GraphInputLink\n\nexport type SankeyNode<N extends SankeyInputNode, L extends SankeyInputLink> = GraphNodeCore<N, L> & {\n id: string;\n /** the node’s value; this is the sum of link.value for the node’s incoming links, or node.fixedValue if defined */\n value: number;\n /** */\n fixedValue?: number;\n /** the node’s zero-based column index, corresponding to its horizontal position */\n layer: number;\n /** */\n isConnected: boolean;\n /** the array of incoming links which have this node as their source */\n sourceLinks?: SankeyLink<N, L>[];\n /** the array of outgoing links which have this node as their target */\n targetLinks: SankeyLink<N, L>[];\n /** the node’s zero-based index within the array of nodes */\n index: number;\n /** the node’s zero-based graph depth, derived from the graph topology */\n depth: number;\n /** node.height - the node’s zero-based graph height, derived from the graph topology */\n height: number;\n /** the node’s minimum horizontal position, derived from node.depth */\n x0: number;\n /** the node’s maximum horizontal position (node.x0 + sankey.nodeWidth) */\n x1: number;\n /** the node’s minimum vertical position */\n y0: number;\n /** the node’s maximum vertical position (node.y1 - node.y0 is proportional to node.value) */\n y1: number;\n /** calculated node width */\n width: number;\n /** internal ui state */\n _state?: {\n greyout?: boolean;\n /* Pre-calculated node height value in pixels that will be used to manually generate the layout when data has no links */\n precalculatedHeight?: number;\n };\n}\n\nexport type SankeyLink<N extends SankeyInputNode, L extends SankeyInputLink> = GraphLinkCore<N, L> & {\n value: number;\n /** the link’s source node */\n source: SankeyNode<N, L>;\n /** the link’s target node */\n target: SankeyNode<N, L>;\n /** the link’s vertical starting position (at source node) */\n y0: number;\n /** the link’s vertical end position (at target node) */\n y1: number;\n /** the link’s width (proportional to link.value) */\n width: number;\n /** the zero-based index of link within the array of links */\n index: number;\n /** internal ui state */\n _state?: {\n greyout?: boolean;\n };\n}\n\nexport enum SankeySubLabelPlacement {\n Inline = 'inline',\n Below = 'below',\n}\n\nexport enum SankeyNodeAlign {\n Left = 'left',\n Right = 'right',\n Center = 'center',\n Justify = 'justify',\n}\n\nexport const SankeyLayout = {\n [SankeyNodeAlign.Left]: sankeyLeft,\n [SankeyNodeAlign.Right]: sankeyRight,\n [SankeyNodeAlign.Center]: sankeyCenter,\n [SankeyNodeAlign.Justify]: sankeyJustify,\n}\n\nexport enum SankeyExitTransitionType {\n Default = 'default',\n ToAncestor = 'to ancestor',\n}\n\nexport enum SankeyEnterTransitionType {\n Default = 'default',\n FromAncestor = 'from ancestor',\n}\n"],"names":[],"mappings":";;AAAA;
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../src/components/sankey/types.ts"],"sourcesContent":["/* eslint-disable no-use-before-define */\nimport { sankeyLeft, sankeyRight, sankeyCenter, sankeyJustify } from 'd3-sankey'\nimport { GraphInputLink, GraphLinkCore, GraphNodeCore } from 'types/graph'\nimport { GraphInputNode } from '../../types'\n\nexport type SankeyInputNode = GraphInputNode\n\nexport type SankeyInputLink = GraphInputLink\n\nexport type SankeyNode<N extends SankeyInputNode, L extends SankeyInputLink> = GraphNodeCore<N, L> & {\n id: string;\n /** the node’s value; this is the sum of link.value for the node’s incoming links, or node.fixedValue if defined */\n value: number;\n /** */\n fixedValue?: number;\n /** the node’s zero-based column index, corresponding to its horizontal position */\n layer: number;\n /** */\n isConnected: boolean;\n /** the array of incoming links which have this node as their source */\n sourceLinks?: SankeyLink<N, L>[];\n /** the array of outgoing links which have this node as their target */\n targetLinks: SankeyLink<N, L>[];\n /** the node’s zero-based index within the array of nodes */\n index: number;\n /** the node’s zero-based graph depth, derived from the graph topology */\n depth: number;\n /** node.height - the node’s zero-based graph height, derived from the graph topology */\n height: number;\n /** the node’s minimum horizontal position, derived from node.depth */\n x0: number;\n /** the node’s maximum horizontal position (node.x0 + sankey.nodeWidth) */\n x1: number;\n /** the node’s minimum vertical position */\n y0: number;\n /** the node’s maximum vertical position (node.y1 - node.y0 is proportional to node.value) */\n y1: number;\n /** calculated node width */\n width: number;\n /** internal ui state */\n _state?: {\n greyout?: boolean;\n /* Pre-calculated node height value in pixels that will be used to manually generate the layout when data has no links */\n precalculatedHeight?: number;\n /** Whether this node is collapsed (hides all connected links) */\n collapsed?: boolean;\n };\n}\n\nexport type SankeyLink<N extends SankeyInputNode, L extends SankeyInputLink> = GraphLinkCore<N, L> & {\n value: number;\n /** the link’s source node */\n source: SankeyNode<N, L>;\n /** the link’s target node */\n target: SankeyNode<N, L>;\n /** the link’s vertical starting position (at source node) */\n y0: number;\n /** the link’s vertical end position (at target node) */\n y1: number;\n /** the link’s width (proportional to link.value) */\n width: number;\n /** the zero-based index of link within the array of links */\n index: number;\n /** internal ui state */\n _state?: {\n greyout?: boolean;\n };\n}\n\nexport enum SankeySubLabelPlacement {\n Inline = 'inline',\n Below = 'below',\n}\n\nexport enum SankeyNodeAlign {\n Left = 'left',\n Right = 'right',\n Center = 'center',\n Justify = 'justify',\n}\n\nexport const SankeyLayout = {\n [SankeyNodeAlign.Left]: sankeyLeft,\n [SankeyNodeAlign.Right]: sankeyRight,\n [SankeyNodeAlign.Center]: sankeyCenter,\n [SankeyNodeAlign.Justify]: sankeyJustify,\n}\n\nexport enum SankeyExitTransitionType {\n Default = 'default',\n ToAncestor = 'to ancestor',\n}\n\nexport enum SankeyEnterTransitionType {\n Default = 'default',\n FromAncestor = 'from ancestor',\n}\n"],"names":[],"mappings":";;AAAA;IAqEY,wBAGX;AAHD,CAAA,UAAY,uBAAuB,EAAA;AACjC,IAAA,uBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,uBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACjB,CAAC,EAHW,uBAAuB,KAAvB,uBAAuB,GAGlC,EAAA,CAAA,CAAA,CAAA;IAEW,gBAKX;AALD,CAAA,UAAY,eAAe,EAAA;AACzB,IAAA,eAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,eAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACf,IAAA,eAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,eAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACrB,CAAC,EALW,eAAe,KAAf,eAAe,GAK1B,EAAA,CAAA,CAAA,CAAA;AAEY,MAAA,YAAY,GAAG;AAC1B,IAAA,CAAC,eAAe,CAAC,IAAI,GAAG,UAAU;AAClC,IAAA,CAAC,eAAe,CAAC,KAAK,GAAG,WAAW;AACpC,IAAA,CAAC,eAAe,CAAC,MAAM,GAAG,YAAY;AACtC,IAAA,CAAC,eAAe,CAAC,OAAO,GAAG,aAAa;EACzC;IAEW,yBAGX;AAHD,CAAA,UAAY,wBAAwB,EAAA;AAClC,IAAA,wBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACnB,IAAA,wBAAA,CAAA,YAAA,CAAA,GAAA,aAA0B,CAAA;AAC5B,CAAC,EAHW,wBAAwB,KAAxB,wBAAwB,GAGnC,EAAA,CAAA,CAAA,CAAA;IAEW,0BAGX;AAHD,CAAA,UAAY,yBAAyB,EAAA;AACnC,IAAA,yBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACnB,IAAA,yBAAA,CAAA,cAAA,CAAA,GAAA,eAA8B,CAAA;AAChC,CAAC,EAHW,yBAAyB,KAAzB,yBAAyB,GAGpC,EAAA,CAAA,CAAA;;;;"}
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import { ComponentConfigInterface } from "../../core/component/config";
|
|
2
2
|
import { ColorAccessor, NumericAccessor, StringAccessor } from "../../types/accessor";
|
|
3
|
+
import { FitMode, TrimMode } from "../../types/text";
|
|
3
4
|
import { TreemapNode } from './types';
|
|
4
5
|
export interface TreemapConfigInterface<Datum> extends ComponentConfigInterface {
|
|
5
6
|
id?: ((d: Datum, i: number) => string | number);
|
|
6
7
|
value?: NumericAccessor<Datum>;
|
|
7
8
|
/** Array of accessor functions to defined the nested groups. Default: `[]` */
|
|
8
9
|
layers: StringAccessor<Datum>[];
|
|
9
|
-
/**
|
|
10
|
+
/** @deprecated Define `tileLabel` instead.
|
|
11
|
+
* A function that accepts a value number and returns a string. Default: `(value: number) => `${value}`` */
|
|
10
12
|
numberFormat?: (value: number) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Function to generate the label text for each tile. Receives the `TreemapNode` and returns a `string`.
|
|
15
|
+
* Default: shows key and formatted value (e.g., "label: value").
|
|
16
|
+
*/
|
|
17
|
+
tileLabel?: (node: TreemapNode<Datum>) => string;
|
|
11
18
|
/** Color accessor function for tiles. Default: `undefined` */
|
|
12
19
|
tileColor?: ColorAccessor<TreemapNode<Datum>>;
|
|
13
20
|
/** Padding passed to D3 treemap layout. Default: `2` */
|
|
@@ -24,6 +31,10 @@ export interface TreemapConfigInterface<Datum> extends ComponentConfigInterface
|
|
|
24
31
|
labelOffsetX?: number;
|
|
25
32
|
/** Label offset in the Y direction. Default: `4` */
|
|
26
33
|
labelOffsetY?: number;
|
|
34
|
+
/** How labels should fit within tiles: wrap or trim. Applicable only for leaf nodes. Default: `FitMode.Wrap` */
|
|
35
|
+
labelFit?: FitMode;
|
|
36
|
+
/** Label trimming mode. Default: `TrimMode.Middle` */
|
|
37
|
+
labelTrimMode?: TrimMode;
|
|
27
38
|
/** Border radius of the tiles in pixels. Default: `2` */
|
|
28
39
|
tileBorderRadius?: number;
|
|
29
40
|
/** Minimum fraction of width for border radius. Default: `1/8` */
|
|
@@ -32,21 +43,17 @@ export interface TreemapConfigInterface<Datum> extends ComponentConfigInterface
|
|
|
32
43
|
enableLightnessVariance?: boolean;
|
|
33
44
|
/** Enable font size variation for leaf node labels based on value. Default: `false` */
|
|
34
45
|
enableTileLabelFontSizeVariation?: boolean;
|
|
35
|
-
/** Small font size for leaf labels (used when enableTileLabelFontSizeVariation is true). Default: `8` */
|
|
46
|
+
/** Small font size for leaf labels (used when `enableTileLabelFontSizeVariation` is `true`). Default: `8` */
|
|
36
47
|
tileLabelSmallFontSize?: number;
|
|
37
|
-
/** Medium font size for leaf labels (used when enableTileLabelFontSizeVariation is true). Default: `12` */
|
|
48
|
+
/** Medium font size for leaf labels (used when `enableTileLabelFontSizeVariation` is `true`). Default: `12` */
|
|
38
49
|
tileLabelMediumFontSize?: number;
|
|
39
|
-
/** Large font size for leaf labels (used when enableTileLabelFontSizeVariation is true). Default: `24` */
|
|
50
|
+
/** Large font size for leaf labels (used when `enableTileLabelFontSizeVariation` is `true`). Default: `24` */
|
|
40
51
|
tileLabelLargeFontSize?: number;
|
|
41
52
|
/** Flag for showing cursor:pointer to indicate leaf tiles are clickable. Default: `undefined` */
|
|
42
53
|
showTileClickAffordance?: boolean;
|
|
43
|
-
/** Amount of lightness variation applied to sibling tiles when enableLightnessVariance is true
|
|
54
|
+
/** Amount of lightness variation applied to sibling tiles when `enableLightnessVariance` is `true`. Default: `0.08` */
|
|
44
55
|
lightnessVariationAmount?: number;
|
|
56
|
+
/** Minimum size for labels in pixels. Default: `20` */
|
|
45
57
|
minTileSizeForLabel?: number;
|
|
46
|
-
/**
|
|
47
|
-
* Function to generate the label text for each tile. Receives the TreemapNode and returns a string.
|
|
48
|
-
* Default: shows key and formatted value (e.g., "label: value").
|
|
49
|
-
*/
|
|
50
|
-
tileLabel?: (node: TreemapNode<Datum>) => string;
|
|
51
58
|
}
|
|
52
59
|
export declare const TreemapDefaultConfig: TreemapConfigInterface<unknown>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ComponentDefaultConfig } from '../../core/component/config.js';
|
|
2
|
+
import { FitMode, TrimMode } from '../../types/text.js';
|
|
2
3
|
|
|
3
|
-
const TreemapDefaultConfig = Object.assign(Object.assign({}, ComponentDefaultConfig), { id: (d, i) => { var _a; return (_a = d.id) !== null && _a !== void 0 ? _a : i; }, value: undefined, tileColor: undefined, layers: [], tilePadding: 2, tilePaddingTop: undefined, labelInternalNodes: false, labelOffsetX: 4, labelOffsetY: 4, tileBorderRadius: 2, tileBorderRadiusFactor: 1 / 8, enableLightnessVariance: false, enableTileLabelFontSizeVariation: true, tileLabelSmallFontSize: 8, tileLabelMediumFontSize: 12, tileLabelLargeFontSize: 22, showTileClickAffordance: false, lightnessVariationAmount: 0.08, minTileSizeForLabel: 20, tileLabel:
|
|
4
|
+
const TreemapDefaultConfig = Object.assign(Object.assign({}, ComponentDefaultConfig), { id: (d, i) => { var _a; return (_a = d.id) !== null && _a !== void 0 ? _a : i; }, value: undefined, tileColor: undefined, layers: [], tilePadding: 2, tilePaddingTop: undefined, labelInternalNodes: false, labelOffsetX: 4, labelOffsetY: 4, labelFit: FitMode.Wrap, labelTrimMode: TrimMode.Middle, tileBorderRadius: 2, tileBorderRadiusFactor: 1 / 8, enableLightnessVariance: false, enableTileLabelFontSizeVariation: true, tileLabelSmallFontSize: 8, tileLabelMediumFontSize: 12, tileLabelLargeFontSize: 22, showTileClickAffordance: false, lightnessVariationAmount: 0.08, minTileSizeForLabel: 20, numberFormat: (value) => `${value}`, tileLabel: function (d) { return `${d.data.key}: ${this.numberFormat(d.value)}`; } });
|
|
4
5
|
|
|
5
6
|
export { TreemapDefaultConfig };
|
|
6
7
|
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sources":["../../../src/components/treemap/config.ts"],"sourcesContent":["import { ComponentConfigInterface, ComponentDefaultConfig } from 'core/component/config'\nimport { ColorAccessor, NumericAccessor, StringAccessor } from 'types/accessor'\nimport { TreemapNode } from './types'\n\nexport interface TreemapConfigInterface<Datum> extends ComponentConfigInterface {\n id?: ((d: Datum, i: number) => string | number);\n /* Numeric accessor for segment size value. Default: `undefined`. */\n value?: NumericAccessor<Datum>;\n\n /** Array of accessor functions to defined the nested groups. Default: `[]` */\n layers: StringAccessor<Datum>[];\n\n /** A function that accepts a value number and returns a string. Default: `
|
|
1
|
+
{"version":3,"file":"config.js","sources":["../../../src/components/treemap/config.ts"],"sourcesContent":["import { ComponentConfigInterface, ComponentDefaultConfig } from 'core/component/config'\nimport { ColorAccessor, NumericAccessor, StringAccessor } from 'types/accessor'\nimport { FitMode, TrimMode } from 'types/text'\nimport { TreemapNode } from './types'\n\nexport interface TreemapConfigInterface<Datum> extends ComponentConfigInterface {\n id?: ((d: Datum, i: number) => string | number);\n /* Numeric accessor for segment size value. Default: `undefined`. */\n value?: NumericAccessor<Datum>;\n\n /** Array of accessor functions to defined the nested groups. Default: `[]` */\n layers: StringAccessor<Datum>[];\n\n /** @deprecated Define `tileLabel` instead.\n * A function that accepts a value number and returns a string. Default: `(value: number) => `${value}`` */\n numberFormat?: (value: number) => string;\n\n /**\n * Function to generate the label text for each tile. Receives the `TreemapNode` and returns a `string`.\n * Default: shows key and formatted value (e.g., \"label: value\").\n */\n tileLabel?: (node: TreemapNode<Datum>) => string;\n\n /** Color accessor function for tiles. Default: `undefined` */\n tileColor?: ColorAccessor<TreemapNode<Datum>>;\n\n /** Padding passed to D3 treemap layout. Default: `2` */\n tilePadding?: number;\n\n /**\n * Top padding passed to D3 treemap layout.\n * Useful to make room for internal node labels.\n * Default: `undefined`\n */\n tilePaddingTop?: number;\n\n /** Label internal nodes. Default: `false` */\n labelInternalNodes?: boolean;\n\n /** Label offset in the X direction. Default: `4` */\n labelOffsetX?: number;\n\n /** Label offset in the Y direction. Default: `4` */\n labelOffsetY?: number;\n\n /** How labels should fit within tiles: wrap or trim. Applicable only for leaf nodes. Default: `FitMode.Wrap` */\n labelFit?: FitMode;\n\n /** Label trimming mode. Default: `TrimMode.Middle` */\n labelTrimMode?: TrimMode;\n\n /** Border radius of the tiles in pixels. Default: `2` */\n tileBorderRadius?: number;\n\n /** Minimum fraction of width for border radius. Default: `1/8` */\n tileBorderRadiusFactor?: number;\n\n /** Enable lightness variance for sibling tiles. Default: `false` */\n enableLightnessVariance?: boolean;\n\n /** Enable font size variation for leaf node labels based on value. Default: `false` */\n enableTileLabelFontSizeVariation?: boolean;\n\n /** Small font size for leaf labels (used when `enableTileLabelFontSizeVariation` is `true`). Default: `8` */\n tileLabelSmallFontSize?: number;\n\n /** Medium font size for leaf labels (used when `enableTileLabelFontSizeVariation` is `true`). Default: `12` */\n tileLabelMediumFontSize?: number;\n\n /** Large font size for leaf labels (used when `enableTileLabelFontSizeVariation` is `true`). Default: `24` */\n tileLabelLargeFontSize?: number;\n\n\n /** Flag for showing cursor:pointer to indicate leaf tiles are clickable. Default: `undefined` */\n showTileClickAffordance?: boolean;\n\n /** Amount of lightness variation applied to sibling tiles when `enableLightnessVariance` is `true`. Default: `0.08` */\n lightnessVariationAmount?: number;\n\n /** Minimum size for labels in pixels. Default: `20` */\n minTileSizeForLabel?: number;\n}\n\nexport const TreemapDefaultConfig: TreemapConfigInterface<unknown> = {\n ...ComponentDefaultConfig,\n id: (d: unknown, i: number): string | number => (d as { id: string }).id ?? i,\n value: undefined,\n tileColor: undefined,\n layers: [],\n tilePadding: 2,\n tilePaddingTop: undefined,\n labelInternalNodes: false,\n labelOffsetX: 4,\n labelOffsetY: 4,\n labelFit: FitMode.Wrap,\n labelTrimMode: TrimMode.Middle,\n tileBorderRadius: 2,\n tileBorderRadiusFactor: 1 / 8,\n enableLightnessVariance: false,\n enableTileLabelFontSizeVariation: true,\n tileLabelSmallFontSize: 8,\n tileLabelMediumFontSize: 12,\n tileLabelLargeFontSize: 22,\n showTileClickAffordance: false,\n lightnessVariationAmount: 0.08,\n minTileSizeForLabel: 20,\n numberFormat: (value: number) => `${value}`,\n tileLabel: function (d: TreemapNode<unknown>): string { return `${d.data.key}: ${this.numberFormat(d.value)}` },\n}\n"],"names":[],"mappings":";;;AAmFO,MAAM,oBAAoB,GAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAC5B,sBAAsB,CACzB,EAAA,EAAA,EAAE,EAAE,CAAC,CAAU,EAAE,CAAS,eAAsB,OAAA,CAAA,EAAA,GAAC,CAAoB,CAAC,EAAE,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,CAAC,CAAA,EAAA,EAC7E,KAAK,EAAE,SAAS,EAChB,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,EAAE,EACV,WAAW,EAAE,CAAC,EACd,cAAc,EAAE,SAAS,EACzB,kBAAkB,EAAE,KAAK,EACzB,YAAY,EAAE,CAAC,EACf,YAAY,EAAE,CAAC,EACf,QAAQ,EAAE,OAAO,CAAC,IAAI,EACtB,aAAa,EAAE,QAAQ,CAAC,MAAM,EAC9B,gBAAgB,EAAE,CAAC,EACnB,sBAAsB,EAAE,CAAC,GAAG,CAAC,EAC7B,uBAAuB,EAAE,KAAK,EAC9B,gCAAgC,EAAE,IAAI,EACtC,sBAAsB,EAAE,CAAC,EACzB,uBAAuB,EAAE,EAAE,EAC3B,sBAAsB,EAAE,EAAE,EAC1B,uBAAuB,EAAE,KAAK,EAC9B,wBAAwB,EAAE,IAAI,EAC9B,mBAAmB,EAAE,EAAE,EACvB,YAAY,EAAE,CAAC,KAAa,KAAK,GAAG,KAAK,CAAA,CAAE,EAC3C,SAAS,EAAE,UAAU,CAAuB,EAAY,EAAA,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAA,EAAA,EAAK,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAE,CAAA,CAAA,EAAE;;;;"}
|
|
@@ -7,8 +7,6 @@ export declare class Treemap<Datum> extends ComponentCore<Datum[], TreemapConfig
|
|
|
7
7
|
static selectors: typeof s;
|
|
8
8
|
protected _defaultConfig: TreemapConfigInterface<Datum>;
|
|
9
9
|
config: TreemapConfigInterface<Datum>;
|
|
10
|
-
/** Default number format for tile labels. */
|
|
11
|
-
private _defaultNumberFormat;
|
|
12
10
|
datamodel: SeriesDataModel<Datum>;
|
|
13
11
|
tiles: Selection<SVGGElement, unknown, SVGGElement, unknown>;
|
|
14
12
|
private _isTileLargeEnough;
|
|
@@ -5,14 +5,15 @@ import { scaleLinear, scaleThreshold } from 'd3-scale';
|
|
|
5
5
|
import { hsl } from 'd3-color';
|
|
6
6
|
import { ComponentCore } from '../../core/component/index.js';
|
|
7
7
|
import { SeriesDataModel } from '../../data-models/series.js';
|
|
8
|
-
import { getColor, getHexValue, brighter } from '../../utils/color.js';
|
|
8
|
+
import { getColor, getHexValue, brighter, isColorDark } from '../../utils/color.js';
|
|
9
9
|
import { isNumber, getString, getNumber } from '../../utils/data.js';
|
|
10
10
|
import { smartTransition } from '../../utils/d3.js';
|
|
11
|
-
import { trimSVGText } from '../../utils/text.js';
|
|
12
|
-
import {
|
|
11
|
+
import { wrapSVGText, trimSVGText } from '../../utils/text.js';
|
|
12
|
+
import { cssvar } from '../../utils/style.js';
|
|
13
|
+
import { FitMode } from '../../types/text.js';
|
|
13
14
|
import { TreemapDefaultConfig } from './config.js';
|
|
14
15
|
import * as style from './style.js';
|
|
15
|
-
import { tiles, tileGroup, tile, clickableTile, labelGroup, label, internalLabel } from './style.js';
|
|
16
|
+
import { tiles, tileGroup, tile, clickableTile, labelGroup, label, variables, internalLabel } from './style.js';
|
|
16
17
|
|
|
17
18
|
class Treemap extends ComponentCore {
|
|
18
19
|
constructor(config) {
|
|
@@ -24,10 +25,6 @@ class Treemap extends ComponentCore {
|
|
|
24
25
|
this.setConfig(config);
|
|
25
26
|
this.tiles = this.g.append('g').attr('class', tiles);
|
|
26
27
|
}
|
|
27
|
-
/** Default number format for tile labels. */
|
|
28
|
-
_defaultNumberFormat(value) {
|
|
29
|
-
return `${value}`;
|
|
30
|
-
}
|
|
31
28
|
_isTileLargeEnough(d) {
|
|
32
29
|
const w = d.x1 - d.x0;
|
|
33
30
|
const h = d.y1 - d.y0;
|
|
@@ -44,11 +41,9 @@ class Treemap extends ComponentCore {
|
|
|
44
41
|
return this.config.lightnessVariationAmount * ((maxValue - node.value) / (maxValue - minValue));
|
|
45
42
|
}
|
|
46
43
|
_render(customDuration) {
|
|
47
|
-
var _a
|
|
44
|
+
var _a;
|
|
48
45
|
super._render(customDuration);
|
|
49
46
|
const { config, datamodel: { data }, _width, _height } = this;
|
|
50
|
-
const { numberFormat } = config;
|
|
51
|
-
const formatNumber = numberFormat !== null && numberFormat !== void 0 ? numberFormat : this._defaultNumberFormat.bind(this);
|
|
52
47
|
const duration = isNumber(customDuration) ? customDuration : config.duration;
|
|
53
48
|
if (!((_a = config.layers) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
54
49
|
console.warn('Unovis | Treemap: No layers defined');
|
|
@@ -66,7 +61,7 @@ class Treemap extends ComponentCore {
|
|
|
66
61
|
const rootNode = hierarchy(nestedData);
|
|
67
62
|
// Compute the aggregation
|
|
68
63
|
if (config.value) {
|
|
69
|
-
rootNode.sum(index =>
|
|
64
|
+
rootNode.sum(index => isNumber(index) && getNumber(data[index], config.value, index));
|
|
70
65
|
}
|
|
71
66
|
else {
|
|
72
67
|
rootNode.count();
|
|
@@ -127,36 +122,33 @@ class Treemap extends ComponentCore {
|
|
|
127
122
|
config.tileLabelMediumFontSize,
|
|
128
123
|
config.tileLabelLargeFontSize,
|
|
129
124
|
]);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const siblings = node.parent.children;
|
|
145
|
-
const lightnessAdjustment = this._getTileLightness(node, siblings);
|
|
146
|
-
hslColor.l = Math.min(1, hslColor.l + lightnessAdjustment);
|
|
147
|
-
}
|
|
148
|
-
// Brightness increase for depth
|
|
149
|
-
node._fill = brighter(hslColor.toString(), brightnessIncrease(node.depth));
|
|
125
|
+
const visibleTiles = descendants.filter(d => d.depth > 0);
|
|
126
|
+
const firstLevelTiles = visibleTiles.filter(d => d.depth === 1);
|
|
127
|
+
const nonFirstLevelTiles = visibleTiles.filter(d => d.depth > 1);
|
|
128
|
+
// Set the fill color for the first level tiles
|
|
129
|
+
firstLevelTiles.forEach((d, i) => {
|
|
130
|
+
d._fill = getColor(d, config.tileColor, i);
|
|
131
|
+
});
|
|
132
|
+
// Set the fill color for the non-first level tiles
|
|
133
|
+
nonFirstLevelTiles.forEach((d, i) => {
|
|
134
|
+
var _a;
|
|
135
|
+
const providedColor = getColor(d, config.tileColor, i, true);
|
|
136
|
+
if (providedColor) {
|
|
137
|
+
d._fill = providedColor;
|
|
138
|
+
return;
|
|
150
139
|
}
|
|
151
|
-
|
|
152
|
-
|
|
140
|
+
const hslColor = hsl(getHexValue((_a = d.parent) === null || _a === void 0 ? void 0 : _a._fill, this.element));
|
|
141
|
+
if (config.enableLightnessVariance && !d.children && d.parent) {
|
|
142
|
+
const siblings = d.parent.children;
|
|
143
|
+
const lightnessAdjustment = this._getTileLightness(d, siblings);
|
|
144
|
+
hslColor.l = Math.min(1, hslColor.l + lightnessAdjustment);
|
|
153
145
|
}
|
|
146
|
+
d._fill = brighter(hslColor.toString(), brightnessIncrease(d.depth));
|
|
154
147
|
});
|
|
155
148
|
// Render tiles
|
|
156
|
-
const visibleNodes = descendants.filter(d => d.depth > 0);
|
|
157
149
|
const tiles = this.tiles
|
|
158
150
|
.selectAll(`g.${tileGroup}`)
|
|
159
|
-
.data(
|
|
151
|
+
.data(visibleTiles, d => `${d.data.key}-${d.depth}`);
|
|
160
152
|
const tilesEnter = tiles
|
|
161
153
|
.enter()
|
|
162
154
|
.append('g')
|
|
@@ -168,92 +160,87 @@ class Treemap extends ComponentCore {
|
|
|
168
160
|
// This ensures that the tile border radius is not
|
|
169
161
|
// larger than the tile size, which makes small tiles
|
|
170
162
|
// look better.
|
|
171
|
-
const
|
|
172
|
-
//
|
|
163
|
+
const getTileBorderRadius = (d) => Math.min(config.tileBorderRadius, (d.x1 - d.x0) * config.tileBorderRadiusFactor);
|
|
164
|
+
// Add clipPath elements
|
|
173
165
|
tilesEnter
|
|
166
|
+
.append('clipPath')
|
|
167
|
+
.attr('id', d => `clip-${this.uid}-${d._id}`)
|
|
168
|
+
.append('rect')
|
|
169
|
+
.attr('rx', getTileBorderRadius)
|
|
170
|
+
.attr('ry', getTileBorderRadius);
|
|
171
|
+
// Tile rectangles
|
|
172
|
+
const tileRects = tilesEnter
|
|
174
173
|
.append('rect')
|
|
175
174
|
.classed(tile, true)
|
|
176
|
-
// Make the leaf tiles clickable if a click handler is provided
|
|
177
175
|
.classed(clickableTile, d => config.showTileClickAffordance && !d.children)
|
|
178
|
-
.attr('rx',
|
|
179
|
-
.attr('ry',
|
|
180
|
-
// Initialize tile positions so that the initial transition is smooth
|
|
176
|
+
.attr('rx', getTileBorderRadius)
|
|
177
|
+
.attr('ry', getTileBorderRadius)
|
|
181
178
|
.attr('x', d => d.x0)
|
|
182
179
|
.attr('y', d => d.y0)
|
|
183
180
|
.attr('width', d => d.x1 - d.x0)
|
|
184
181
|
.attr('height', d => d.y1 - d.y0)
|
|
185
|
-
.style('fill', d =>
|
|
182
|
+
.style('fill', d => d._fill)
|
|
186
183
|
.style('opacity', 0)
|
|
187
184
|
.style('cursor', config.showTileClickAffordance ? d => !d.children ? 'pointer' : null : null);
|
|
188
|
-
|
|
189
|
-
smartTransition(mergedTiles.select(`rect.${tile}`), duration)
|
|
190
|
-
.style('fill', d => { var _a; return (_a = d._fill) !== null && _a !== void 0 ? _a : getColor(d, config.tileColor); })
|
|
191
|
-
.style('opacity', 1)
|
|
192
|
-
.attr('x', d => d.x0)
|
|
193
|
-
.attr('y', d => d.y0)
|
|
194
|
-
.attr('width', d => d.x1 - d.x0)
|
|
195
|
-
.attr('height', d => d.y1 - d.y0);
|
|
196
|
-
// Update clipPath rects
|
|
197
|
-
let svg = this.g.node();
|
|
198
|
-
while (svg && !(svg instanceof SVGSVGElement))
|
|
199
|
-
svg = svg.parentElement;
|
|
200
|
-
const defs = svg ? (select(svg).select('defs').empty() ? select(svg).append('defs') : select(svg).select('defs')) : null;
|
|
201
|
-
if (!defs)
|
|
202
|
-
return;
|
|
203
|
-
const defsSelection = defs;
|
|
204
|
-
const clipPaths = defsSelection.selectAll('clipPath')
|
|
205
|
-
.data(visibleNodes, (d) => d._id);
|
|
206
|
-
clipPaths.enter()
|
|
207
|
-
.append('clipPath')
|
|
208
|
-
.attr('id', (d) => `clip-${d._id}`)
|
|
209
|
-
.append('rect')
|
|
210
|
-
.attr('x', (d) => d.x0)
|
|
211
|
-
.attr('y', (d) => d.y0)
|
|
212
|
-
.attr('width', (d) => Math.max(0.1, d.x1 - d.x0))
|
|
213
|
-
.attr('height', (d) => Math.max(0.1, d.y1 - d.y0))
|
|
214
|
-
.attr('rx', rx)
|
|
215
|
-
.attr('ry', rx);
|
|
216
|
-
clipPaths.exit().remove();
|
|
185
|
+
tileRects.append('title');
|
|
217
186
|
tilesEnter
|
|
218
187
|
.append('g')
|
|
219
188
|
.attr('class', labelGroup)
|
|
189
|
+
.attr('clip-path', d => `url(#clip-${this.uid}-${d._id})`)
|
|
220
190
|
.attr('transform', d => `translate(${d.x0 + config.labelOffsetX},${d.y0 + config.labelOffsetY})`)
|
|
191
|
+
.style('opacity', 0)
|
|
221
192
|
.append('text')
|
|
222
193
|
.attr('class', label)
|
|
223
194
|
.attr('x', 0)
|
|
224
|
-
.attr('y', 0)
|
|
225
|
-
|
|
226
|
-
const
|
|
195
|
+
.attr('y', 0);
|
|
196
|
+
const mergedTiles = tiles.merge(tilesEnter);
|
|
197
|
+
const tileRectsMerged = mergedTiles.select(`rect.${tile}`);
|
|
198
|
+
smartTransition(tileRectsMerged, duration)
|
|
199
|
+
.style('fill', d => d._fill)
|
|
200
|
+
.style('opacity', 1)
|
|
201
|
+
.attr('x', d => d.x0)
|
|
202
|
+
.attr('y', d => d.y0)
|
|
203
|
+
.attr('width', d => d.x1 - d.x0)
|
|
204
|
+
.attr('height', d => d.y1 - d.y0);
|
|
205
|
+
tileRectsMerged.select('title')
|
|
206
|
+
.text(d => config.tileLabel(d));
|
|
207
|
+
// Update clipPath rects
|
|
208
|
+
mergedTiles.select('clipPath rect')
|
|
209
|
+
.attr('width', d => d.x1 - d.x0 - 2 * config.labelOffsetX)
|
|
210
|
+
.attr('height', d => d.y1 - d.y0 - 2 * config.labelOffsetY);
|
|
227
211
|
const textSelection = mergedTiles.selectAll(`g.${labelGroup} text`);
|
|
228
212
|
textSelection
|
|
229
|
-
.text(d =>
|
|
230
|
-
.
|
|
213
|
+
.text(d => config.tileLabel(d))
|
|
214
|
+
.attr('title', d => config.tileLabel(d))
|
|
215
|
+
.property('font-size-px', d => {
|
|
231
216
|
var _a;
|
|
232
217
|
const sqrtVal = Math.sqrt((_a = d.value) !== null && _a !== void 0 ? _a : 0);
|
|
233
218
|
return config.enableTileLabelFontSizeVariation && !d.children
|
|
234
|
-
?
|
|
235
|
-
:
|
|
219
|
+
? fontSizeScale(sqrtVal)
|
|
220
|
+
: null; // Use the default css variable value
|
|
236
221
|
})
|
|
237
|
-
.
|
|
238
|
-
|
|
239
|
-
|
|
222
|
+
.style('font-size', (_, i, els) => `${select(els[i]).property('font-size-px')}px`)
|
|
223
|
+
.style('fill', d => cssvar(isColorDark(d._fill) ? variables.treemapLabelTextColorLight : variables.treemapLabelTextColor));
|
|
224
|
+
// Fit label (wrap or trim)
|
|
225
|
+
textSelection.each((d, i, els) => {
|
|
240
226
|
var _a;
|
|
241
|
-
const
|
|
227
|
+
const isLeafNode = !d.children;
|
|
228
|
+
const el = els[i];
|
|
229
|
+
const text = select(el);
|
|
242
230
|
const tileWidth = d.x1 - d.x0 - ((_a = config.labelOffsetX) !== null && _a !== void 0 ? _a : 0) * 2;
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
231
|
+
const fontSize = parseFloat(text.property('font-size-px')) || parseFloat(window.getComputedStyle(el).fontSize);
|
|
232
|
+
if (config.labelFit === FitMode.Wrap && isLeafNode) {
|
|
233
|
+
wrapSVGText(text, tileWidth);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
trimSVGText(text, tileWidth, config.labelTrimMode, true, fontSize);
|
|
247
237
|
}
|
|
248
|
-
trimSVGText(text, tileWidth, TrimMode.End, true, fontSize);
|
|
249
|
-
text.attr('title', fullLabel);
|
|
250
|
-
text.selectAll('tspan').attr('dominant-baseline', 'middle');
|
|
251
238
|
});
|
|
252
239
|
// Transition group position
|
|
253
240
|
smartTransition(mergedTiles.select(`g.${labelGroup}`), duration)
|
|
254
241
|
.attr('transform', d => `translate(${d.x0 + config.labelOffsetX},${d.y0 + config.labelOffsetY})`);
|
|
255
242
|
// Transition text opacity only (fade-in)
|
|
256
|
-
smartTransition(mergedTiles.select(`g.${labelGroup}
|
|
243
|
+
smartTransition(mergedTiles.select(`g.${labelGroup}`), duration)
|
|
257
244
|
.style('opacity', 1);
|
|
258
245
|
// Hide labels that don't meet criteria
|
|
259
246
|
mergedTiles.select(`text.${label}`)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/treemap/index.ts"],"sourcesContent":["import { Selection, select } from 'd3-selection'\nimport { hierarchy, HierarchyNode, treemap } from 'd3-hierarchy'\nimport { group, max, extent } from 'd3-array'\nimport { scaleLinear, scaleThreshold } from 'd3-scale'\nimport { hsl } from 'd3-color'\nimport { ComponentCore } from 'core/component'\nimport { SeriesDataModel } from 'data-models/series'\nimport { getColor, brighter, getHexValue } from 'utils/color'\nimport { getString, getNumber, isNumber } from 'utils/data'\nimport { smartTransition } from 'utils/d3'\nimport { trimSVGText } from 'utils/text'\nimport { TrimMode } from 'types/text'\nimport { TreemapConfigInterface, TreemapDefaultConfig } from './config'\nimport { TreemapDatum, TreemapNode } from './types'\nimport * as s from './style'\n\nexport class Treemap<Datum> extends ComponentCore<Datum[], TreemapConfigInterface<Datum>> {\n static selectors = s\n protected _defaultConfig = TreemapDefaultConfig as TreemapConfigInterface<Datum>\n public config: TreemapConfigInterface<Datum> = this._defaultConfig\n\n /** Default number format for tile labels. */\n private _defaultNumberFormat (value: number): string {\n return `${value}`\n }\n\n datamodel: SeriesDataModel<Datum> = new SeriesDataModel()\n tiles: Selection<SVGGElement, unknown, SVGGElement, unknown>\n\n private _isTileLargeEnough (d: TreemapNode<Datum>): boolean {\n const w = d.x1 - d.x0\n const h = d.y1 - d.y0\n return (w >= this.config.minTileSizeForLabel) && (h >= this.config.minTileSizeForLabel)\n }\n\n private _getTileLightness (node: TreemapNode<Datum>, siblings: TreemapNode<Datum>[]): number {\n // Get the value extent of the sibling group\n const [minValue, maxValue] = extent(siblings, d => d.value)\n\n // If there's no range or no value, return default lightness\n if (minValue === maxValue || !node.value) return 0\n\n // Calculate relative position in the range (0 to 1)\n // Larger values will be closer to 0 (darker)\n return this.config.lightnessVariationAmount * ((maxValue - node.value) / (maxValue - minValue))\n }\n\n constructor (config?: TreemapConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n this.tiles = this.g.append('g').attr('class', s.tiles)\n }\n\n _render (customDuration?: number): void {\n super._render(customDuration)\n const { config, datamodel: { data }, _width, _height } = this\n const { numberFormat } = config\n const formatNumber = numberFormat ?? this._defaultNumberFormat.bind(this)\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n if (!config.layers?.length) {\n console.warn('Unovis | Treemap: No layers defined')\n return\n }\n\n // Map each layer accessor function to get string values from the data array\n const layerAccessors = config.layers.map(layerAccessor => {\n return (i: number) => getString(data[i], layerAccessor, i)\n })\n\n // Group the data indices by the layer accessors to create a hierarchical structure\n const nestedData = group(data.keys(), ...layerAccessors as [(d: number) => string])\n\n // Create the hierarchy from the grouped data,\n // which by itself is not quite right because there is an extra\n // level of nesting that we don't want, just above the leaf nodes.\n const rootNode = hierarchy(nestedData)\n\n // Compute the aggregation\n if (config.value) {\n rootNode.sum(index => typeof index === 'number' && getNumber(data[index], config.value, index))\n } else {\n rootNode.count()\n }\n\n // Fix the hierarchy by removing the extra level of nesting\n rootNode.each(node => {\n if (!node.children && node.parent) {\n node.parent.children = null\n }\n })\n\n const treemapLayout = treemap()\n .size([_width, _height])\n .round(true)\n .padding(config.tilePadding)\n\n // Apply padding to the top of each tile,\n // but not for the root node.\n if (this.config.tilePaddingTop !== undefined) {\n treemapLayout.paddingTop(d => d.parent ? config.tilePaddingTop : 0)\n }\n\n // Compute the treemap layout\n const treemapData = treemapLayout(rootNode) as TreemapNode<Datum>\n\n // Process the resulting hierarchy into the type we need\n let nodeId = 0\n treemapData.each(node => {\n const n = node as unknown as HierarchyNode<[string, number[]]>\n // Generate unique IDs for each node\n node._id = `node-${nodeId++}`\n\n const treemapDatum: TreemapDatum<Datum> = {\n key: n.data[0],\n }\n\n // Populate the index and datum for leaf nodes\n const isLeafNode = !n.children\n if (isLeafNode) {\n treemapDatum.index = n.data[1][0]\n treemapDatum.datum = data[treemapDatum.index]\n }\n\n node.data = treemapDatum\n })\n\n const descendants = treemapData.descendants()\n\n // Set up the brightness increase scale based on depth\n const maxDepth = max(descendants, d => d.depth)\n\n const brightnessIncrease = scaleLinear()\n .domain([1, maxDepth])\n .range([0, 1])\n\n // Get all leaf node values and calculate their square roots\n // (since area is proportional to value)\n const leafValues = descendants.filter(d => !d.children).map(d => d.value)\n const maxLeafValue = Math.sqrt(max(leafValues)) || 0\n // Divide the range into three equal intervals based on the square root of values\n // This accounts for the fact that area is proportional to value\n const fontSizeScale = scaleThreshold<number, number>()\n .domain([\n maxLeafValue / 3, // First third of the max value\n (maxLeafValue * 2) / 3, // Second third of the max value\n ])\n .range([\n config.tileLabelSmallFontSize,\n config.tileLabelMediumFontSize,\n config.tileLabelLargeFontSize,\n ])\n\n // First pass: Set base colors without considering tileColor config\n treemapData.eachBefore((node) => {\n // Get base color: user accessor or default\n let color = config.tileColor\n ? getColor(node, config.tileColor)\n : getColor(node, undefined, node.parent?.children?.indexOf(node), node.depth !== 1)\n\n // Fallback to parent color if needed\n color = color ?? (node.parent as TreemapNode<Datum>)?._fill\n\n const hexColor = color ? getHexValue(color, this.g.node()) : null\n\n if (hexColor) {\n const hslColor = hsl(hexColor)\n\n // Lightness adjustment for siblings (if enabled)\n if (config.enableLightnessVariance && !node.children && node.parent) {\n const siblings = node.parent.children\n const lightnessAdjustment = this._getTileLightness(node, siblings)\n hslColor.l = Math.min(1, hslColor.l + lightnessAdjustment)\n }\n\n // Brightness increase for depth\n node._fill = brighter(hslColor.toString(), brightnessIncrease(node.depth))\n } else {\n node._fill = null\n }\n })\n\n // Render tiles\n const visibleNodes = descendants.filter(d => d.depth > 0)\n const tiles = this.tiles\n .selectAll<SVGGElement, TreemapNode<Datum>>(`g.${s.tileGroup}`)\n .data(visibleNodes, d => `${d.data.key}-${d.depth}`)\n\n const tilesEnter = tiles\n .enter()\n .append('g')\n .attr('class', s.tileGroup)\n\n // Computes the rect border radius for a given tile.\n // The rx and ry values are the minimum of the tile\n // border radius and some fraction the width of the tile,\n // based on the tileBorderRadiusFactor config.\n // This ensures that the tile border radius is not\n // larger than the tile size, which makes small tiles\n // look better.\n const rx = (d: TreemapNode<Datum>): number =>\n Math.min(config.tileBorderRadius, (d.x1 - d.x0) * config.tileBorderRadiusFactor)\n\n // Tile rectangles\n tilesEnter\n .append('rect')\n .classed(s.tile, true)\n\n // Make the leaf tiles clickable if a click handler is provided\n .classed(s.clickableTile, d => config.showTileClickAffordance && !d.children)\n\n .attr('rx', rx)\n .attr('ry', rx)\n // Initialize tile positions so that the initial transition is smooth\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n .style('fill', d => d._fill ?? getColor(d, config.tileColor))\n .style('opacity', 0)\n .style('cursor', config.showTileClickAffordance ? d => !d.children ? 'pointer' : null : null)\n\n\n const mergedTiles = tiles.merge(tilesEnter)\n\n smartTransition(mergedTiles.select(`rect.${s.tile}`), duration)\n .style('fill', d => d._fill ?? getColor(d, config.tileColor))\n .style('opacity', 1)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n\n // Update clipPath rects\n let svg: Element | null = this.g.node()\n while (svg && !(svg instanceof SVGSVGElement)) svg = svg.parentElement\n const defs = svg ? (select(svg).select('defs').empty() ? select(svg).append('defs') : select(svg).select('defs')) : null\n if (!defs) return\n const defsSelection = (defs as Selection<SVGDefsElement, unknown, null, undefined>)\n const clipPaths = defsSelection.selectAll<SVGClipPathElement, TreemapNode<Datum>>('clipPath')\n .data(visibleNodes, (d: TreemapNode<Datum>) => d._id)\n\n clipPaths.enter()\n .append('clipPath')\n .attr('id', (d: TreemapNode<Datum>) => `clip-${d._id}`)\n .append('rect')\n .attr('x', (d: TreemapNode<Datum>) => d.x0)\n .attr('y', (d: TreemapNode<Datum>) => d.y0)\n .attr('width', (d: TreemapNode<Datum>) => Math.max(0.1, d.x1 - d.x0))\n .attr('height', (d: TreemapNode<Datum>) => Math.max(0.1, d.y1 - d.y0))\n .attr('rx', rx)\n .attr('ry', rx)\n\n clipPaths.exit().remove()\n\n tilesEnter\n .append('g')\n .attr('class', s.labelGroup)\n .attr('transform', d => `translate(${d.x0 + config.labelOffsetX},${d.y0 + config.labelOffsetY})`)\n .append('text')\n .attr('class', s.label)\n .attr('x', 0)\n .attr('y', 0)\n .style('opacity', 0)\n\n const getTileLabel = config.tileLabel ?? ((d: TreemapNode<Datum>) => `${d.data.key}: ${formatNumber(d.value)}`)\n const textSelection = mergedTiles.selectAll<SVGTextElement, TreemapNode<Datum>>(`g.${s.labelGroup} text`)\n textSelection\n .text(d => getTileLabel(d))\n .style('font-size', function (d) {\n const sqrtVal = Math.sqrt(d.value ?? 0)\n return config.enableTileLabelFontSizeVariation && !d.children\n ? `${fontSizeScale(sqrtVal)}px`\n : `${fontSizeScale.range()[1]}px`\n })\n .attr('dominant-baseline', 'middle')\n\n // Trim label and set dominant-baseline for tspans in one pass\n textSelection.each((d, i, nodes) => {\n const text = select(nodes[i] as SVGTextElement)\n const tileWidth = d.x1 - d.x0 - (config.labelOffsetX ?? 0) * 2\n const fullLabel = text.text()\n let fontSize = parseFloat(text.style('font-size'))\n if (!fontSize) {\n fontSize = parseFloat(window.getComputedStyle(nodes[i] as SVGTextElement).fontSize)\n }\n trimSVGText(text, tileWidth, TrimMode.End, true, fontSize)\n text.attr('title', fullLabel)\n text.selectAll('tspan').attr('dominant-baseline', 'middle')\n })\n\n // Transition group position\n smartTransition(mergedTiles.select(`g.${s.labelGroup}`), duration)\n .attr('transform', d => `translate(${d.x0 + config.labelOffsetX},${d.y0 + config.labelOffsetY})`)\n\n // Transition text opacity only (fade-in)\n smartTransition(mergedTiles.select(`g.${s.labelGroup} text`), duration)\n .style('opacity', 1)\n\n // Hide labels that don't meet criteria\n mergedTiles.select(`text.${s.label}`)\n .style('display', d => {\n const isAllowedNode = config.labelInternalNodes ? true : !d.children\n return isAllowedNode && this._isTileLargeEnough(d) ? null : 'none'\n })\n // Make the internal labels semibold via class\n .attr('class', d => d.children ? `${s.label} ${s.internalLabel}` : s.label)\n\n smartTransition(tiles.exit(), duration)\n .style('opacity', 0)\n .remove()\n }\n}\n"],"names":["s.tiles","s.tileGroup","s.tile","s.clickableTile","s.labelGroup","s.label","s.internalLabel","s"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/treemap/index.ts"],"sourcesContent":["import { Selection, select } from 'd3-selection'\nimport { hierarchy, HierarchyNode, treemap } from 'd3-hierarchy'\nimport { group, max, extent } from 'd3-array'\nimport { scaleLinear, scaleThreshold } from 'd3-scale'\nimport { hsl } from 'd3-color'\n\n// Core\nimport { ComponentCore } from 'core/component'\n\n// Data Model\nimport { SeriesDataModel } from 'data-models/series'\n\n// Utils\nimport { getColor, brighter, getHexValue, isColorDark } from 'utils/color'\nimport { getString, getNumber, isNumber } from 'utils/data'\nimport { smartTransition } from 'utils/d3'\nimport { trimSVGText, wrapSVGText } from 'utils/text'\nimport { cssvar } from 'utils/style'\n\n// Types\nimport { FitMode } from 'types/text'\n\n// Config\nimport { TreemapConfigInterface, TreemapDefaultConfig } from './config'\n\n// Local Types\nimport { TreemapDatum, TreemapNode } from './types'\n\n// Styles\nimport * as s from './style'\n\nexport class Treemap<Datum> extends ComponentCore<Datum[], TreemapConfigInterface<Datum>> {\n static selectors = s\n protected _defaultConfig = TreemapDefaultConfig as TreemapConfigInterface<Datum>\n public config: TreemapConfigInterface<Datum> = this._defaultConfig\n\n datamodel: SeriesDataModel<Datum> = new SeriesDataModel()\n tiles: Selection<SVGGElement, unknown, SVGGElement, unknown>\n\n private _isTileLargeEnough (d: TreemapNode<Datum>): boolean {\n const w = d.x1 - d.x0\n const h = d.y1 - d.y0\n return (w >= this.config.minTileSizeForLabel) && (h >= this.config.minTileSizeForLabel)\n }\n\n private _getTileLightness (node: TreemapNode<Datum>, siblings: TreemapNode<Datum>[]): number {\n // Get the value extent of the sibling group\n const [minValue, maxValue] = extent(siblings, d => d.value)\n\n // If there's no range or no value, return default lightness\n if (minValue === maxValue || !node.value) return 0\n\n // Calculate relative position in the range (0 to 1)\n // Larger values will be closer to 0 (darker)\n return this.config.lightnessVariationAmount * ((maxValue - node.value) / (maxValue - minValue))\n }\n\n constructor (config?: TreemapConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n this.tiles = this.g.append('g').attr('class', s.tiles)\n }\n\n _render (customDuration?: number): void {\n super._render(customDuration)\n const { config, datamodel: { data }, _width, _height } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n if (!config.layers?.length) {\n console.warn('Unovis | Treemap: No layers defined')\n return\n }\n\n // Map each layer accessor function to get string values from the data array\n const layerAccessors = config.layers.map(layerAccessor => {\n return (i: number) => getString(data[i], layerAccessor, i)\n })\n\n // Group the data indices by the layer accessors to create a hierarchical structure\n const nestedData = group(data.keys(), ...layerAccessors as [(d: number) => string])\n\n // Create the hierarchy from the grouped data,\n // which by itself is not quite right because there is an extra\n // level of nesting that we don't want, just above the leaf nodes.\n const rootNode = hierarchy(nestedData)\n\n // Compute the aggregation\n if (config.value) {\n rootNode.sum(index => isNumber(index) && getNumber(data[index], config.value, index))\n } else {\n rootNode.count()\n }\n\n // Fix the hierarchy by removing the extra level of nesting\n rootNode.each(node => {\n if (!node.children && node.parent) {\n node.parent.children = null\n }\n })\n\n const treemapLayout = treemap()\n .size([_width, _height])\n .round(true)\n .padding(config.tilePadding)\n\n // Apply padding to the top of each tile,\n // but not for the root node.\n if (this.config.tilePaddingTop !== undefined) {\n treemapLayout.paddingTop(d => d.parent ? config.tilePaddingTop : 0)\n }\n\n // Compute the treemap layout\n const treemapData = treemapLayout(rootNode) as TreemapNode<Datum>\n\n // Process the resulting hierarchy into the type we need\n let nodeId = 0\n treemapData.each(node => {\n const n = node as unknown as HierarchyNode<[string, number[]]>\n // Generate unique IDs for each node\n node._id = `node-${nodeId++}`\n\n const treemapDatum: TreemapDatum<Datum> = {\n key: n.data[0],\n }\n\n // Populate the index and datum for leaf nodes\n const isLeafNode = !n.children\n if (isLeafNode) {\n treemapDatum.index = n.data[1][0]\n treemapDatum.datum = data[treemapDatum.index]\n }\n\n node.data = treemapDatum\n })\n\n const descendants = treemapData.descendants()\n\n // Set up the brightness increase scale based on depth\n const maxDepth = max(descendants, d => d.depth)\n\n const brightnessIncrease = scaleLinear()\n .domain([1, maxDepth])\n .range([0, 1])\n\n // Get all leaf node values and calculate their square roots\n // (since area is proportional to value)\n const leafValues = descendants.filter(d => !d.children).map(d => d.value)\n const maxLeafValue = Math.sqrt(max(leafValues)) || 0\n // Divide the range into three equal intervals based on the square root of values\n // This accounts for the fact that area is proportional to value\n const fontSizeScale = scaleThreshold<number, number>()\n .domain([\n maxLeafValue / 3, // First third of the max value\n (maxLeafValue * 2) / 3, // Second third of the max value\n ])\n .range([\n config.tileLabelSmallFontSize,\n config.tileLabelMediumFontSize,\n config.tileLabelLargeFontSize,\n ])\n\n const visibleTiles = descendants.filter(d => d.depth > 0)\n const firstLevelTiles = visibleTiles.filter(d => d.depth === 1)\n const nonFirstLevelTiles = visibleTiles.filter(d => d.depth > 1)\n\n // Set the fill color for the first level tiles\n firstLevelTiles.forEach((d, i) => {\n d._fill = getColor(d, config.tileColor, i)\n })\n\n // Set the fill color for the non-first level tiles\n nonFirstLevelTiles.forEach((d, i) => {\n const providedColor = getColor(d, config.tileColor, i, true)\n if (providedColor) {\n d._fill = providedColor\n return\n }\n\n const hslColor = hsl(getHexValue(d.parent?._fill, this.element))\n\n if (config.enableLightnessVariance && !d.children && d.parent) {\n const siblings = d.parent.children\n const lightnessAdjustment = this._getTileLightness(d, siblings)\n hslColor.l = Math.min(1, hslColor.l + lightnessAdjustment)\n }\n\n d._fill = brighter(hslColor.toString(), brightnessIncrease(d.depth))\n })\n\n\n // Render tiles\n const tiles = this.tiles\n .selectAll<SVGGElement, TreemapNode<Datum>>(`g.${s.tileGroup}`)\n .data(visibleTiles, d => `${d.data.key}-${d.depth}`)\n\n const tilesEnter = tiles\n .enter()\n .append('g')\n .attr('class', s.tileGroup)\n\n // Computes the rect border radius for a given tile.\n // The rx and ry values are the minimum of the tile\n // border radius and some fraction the width of the tile,\n // based on the tileBorderRadiusFactor config.\n // This ensures that the tile border radius is not\n // larger than the tile size, which makes small tiles\n // look better.\n const getTileBorderRadius = (d: TreemapNode<Datum>): number =>\n Math.min(config.tileBorderRadius, (d.x1 - d.x0) * config.tileBorderRadiusFactor)\n\n // Add clipPath elements\n tilesEnter\n .append('clipPath')\n .attr('id', d => `clip-${this.uid}-${d._id}`)\n .append('rect')\n .attr('rx', getTileBorderRadius)\n .attr('ry', getTileBorderRadius)\n\n // Tile rectangles\n const tileRects = tilesEnter\n .append('rect')\n .classed(s.tile, true)\n .classed(s.clickableTile, d => config.showTileClickAffordance && !d.children)\n .attr('rx', getTileBorderRadius)\n .attr('ry', getTileBorderRadius)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n .style('fill', d => d._fill)\n .style('opacity', 0)\n .style('cursor', config.showTileClickAffordance ? d => !d.children ? 'pointer' : null : null)\n\n tileRects.append('title')\n\n tilesEnter\n .append('g')\n .attr('class', s.labelGroup)\n .attr('clip-path', d => `url(#clip-${this.uid}-${d._id})`)\n .attr('transform', d => `translate(${d.x0 + config.labelOffsetX},${d.y0 + config.labelOffsetY})`)\n .style('opacity', 0)\n .append('text')\n .attr('class', s.label)\n .attr('x', 0)\n .attr('y', 0)\n\n const mergedTiles = tiles.merge(tilesEnter)\n const tileRectsMerged = mergedTiles.select(`rect.${s.tile}`)\n smartTransition(tileRectsMerged, duration)\n .style('fill', d => d._fill)\n .style('opacity', 1)\n .attr('x', d => d.x0)\n .attr('y', d => d.y0)\n .attr('width', d => d.x1 - d.x0)\n .attr('height', d => d.y1 - d.y0)\n\n tileRectsMerged.select('title')\n .text(d => config.tileLabel(d))\n\n // Update clipPath rects\n mergedTiles.select('clipPath rect')\n .attr('width', d => d.x1 - d.x0 - 2 * config.labelOffsetX)\n .attr('height', d => d.y1 - d.y0 - 2 * config.labelOffsetY)\n\n const textSelection = mergedTiles.selectAll<SVGTextElement, TreemapNode<Datum>>(`g.${s.labelGroup} text`)\n textSelection\n .text(d => config.tileLabel(d))\n .attr('title', d => config.tileLabel(d))\n .property('font-size-px', d => {\n const sqrtVal = Math.sqrt(d.value ?? 0)\n return config.enableTileLabelFontSizeVariation && !d.children\n ? fontSizeScale(sqrtVal)\n : null // Use the default css variable value\n })\n .style('font-size', (_, i, els) => `${select(els[i]).property('font-size-px')}px`)\n .style('fill', d => cssvar(\n isColorDark(d._fill) ? s.variables.treemapLabelTextColorLight : s.variables.treemapLabelTextColor)\n )\n\n // Fit label (wrap or trim)\n textSelection.each((d, i, els) => {\n const isLeafNode = !d.children\n const el = els[i] as SVGTextElement\n const text = select(el)\n const tileWidth = d.x1 - d.x0 - (config.labelOffsetX ?? 0) * 2\n const fontSize = parseFloat(text.property('font-size-px')) || parseFloat(window.getComputedStyle(el).fontSize)\n\n if (config.labelFit === FitMode.Wrap && isLeafNode) {\n wrapSVGText(text, tileWidth)\n } else {\n trimSVGText(text, tileWidth, config.labelTrimMode, true, fontSize)\n }\n })\n\n // Transition group position\n smartTransition(mergedTiles.select(`g.${s.labelGroup}`), duration)\n .attr('transform', d => `translate(${d.x0 + config.labelOffsetX},${d.y0 + config.labelOffsetY})`)\n\n // Transition text opacity only (fade-in)\n smartTransition(mergedTiles.select(`g.${s.labelGroup}`), duration)\n .style('opacity', 1)\n\n // Hide labels that don't meet criteria\n mergedTiles.select(`text.${s.label}`)\n .style('display', d => {\n const isAllowedNode = config.labelInternalNodes ? true : !d.children\n return isAllowedNode && this._isTileLargeEnough(d) ? null : 'none'\n })\n // Make the internal labels semibold via class\n .attr('class', d => d.children ? `${s.label} ${s.internalLabel}` : s.label)\n\n smartTransition(tiles.exit(), duration)\n .style('opacity', 0)\n .remove()\n }\n}\n"],"names":["s.tiles","s.tileGroup","s.tile","s.clickableTile","s.labelGroup","s.label","s.variables","s.internalLabel","s"],"mappings":";;;;;;;;;;;;;;;;;AA+BM,MAAO,OAAe,SAAQ,aAAqD,CAAA;AA0BvF,IAAA,WAAA,CAAa,MAAsC,EAAA;AACjD,QAAA,KAAK,EAAE,CAAA;QAzBC,IAAc,CAAA,cAAA,GAAG,oBAAqD,CAAA;AACzE,QAAA,IAAA,CAAA,MAAM,GAAkC,IAAI,CAAC,cAAc,CAAA;AAElE,QAAA,IAAA,CAAA,SAAS,GAA2B,IAAI,eAAe,EAAE,CAAA;AAuBvD,QAAA,IAAI,MAAM;AAAE,YAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QAClC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,EAAEA,KAAO,CAAC,CAAA;KACvD;AAtBO,IAAA,kBAAkB,CAAE,CAAqB,EAAA;QAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAA;QACrB,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAA;AACrB,QAAA,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,mBAAmB,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;KACxF;IAEO,iBAAiB,CAAE,IAAwB,EAAE,QAA8B,EAAA;;AAEjF,QAAA,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAA;;AAG3D,QAAA,IAAI,QAAQ,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,CAAC,CAAA;;;QAIlD,OAAO,IAAI,CAAC,MAAM,CAAC,wBAAwB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,KAAK,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAA;KAChG;AAQD,IAAA,OAAO,CAAE,cAAuB,EAAA;;AAC9B,QAAA,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;AAC7B,QAAA,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;AAC7D,QAAA,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAA;QAE5E,IAAI,EAAC,CAAA,EAAA,GAAA,MAAM,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,MAAM,CAAA,EAAE;AAC1B,YAAA,OAAO,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAA;YACnD,OAAM;AACP,SAAA;;QAGD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,IAAG;AACvD,YAAA,OAAO,CAAC,CAAS,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAA;AAC5D,SAAC,CAAC,CAAA;;AAGF,QAAA,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,cAAyC,CAAC,CAAA;;;;AAKnF,QAAA,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;;QAGtC,IAAI,MAAM,CAAC,KAAK,EAAE;YAChB,QAAQ,CAAC,GAAG,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;AACtF,SAAA;AAAM,aAAA;YACL,QAAQ,CAAC,KAAK,EAAE,CAAA;AACjB,SAAA;;AAGD,QAAA,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAG;YACnB,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE;AACjC,gBAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAA;AAC5B,aAAA;AACH,SAAC,CAAC,CAAA;QAEF,MAAM,aAAa,GAAG,OAAO,EAAE;AAC5B,aAAA,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;aACvB,KAAK,CAAC,IAAI,CAAC;AACX,aAAA,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;;;AAI9B,QAAA,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS,EAAE;YAC5C,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC,CAAA;AACpE,SAAA;;AAGD,QAAA,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAuB,CAAA;;QAGjE,IAAI,MAAM,GAAG,CAAC,CAAA;AACd,QAAA,WAAW,CAAC,IAAI,CAAC,IAAI,IAAG;YACtB,MAAM,CAAC,GAAG,IAAoD,CAAA;;AAE9D,YAAA,IAAI,CAAC,GAAG,GAAG,QAAQ,MAAM,EAAE,EAAE,CAAA;AAE7B,YAAA,MAAM,YAAY,GAAwB;AACxC,gBAAA,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;aACf,CAAA;;AAGD,YAAA,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC9B,YAAA,IAAI,UAAU,EAAE;AACd,gBAAA,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;gBACjC,YAAY,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;AAC9C,aAAA;AAED,YAAA,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;AAC1B,SAAC,CAAC,CAAA;AAEF,QAAA,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,EAAE,CAAA;;AAG7C,QAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAA;QAE/C,MAAM,kBAAkB,GAAG,WAAW,EAAE;AACrC,aAAA,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AACrB,aAAA,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;;;QAIhB,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAA;AACzE,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAA;;;QAGpD,MAAM,aAAa,GAAG,cAAc,EAAkB;AACnD,aAAA,MAAM,CAAC;AACN,YAAA,YAAY,GAAG,CAAC;AAChB,YAAA,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC;SACvB,CAAC;AACD,aAAA,KAAK,CAAC;AACL,YAAA,MAAM,CAAC,sBAAsB;AAC7B,YAAA,MAAM,CAAC,uBAAuB;AAC9B,YAAA,MAAM,CAAC,sBAAsB;AAC9B,SAAA,CAAC,CAAA;AAEJ,QAAA,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;AACzD,QAAA,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAA;AAC/D,QAAA,MAAM,kBAAkB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;;QAGhE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;AAC/B,YAAA,CAAC,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;AAC5C,SAAC,CAAC,CAAA;;QAGF,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;;AAClC,YAAA,MAAM,aAAa,GAAG,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,CAAC,CAAA;AAC5D,YAAA,IAAI,aAAa,EAAE;AACjB,gBAAA,CAAC,CAAC,KAAK,GAAG,aAAa,CAAA;gBACvB,OAAM;AACP,aAAA;AAED,YAAA,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,MAAA,CAAC,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;AAEhE,YAAA,IAAI,MAAM,CAAC,uBAAuB,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,EAAE;AAC7D,gBAAA,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAA;gBAClC,MAAM,mBAAmB,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;AAC/D,gBAAA,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAA;AAC3D,aAAA;AAED,YAAA,CAAC,CAAC,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;AACtE,SAAC,CAAC,CAAA;;AAIF,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK;AACrB,aAAA,SAAS,CAAkC,CAAK,EAAA,EAAAC,SAAW,EAAE,CAAC;AAC9D,aAAA,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAG,EAAA,CAAC,CAAC,IAAI,CAAC,GAAG,CAAI,CAAA,EAAA,CAAC,CAAC,KAAK,CAAA,CAAE,CAAC,CAAA;QAEtD,MAAM,UAAU,GAAG,KAAK;AACrB,aAAA,KAAK,EAAE;aACP,MAAM,CAAC,GAAG,CAAC;AACX,aAAA,IAAI,CAAC,OAAO,EAAEA,SAAW,CAAC,CAAA;;;;;;;;AAS7B,QAAA,MAAM,mBAAmB,GAAG,CAAC,CAAqB,KAChD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,MAAM,CAAC,sBAAsB,CAAC,CAAA;;QAGlF,UAAU;aACP,MAAM,CAAC,UAAU,CAAC;AAClB,aAAA,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,CAAA,KAAA,EAAQ,IAAI,CAAC,GAAG,CAAI,CAAA,EAAA,CAAC,CAAC,GAAG,EAAE,CAAC;aAC5C,MAAM,CAAC,MAAM,CAAC;AACd,aAAA,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC;AAC/B,aAAA,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAA;;QAGlC,MAAM,SAAS,GAAG,UAAU;aACzB,MAAM,CAAC,MAAM,CAAC;AACd,aAAA,OAAO,CAACC,IAAM,EAAE,IAAI,CAAC;AACrB,aAAA,OAAO,CAACC,aAAe,EAAE,CAAC,IAAI,MAAM,CAAC,uBAAuB,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC5E,aAAA,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC;AAC/B,aAAA,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC;aAC/B,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;aACpB,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;AACpB,aAAA,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;AAC/B,aAAA,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;aAChC,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;AAC3B,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;AACnB,aAAA,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,uBAAuB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC,CAAA;AAE/F,QAAA,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAEzB,UAAU;aACP,MAAM,CAAC,GAAG,CAAC;AACX,aAAA,IAAI,CAAC,OAAO,EAAEC,UAAY,CAAC;AAC3B,aAAA,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAA,UAAA,EAAa,IAAI,CAAC,GAAG,CAAI,CAAA,EAAA,CAAC,CAAC,GAAG,GAAG,CAAC;aACzD,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAA,UAAA,EAAa,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,YAAY,CAAI,CAAA,EAAA,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,YAAY,CAAA,CAAA,CAAG,CAAC;AAChG,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;aACnB,MAAM,CAAC,MAAM,CAAC;AACd,aAAA,IAAI,CAAC,OAAO,EAAEC,KAAO,CAAC;AACtB,aAAA,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;AACZ,aAAA,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QAEf,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;AAC3C,QAAA,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,CAAC,CAAQ,KAAA,EAAAH,IAAM,CAAE,CAAA,CAAC,CAAA;AAC5D,QAAA,eAAe,CAAC,eAAe,EAAE,QAAQ,CAAC;aACvC,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;AAC3B,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;aACnB,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;aACpB,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;AACpB,aAAA,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;AAC/B,aAAA,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAA;AAEnC,QAAA,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC;AAC5B,aAAA,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;;AAGjC,QAAA,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC;aAChC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC;aACzD,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;AAE7D,QAAA,MAAM,aAAa,GAAG,WAAW,CAAC,SAAS,CAAqC,CAAK,EAAA,EAAAE,UAAY,CAAO,KAAA,CAAA,CAAC,CAAA;QACzG,aAAa;aACV,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC9B,aAAA,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACvC,aAAA,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAG;;AAC5B,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA,EAAA,GAAA,CAAC,CAAC,KAAK,MAAI,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAA,CAAC,CAAC,CAAA;AACvC,YAAA,OAAO,MAAM,CAAC,gCAAgC,IAAI,CAAC,CAAC,CAAC,QAAQ;AAC3D,kBAAE,aAAa,CAAC,OAAO,CAAC;AACxB,kBAAE,IAAI,CAAA;AACV,SAAC,CAAC;aACD,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,KAAK,CAAA,EAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAA,EAAA,CAAI,CAAC;AACjF,aAAA,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,MAAM,CACxB,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,GAAGE,SAAW,CAAC,0BAA0B,GAAGA,SAAW,CAAC,qBAAqB,CAAC,CACnG,CAAA;;QAGH,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,KAAI;;AAC/B,YAAA,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAA;AAC9B,YAAA,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAmB,CAAA;AACnC,YAAA,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAA;YACvB,MAAM,SAAS,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA,EAAA,GAAA,MAAM,CAAC,YAAY,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,CAAC,IAAI,CAAC,CAAA;YAC9D,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAA;YAE9G,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,IAAI,IAAI,UAAU,EAAE;AAClD,gBAAA,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;AAC7B,aAAA;AAAM,iBAAA;AACL,gBAAA,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,aAAa,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;AACnE,aAAA;AACH,SAAC,CAAC,CAAA;;AAGF,QAAA,eAAe,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA,EAAA,EAAKF,UAAY,CAAA,CAAE,CAAC,EAAE,QAAQ,CAAC;aAC/D,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAA,UAAA,EAAa,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,YAAY,CAAI,CAAA,EAAA,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,YAAY,CAAG,CAAA,CAAA,CAAC,CAAA;;AAGnG,QAAA,eAAe,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA,EAAA,EAAKA,UAAY,CAAA,CAAE,CAAC,EAAE,QAAQ,CAAC;AAC/D,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;;QAGtB,WAAW,CAAC,MAAM,CAAC,CAAA,KAAA,EAAQC,KAAO,EAAE,CAAC;AAClC,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,IAAG;AACpB,YAAA,MAAM,aAAa,GAAG,MAAM,CAAC,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAA;AACpE,YAAA,OAAO,aAAa,IAAI,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,MAAM,CAAA;AACpE,SAAC,CAAC;;AAED,aAAA,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAA,EAAGA,KAAO,CAAA,CAAA,EAAIE,aAAe,CAAA,CAAE,GAAGF,KAAO,CAAC,CAAA;AAE7E,QAAA,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC;AACpC,aAAA,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;AACnB,aAAA,MAAM,EAAE,CAAA;KACZ;;AA1RM,OAAS,CAAA,SAAA,GAAGG,KAAC;;;;"}
|
|
@@ -4,16 +4,11 @@ export declare const variables: {
|
|
|
4
4
|
treemapTileStrokeWidth: "--vis-treemap-tile-stroke-width";
|
|
5
5
|
treemapTileHoverStrokeColor: "--vis-treemap-tile-hover-stroke-color";
|
|
6
6
|
treemapTileHoverStrokeOpacity: "--vis-treemap-tile-hover-stroke-opacity";
|
|
7
|
-
treemapTileFillColor: "--vis-treemap-tile-fill-color";
|
|
8
|
-
treemapTileBackgroundColor: "--vis-treemap-tile-background-color";
|
|
9
|
-
treemapTileCursor: "--vis-treemap-tile-cursor";
|
|
10
|
-
treemapLabelTextColor: "--vis-treemap-label-text-color";
|
|
11
|
-
treemapLabelFontSize: "--vis-treemap-label-font-size";
|
|
12
7
|
treemapLabelOpacity: "--vis-treemap-label-opacity";
|
|
13
8
|
treemapLabelFontWeight: "--vis-treemap-label-font-weight";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
treemapLabelTextColor: "--vis-treemap-label-text-color";
|
|
10
|
+
treemapLabelTextColorLight: "--vis-treemap-label-text-color-light";
|
|
11
|
+
treemapLabelFontSize: "--vis-treemap-label-font-size";
|
|
17
12
|
};
|
|
18
13
|
export declare const tiles: string;
|
|
19
14
|
export declare const tileGroup: string;
|
|
@@ -6,18 +6,12 @@ const cssVarDefaults = {
|
|
|
6
6
|
'--vis-treemap-tile-stroke-width': '2px',
|
|
7
7
|
'--vis-treemap-tile-hover-stroke-color': '#fff',
|
|
8
8
|
'--vis-treemap-tile-hover-stroke-opacity': 0,
|
|
9
|
-
|
|
10
|
-
'--vis-treemap-tile-background-color': '#fff',
|
|
11
|
-
'--vis-treemap-tile-cursor': 'default',
|
|
12
|
-
'--vis-treemap-label-text-color': '#000',
|
|
13
|
-
'--vis-treemap-label-font-size': '12px',
|
|
14
|
-
/* Label opacity */
|
|
9
|
+
/* Labels */
|
|
15
10
|
'--vis-treemap-label-opacity': 0.8,
|
|
16
11
|
'--vis-treemap-label-font-weight': 'normal',
|
|
17
|
-
|
|
18
|
-
'--vis-
|
|
19
|
-
'--vis-
|
|
20
|
-
'--vis-dark-treemap-label-text-color': '#5b5f6d',
|
|
12
|
+
'--vis-treemap-label-text-color': '#000',
|
|
13
|
+
'--vis-treemap-label-text-color-light': '#fff',
|
|
14
|
+
'--vis-treemap-label-font-size': '12px',
|
|
21
15
|
};
|
|
22
16
|
const root = css `
|
|
23
17
|
label: treemap-component;
|
|
@@ -36,7 +30,7 @@ const tile = css `
|
|
|
36
30
|
stroke-opacity: 0;
|
|
37
31
|
|
|
38
32
|
&:hover {
|
|
39
|
-
stroke-opacity: var(
|
|
33
|
+
stroke-opacity: var(${variables.treemapTileHoverStrokeOpacity})
|
|
40
34
|
}
|
|
41
35
|
`;
|
|
42
36
|
// The leaf tiles are clickable
|
|
@@ -53,12 +47,13 @@ const label = css `
|
|
|
53
47
|
dominant-baseline: hanging;
|
|
54
48
|
user-select: none;
|
|
55
49
|
pointer-events: none;
|
|
56
|
-
font-size: var(
|
|
57
|
-
opacity: var(
|
|
58
|
-
fill: var(
|
|
59
|
-
font-weight: var(
|
|
50
|
+
font-size: var(${variables.treemapLabelFontSize});
|
|
51
|
+
opacity: var(${variables.treemapLabelOpacity});
|
|
52
|
+
fill: var(${variables.treemapLabelTextColor});
|
|
53
|
+
font-weight: var(${variables.treemapLabelFontWeight});
|
|
60
54
|
`;
|
|
61
55
|
const internalLabel = css `
|
|
56
|
+
label: internal-label;
|
|
62
57
|
font-weight: 500;
|
|
63
58
|
`;
|
|
64
59
|
const labelGroup = css `
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.js","sources":["../../../src/components/treemap/style.ts"],"sourcesContent":["import { css } from '@emotion/css'\n\n// Utils\nimport { getCssVarNames, injectGlobalCssVariables } from 'utils/style'\n\nconst cssVarDefaults = {\n '--vis-treemap-tile-stroke-color': '#fff',\n '--vis-treemap-tile-stroke-width': '2px',\n '--vis-treemap-tile-hover-stroke-color': '#fff',\n '--vis-treemap-tile-hover-stroke-opacity': 0,\n
|
|
1
|
+
{"version":3,"file":"style.js","sources":["../../../src/components/treemap/style.ts"],"sourcesContent":["import { css } from '@emotion/css'\n\n// Utils\nimport { getCssVarNames, injectGlobalCssVariables } from 'utils/style'\n\nconst cssVarDefaults = {\n '--vis-treemap-tile-stroke-color': '#fff',\n '--vis-treemap-tile-stroke-width': '2px',\n '--vis-treemap-tile-hover-stroke-color': '#fff',\n '--vis-treemap-tile-hover-stroke-opacity': 0,\n\n /* Labels */\n '--vis-treemap-label-opacity': 0.8,\n '--vis-treemap-label-font-weight': 'normal',\n '--vis-treemap-label-text-color': '#000',\n '--vis-treemap-label-text-color-light': '#fff',\n '--vis-treemap-label-font-size': '12px',\n}\n\nexport const root = css`\n label: treemap-component;\n`\n\nexport const variables = getCssVarNames(cssVarDefaults)\ninjectGlobalCssVariables(cssVarDefaults, root)\n\nexport const tiles = css`\n label: g-tiles;\n`\n\nexport const tileGroup = css`\n label: tile-group;\n`\n\nexport const tile = css`\n label: tile;\n stroke: var(${variables.treemapTileHoverStrokeColor});\n stroke-opacity: 0;\n\n &:hover {\n stroke-opacity: var(${variables.treemapTileHoverStrokeOpacity})\n }\n`\n\n// The leaf tiles are clickable\nexport const clickableTile = css`\n label: clickable-tile;\n cursor: pointer;\n`\n\nexport const tileForeground = css`\n label: tile-foreground;\n`\n\nexport const label = css`\n label: label;\n text-anchor: start;\n dominant-baseline: hanging;\n user-select: none;\n pointer-events: none;\n font-size: var(${variables.treemapLabelFontSize});\n opacity: var(${variables.treemapLabelOpacity});\n fill: var(${variables.treemapLabelTextColor});\n font-weight: var(${variables.treemapLabelFontWeight});\n`\n\nexport const internalLabel = css`\n label: internal-label;\n font-weight: 500;\n`\n\nexport const labelGroup = css`\n label: label-group;\n`\n"],"names":[],"mappings":";;;AAKA,MAAM,cAAc,GAAG;AACrB,IAAA,iCAAiC,EAAE,MAAM;AACzC,IAAA,iCAAiC,EAAE,KAAK;AACxC,IAAA,uCAAuC,EAAE,MAAM;AAC/C,IAAA,yCAAyC,EAAE,CAAC;;AAG5C,IAAA,6BAA6B,EAAE,GAAG;AAClC,IAAA,iCAAiC,EAAE,QAAQ;AAC3C,IAAA,gCAAgC,EAAE,MAAM;AACxC,IAAA,sCAAsC,EAAE,MAAM;AAC9C,IAAA,+BAA+B,EAAE,MAAM;CACxC,CAAA;AAEM,MAAM,IAAI,GAAG,GAAG,CAAA,CAAA;;EAEtB;MAEY,SAAS,GAAG,cAAc,CAAC,cAAc,EAAC;AACvD,wBAAwB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAA;AAEvC,MAAM,KAAK,GAAG,GAAG,CAAA,CAAA;;EAEvB;AAEM,MAAM,SAAS,GAAG,GAAG,CAAA,CAAA;;EAE3B;AAEM,MAAM,IAAI,GAAG,GAAG,CAAA,CAAA;;AAEP,cAAA,EAAA,SAAS,CAAC,2BAA2B,CAAA;;;;AAI3B,wBAAA,EAAA,SAAS,CAAC,6BAA6B,CAAA;;EAEhE;AAED;AACO,MAAM,aAAa,GAAG,GAAG,CAAA,CAAA;;;EAG/B;AAEM,MAAM,cAAc,GAAG,GAAG,CAAA,CAAA;;EAEhC;AAEM,MAAM,KAAK,GAAG,GAAG,CAAA,CAAA;;;;;;AAML,iBAAA,EAAA,SAAS,CAAC,oBAAoB,CAAA;AAChC,eAAA,EAAA,SAAS,CAAC,mBAAmB,CAAA;AAChC,YAAA,EAAA,SAAS,CAAC,qBAAqB,CAAA;AACxB,mBAAA,EAAA,SAAS,CAAC,sBAAsB,CAAA;EACpD;AAEM,MAAM,aAAa,GAAG,GAAG,CAAA,CAAA;;;EAG/B;AAEM,MAAM,UAAU,GAAG,GAAG,CAAA,CAAA;;;;;;"}
|
package/index.js
CHANGED
|
@@ -69,7 +69,7 @@ export { PlotbandLabelOrientation, PlotbandLabelPosition } from './components/pl
|
|
|
69
69
|
export { arrayOfIndices, clamp, clean, cloneDeep, countUnique, ensureArray, filterDataByRange, flatten, getBoolean, getExtent, getMax, getMin, getNearest, getNumber, getStackedData, getStackedExtent, getStackedValues, getString, getValue, groupBy, isAClassInstance, isArray, isEmpty, isEqual, isFunction, isNil, isNumber, isNumberWithinRange, isObject, isPlainObject, isString, isUndefined, merge, omit, shallowDiff, sortBy, throttle, unique, without } from './utils/data.js';
|
|
70
70
|
export { allowedSvgTextTags, escapeStringKeepHash, estimateStringPixelLength, estimateTextSize, estimateWrappedTextHeight, getPreciseStringLengthPx, getWrappedText, kebabCase, kebabCaseToCamel, renderTextIntoFrame, renderTextToSvgTextElement, splitString, textAlignToAnchor, trimSVGText, trimString, trimStringEnd, trimStringMiddle, trimStringStart, wrapSVGText } from './utils/text.js';
|
|
71
71
|
export { allowedSvgTags, getTransformValues, isStringSvg, sanitizeSvgString, transformValuesToString } from './utils/svg.js';
|
|
72
|
-
export { brighter, getColor, getHexValue, hexToBrightness, hexToRgb, rgbToBrightness, rgbaToRgb } from './utils/color.js';
|
|
72
|
+
export { brighter, getColor, getHexValue, hexToBrightness, hexToRgb, isColorDark, rgbToBrightness, rgbaToRgb } from './utils/color.js';
|
|
73
73
|
export { arrowPolylinePath, circlePath, convertLineToArc, polygon, roundedRectPath, scoreRectPath } from './utils/path.js';
|
|
74
74
|
export { getCSSVariableValue, getCSSVariableValueInPixels, getHref, getPixelValue, guid, isStringCSSVariable, parseUnit, rectIntersect, stringToHtmlId } from './utils/misc.js';
|
|
75
75
|
export { DefaultRange } from './utils/scale.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unovis/ts",
|
|
3
3
|
"description": "Modular data visualization framework for React, Angular, Svelte, Vue, Solid, and vanilla TypeScript or JavaScript",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.7.0-Phoenix.0",
|
|
5
5
|
"packageManager": "npm@10.9.1",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
package/utils/color.d.ts
CHANGED
|
@@ -18,4 +18,5 @@ export declare function rgbaToRgb(rgba: string, backgroundColor?: string): RGBCo
|
|
|
18
18
|
* @returns The brightened color in hex format
|
|
19
19
|
*/
|
|
20
20
|
export declare function brighter(inputColor: string, amount: number): string;
|
|
21
|
+
export declare function isColorDark(color: string, threshold?: number): boolean;
|
|
21
22
|
export {};
|
package/utils/color.js
CHANGED
|
@@ -54,7 +54,13 @@ function brighter(inputColor, amount) {
|
|
|
54
54
|
if (!c)
|
|
55
55
|
return inputColor;
|
|
56
56
|
return c.brighter(amount).formatHex();
|
|
57
|
+
}
|
|
58
|
+
function isColorDark(color, threshold = 0.55) {
|
|
59
|
+
const hex = getHexValue(color, document.body);
|
|
60
|
+
if (!hex)
|
|
61
|
+
return false;
|
|
62
|
+
return hexToBrightness(hex) < threshold;
|
|
57
63
|
}
|
|
58
64
|
|
|
59
|
-
export { brighter, getColor, getHexValue, hexToBrightness, hexToRgb, rgbToBrightness, rgbaToRgb };
|
|
65
|
+
export { brighter, getColor, getHexValue, hexToBrightness, hexToRgb, isColorDark, rgbToBrightness, rgbaToRgb };
|
|
60
66
|
//# sourceMappingURL=color.js.map
|
package/utils/color.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color.js","sources":["../../src/utils/color.ts"],"sourcesContent":["import { color, hcl } from 'd3-color'\n\n// Core\nimport { getCSSColorVariable } from 'styles/colors'\n\n// Utils\nimport { ColorAccessor, StringAccessor } from 'types/accessor'\nimport { getString, isNumber } from 'utils/data'\nimport { isStringCSSVariable, getCSSVariableValue } from 'utils/misc'\n\ntype RGBColor = { r: number; g: number; b: number }\n\n/** Retrieves color from the data if provided, fallbacks to CSS variables if the index was passed */\nexport function getColor<T> (\n d: T,\n accessor: ColorAccessor<T>,\n index?: number,\n dontFallbackToCssVar?: boolean\n): string | null {\n if (Array.isArray(accessor) && isFinite(index)) return accessor[index % accessor.length]\n\n const value = getString(d, accessor as StringAccessor<T>, index)\n return (value || ((isNumber(index) && !dontFallbackToCssVar) ? `var(${getCSSColorVariable(index)})` : null))\n}\n\nexport function hexToRgb (hex: string): RGBColor {\n const parsed = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex)\n return parsed ? {\n r: parseInt(parsed[1], 16),\n g: parseInt(parsed[2], 16),\n b: parseInt(parsed[3], 16),\n } : { r: 0, g: 0, b: 0 }\n}\n\nexport function rgbToBrightness (rgb: RGBColor): number {\n return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b) / 255\n}\n\nexport function hexToBrightness (hex: string): number {\n const rgb = hexToRgb(hex)\n return rgbToBrightness(rgb)\n}\n\nexport function getHexValue (s: string, context: HTMLElement | SVGElement): string {\n const hex = isStringCSSVariable(s) ? getCSSVariableValue(s, context) : s\n return color(hex)?.formatHex()\n}\n\nexport function rgbaToRgb (rgba: string, backgroundColor?: string): RGBColor {\n const rgb = color(rgba)?.rgb()\n if (!rgb || rgb.opacity === 1) return rgb\n const alpha = 1 - rgb.opacity\n const bg = color(backgroundColor ?? '#fff').rgb()\n return {\n r: Math.round((rgb.opacity * (rgb.r / 255) + (alpha * (bg.r / 255))) * 255),\n g: Math.round((rgb.opacity * (rgb.g / 255) + (alpha * (bg.g / 255))) * 255),\n b: Math.round((rgb.opacity * (rgb.b / 255) + (alpha * (bg.b / 255))) * 255),\n }\n}\n\n/**\n * Makes a color brighter by a certain amount\n * @param inputColor - The color to brighten (hex, rgb, or rgba)\n * @param amount - Amount to brighten by (0-1)\n * @returns The brightened color in hex format\n */\nexport function brighter (inputColor: string, amount: number): string {\n const c = hcl(inputColor)\n if (!c) return inputColor\n return c.brighter(amount).formatHex()\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"color.js","sources":["../../src/utils/color.ts"],"sourcesContent":["import { color, hcl } from 'd3-color'\n\n// Core\nimport { getCSSColorVariable } from 'styles/colors'\n\n// Utils\nimport { ColorAccessor, StringAccessor } from 'types/accessor'\nimport { getString, isNumber } from 'utils/data'\nimport { isStringCSSVariable, getCSSVariableValue } from 'utils/misc'\n\ntype RGBColor = { r: number; g: number; b: number }\n\n/** Retrieves color from the data if provided, fallbacks to CSS variables if the index was passed */\nexport function getColor<T> (\n d: T,\n accessor: ColorAccessor<T>,\n index?: number,\n dontFallbackToCssVar?: boolean\n): string | null {\n if (Array.isArray(accessor) && isFinite(index)) return accessor[index % accessor.length]\n\n const value = getString(d, accessor as StringAccessor<T>, index)\n return (value || ((isNumber(index) && !dontFallbackToCssVar) ? `var(${getCSSColorVariable(index)})` : null))\n}\n\nexport function hexToRgb (hex: string): RGBColor {\n const parsed = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex)\n return parsed ? {\n r: parseInt(parsed[1], 16),\n g: parseInt(parsed[2], 16),\n b: parseInt(parsed[3], 16),\n } : { r: 0, g: 0, b: 0 }\n}\n\nexport function rgbToBrightness (rgb: RGBColor): number {\n return (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b) / 255\n}\n\nexport function hexToBrightness (hex: string): number {\n const rgb = hexToRgb(hex)\n return rgbToBrightness(rgb)\n}\n\nexport function getHexValue (s: string, context: HTMLElement | SVGElement): string {\n const hex = isStringCSSVariable(s) ? getCSSVariableValue(s, context) : s\n return color(hex)?.formatHex()\n}\n\nexport function rgbaToRgb (rgba: string, backgroundColor?: string): RGBColor {\n const rgb = color(rgba)?.rgb()\n if (!rgb || rgb.opacity === 1) return rgb\n const alpha = 1 - rgb.opacity\n const bg = color(backgroundColor ?? '#fff').rgb()\n return {\n r: Math.round((rgb.opacity * (rgb.r / 255) + (alpha * (bg.r / 255))) * 255),\n g: Math.round((rgb.opacity * (rgb.g / 255) + (alpha * (bg.g / 255))) * 255),\n b: Math.round((rgb.opacity * (rgb.b / 255) + (alpha * (bg.b / 255))) * 255),\n }\n}\n\n/**\n * Makes a color brighter by a certain amount\n * @param inputColor - The color to brighten (hex, rgb, or rgba)\n * @param amount - Amount to brighten by (0-1)\n * @returns The brightened color in hex format\n */\nexport function brighter (inputColor: string, amount: number): string {\n const c = hcl(inputColor)\n if (!c) return inputColor\n return c.brighter(amount).formatHex()\n}\n\nexport function isColorDark (color: string, threshold = 0.55): boolean {\n const hex = getHexValue(color, document.body)\n if (!hex) return false\n return hexToBrightness(hex) < threshold\n}\n"],"names":[],"mappings":"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"}
|
package/utils/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { arrayOfIndices, clamp, clean, cloneDeep, countUnique, ensureArray, filterDataByRange, flatten, getBoolean, getExtent, getMax, getMin, getNearest, getNumber, getStackedData, getStackedExtent, getStackedValues, getString, getValue, groupBy, isAClassInstance, isArray, isEmpty, isEqual, isFunction, isNil, isNumber, isNumberWithinRange, isObject, isPlainObject, isString, isUndefined, merge, omit, shallowDiff, sortBy, throttle, unique, without } from './data.js';
|
|
2
2
|
export { allowedSvgTextTags, escapeStringKeepHash, estimateStringPixelLength, estimateTextSize, estimateWrappedTextHeight, getPreciseStringLengthPx, getWrappedText, kebabCase, kebabCaseToCamel, renderTextIntoFrame, renderTextToSvgTextElement, splitString, textAlignToAnchor, trimSVGText, trimString, trimStringEnd, trimStringMiddle, trimStringStart, wrapSVGText } from './text.js';
|
|
3
3
|
export { allowedSvgTags, getTransformValues, isStringSvg, sanitizeSvgString, transformValuesToString } from './svg.js';
|
|
4
|
-
export { brighter, getColor, getHexValue, hexToBrightness, hexToRgb, rgbToBrightness, rgbaToRgb } from './color.js';
|
|
4
|
+
export { brighter, getColor, getHexValue, hexToBrightness, hexToRgb, isColorDark, rgbToBrightness, rgbaToRgb } from './color.js';
|
|
5
5
|
export { arrowPolylinePath, circlePath, convertLineToArc, polygon, roundedRectPath, scoreRectPath } from './path.js';
|
|
6
6
|
export { getCSSVariableValue, getCSSVariableValueInPixels, getHref, getPixelValue, guid, isStringCSSVariable, parseUnit, rectIntersect, stringToHtmlId } from './misc.js';
|
|
7
7
|
import './type.js';
|