@unovis/ts 1.6.0-pre.2 → 1.6.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/area/index.js +2 -1
- package/components/area/index.js.map +1 -1
- package/components/axis/config.d.ts +4 -0
- package/components/axis/config.js +2 -2
- package/components/axis/config.js.map +1 -1
- package/components/axis/index.d.ts +0 -1
- package/components/axis/index.js +51 -19
- package/components/axis/index.js.map +1 -1
- package/components/axis/style.d.ts +40 -1
- package/components/axis/style.js +34 -35
- package/components/axis/style.js.map +1 -1
- package/components/brush/config.d.ts +1 -1
- package/components/brush/config.js.map +1 -1
- package/components/bullet-legend/config.d.ts +2 -0
- package/components/bullet-legend/config.js +1 -0
- package/components/bullet-legend/config.js.map +1 -1
- package/components/bullet-legend/index.js +10 -2
- package/components/bullet-legend/index.js.map +1 -1
- package/components/bullet-legend/modules/shape.d.ts +1 -0
- package/components/bullet-legend/modules/shape.js +61 -41
- package/components/bullet-legend/modules/shape.js.map +1 -1
- package/components/bullet-legend/types.d.ts +1 -1
- package/components/bullet-legend/types.js.map +1 -1
- package/components/crosshair/config.d.ts +20 -7
- package/components/crosshair/config.js +1 -1
- package/components/crosshair/config.js.map +1 -1
- package/components/crosshair/index.d.ts +8 -7
- package/components/crosshair/index.js +144 -72
- package/components/crosshair/index.js.map +1 -1
- package/components/graph/config.d.ts +8 -0
- package/components/graph/config.js +1 -1
- package/components/graph/config.js.map +1 -1
- package/components/graph/index.d.ts +1 -0
- package/components/graph/index.js +14 -9
- package/components/graph/index.js.map +1 -1
- package/components/graph/modules/layout.js +33 -31
- package/components/graph/modules/layout.js.map +1 -1
- package/components/graph/modules/link/index.js +1 -1
- package/components/graph/modules/link/index.js.map +1 -1
- package/components/graph/types.d.ts +2 -1
- package/components/graph/types.js.map +1 -1
- package/components/nested-donut/config.d.ts +1 -1
- package/components/nested-donut/config.js.map +1 -1
- package/components/plotband/config.d.ts +59 -0
- package/components/plotband/config.js +9 -0
- package/components/plotband/config.js.map +1 -0
- package/components/plotband/constants.d.ts +5 -0
- package/components/plotband/constants.js +413 -0
- package/components/plotband/constants.js.map +1 -0
- package/components/plotband/index.d.ts +15 -0
- package/components/plotband/index.js +92 -0
- package/components/plotband/index.js.map +1 -0
- package/components/plotband/style.d.ts +4 -0
- package/components/plotband/style.js +38 -0
- package/components/plotband/style.js.map +1 -0
- package/components/plotband/types.d.ts +51 -0
- package/components/plotband/types.js +27 -0
- package/components/plotband/types.js.map +1 -0
- package/components/plotline/config.d.ts +91 -0
- package/components/plotline/config.js +9 -0
- package/components/plotline/config.js.map +1 -0
- package/components/plotline/constants.d.ts +6 -0
- package/components/plotline/constants.js +58 -0
- package/components/plotline/constants.js.map +1 -0
- package/components/plotline/index.d.ts +14 -0
- package/components/plotline/index.js +102 -0
- package/components/plotline/index.js.map +1 -0
- package/components/plotline/style.d.ts +4 -0
- package/components/plotline/style.js +42 -0
- package/components/plotline/style.js.map +1 -0
- package/components/plotline/types.d.ts +53 -0
- package/components/plotline/types.js +33 -0
- package/components/plotline/types.js.map +1 -0
- package/components/rolling-pin-legend/config.d.ts +19 -0
- package/components/rolling-pin-legend/config.js +11 -0
- package/components/rolling-pin-legend/config.js.map +1 -0
- package/components/rolling-pin-legend/index.d.ts +16 -0
- package/components/rolling-pin-legend/index.js +69 -0
- package/components/rolling-pin-legend/index.js.map +1 -0
- package/components/rolling-pin-legend/style.d.ts +22 -0
- package/components/rolling-pin-legend/style.js +39 -0
- package/components/rolling-pin-legend/style.js.map +1 -0
- package/components/rolling-pin-legend/types.d.ts +1 -0
- package/components/rolling-pin-legend/types.js +2 -0
- package/components/rolling-pin-legend/types.js.map +1 -0
- package/components/scatter/index.d.ts +1 -0
- package/components/scatter/index.js +11 -1
- package/components/scatter/index.js.map +1 -1
- package/components/timeline/config.d.ts +65 -14
- package/components/timeline/config.js +15 -1
- package/components/timeline/config.js.map +1 -1
- package/components/timeline/constants.d.ts +3 -0
- package/components/timeline/constants.js +6 -0
- package/components/timeline/constants.js.map +1 -0
- package/components/timeline/index.d.ts +21 -10
- package/components/timeline/index.js +380 -95
- package/components/timeline/index.js.map +1 -1
- package/components/timeline/style.d.ts +7 -0
- package/components/timeline/style.js +40 -1
- package/components/timeline/style.js.map +1 -1
- package/components/timeline/types.d.ts +62 -0
- package/components/timeline/types.js +2 -0
- package/components/timeline/types.js.map +1 -0
- package/components/timeline/utils.d.ts +2 -0
- package/components/timeline/utils.js +16 -0
- package/components/timeline/utils.js.map +1 -0
- package/components/tooltip/index.js +4 -3
- package/components/tooltip/index.js.map +1 -1
- package/components/treemap/config.d.ts +52 -0
- package/components/treemap/config.js +6 -0
- package/components/treemap/config.js.map +1 -0
- package/components/treemap/index.d.ts +18 -0
- package/components/treemap/index.js +274 -0
- package/components/treemap/index.js.map +1 -0
- package/components/treemap/style.d.ts +25 -0
- package/components/treemap/style.js +69 -0
- package/components/treemap/style.js.map +1 -0
- package/components/treemap/types.d.ts +11 -0
- package/components/treemap/types.js +2 -0
- package/components/treemap/types.js.map +1 -0
- package/components/xy-labels/index.js +1 -1
- package/components/xy-labels/index.js.map +1 -1
- package/components.d.ts +10 -2
- package/components.js +4 -0
- package/components.js.map +1 -1
- package/containers/single-container/index.js +3 -1
- package/containers/single-container/index.js.map +1 -1
- package/containers/xy-container/config.d.ts +2 -0
- package/containers/xy-container/config.js +1 -1
- package/containers/xy-container/config.js.map +1 -1
- package/containers/xy-container/index.js +17 -7
- package/containers/xy-container/index.js.map +1 -1
- package/core/component/index.d.ts +4 -0
- package/core/component/index.js +6 -0
- package/core/component/index.js.map +1 -1
- package/core/xy-component/index.d.ts +1 -0
- package/core/xy-component/index.js +3 -1
- package/core/xy-component/index.js.map +1 -1
- package/index.js +10 -3
- package/index.js.map +1 -1
- package/package.json +2 -2
- package/styles/index.js +1 -0
- package/styles/index.js.map +1 -1
- package/types/data.d.ts +5 -0
- package/types/data.js +7 -0
- package/types/data.js.map +1 -1
- package/types/position.d.ts +2 -1
- package/types/position.js +1 -0
- package/types/position.js.map +1 -1
- package/types/text.d.ts +1 -1
- package/types/text.js.map +1 -1
- package/types.d.ts +5 -0
- package/types.js +6 -1
- package/types.js.map +1 -1
- package/utils/color.d.ts +7 -0
- package/utils/color.js +14 -2
- package/utils/color.js.map +1 -1
- package/utils/data.d.ts +4 -4
- package/utils/data.js +41 -10
- package/utils/data.js.map +1 -1
- package/utils/index.js +3 -3
- package/utils/path.d.ts +8 -0
- package/utils/path.js +109 -1
- package/utils/path.js.map +1 -1
- package/utils/text.d.ts +3 -2
- package/utils/text.js +22 -10
- package/utils/text.js.map +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ComponentConfigInterface } from "../../core/component/config";
|
|
2
|
+
import { ColorAccessor, NumericAccessor, StringAccessor } from "../../types/accessor";
|
|
3
|
+
import { TreemapNode } from './types';
|
|
4
|
+
export interface TreemapConfigInterface<Datum> extends ComponentConfigInterface {
|
|
5
|
+
id?: ((d: Datum, i: number) => string | number);
|
|
6
|
+
value?: NumericAccessor<Datum>;
|
|
7
|
+
/** Array of accessor functions to defined the nested groups. Default: `[]` */
|
|
8
|
+
layers: StringAccessor<Datum>[];
|
|
9
|
+
/** A function that accepts a value number and returns a string. Default: `undefined` */
|
|
10
|
+
numberFormat?: (value: number) => string;
|
|
11
|
+
/** Color accessor function for tiles. Default: `undefined` */
|
|
12
|
+
tileColor?: ColorAccessor<TreemapNode<Datum>>;
|
|
13
|
+
/** Padding passed to D3 treemap layout. Default: `2` */
|
|
14
|
+
tilePadding?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Top padding passed to D3 treemap layout.
|
|
17
|
+
* Useful to make room for internal node labels.
|
|
18
|
+
* Default: `undefined`
|
|
19
|
+
*/
|
|
20
|
+
tilePaddingTop?: number;
|
|
21
|
+
/** Label internal nodes. Default: `false` */
|
|
22
|
+
labelInternalNodes?: boolean;
|
|
23
|
+
/** Label offset in the X direction. Default: `4` */
|
|
24
|
+
labelOffsetX?: number;
|
|
25
|
+
/** Label offset in the Y direction. Default: `4` */
|
|
26
|
+
labelOffsetY?: number;
|
|
27
|
+
/** Border radius of the tiles in pixels. Default: `2` */
|
|
28
|
+
tileBorderRadius?: number;
|
|
29
|
+
/** Minimum fraction of width for border radius. Default: `1/8` */
|
|
30
|
+
tileBorderRadiusFactor?: number;
|
|
31
|
+
/** Enable lightness variance for sibling tiles. Default: `false` */
|
|
32
|
+
enableLightnessVariance?: boolean;
|
|
33
|
+
/** Enable font size variation for leaf node labels based on value. Default: `false` */
|
|
34
|
+
enableTileLabelFontSizeVariation?: boolean;
|
|
35
|
+
/** Small font size for leaf labels (used when enableTileLabelFontSizeVariation is true). Default: `8` */
|
|
36
|
+
tileLabelSmallFontSize?: number;
|
|
37
|
+
/** Medium font size for leaf labels (used when enableTileLabelFontSizeVariation is true). Default: `12` */
|
|
38
|
+
tileLabelMediumFontSize?: number;
|
|
39
|
+
/** Large font size for leaf labels (used when enableTileLabelFontSizeVariation is true). Default: `24` */
|
|
40
|
+
tileLabelLargeFontSize?: number;
|
|
41
|
+
/** Flag for showing cursor:pointer to indicate leaf tiles are clickable. Default: `undefined` */
|
|
42
|
+
showTileClickAffordance?: boolean;
|
|
43
|
+
/** Amount of lightness variation applied to sibling tiles when enableLightnessVariance is true. Default: `0.08` */
|
|
44
|
+
lightnessVariationAmount?: number;
|
|
45
|
+
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
|
+
}
|
|
52
|
+
export declare const TreemapDefaultConfig: TreemapConfigInterface<unknown>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ComponentDefaultConfig } from '../../core/component/config.js';
|
|
2
|
+
|
|
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: undefined });
|
|
4
|
+
|
|
5
|
+
export { TreemapDefaultConfig };
|
|
6
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +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: `undefined` */\n numberFormat?: (value: number) => 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 /** 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 minTileSizeForLabel?: number;\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\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 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 tileLabel: undefined,\n}\n"],"names":[],"mappings":";;MAyEa,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,MAAI,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAA,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,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,SAAS,EAAE,SAAS,EAAA;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Selection } from 'd3-selection';
|
|
2
|
+
import { ComponentCore } from "../../core/component";
|
|
3
|
+
import { SeriesDataModel } from "../../data-models/series";
|
|
4
|
+
import { TreemapConfigInterface } from './config';
|
|
5
|
+
import * as s from './style';
|
|
6
|
+
export declare class Treemap<Datum> extends ComponentCore<Datum[], TreemapConfigInterface<Datum>> {
|
|
7
|
+
static selectors: typeof s;
|
|
8
|
+
protected _defaultConfig: TreemapConfigInterface<Datum>;
|
|
9
|
+
config: TreemapConfigInterface<Datum>;
|
|
10
|
+
/** Default number format for tile labels. */
|
|
11
|
+
private _defaultNumberFormat;
|
|
12
|
+
datamodel: SeriesDataModel<Datum>;
|
|
13
|
+
tiles: Selection<SVGGElement, unknown, SVGGElement, unknown>;
|
|
14
|
+
private _isTileLargeEnough;
|
|
15
|
+
private _getTileLightness;
|
|
16
|
+
constructor(config?: TreemapConfigInterface<Datum>);
|
|
17
|
+
_render(customDuration?: number): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { select } from 'd3-selection';
|
|
2
|
+
import { hierarchy, treemap } from 'd3-hierarchy';
|
|
3
|
+
import { extent, group, max } from 'd3-array';
|
|
4
|
+
import { scaleLinear, scaleThreshold } from 'd3-scale';
|
|
5
|
+
import { hsl } from 'd3-color';
|
|
6
|
+
import { ComponentCore } from '../../core/component/index.js';
|
|
7
|
+
import { SeriesDataModel } from '../../data-models/series.js';
|
|
8
|
+
import { getColor, getHexValue, brighter } from '../../utils/color.js';
|
|
9
|
+
import { isNumber, getString, getNumber } from '../../utils/data.js';
|
|
10
|
+
import { smartTransition } from '../../utils/d3.js';
|
|
11
|
+
import { trimSVGText } from '../../utils/text.js';
|
|
12
|
+
import { TrimMode } from '../../types/text.js';
|
|
13
|
+
import { TreemapDefaultConfig } from './config.js';
|
|
14
|
+
import * as style from './style.js';
|
|
15
|
+
import { tiles, tileGroup, tile, clickableTile, labelGroup, label, internalLabel } from './style.js';
|
|
16
|
+
|
|
17
|
+
class Treemap extends ComponentCore {
|
|
18
|
+
constructor(config) {
|
|
19
|
+
super();
|
|
20
|
+
this._defaultConfig = TreemapDefaultConfig;
|
|
21
|
+
this.config = this._defaultConfig;
|
|
22
|
+
this.datamodel = new SeriesDataModel();
|
|
23
|
+
if (config)
|
|
24
|
+
this.setConfig(config);
|
|
25
|
+
this.tiles = this.g.append('g').attr('class', tiles);
|
|
26
|
+
}
|
|
27
|
+
/** Default number format for tile labels. */
|
|
28
|
+
_defaultNumberFormat(value) {
|
|
29
|
+
return `${value}`;
|
|
30
|
+
}
|
|
31
|
+
_isTileLargeEnough(d) {
|
|
32
|
+
const w = d.x1 - d.x0;
|
|
33
|
+
const h = d.y1 - d.y0;
|
|
34
|
+
return (w >= this.config.minTileSizeForLabel) && (h >= this.config.minTileSizeForLabel);
|
|
35
|
+
}
|
|
36
|
+
_getTileLightness(node, siblings) {
|
|
37
|
+
// Get the value extent of the sibling group
|
|
38
|
+
const [minValue, maxValue] = extent(siblings, d => d.value);
|
|
39
|
+
// If there's no range or no value, return default lightness
|
|
40
|
+
if (minValue === maxValue || !node.value)
|
|
41
|
+
return 0;
|
|
42
|
+
// Calculate relative position in the range (0 to 1)
|
|
43
|
+
// Larger values will be closer to 0 (darker)
|
|
44
|
+
return this.config.lightnessVariationAmount * ((maxValue - node.value) / (maxValue - minValue));
|
|
45
|
+
}
|
|
46
|
+
_render(customDuration) {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
super._render(customDuration);
|
|
49
|
+
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
|
+
const duration = isNumber(customDuration) ? customDuration : config.duration;
|
|
53
|
+
if (!((_a = config.layers) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
54
|
+
console.warn('Unovis | Treemap: No layers defined');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Map each layer accessor function to get string values from the data array
|
|
58
|
+
const layerAccessors = config.layers.map(layerAccessor => {
|
|
59
|
+
return (i) => getString(data[i], layerAccessor, i);
|
|
60
|
+
});
|
|
61
|
+
// Group the data indices by the layer accessors to create a hierarchical structure
|
|
62
|
+
const nestedData = group(data.keys(), ...layerAccessors);
|
|
63
|
+
// Create the hierarchy from the grouped data,
|
|
64
|
+
// which by itself is not quite right because there is an extra
|
|
65
|
+
// level of nesting that we don't want, just above the leaf nodes.
|
|
66
|
+
const rootNode = hierarchy(nestedData);
|
|
67
|
+
// Compute the aggregation
|
|
68
|
+
if (config.value) {
|
|
69
|
+
rootNode.sum(index => typeof index === 'number' && getNumber(data[index], config.value, index));
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
rootNode.count();
|
|
73
|
+
}
|
|
74
|
+
// Fix the hierarchy by removing the extra level of nesting
|
|
75
|
+
rootNode.each(node => {
|
|
76
|
+
if (!node.children && node.parent) {
|
|
77
|
+
node.parent.children = null;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
const treemapLayout = treemap()
|
|
81
|
+
.size([_width, _height])
|
|
82
|
+
.round(true)
|
|
83
|
+
.padding(config.tilePadding);
|
|
84
|
+
// Apply padding to the top of each tile,
|
|
85
|
+
// but not for the root node.
|
|
86
|
+
if (this.config.tilePaddingTop !== undefined) {
|
|
87
|
+
treemapLayout.paddingTop(d => d.parent ? config.tilePaddingTop : 0);
|
|
88
|
+
}
|
|
89
|
+
// Compute the treemap layout
|
|
90
|
+
const treemapData = treemapLayout(rootNode);
|
|
91
|
+
// Process the resulting hierarchy into the type we need
|
|
92
|
+
let nodeId = 0;
|
|
93
|
+
treemapData.each(node => {
|
|
94
|
+
const n = node;
|
|
95
|
+
// Generate unique IDs for each node
|
|
96
|
+
node._id = `node-${nodeId++}`;
|
|
97
|
+
const treemapDatum = {
|
|
98
|
+
key: n.data[0],
|
|
99
|
+
};
|
|
100
|
+
// Populate the index and datum for leaf nodes
|
|
101
|
+
const isLeafNode = !n.children;
|
|
102
|
+
if (isLeafNode) {
|
|
103
|
+
treemapDatum.index = n.data[1][0];
|
|
104
|
+
treemapDatum.datum = data[treemapDatum.index];
|
|
105
|
+
}
|
|
106
|
+
node.data = treemapDatum;
|
|
107
|
+
});
|
|
108
|
+
const descendants = treemapData.descendants();
|
|
109
|
+
// Set up the brightness increase scale based on depth
|
|
110
|
+
const maxDepth = max(descendants, d => d.depth);
|
|
111
|
+
const brightnessIncrease = scaleLinear()
|
|
112
|
+
.domain([1, maxDepth])
|
|
113
|
+
.range([0, 1]);
|
|
114
|
+
// Get all leaf node values and calculate their square roots
|
|
115
|
+
// (since area is proportional to value)
|
|
116
|
+
const leafValues = descendants.filter(d => !d.children).map(d => d.value);
|
|
117
|
+
const maxLeafValue = Math.sqrt(max(leafValues)) || 0;
|
|
118
|
+
// Divide the range into three equal intervals based on the square root of values
|
|
119
|
+
// This accounts for the fact that area is proportional to value
|
|
120
|
+
const fontSizeScale = scaleThreshold()
|
|
121
|
+
.domain([
|
|
122
|
+
maxLeafValue / 3,
|
|
123
|
+
(maxLeafValue * 2) / 3, // Second third of the max value
|
|
124
|
+
])
|
|
125
|
+
.range([
|
|
126
|
+
config.tileLabelSmallFontSize,
|
|
127
|
+
config.tileLabelMediumFontSize,
|
|
128
|
+
config.tileLabelLargeFontSize,
|
|
129
|
+
]);
|
|
130
|
+
// First pass: Set base colors without considering tileColor config
|
|
131
|
+
treemapData.eachBefore((node) => {
|
|
132
|
+
var _a, _b, _c;
|
|
133
|
+
// Get base color: user accessor or default
|
|
134
|
+
let color = config.tileColor
|
|
135
|
+
? getColor(node, config.tileColor)
|
|
136
|
+
: getColor(node, undefined, (_b = (_a = node.parent) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b.indexOf(node), node.depth !== 1);
|
|
137
|
+
// Fallback to parent color if needed
|
|
138
|
+
color = color !== null && color !== void 0 ? color : (_c = node.parent) === null || _c === void 0 ? void 0 : _c._fill;
|
|
139
|
+
const hexColor = color ? getHexValue(color, this.g.node()) : null;
|
|
140
|
+
if (hexColor) {
|
|
141
|
+
const hslColor = hsl(hexColor);
|
|
142
|
+
// Lightness adjustment for siblings (if enabled)
|
|
143
|
+
if (config.enableLightnessVariance && !node.children && node.parent) {
|
|
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));
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
node._fill = null;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
// Render tiles
|
|
156
|
+
const visibleNodes = descendants.filter(d => d.depth > 0);
|
|
157
|
+
const tiles = this.tiles
|
|
158
|
+
.selectAll(`g.${tileGroup}`)
|
|
159
|
+
.data(visibleNodes, d => `${d.data.key}-${d.depth}`);
|
|
160
|
+
const tilesEnter = tiles
|
|
161
|
+
.enter()
|
|
162
|
+
.append('g')
|
|
163
|
+
.attr('class', tileGroup);
|
|
164
|
+
// Computes the rect border radius for a given tile.
|
|
165
|
+
// The rx and ry values are the minimum of the tile
|
|
166
|
+
// border radius and some fraction the width of the tile,
|
|
167
|
+
// based on the tileBorderRadiusFactor config.
|
|
168
|
+
// This ensures that the tile border radius is not
|
|
169
|
+
// larger than the tile size, which makes small tiles
|
|
170
|
+
// look better.
|
|
171
|
+
const rx = (d) => Math.min(config.tileBorderRadius, (d.x1 - d.x0) * config.tileBorderRadiusFactor);
|
|
172
|
+
// Tile rectangles
|
|
173
|
+
tilesEnter
|
|
174
|
+
.append('rect')
|
|
175
|
+
.classed(tile, true)
|
|
176
|
+
// Make the leaf tiles clickable if a click handler is provided
|
|
177
|
+
.classed(clickableTile, d => config.showTileClickAffordance && !d.children)
|
|
178
|
+
.attr('rx', rx)
|
|
179
|
+
.attr('ry', rx)
|
|
180
|
+
// Initialize tile positions so that the initial transition is smooth
|
|
181
|
+
.attr('x', d => d.x0)
|
|
182
|
+
.attr('y', d => d.y0)
|
|
183
|
+
.attr('width', d => d.x1 - d.x0)
|
|
184
|
+
.attr('height', d => d.y1 - d.y0)
|
|
185
|
+
.style('fill', d => { var _a; return (_a = d._fill) !== null && _a !== void 0 ? _a : getColor(d, config.tileColor); })
|
|
186
|
+
.style('opacity', 0)
|
|
187
|
+
.style('cursor', config.showTileClickAffordance ? d => !d.children ? 'pointer' : null : null);
|
|
188
|
+
const mergedTiles = tiles.merge(tilesEnter);
|
|
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();
|
|
217
|
+
tilesEnter
|
|
218
|
+
.append('g')
|
|
219
|
+
.attr('class', labelGroup)
|
|
220
|
+
.attr('transform', d => `translate(${d.x0 + config.labelOffsetX},${d.y0 + config.labelOffsetY})`)
|
|
221
|
+
.append('text')
|
|
222
|
+
.attr('class', label)
|
|
223
|
+
.attr('x', 0)
|
|
224
|
+
.attr('y', 0)
|
|
225
|
+
.style('opacity', 0);
|
|
226
|
+
const getTileLabel = (_b = config.tileLabel) !== null && _b !== void 0 ? _b : ((d) => `${d.data.key}: ${formatNumber(d.value)}`);
|
|
227
|
+
const textSelection = mergedTiles.selectAll(`g.${labelGroup} text`);
|
|
228
|
+
textSelection
|
|
229
|
+
.text(d => getTileLabel(d))
|
|
230
|
+
.style('font-size', function (d) {
|
|
231
|
+
var _a;
|
|
232
|
+
const sqrtVal = Math.sqrt((_a = d.value) !== null && _a !== void 0 ? _a : 0);
|
|
233
|
+
return config.enableTileLabelFontSizeVariation && !d.children
|
|
234
|
+
? `${fontSizeScale(sqrtVal)}px`
|
|
235
|
+
: `${fontSizeScale.range()[1]}px`;
|
|
236
|
+
})
|
|
237
|
+
.attr('dominant-baseline', 'middle');
|
|
238
|
+
// Trim label and set dominant-baseline for tspans in one pass
|
|
239
|
+
textSelection.each((d, i, nodes) => {
|
|
240
|
+
var _a;
|
|
241
|
+
const text = select(nodes[i]);
|
|
242
|
+
const tileWidth = d.x1 - d.x0 - ((_a = config.labelOffsetX) !== null && _a !== void 0 ? _a : 0) * 2;
|
|
243
|
+
const fullLabel = text.text();
|
|
244
|
+
let fontSize = parseFloat(text.style('font-size'));
|
|
245
|
+
if (!fontSize) {
|
|
246
|
+
fontSize = parseFloat(window.getComputedStyle(nodes[i]).fontSize);
|
|
247
|
+
}
|
|
248
|
+
trimSVGText(text, tileWidth, TrimMode.End, true, fontSize);
|
|
249
|
+
text.attr('title', fullLabel);
|
|
250
|
+
text.selectAll('tspan').attr('dominant-baseline', 'middle');
|
|
251
|
+
});
|
|
252
|
+
// Transition group position
|
|
253
|
+
smartTransition(mergedTiles.select(`g.${labelGroup}`), duration)
|
|
254
|
+
.attr('transform', d => `translate(${d.x0 + config.labelOffsetX},${d.y0 + config.labelOffsetY})`);
|
|
255
|
+
// Transition text opacity only (fade-in)
|
|
256
|
+
smartTransition(mergedTiles.select(`g.${labelGroup} text`), duration)
|
|
257
|
+
.style('opacity', 1);
|
|
258
|
+
// Hide labels that don't meet criteria
|
|
259
|
+
mergedTiles.select(`text.${label}`)
|
|
260
|
+
.style('display', d => {
|
|
261
|
+
const isAllowedNode = config.labelInternalNodes ? true : !d.children;
|
|
262
|
+
return isAllowedNode && this._isTileLargeEnough(d) ? null : 'none';
|
|
263
|
+
})
|
|
264
|
+
// Make the internal labels semibold via class
|
|
265
|
+
.attr('class', d => d.children ? `${label} ${internalLabel}` : label);
|
|
266
|
+
smartTransition(tiles.exit(), duration)
|
|
267
|
+
.style('opacity', 0)
|
|
268
|
+
.remove();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
Treemap.selectors = style;
|
|
272
|
+
|
|
273
|
+
export { Treemap };
|
|
274
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const root: string;
|
|
2
|
+
export declare const variables: {
|
|
3
|
+
treemapTileStrokeColor: "--vis-treemap-tile-stroke-color";
|
|
4
|
+
treemapTileStrokeWidth: "--vis-treemap-tile-stroke-width";
|
|
5
|
+
treemapTileHoverStrokeColor: "--vis-treemap-tile-hover-stroke-color";
|
|
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
|
+
treemapLabelOpacity: "--vis-treemap-label-opacity";
|
|
13
|
+
treemapLabelFontWeight: "--vis-treemap-label-font-weight";
|
|
14
|
+
darkTreemapTileStrokeColor: "--vis-dark-treemap-tile-stroke-color";
|
|
15
|
+
darkTreemapTileFillColor: "--vis-dark-treemap-tile-fill-color";
|
|
16
|
+
darkTreemapLabelTextColor: "--vis-dark-treemap-label-text-color";
|
|
17
|
+
};
|
|
18
|
+
export declare const tiles: string;
|
|
19
|
+
export declare const tileGroup: string;
|
|
20
|
+
export declare const tile: string;
|
|
21
|
+
export declare const clickableTile: string;
|
|
22
|
+
export declare const tileForeground: string;
|
|
23
|
+
export declare const label: string;
|
|
24
|
+
export declare const internalLabel: string;
|
|
25
|
+
export declare const labelGroup: string;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { css } from '@emotion/css';
|
|
2
|
+
import { getCssVarNames, injectGlobalCssVariables } from '../../utils/style.js';
|
|
3
|
+
|
|
4
|
+
const cssVarDefaults = {
|
|
5
|
+
'--vis-treemap-tile-stroke-color': '#fff',
|
|
6
|
+
'--vis-treemap-tile-stroke-width': '2px',
|
|
7
|
+
'--vis-treemap-tile-hover-stroke-color': '#fff',
|
|
8
|
+
'--vis-treemap-tile-hover-stroke-opacity': 0,
|
|
9
|
+
'--vis-treemap-tile-fill-color': '#B9BEC3',
|
|
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 */
|
|
15
|
+
'--vis-treemap-label-opacity': 0.8,
|
|
16
|
+
'--vis-treemap-label-font-weight': 'normal',
|
|
17
|
+
/* Dark Theme */
|
|
18
|
+
'--vis-dark-treemap-tile-stroke-color': '#2c2c2c',
|
|
19
|
+
'--vis-dark-treemap-tile-fill-color': '#5b5f6d',
|
|
20
|
+
'--vis-dark-treemap-label-text-color': '#5b5f6d',
|
|
21
|
+
};
|
|
22
|
+
const root = css `
|
|
23
|
+
label: treemap-component;
|
|
24
|
+
`;
|
|
25
|
+
const variables = getCssVarNames(cssVarDefaults);
|
|
26
|
+
injectGlobalCssVariables(cssVarDefaults, root);
|
|
27
|
+
const tiles = css `
|
|
28
|
+
label: g-tiles;
|
|
29
|
+
`;
|
|
30
|
+
const tileGroup = css `
|
|
31
|
+
label: tile-group;
|
|
32
|
+
`;
|
|
33
|
+
const tile = css `
|
|
34
|
+
label: tile;
|
|
35
|
+
stroke: var(${variables.treemapTileHoverStrokeColor});
|
|
36
|
+
stroke-opacity: 0;
|
|
37
|
+
|
|
38
|
+
&:hover {
|
|
39
|
+
stroke-opacity: var(--vis-treemap-tile-hover-stroke-opacity);
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
// The leaf tiles are clickable
|
|
43
|
+
const clickableTile = css `
|
|
44
|
+
label: clickable-tile;
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
`;
|
|
47
|
+
const tileForeground = css `
|
|
48
|
+
label: tile-foreground;
|
|
49
|
+
`;
|
|
50
|
+
const label = css `
|
|
51
|
+
label: label;
|
|
52
|
+
text-anchor: start;
|
|
53
|
+
dominant-baseline: hanging;
|
|
54
|
+
user-select: none;
|
|
55
|
+
pointer-events: none;
|
|
56
|
+
font-size: var(--vis-treemap-label-font-size);
|
|
57
|
+
opacity: var(--vis-treemap-label-opacity);
|
|
58
|
+
fill: var(--vis-treemap-label-text-color);
|
|
59
|
+
font-weight: var(--vis-treemap-label-font-weight);
|
|
60
|
+
`;
|
|
61
|
+
const internalLabel = css `
|
|
62
|
+
font-weight: 500;
|
|
63
|
+
`;
|
|
64
|
+
const labelGroup = css `
|
|
65
|
+
label: label-group;
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
export { clickableTile, internalLabel, label, labelGroup, root, tile, tileForeground, tileGroup, tiles, variables };
|
|
69
|
+
//# sourceMappingURL=style.js.map
|
|
@@ -0,0 +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 '--vis-treemap-tile-fill-color': '#B9BEC3',\n '--vis-treemap-tile-background-color': '#fff',\n '--vis-treemap-tile-cursor': 'default',\n '--vis-treemap-label-text-color': '#000',\n '--vis-treemap-label-font-size': '12px',\n\n /* Label opacity */\n '--vis-treemap-label-opacity': 0.8,\n '--vis-treemap-label-font-weight': 'normal',\n\n /* Dark Theme */\n '--vis-dark-treemap-tile-stroke-color': '#2c2c2c',\n '--vis-dark-treemap-tile-fill-color': '#5b5f6d',\n '--vis-dark-treemap-label-text-color': '#5b5f6d',\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(--vis-treemap-tile-hover-stroke-opacity);\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(--vis-treemap-label-font-size);\n opacity: var(--vis-treemap-label-opacity);\n fill: var(--vis-treemap-label-text-color);\n font-weight: var(--vis-treemap-label-font-weight);\n`\n\nexport const internalLabel = css`\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;AAC5C,IAAA,+BAA+B,EAAE,SAAS;AAC1C,IAAA,qCAAqC,EAAE,MAAM;AAC7C,IAAA,2BAA2B,EAAE,SAAS;AACtC,IAAA,gCAAgC,EAAE,MAAM;AACxC,IAAA,+BAA+B,EAAE,MAAM;;AAGvC,IAAA,6BAA6B,EAAE,GAAG;AAClC,IAAA,iCAAiC,EAAE,QAAQ;;AAG3C,IAAA,sCAAsC,EAAE,SAAS;AACjD,IAAA,oCAAoC,EAAE,SAAS;AAC/C,IAAA,qCAAqC,EAAE,SAAS;CACjD,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;;;;;;EAMpD;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;;;;;;;;;;EAUvB;AAEM,MAAM,aAAa,GAAG,GAAG,CAAA,CAAA;;EAE/B;AAEM,MAAM,UAAU,GAAG,GAAG,CAAA,CAAA;;;;;;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HierarchyRectangularNode } from 'd3-hierarchy';
|
|
2
|
+
export declare type TreemapDatum<Datum> = {
|
|
3
|
+
key?: string;
|
|
4
|
+
index?: number;
|
|
5
|
+
datum?: Datum;
|
|
6
|
+
};
|
|
7
|
+
export interface TreemapNode<Datum> extends HierarchyRectangularNode<TreemapDatum<Datum>> {
|
|
8
|
+
_id: string;
|
|
9
|
+
_fill?: string;
|
|
10
|
+
_fillOpacity?: number | null;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -41,7 +41,7 @@ class XYLabels extends XYComponentCore {
|
|
|
41
41
|
var _a, _b;
|
|
42
42
|
const { config, datamodel } = this;
|
|
43
43
|
const xRange = this.xScale.range();
|
|
44
|
-
const yRange = this.
|
|
44
|
+
const yRange = this.yScale.range();
|
|
45
45
|
const labels = (_b = (_a = datamodel.data) === null || _a === void 0 ? void 0 : _a.reduce((acc, d) => {
|
|
46
46
|
const xPositioning = getValue(d, config.xPositioning);
|
|
47
47
|
const yPositioning = getValue(d, config.yPositioning);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/xy-labels/index.ts"],"sourcesContent":["// Core\nimport { XYComponentCore } from 'core/xy-component'\n\n// Utils\nimport { getValue, isNumber, isNumberWithinRange } from 'utils/data'\nimport { rectIntersect } from 'utils/misc'\n\n// Local Types\nimport { XYLabelCluster, XYLabel, XYLabelPositioning } from './types'\n\n// Config\nimport { XYLabelsDefaultConfig, XYLabelsConfigInterface } from './config'\n\n// Modules\nimport { createLabels, updateLabels, removeLabels, getLabelRenderProps } from './modules/label'\n\n// Styles\nimport * as s from './style'\n\nexport class XYLabels<Datum> extends XYComponentCore<Datum, XYLabelsConfigInterface<Datum>> {\n static selectors = s\n clippable = false\n protected _defaultConfig = XYLabelsDefaultConfig as XYLabelsConfigInterface<Datum>\n public config: XYLabelsConfigInterface<Datum> = this._defaultConfig\n\n events = {\n [XYLabels.selectors.label]: {},\n }\n\n constructor (config?: XYLabelsConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n }\n\n _render (customDuration?: number): void {\n const { config } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n const labelGroups = this.g\n .selectAll<SVGGElement, XYLabel<Datum> | XYLabelCluster<Datum>>(`.${s.labelGroup}`)\n .data(this._getDataToRender())\n\n const labelGroupsExit = labelGroups.exit<XYLabel<Datum> | XYLabelCluster<Datum>>()\n removeLabels(labelGroupsExit, duration)\n\n const labelGroupsEnter = labelGroups.enter().append('g')\n .attr('class', s.labelGroup)\n .call(createLabels)\n\n const labelGroupsMerged = labelGroupsEnter\n .merge(labelGroups)\n .classed(s.cluster, d => !!(d as XYLabelCluster<Datum>).records)\n .classed(s.label, d => !(d as XYLabelCluster<Datum>).records)\n\n labelGroupsMerged.call(updateLabels, config, duration)\n }\n\n private _getDataToRender (): (XYLabel<Datum> | XYLabelCluster<Datum>)[] {\n const { config, datamodel } = this\n\n const xRange = this.xScale.range() as [number, number]\n const yRange = this.
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/xy-labels/index.ts"],"sourcesContent":["// Core\nimport { XYComponentCore } from 'core/xy-component'\n\n// Utils\nimport { getValue, isNumber, isNumberWithinRange } from 'utils/data'\nimport { rectIntersect } from 'utils/misc'\n\n// Local Types\nimport { XYLabelCluster, XYLabel, XYLabelPositioning } from './types'\n\n// Config\nimport { XYLabelsDefaultConfig, XYLabelsConfigInterface } from './config'\n\n// Modules\nimport { createLabels, updateLabels, removeLabels, getLabelRenderProps } from './modules/label'\n\n// Styles\nimport * as s from './style'\n\nexport class XYLabels<Datum> extends XYComponentCore<Datum, XYLabelsConfigInterface<Datum>> {\n static selectors = s\n clippable = false\n protected _defaultConfig = XYLabelsDefaultConfig as XYLabelsConfigInterface<Datum>\n public config: XYLabelsConfigInterface<Datum> = this._defaultConfig\n\n events = {\n [XYLabels.selectors.label]: {},\n }\n\n constructor (config?: XYLabelsConfigInterface<Datum>) {\n super()\n if (config) this.setConfig(config)\n }\n\n _render (customDuration?: number): void {\n const { config } = this\n const duration = isNumber(customDuration) ? customDuration : config.duration\n\n const labelGroups = this.g\n .selectAll<SVGGElement, XYLabel<Datum> | XYLabelCluster<Datum>>(`.${s.labelGroup}`)\n .data(this._getDataToRender())\n\n const labelGroupsExit = labelGroups.exit<XYLabel<Datum> | XYLabelCluster<Datum>>()\n removeLabels(labelGroupsExit, duration)\n\n const labelGroupsEnter = labelGroups.enter().append('g')\n .attr('class', s.labelGroup)\n .call(createLabels)\n\n const labelGroupsMerged = labelGroupsEnter\n .merge(labelGroups)\n .classed(s.cluster, d => !!(d as XYLabelCluster<Datum>).records)\n .classed(s.label, d => !(d as XYLabelCluster<Datum>).records)\n\n labelGroupsMerged.call(updateLabels, config, duration)\n }\n\n private _getDataToRender (): (XYLabel<Datum> | XYLabelCluster<Datum>)[] {\n const { config, datamodel } = this\n\n const xRange = this.xScale.range() as [number, number]\n const yRange = this.yScale.range() as [number, number]\n\n const labels = datamodel.data?.reduce<XYLabel<Datum>[]>((acc, d) => {\n const xPositioning = getValue<Datum, XYLabelPositioning>(d, config.xPositioning)\n const yPositioning = getValue<Datum, XYLabelPositioning>(d, config.yPositioning)\n const props = getLabelRenderProps(d, this.element, config, this.xScale, this.yScale)\n\n if (\n ((xPositioning !== XYLabelPositioning.DataSpace) || isNumberWithinRange(props.x, xRange)) &&\n ((yPositioning !== XYLabelPositioning.DataSpace) || isNumberWithinRange(props.y, yRange))\n ) {\n acc.push({ ...d, _screen: props })\n }\n\n return acc\n }, []) ?? []\n\n return config.clustering ? this._getClusteredLabels(labels) : labels\n }\n\n private _getClusteredLabels (labels: XYLabel<Datum>[]): (XYLabel<Datum> | XYLabelCluster<Datum>)[] {\n const labelsNonOverlapping = [...labels]\n const clusterMap = new Map<XYLabel<Datum>, XYLabel<Datum>[]>()\n for (let i = 0; i < labelsNonOverlapping.length; i += 1) {\n const label1 = labelsNonOverlapping[i]\n for (let j = i + 1; j < labelsNonOverlapping.length; j += 1) {\n const label2 = labelsNonOverlapping[j]\n const isIntersecting = rectIntersect(label1._screen, label2._screen)\n if (isIntersecting) {\n if (!clusterMap.has(label1)) clusterMap.set(label1, [label1])\n clusterMap.get(label1).push(label2)\n labelsNonOverlapping.splice(j, 1)\n j -= 1\n }\n }\n\n if (clusterMap.has(label1)) {\n labelsNonOverlapping.splice(i, 1)\n i -= 1\n }\n }\n\n const clusters = Array.from(clusterMap.values()).map(records => ({\n _screen: getLabelRenderProps(records, this.element, this.config, this.xScale, this.yScale),\n records,\n }))\n\n return [...labelsNonOverlapping, ...clusters]\n }\n}\n"],"names":["s.labelGroup","s.cluster","s.label","s"],"mappings":"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"}
|