@cdx-ui/components 0.3.13 → 0.3.14
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/coverage.svg +1 -1
- package/docs/components/alert-dialog/content.md +359 -0
- package/docs/components/bar-chart/content.md +108 -2
- package/docs/components/dialog/content.md +468 -13
- package/docs/components/line-chart/content.md +1 -0
- package/docs/foundations/expressions/icons/content.md +1 -1
- package/docs/llms.txt +1 -0
- package/docs/resources/release-notes/0.3.13/content.md +21 -0
- package/docs/resources/release-notes/content.md +1 -0
- package/lib/commonjs/components/BarChart/geometry.js +95 -10
- package/lib/commonjs/components/BarChart/geometry.js.map +1 -1
- package/lib/commonjs/components/BarChart/index.js +8 -6
- package/lib/commonjs/components/BarChart/index.js.map +1 -1
- package/lib/module/components/BarChart/geometry.js +93 -9
- package/lib/module/components/BarChart/geometry.js.map +1 -1
- package/lib/module/components/BarChart/index.js +9 -7
- package/lib/module/components/BarChart/index.js.map +1 -1
- package/lib/typescript/components/BarChart/geometry.d.ts +19 -2
- package/lib/typescript/components/BarChart/geometry.d.ts.map +1 -1
- package/lib/typescript/components/BarChart/index.d.ts +4 -2
- package/lib/typescript/components/BarChart/index.d.ts.map +1 -1
- package/lib/typescript/components/chart/types.d.ts +7 -0
- package/lib/typescript/components/chart/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/components/BarChart/geometry.ts +126 -10
- package/src/components/BarChart/index.tsx +24 -16
- package/src/components/chart/types.ts +7 -0
|
@@ -57,14 +57,16 @@ export interface BarChartProps<TRow extends object = object> extends ViewProps,
|
|
|
57
57
|
/**
|
|
58
58
|
* Horizontal axis. In `vertical` layout it is the category (band) axis: `dataKey` names the
|
|
59
59
|
* category column, `position` (`'bottom'`, `'top'`, `'none'`) places its labels, and
|
|
60
|
-
* `tickLabelInterval` picks which labels draw
|
|
60
|
+
* `tickLabelInterval` picks which labels draw, and `tickLabelMaxLines` caps how far a long
|
|
61
|
+
* name wraps before it ends in `…`. In `horizontal` layout it is the value axis.
|
|
61
62
|
* Only the first axis is used.
|
|
62
63
|
*/
|
|
63
64
|
xAxis?: readonly ChartAxis<TRow>[];
|
|
64
65
|
/**
|
|
65
66
|
* Vertical axis. In `vertical` layout it is the value axis (`min`, `max`, `tickNumber`,
|
|
66
67
|
* `valueFormatter`; `position: 'none'` hides its ticks). In `horizontal` layout it is the
|
|
67
|
-
* category axis (`position` `'left'`, `'right'`, or `'none'`
|
|
68
|
+
* category axis (`position` `'left'`, `'right'`, or `'none'`; `tickLabelMaxLines` as on
|
|
69
|
+
* `xAxis`). Only the first axis is used.
|
|
68
70
|
*/
|
|
69
71
|
yAxis?: readonly ChartAxis<TRow>[];
|
|
70
72
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/BarChart/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,YAAY,EACjB,KAAK,YAAY,EAElB,MAAM,OAAO,CAAC;AACf,OAAO,EAGL,IAAI,EAGJ,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAKtB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAc/D,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,cAAc,EAGd,iBAAiB,EAGlB,MAAM,gBAAgB,CAAC;AAQxB,OAAO,EAWL,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/BarChart/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -69,6 +69,13 @@ export interface ChartAxis<TRow> {
|
|
|
69
69
|
* @default 'auto'
|
|
70
70
|
*/
|
|
71
71
|
tickLabelInterval?: 'auto' | ((value: unknown, index: number) => boolean);
|
|
72
|
+
/**
|
|
73
|
+
* Most lines a category name may wrap onto before it ends in `…`. `1` truncates without
|
|
74
|
+
* wrapping. Read by `BarChart` on its category axis; a horizontal chart also stops at the
|
|
75
|
+
* lines its rows are tall enough to hold. Forge only; MUI X has no equivalent.
|
|
76
|
+
* @default 2
|
|
77
|
+
*/
|
|
78
|
+
tickLabelMaxLines?: number;
|
|
72
79
|
}
|
|
73
80
|
export type ChartAxisPosition = 'top' | 'bottom' | 'left' | 'right' | 'none';
|
|
74
81
|
/** Grid lines across the plot. A chart draws the lines that run along its value axis. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/chart/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,wCAAwC;AACxC,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAEvE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,OAAO,EAAE,0BAA0B,KAChC,MAAM,CAAC;AAEZ,4DAA4D;AAC5D,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iGAAiG;IACjG,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB;;;;OAIG;IACH,cAAc,CAAC,EAAE,mBAAmB,CAAC;CACtC;AAED,6DAA6D;AAC7D,MAAM,WAAW,eAAe,CAAC,IAAI,CAAE,SAAQ,iBAAiB;IAC9D,yFAAyF;IACzF,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE/C,MAAM,WAAW,SAAS,CAAC,IAAI;IAC7B,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,MAAM,CAAC;IAC9B,+EAA+E;IAC/E,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/chart/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdx-ui/components",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.14",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -106,10 +106,10 @@
|
|
|
106
106
|
"@marceloterreiro/flash-calendar": "2.0.0",
|
|
107
107
|
"react-native-reanimated-carousel": "5.0.0-beta.5",
|
|
108
108
|
"uniwind": "1.12.2",
|
|
109
|
-
"@cdx-ui/
|
|
110
|
-
"@cdx-ui/
|
|
111
|
-
"@cdx-ui/
|
|
112
|
-
"@cdx-ui/utils": "0.3.
|
|
109
|
+
"@cdx-ui/primitives": "0.3.14",
|
|
110
|
+
"@cdx-ui/formatters": "0.3.14",
|
|
111
|
+
"@cdx-ui/icons": "0.3.14",
|
|
112
|
+
"@cdx-ui/utils": "0.3.14"
|
|
113
113
|
},
|
|
114
114
|
"devDependencies": {
|
|
115
115
|
"@dnd-kit/core": "6.3.1",
|
|
@@ -74,6 +74,12 @@ export interface BarLabelAnchor {
|
|
|
74
74
|
readonly textAnchor: 'start' | 'middle' | 'end';
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
/** A category name fitted to its slot. `y` is the first line; each next line sits one line lower. */
|
|
78
|
+
export interface BarCategoryLabel extends BarLabelAnchor {
|
|
79
|
+
/** Up to two lines. The last line ends in `…` when the name did not fit. */
|
|
80
|
+
readonly lines: readonly string[];
|
|
81
|
+
}
|
|
82
|
+
|
|
77
83
|
export interface BarValueTick {
|
|
78
84
|
readonly value: number;
|
|
79
85
|
readonly x: number;
|
|
@@ -94,7 +100,7 @@ export interface BarReferenceLineLayout extends BarGridLine {
|
|
|
94
100
|
|
|
95
101
|
export interface BarChartLayout {
|
|
96
102
|
readonly bars: BarRect[];
|
|
97
|
-
readonly categoryLabels:
|
|
103
|
+
readonly categoryLabels: BarCategoryLabel[];
|
|
98
104
|
readonly valueTicks: BarValueTick[];
|
|
99
105
|
readonly gridLines: BarGridLine[];
|
|
100
106
|
readonly referenceLines: readonly BarReferenceLineLayout[];
|
|
@@ -373,6 +379,12 @@ function categoryLabelPadding(
|
|
|
373
379
|
const CATEGORY_EDGE_GUTTER = 28;
|
|
374
380
|
/** Average `text-xs` glyph width; SVG text cannot be measured before layout. */
|
|
375
381
|
const CATEGORY_LABEL_CHAR_WIDTH = 6.5;
|
|
382
|
+
/** Line pitch for a wrapped category name at `text-xs`. */
|
|
383
|
+
export const CATEGORY_LABEL_LINE_HEIGHT = 14;
|
|
384
|
+
/** Default for `ChartAxis.tickLabelMaxLines`. */
|
|
385
|
+
export const CATEGORY_LABEL_MAX_LINES = 2;
|
|
386
|
+
/** Space kept clear between neighboring category names. */
|
|
387
|
+
const CATEGORY_LABEL_GAP = 4;
|
|
376
388
|
const VALUE_TICK_LEFT = 40;
|
|
377
389
|
const VALUE_TICK_END = 28;
|
|
378
390
|
const TIGHT_GUTTER = 8;
|
|
@@ -383,6 +395,30 @@ const VALUES_TOP_GUTTER = 36;
|
|
|
383
395
|
const PLOT_END_GUTTER = 20;
|
|
384
396
|
const NEGATIVE_VALUES_GUTTER = 16;
|
|
385
397
|
|
|
398
|
+
/**
|
|
399
|
+
* Breaks a category name into lines no wider than `maxWidth`, at word boundaries. Text that
|
|
400
|
+
* still does not fit in `maxLines` ends in `…`; the full name stays on the bar's accessibility
|
|
401
|
+
* label and tooltip.
|
|
402
|
+
*/
|
|
403
|
+
export function fitCategoryLabel(label: string, maxWidth: number, maxLines: number): string[] {
|
|
404
|
+
const perLine = Math.max(Math.floor(maxWidth / CATEGORY_LABEL_CHAR_WIDTH), 1);
|
|
405
|
+
if (label.length <= perLine) {
|
|
406
|
+
return [label];
|
|
407
|
+
}
|
|
408
|
+
const lines: string[] = [];
|
|
409
|
+
let rest = label.trim();
|
|
410
|
+
while (lines.length < maxLines - 1 && rest.length > perLine) {
|
|
411
|
+
const cut = rest.lastIndexOf(' ', perLine);
|
|
412
|
+
if (cut <= 0) {
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
lines.push(rest.slice(0, cut).trimEnd());
|
|
416
|
+
rest = rest.slice(cut + 1).trimStart();
|
|
417
|
+
}
|
|
418
|
+
lines.push(rest.length <= perLine ? rest : `${rest.slice(0, perLine - 1).trimEnd()}…`);
|
|
419
|
+
return lines;
|
|
420
|
+
}
|
|
421
|
+
|
|
386
422
|
export function resolveCategoryLabelPosition(
|
|
387
423
|
orientation: BarChartOrientation,
|
|
388
424
|
position: BarChartCategoryLabelPosition | undefined,
|
|
@@ -919,6 +955,50 @@ export function barPath(bar: BarShape, orientation: BarChartOrientation, radius:
|
|
|
919
955
|
return `M ${String(x2)} ${String(y)} L ${String(x2)} ${String(y2)} L ${String(x + r)} ${String(y2)} Q ${String(x)} ${String(y2)} ${String(x)} ${String(y2 - r)} L ${String(x)} ${String(y + r)} Q ${String(x)} ${String(y)} ${String(x + r)} ${String(y)} Z`;
|
|
920
956
|
}
|
|
921
957
|
|
|
958
|
+
/**
|
|
959
|
+
* Fits each shown category name to the room it has. Vertical names get their slot plus any
|
|
960
|
+
* empty slots up to the nearest shown neighbor, so thinned labels may spread wider. Horizontal
|
|
961
|
+
* names get the side gutter, and wrap only onto as many lines as the row is tall enough for.
|
|
962
|
+
*/
|
|
963
|
+
function fitCategoryLabels({
|
|
964
|
+
labels,
|
|
965
|
+
orientation,
|
|
966
|
+
position,
|
|
967
|
+
band,
|
|
968
|
+
sideGutter,
|
|
969
|
+
maxLines,
|
|
970
|
+
}: {
|
|
971
|
+
readonly labels: readonly string[];
|
|
972
|
+
readonly orientation: BarChartOrientation;
|
|
973
|
+
readonly position: BarChartCategoryLabelPosition;
|
|
974
|
+
readonly band: number;
|
|
975
|
+
readonly sideGutter: number;
|
|
976
|
+
readonly maxLines: number;
|
|
977
|
+
}): string[][] {
|
|
978
|
+
if (position === 'none') {
|
|
979
|
+
return labels.map((label) => [label]);
|
|
980
|
+
}
|
|
981
|
+
if (orientation === 'horizontal') {
|
|
982
|
+
const rowLines = clamp(Math.floor(band / CATEGORY_LABEL_LINE_HEIGHT), 1, maxLines);
|
|
983
|
+
// Labels sit 8px off the plot; keep 8px clear of the chart edge.
|
|
984
|
+
return labels.map((label) => fitCategoryLabel(label, sideGutter - 16, rowLines));
|
|
985
|
+
}
|
|
986
|
+
const shown = labels.flatMap((label, index) => (label.length > 0 ? [index] : []));
|
|
987
|
+
return labels.map((label, index) => {
|
|
988
|
+
if (label.length === 0) {
|
|
989
|
+
return [label];
|
|
990
|
+
}
|
|
991
|
+
const at = shown.indexOf(index);
|
|
992
|
+
const prev = at > 0 ? shown.at(at - 1) : undefined;
|
|
993
|
+
const next = shown.at(at + 1);
|
|
994
|
+
const slots = Math.min(
|
|
995
|
+
prev === undefined ? labels.length : index - prev,
|
|
996
|
+
next === undefined ? labels.length : next - index,
|
|
997
|
+
);
|
|
998
|
+
return fitCategoryLabel(label, band * slots - CATEGORY_LABEL_GAP, maxLines);
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
|
|
922
1002
|
const EMPTY_LAYOUT: BarChartLayout = {
|
|
923
1003
|
bars: [],
|
|
924
1004
|
categoryLabels: [],
|
|
@@ -954,6 +1034,7 @@ export function layoutBarChart({
|
|
|
954
1034
|
categoryGapRatio = CATEGORY_GAP_RATIO,
|
|
955
1035
|
barGapRatio = BAR_GAP_RATIO,
|
|
956
1036
|
showCategoryLabel,
|
|
1037
|
+
categoryLabelMaxLines,
|
|
957
1038
|
}: {
|
|
958
1039
|
readonly dataset: readonly object[];
|
|
959
1040
|
/** One name per row, from the category axis. Defaults to the row index. */
|
|
@@ -977,6 +1058,8 @@ export function layoutBarChart({
|
|
|
977
1058
|
readonly barGapRatio?: number;
|
|
978
1059
|
/** Keeps the category name at `index` when it returns `true`. Others draw no text. */
|
|
979
1060
|
readonly showCategoryLabel?: (index: number) => boolean;
|
|
1061
|
+
/** Most lines per category name before `…`. Values below 1 or not whole read as the default. */
|
|
1062
|
+
readonly categoryLabelMaxLines?: number;
|
|
980
1063
|
}): BarChartLayout {
|
|
981
1064
|
if (width <= 0 || height <= 0 || dataset.length === 0 || series.length === 0) {
|
|
982
1065
|
return EMPTY_LAYOUT;
|
|
@@ -1000,11 +1083,39 @@ export function layoutBarChart({
|
|
|
1000
1083
|
showTicks,
|
|
1001
1084
|
overlay,
|
|
1002
1085
|
});
|
|
1086
|
+
const categoryCount = dataset.length;
|
|
1087
|
+
const plotWidth = Math.max(width - paddingLeft - paddingRight, 0);
|
|
1088
|
+
const shownCategories = resolvedCategories.map((label, index) =>
|
|
1089
|
+
showCategoryLabel === undefined || showCategoryLabel(index) ? label : '',
|
|
1090
|
+
);
|
|
1091
|
+
const labelLines = fitCategoryLabels({
|
|
1092
|
+
labels: shownCategories,
|
|
1093
|
+
orientation,
|
|
1094
|
+
position: labels,
|
|
1095
|
+
band:
|
|
1096
|
+
orientation === 'vertical'
|
|
1097
|
+
? plotWidth / categoryCount
|
|
1098
|
+
: Math.max(height - paddingTop - paddingBottom, 0) / categoryCount,
|
|
1099
|
+
sideGutter: labels === 'right' ? paddingRight : paddingLeft,
|
|
1100
|
+
maxLines:
|
|
1101
|
+
categoryLabelMaxLines !== undefined &&
|
|
1102
|
+
Number.isInteger(categoryLabelMaxLines) &&
|
|
1103
|
+
categoryLabelMaxLines >= 1
|
|
1104
|
+
? categoryLabelMaxLines
|
|
1105
|
+
: CATEGORY_LABEL_MAX_LINES,
|
|
1106
|
+
});
|
|
1107
|
+
// Vertical names that wrap get one more line of gutter on their side of the plot.
|
|
1108
|
+
const wrapGutter =
|
|
1109
|
+
orientation === 'vertical'
|
|
1110
|
+
? CATEGORY_LABEL_LINE_HEIGHT *
|
|
1111
|
+
(labelLines.reduce((max, lines) => Math.max(max, lines.length), 1) - 1)
|
|
1112
|
+
: 0;
|
|
1113
|
+
const plotTop = paddingTop + (labels === 'top' ? wrapGutter : 0);
|
|
1003
1114
|
const plot = {
|
|
1004
1115
|
x: paddingLeft,
|
|
1005
|
-
y:
|
|
1006
|
-
width:
|
|
1007
|
-
height: Math.max(height -
|
|
1116
|
+
y: plotTop,
|
|
1117
|
+
width: plotWidth,
|
|
1118
|
+
height: Math.max(height - plotTop - paddingBottom - (labels === 'bottom' ? wrapGutter : 0), 0),
|
|
1008
1119
|
};
|
|
1009
1120
|
|
|
1010
1121
|
const waterfallSeries = series.at(0);
|
|
@@ -1025,7 +1136,6 @@ export function layoutBarChart({
|
|
|
1025
1136
|
const domainMin = scale.min;
|
|
1026
1137
|
const domainMax = scale.max;
|
|
1027
1138
|
const span = domainMax - domainMin || 1;
|
|
1028
|
-
const categoryCount = dataset.length;
|
|
1029
1139
|
const slotCount = overlay || waterfall ? 1 : groups.length;
|
|
1030
1140
|
const band =
|
|
1031
1141
|
orientation === 'vertical' ? plot.width / categoryCount : plot.height / categoryCount;
|
|
@@ -1046,18 +1156,20 @@ export function layoutBarChart({
|
|
|
1046
1156
|
const valueToX = (value: number) => plot.x + plot.width * toPlot(value);
|
|
1047
1157
|
|
|
1048
1158
|
const bars: BarRect[] = [];
|
|
1049
|
-
const categoryLabels:
|
|
1159
|
+
const categoryLabels: BarCategoryLabel[] = [];
|
|
1050
1160
|
const connectors: BarGridLine[] = [];
|
|
1051
1161
|
let waterfallCursor = 0;
|
|
1052
1162
|
let waterfallPrev: { readonly bar: BarRect; readonly total: number } | null = null;
|
|
1053
1163
|
|
|
1054
1164
|
dataset.forEach((row, index) => {
|
|
1055
1165
|
const label = categoryOf(index);
|
|
1056
|
-
const shownLabel =
|
|
1166
|
+
const shownLabel = shownCategories[index] ?? '';
|
|
1167
|
+
const lines = labelLines[index] ?? [shownLabel];
|
|
1057
1168
|
// With `none`, category names still reach the tooltip and screen readers through the bars.
|
|
1058
1169
|
if (labels !== 'none' && orientation === 'vertical') {
|
|
1059
1170
|
const center = plot.x + index * band + band / 2;
|
|
1060
|
-
const
|
|
1171
|
+
const widest = lines.reduce((max, line) => Math.max(max, line.length), 0);
|
|
1172
|
+
const halfWidth = (widest * CATEGORY_LABEL_CHAR_WIDTH) / 2;
|
|
1061
1173
|
const anchor =
|
|
1062
1174
|
center - halfWidth < plot.x
|
|
1063
1175
|
? { x: plot.x, textAnchor: 'start' as const }
|
|
@@ -1066,15 +1178,19 @@ export function layoutBarChart({
|
|
|
1066
1178
|
: { x: center, textAnchor: 'middle' as const };
|
|
1067
1179
|
categoryLabels.push({
|
|
1068
1180
|
label: shownLabel,
|
|
1181
|
+
lines,
|
|
1069
1182
|
x: round2(anchor.x),
|
|
1070
|
-
y: round2(labels === 'top' ? paddingTop / 2 : height - 8),
|
|
1183
|
+
y: round2(labels === 'top' ? paddingTop / 2 : height - 8 - wrapGutter),
|
|
1071
1184
|
textAnchor: anchor.textAnchor,
|
|
1072
1185
|
});
|
|
1073
1186
|
} else if (labels !== 'none') {
|
|
1074
1187
|
categoryLabels.push({
|
|
1075
1188
|
label: shownLabel,
|
|
1189
|
+
lines,
|
|
1076
1190
|
x: round2(labels === 'right' ? plot.x + plot.width + 8 : plot.x - 8),
|
|
1077
|
-
y: round2(
|
|
1191
|
+
y: round2(
|
|
1192
|
+
plot.y + index * band + band / 2 - ((lines.length - 1) * CATEGORY_LABEL_LINE_HEIGHT) / 2,
|
|
1193
|
+
),
|
|
1078
1194
|
textAnchor: labels === 'right' ? 'start' : 'end',
|
|
1079
1195
|
});
|
|
1080
1196
|
}
|
|
@@ -73,6 +73,7 @@ import {
|
|
|
73
73
|
import {
|
|
74
74
|
BAR_GAP_RATIO,
|
|
75
75
|
CATEGORY_GAP_RATIO,
|
|
76
|
+
CATEGORY_LABEL_LINE_HEIGHT,
|
|
76
77
|
barKeyboardNeighbor,
|
|
77
78
|
barPath,
|
|
78
79
|
barValueAnchor,
|
|
@@ -169,14 +170,16 @@ export interface BarChartProps<TRow extends object = object> extends ViewProps,
|
|
|
169
170
|
/**
|
|
170
171
|
* Horizontal axis. In `vertical` layout it is the category (band) axis: `dataKey` names the
|
|
171
172
|
* category column, `position` (`'bottom'`, `'top'`, `'none'`) places its labels, and
|
|
172
|
-
* `tickLabelInterval` picks which labels draw
|
|
173
|
+
* `tickLabelInterval` picks which labels draw, and `tickLabelMaxLines` caps how far a long
|
|
174
|
+
* name wraps before it ends in `…`. In `horizontal` layout it is the value axis.
|
|
173
175
|
* Only the first axis is used.
|
|
174
176
|
*/
|
|
175
177
|
xAxis?: readonly ChartAxis<TRow>[];
|
|
176
178
|
/**
|
|
177
179
|
* Vertical axis. In `vertical` layout it is the value axis (`min`, `max`, `tickNumber`,
|
|
178
180
|
* `valueFormatter`; `position: 'none'` hides its ticks). In `horizontal` layout it is the
|
|
179
|
-
* category axis (`position` `'left'`, `'right'`, or `'none'`
|
|
181
|
+
* category axis (`position` `'left'`, `'right'`, or `'none'`; `tickLabelMaxLines` as on
|
|
182
|
+
* `xAxis`). Only the first axis is used.
|
|
180
183
|
*/
|
|
181
184
|
yAxis?: readonly ChartAxis<TRow>[];
|
|
182
185
|
/**
|
|
@@ -426,6 +429,7 @@ function BarChartInner<TRow extends object>(
|
|
|
426
429
|
? true
|
|
427
430
|
: (orientation === 'vertical' ? grid.horizontal : grid.vertical) === true;
|
|
428
431
|
const tickLabelInterval = categoryAxis?.tickLabelInterval;
|
|
432
|
+
const tickLabelMaxLines = categoryAxis?.tickLabelMaxLines;
|
|
429
433
|
const categories = useMemo(
|
|
430
434
|
() =>
|
|
431
435
|
dataset.map((row, index) => {
|
|
@@ -555,6 +559,7 @@ function BarChartInner<TRow extends object>(
|
|
|
555
559
|
categoryGapRatio,
|
|
556
560
|
barGapRatio,
|
|
557
561
|
showCategoryLabel,
|
|
562
|
+
categoryLabelMaxLines: tickLabelMaxLines,
|
|
558
563
|
}),
|
|
559
564
|
[
|
|
560
565
|
dataset,
|
|
@@ -575,6 +580,7 @@ function BarChartInner<TRow extends object>(
|
|
|
575
580
|
categoryGapRatio,
|
|
576
581
|
barGapRatio,
|
|
577
582
|
showCategoryLabel,
|
|
583
|
+
tickLabelMaxLines,
|
|
578
584
|
],
|
|
579
585
|
);
|
|
580
586
|
const overflowsX = content.width > viewportWidth + 0.5;
|
|
@@ -1050,20 +1056,22 @@ function BarPlot({
|
|
|
1050
1056
|
/>
|
|
1051
1057
|
);
|
|
1052
1058
|
})}
|
|
1053
|
-
{layout.categoryLabels.
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1059
|
+
{layout.categoryLabels.flatMap((item, index) =>
|
|
1060
|
+
item.lines.map((line, lineIndex) => (
|
|
1061
|
+
<SvgText
|
|
1062
|
+
key={`cat-${String(index)}-${String(lineIndex)}-${item.label}`}
|
|
1063
|
+
x={item.x}
|
|
1064
|
+
y={item.y + lineIndex * CATEGORY_LABEL_LINE_HEIGHT}
|
|
1065
|
+
fill={chrome.label}
|
|
1066
|
+
fontFamily={chrome.fontFamily}
|
|
1067
|
+
fontSize={chrome.labelSize}
|
|
1068
|
+
textAnchor={item.textAnchor}
|
|
1069
|
+
alignmentBaseline="middle"
|
|
1070
|
+
>
|
|
1071
|
+
{line}
|
|
1072
|
+
</SvgText>
|
|
1073
|
+
)),
|
|
1074
|
+
)}
|
|
1067
1075
|
{barLabel ? (
|
|
1068
1076
|
<ValueLabels
|
|
1069
1077
|
animated={animated}
|
|
@@ -79,6 +79,13 @@ export interface ChartAxis<TRow> {
|
|
|
79
79
|
* @default 'auto'
|
|
80
80
|
*/
|
|
81
81
|
tickLabelInterval?: 'auto' | ((value: unknown, index: number) => boolean);
|
|
82
|
+
/**
|
|
83
|
+
* Most lines a category name may wrap onto before it ends in `…`. `1` truncates without
|
|
84
|
+
* wrapping. Read by `BarChart` on its category axis; a horizontal chart also stops at the
|
|
85
|
+
* lines its rows are tall enough to hold. Forge only; MUI X has no equivalent.
|
|
86
|
+
* @default 2
|
|
87
|
+
*/
|
|
88
|
+
tickLabelMaxLines?: number;
|
|
82
89
|
}
|
|
83
90
|
|
|
84
91
|
export type ChartAxisPosition = 'top' | 'bottom' | 'left' | 'right' | 'none';
|