bento-charts 2.13.1 → 2.14.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.
@@ -1,3 +1,3 @@
1
- import type { BaseBarChartProps } from '../../types/chartTypes';
2
- declare const BaseBarChart: ({ height, width, units, title, onClick, onChartClick, chartFill, otherFill, ...params }: BaseBarChartProps) => import("react/jsx-runtime").JSX.Element;
1
+ import { BaseBarChartProps } from '../../types/chartTypes';
2
+ declare const BaseBarChart: ({ height, width, units, title, onClick, onChartClick, chartFill, otherFill, showBarCounts, barCountFillMode, ...params }: BaseBarChartProps) => import("react/jsx-runtime").JSX.Element;
3
3
  export default BaseBarChart;
@@ -1,3 +1,14 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
1
12
  var __rest = (this && this.__rest) || function (s, e) {
2
13
  var t = {};
3
14
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -10,7 +21,7 @@ var __rest = (this && this.__rest) || function (s, e) {
10
21
  return t;
11
22
  };
12
23
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
- import { useCallback } from 'react';
24
+ import { createContext, useCallback, useContext, useMemo } from 'react';
14
25
  import { Bar, BarChart, CartesianGrid, Cell, Label, ResponsiveContainer, Tooltip, XAxis, YAxis, } from 'recharts';
15
26
  import { TOOLTIP_STYLE, COUNT_STYLE, LABEL_STYLE, MAX_TICK_LABEL_CHARS, TITLE_STYLE, TICKS_SHOW_ALL_LABELS_BELOW, UNITS_LABEL_OFFSET, TICK_MARGIN, COUNT_KEY, } from '../../constants/chartConstants';
16
27
  import { useChartTranslation } from '../../ChartConfigProvider';
@@ -23,10 +34,19 @@ var tickFormatter = function (tickLabel) {
23
34
  }
24
35
  return "".concat(tickLabel.substring(0, MAX_TICK_LABEL_CHARS), "...");
25
36
  };
26
- var BAR_CHART_MARGINS = { top: 10, bottom: 100, right: 20 };
37
+ var BAR_CHART_MARGINS = { bottom: 100, right: 0 };
38
+ var BAR_CHART_MARGIN_TOP_COUNTS = 35;
39
+ var BAR_CHART_MARGIN_TOP_NO_COUNTS = 10;
40
+ var MIN_BAR_WIDTH_FOR_COUNTS = 11;
41
+ var BAR_LABEL_SPACING = 4; // Spacing of a BarLabel above the actual bar, in pixels.
42
+ var BAR_LABEL_APPROX_NUMBER_WIDTH = 9.2;
27
43
  var BaseBarChart = function (_a) {
28
- var height = _a.height, width = _a.width, units = _a.units, title = _a.title, onClick = _a.onClick, onChartClick = _a.onChartClick, chartFill = _a.chartFill, otherFill = _a.otherFill, params = __rest(_a, ["height", "width", "units", "title", "onClick", "onChartClick", "chartFill", "otherFill"]);
44
+ var height = _a.height, width = _a.width, units = _a.units, title = _a.title, onClick = _a.onClick, onChartClick = _a.onChartClick, chartFill = _a.chartFill, otherFill = _a.otherFill, showBarCounts = _a.showBarCounts, barCountFillMode = _a.barCountFillMode, params = __rest(_a, ["height", "width", "units", "title", "onClick", "onChartClick", "chartFill", "otherFill", "showBarCounts", "barCountFillMode"]);
45
+ showBarCounts = showBarCounts !== null && showBarCounts !== void 0 ? showBarCounts : true; // Show bar counts by default
29
46
  var t = useChartTranslation();
47
+ var margins = useMemo(function () { return (__assign(__assign({}, BAR_CHART_MARGINS), {
48
+ // Top margin needs to accommodate bar count labels:
49
+ top: showBarCounts ? BAR_CHART_MARGIN_TOP_COUNTS : BAR_CHART_MARGIN_TOP_NO_COUNTS })); }, [showBarCounts]);
30
50
  var fill = function (entry, index) {
31
51
  return entry.x === 'missing' ? otherFill : chartFill[index % chartFill.length];
32
52
  };
@@ -45,7 +65,9 @@ var BaseBarChart = function (_a) {
45
65
  // Basically, if data is empty, Recharts will default to a domain of [0, "auto"] and our tickFormatter trips up
46
66
  // on formatting a non-string. This hack manually overrides the ticks for the axis and blanks it out.
47
67
  // - David L, 2023-01-03
48
- return (_jsxs(ChartWrapper, { responsive: typeof width !== 'number', children: [_jsx("div", { style: TITLE_STYLE, children: title }), _jsx(ResponsiveContainer, { width: width !== null && width !== void 0 ? width : '100%', height: height, children: _jsxs(BarChart, { data: data, margin: BAR_CHART_MARGINS, onClick: onChartClick, children: [_jsx(XAxis, { dataKey: "x", height: 20, angle: -45, ticks: data.length ? undefined : [''], tickFormatter: tickFormatter, tickMargin: TICK_MARGIN, textAnchor: "end", interval: data.length < TICKS_SHOW_ALL_LABELS_BELOW ? 0 : 'preserveStartEnd', children: _jsx(Label, { value: units, offset: UNITS_LABEL_OFFSET, position: "insideBottom" }) }), _jsx(YAxis, { children: _jsx(Label, { value: t[COUNT_KEY], offset: -10, position: "left", angle: 270 }) }), _jsx(CartesianGrid, { strokeDasharray: "3 3", vertical: false }), _jsx(Tooltip, { content: _jsx(BarTooltip, { totalCount: totalCount }) }), _jsx(Bar, { dataKey: "y", isAnimationActive: false, onClick: onClick, onMouseEnter: onHover, maxBarSize: 70, children: data.map(function (entry, index) { return (_jsx(Cell, { fill: fill(entry, index) }, entry.x)); }) })] }) })] }));
68
+ return (_jsx(BarLabelContext.Provider, { value: { barCountFillMode: barCountFillMode !== null && barCountFillMode !== void 0 ? barCountFillMode : 'neutral' }, children: _jsxs(ChartWrapper, { responsive: typeof width !== 'number', children: [_jsx("div", { style: TITLE_STYLE, children: title }), _jsx(ResponsiveContainer, { width: width !== null && width !== void 0 ? width : '100%', height: height, children: _jsxs(BarChart, { data: data, margin: margins, onClick: onChartClick, barCategoryGap: 1.5, children: [_jsx(XAxis, { dataKey: "x", height: 20, angle: -45, ticks: data.length ? undefined : [''], tickFormatter: tickFormatter, tickMargin: TICK_MARGIN, textAnchor: "end", interval: data.length < TICKS_SHOW_ALL_LABELS_BELOW ? 0 : 'preserveStartEnd', children: _jsx(Label, { value: units, offset: UNITS_LABEL_OFFSET, position: "insideBottom" }) }), _jsx(YAxis, { children: _jsx(Label, { value: t[COUNT_KEY], offset: -10, position: "left", angle: 270 }) }), _jsx(CartesianGrid, { strokeDasharray: "3 3", vertical: false }), _jsx(Tooltip, { content: _jsx(BarTooltip, { totalCount: totalCount }) }), _jsx(Bar, { dataKey: "y", isAnimationActive: false, onClick: onClick, onMouseEnter: onHover,
69
+ // maxBarSize={70}
70
+ label: showBarCounts ? BarLabel : undefined, children: data.map(function (entry, index) { return (_jsx(Cell, { fill: fill(entry, index) }, entry.x)); }) })] }) })] }) }));
49
71
  };
50
72
  var BarTooltip = function (_a) {
51
73
  var _b, _c, _d;
@@ -58,5 +80,23 @@ var BarTooltip = function (_a) {
58
80
  var percentage = totalCount ? Math.round((value / totalCount) * 100) : 0;
59
81
  return (_jsxs("div", { style: TOOLTIP_STYLE, children: [_jsx("p", { style: LABEL_STYLE, children: name }), _jsxs("p", { style: COUNT_STYLE, children: [value, " (", percentage, "%)"] })] }));
60
82
  };
83
+ var BarLabelContext = createContext({ barCountFillMode: 'neutral' });
84
+ /**
85
+ * Component for rendering bar counts directly above bars in the plot.
86
+ */
87
+ var BarLabel = function (_a) {
88
+ var x = _a.x, y = _a.y, width = _a.width, value = _a.value, fill = _a.fill;
89
+ var barCountFillMode = useContext(BarLabelContext).barCountFillMode;
90
+ // Funky conversion to placate TypeScript. In reality, width should always be a number here, the Recharts types are
91
+ // just incorrect or something.
92
+ // noinspection SuspiciousTypeOfGuard
93
+ var finalWidth = typeof width === 'string' ? MIN_BAR_WIDTH_FOR_COUNTS : (width !== null && width !== void 0 ? width : 0);
94
+ // Flip the labels to vertical text when the bar width is (roughly) less than the text width
95
+ // noinspection SuspiciousTypeOfGuard
96
+ var vertical = finalWidth < (value !== null && value !== void 0 ? value : '').toString().length * BAR_LABEL_APPROX_NUMBER_WIDTH;
97
+ // noinspection SuspiciousTypeOfGuard
98
+ var xPos = typeof x === 'number' ? x + finalWidth / 2 : x;
99
+ return (_jsx("g", { transform: "translate(".concat(xPos, ", ").concat(y, ")"), children: _jsx("text", { textAnchor: vertical ? 'start' : 'middle', dominantBaseline: vertical ? 'central' : undefined, transform: vertical ? 'rotate(-90)' : undefined, letterSpacing: vertical ? -1 : undefined, dy: vertical ? 0 : -1 * BAR_LABEL_SPACING, dx: vertical ? BAR_LABEL_SPACING : 0, fill: barCountFillMode === 'neutral' ? '#666666' : fill, children: finalWidth < MIN_BAR_WIDTH_FOR_COUNTS || value === 0 ? '' : value }) }));
100
+ };
61
101
  export default BaseBarChart;
62
102
  //# sourceMappingURL=BaseBarChart.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BaseBarChart.js","sourceRoot":"","sources":["../../../src/Components/Charts/BaseBarChart.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BaseBarChart.js","sourceRoot":"","sources":["../../../src/Components/Charts/BaseBarChart.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  import { HistogramProps } from '../../types/chartTypes';
2
- declare const BentoHistogram: ({ colorTheme, ...params }: HistogramProps) => import("react/jsx-runtime").JSX.Element;
2
+ declare const BentoHistogram: ({ colorTheme, barCountFillMode, ...params }: HistogramProps) => import("react/jsx-runtime").JSX.Element;
3
3
  export default BentoHistogram;
@@ -24,9 +24,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
24
24
  import { useChartTheme } from '../../ChartConfigProvider';
25
25
  import BaseBarChart from './BaseBarChart';
26
26
  var BentoHistogram = function (_a) {
27
- var _b = _a.colorTheme, colorTheme = _b === void 0 ? 'default' : _b, params = __rest(_a, ["colorTheme"]);
27
+ var _b = _a.colorTheme, colorTheme = _b === void 0 ? 'default' : _b, barCountFillMode = _a.barCountFillMode, params = __rest(_a, ["colorTheme", "barCountFillMode"]);
28
28
  var _c = useChartTheme().histogram[colorTheme], chartFill = _c.fill, otherFill = _c.other;
29
- return _jsx(BaseBarChart, __assign({ chartFill: chartFill, otherFill: otherFill }, params));
29
+ return (_jsx(BaseBarChart, __assign({ chartFill: chartFill, otherFill: otherFill, barCountFillMode: barCountFillMode !== null && barCountFillMode !== void 0 ? barCountFillMode : 'match' }, params)));
30
30
  };
31
31
  export default BentoHistogram;
32
32
  //# sourceMappingURL=BentoHistogram.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BentoHistogram.js","sourceRoot":"","sources":["../../../src/Components/Charts/BentoHistogram.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C,IAAM,cAAc,GAAG,UAAC,EAAqD;IAAnD,IAAA,kBAAsB,EAAtB,UAAU,mBAAG,SAAS,KAAA,EAAK,MAAM,cAAnC,cAAqC,CAAF;IACnD,IAAA,KAAwC,aAAa,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,EAArE,SAAS,UAAA,EAAS,SAAS,WAA0C,CAAC;IAEpF,OAAO,KAAC,YAAY,aAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,IAAM,MAAM,EAAI,CAAC;AAClF,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"BentoHistogram.js","sourceRoot":"","sources":["../../../src/Components/Charts/BentoHistogram.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C,IAAM,cAAc,GAAG,UAAC,EAAuE;IAArE,IAAA,kBAAsB,EAAtB,UAAU,mBAAG,SAAS,KAAA,EAAE,gBAAgB,sBAAA,EAAK,MAAM,cAArD,kCAAuD,CAAF;IACrE,IAAA,KAAwC,aAAa,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,EAArE,SAAS,UAAA,EAAS,SAAS,WAA0C,CAAC;IAEpF,OAAO,CACL,KAAC,YAAY,aACX,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,gBAAgB,aAAhB,gBAAgB,cAAhB,gBAAgB,GAAI,OAAO,IACzC,MAAM,EACV,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -62,6 +62,7 @@ export interface PieChartProps extends BaseCategoricalChartProps {
62
62
  chartThreshold?: number;
63
63
  maxLabelChars?: number;
64
64
  }
65
+ export type BarCountFillMode = 'match' | 'neutral';
65
66
  export interface BaseBarChartProps extends BaseCategoricalChartProps {
66
67
  chartFill: HexColor[];
67
68
  otherFill: HexColor;
@@ -69,6 +70,8 @@ export interface BaseBarChartProps extends BaseCategoricalChartProps {
69
70
  units: string;
70
71
  onClick?: BarProps['onClick'];
71
72
  onChartClick?: RechartsBarChartProps['onClick'];
73
+ showBarCounts?: boolean;
74
+ barCountFillMode?: BarCountFillMode;
72
75
  }
73
76
  export interface BarChartProps extends Omit<BaseBarChartProps, 'chartFill' | 'otherFill'> {
74
77
  colorTheme?: keyof ChartTheme['bar'];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bento-charts",
3
- "version": "2.13.1",
3
+ "version": "2.14.0",
4
4
  "description": "Charts library for Bento-platform",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,11 +1,12 @@
1
- import { useCallback } from 'react';
1
+ import { createContext, useCallback, useContext, useMemo } from 'react';
2
2
  import {
3
3
  Bar,
4
4
  BarChart,
5
- BarProps,
5
+ type BarProps,
6
6
  CartesianGrid,
7
7
  Cell,
8
8
  Label,
9
+ type LabelProps,
9
10
  ResponsiveContainer,
10
11
  Tooltip,
11
12
  XAxis,
@@ -23,7 +24,7 @@ import {
23
24
  COUNT_KEY,
24
25
  } from '../../constants/chartConstants';
25
26
 
26
- import type { BaseBarChartProps, CategoricalChartDataItem, TooltipPayload } from '../../types/chartTypes';
27
+ import { BarCountFillMode, BaseBarChartProps, CategoricalChartDataItem, TooltipPayload } from '../../types/chartTypes';
27
28
  import { useChartTranslation } from '../../ChartConfigProvider';
28
29
  import NoData from '../NoData';
29
30
  import { useTransformedChartData } from '../../util/chartUtils';
@@ -36,7 +37,12 @@ const tickFormatter = (tickLabel: string) => {
36
37
  return `${tickLabel.substring(0, MAX_TICK_LABEL_CHARS)}...`;
37
38
  };
38
39
 
39
- const BAR_CHART_MARGINS = { top: 10, bottom: 100, right: 20 };
40
+ const BAR_CHART_MARGINS = { bottom: 100, right: 0 };
41
+ const BAR_CHART_MARGIN_TOP_COUNTS = 35;
42
+ const BAR_CHART_MARGIN_TOP_NO_COUNTS = 10;
43
+ const MIN_BAR_WIDTH_FOR_COUNTS = 11;
44
+ const BAR_LABEL_SPACING = 4; // Spacing of a BarLabel above the actual bar, in pixels.
45
+ const BAR_LABEL_APPROX_NUMBER_WIDTH = 9.2;
40
46
 
41
47
  const BaseBarChart = ({
42
48
  height,
@@ -47,10 +53,23 @@ const BaseBarChart = ({
47
53
  onChartClick,
48
54
  chartFill,
49
55
  otherFill,
56
+ showBarCounts,
57
+ barCountFillMode,
50
58
  ...params
51
59
  }: BaseBarChartProps) => {
60
+ showBarCounts = showBarCounts ?? true; // Show bar counts by default
61
+
52
62
  const t = useChartTranslation();
53
63
 
64
+ const margins = useMemo(
65
+ () => ({
66
+ ...BAR_CHART_MARGINS,
67
+ // Top margin needs to accommodate bar count labels:
68
+ top: showBarCounts ? BAR_CHART_MARGIN_TOP_COUNTS : BAR_CHART_MARGIN_TOP_NO_COUNTS,
69
+ }),
70
+ [showBarCounts]
71
+ );
72
+
54
73
  const fill = (entry: CategoricalChartDataItem, index: number) =>
55
74
  entry.x === 'missing' ? otherFill : chartFill[index % chartFill.length];
56
75
 
@@ -76,35 +95,44 @@ const BaseBarChart = ({
76
95
  // on formatting a non-string. This hack manually overrides the ticks for the axis and blanks it out.
77
96
  // - David L, 2023-01-03
78
97
  return (
79
- <ChartWrapper responsive={typeof width !== 'number'}>
80
- <div style={TITLE_STYLE}>{title}</div>
81
- <ResponsiveContainer width={width ?? '100%'} height={height}>
82
- <BarChart data={data} margin={BAR_CHART_MARGINS} onClick={onChartClick}>
83
- <XAxis
84
- dataKey="x"
85
- height={20}
86
- angle={-45}
87
- ticks={data.length ? undefined : ['']}
88
- tickFormatter={tickFormatter}
89
- tickMargin={TICK_MARGIN}
90
- textAnchor="end"
91
- interval={data.length < TICKS_SHOW_ALL_LABELS_BELOW ? 0 : 'preserveStartEnd'}
92
- >
93
- <Label value={units} offset={UNITS_LABEL_OFFSET} position="insideBottom" />
94
- </XAxis>
95
- <YAxis>
96
- <Label value={t[COUNT_KEY]} offset={-10} position="left" angle={270} />
97
- </YAxis>
98
- <CartesianGrid strokeDasharray="3 3" vertical={false} />
99
- <Tooltip content={<BarTooltip totalCount={totalCount} />} />
100
- <Bar dataKey="y" isAnimationActive={false} onClick={onClick} onMouseEnter={onHover} maxBarSize={70}>
101
- {data.map((entry, index) => (
102
- <Cell key={entry.x} fill={fill(entry, index)} />
103
- ))}
104
- </Bar>
105
- </BarChart>
106
- </ResponsiveContainer>
107
- </ChartWrapper>
98
+ <BarLabelContext.Provider value={{ barCountFillMode: barCountFillMode ?? 'neutral' }}>
99
+ <ChartWrapper responsive={typeof width !== 'number'}>
100
+ <div style={TITLE_STYLE}>{title}</div>
101
+ <ResponsiveContainer width={width ?? '100%'} height={height}>
102
+ <BarChart data={data} margin={margins} onClick={onChartClick} barCategoryGap={1.5}>
103
+ <XAxis
104
+ dataKey="x"
105
+ height={20}
106
+ angle={-45}
107
+ ticks={data.length ? undefined : ['']}
108
+ tickFormatter={tickFormatter}
109
+ tickMargin={TICK_MARGIN}
110
+ textAnchor="end"
111
+ interval={data.length < TICKS_SHOW_ALL_LABELS_BELOW ? 0 : 'preserveStartEnd'}
112
+ >
113
+ <Label value={units} offset={UNITS_LABEL_OFFSET} position="insideBottom" />
114
+ </XAxis>
115
+ <YAxis>
116
+ <Label value={t[COUNT_KEY]} offset={-10} position="left" angle={270} />
117
+ </YAxis>
118
+ <CartesianGrid strokeDasharray="3 3" vertical={false} />
119
+ <Tooltip content={<BarTooltip totalCount={totalCount} />} />
120
+ <Bar
121
+ dataKey="y"
122
+ isAnimationActive={false}
123
+ onClick={onClick}
124
+ onMouseEnter={onHover}
125
+ // maxBarSize={70}
126
+ label={showBarCounts ? BarLabel : undefined}
127
+ >
128
+ {data.map((entry, index) => (
129
+ <Cell key={entry.x} fill={fill(entry, index)} />
130
+ ))}
131
+ </Bar>
132
+ </BarChart>
133
+ </ResponsiveContainer>
134
+ </ChartWrapper>
135
+ </BarLabelContext.Provider>
108
136
  );
109
137
  };
110
138
 
@@ -135,4 +163,41 @@ const BarTooltip = ({
135
163
  );
136
164
  };
137
165
 
166
+ const BarLabelContext = createContext<{ barCountFillMode: BarCountFillMode }>({ barCountFillMode: 'neutral' });
167
+
168
+ /**
169
+ * Component for rendering bar counts directly above bars in the plot.
170
+ */
171
+ const BarLabel = ({ x, y, width, value, fill }: LabelProps) => {
172
+ const { barCountFillMode } = useContext(BarLabelContext);
173
+
174
+ // Funky conversion to placate TypeScript. In reality, width should always be a number here, the Recharts types are
175
+ // just incorrect or something.
176
+ // noinspection SuspiciousTypeOfGuard
177
+ const finalWidth = typeof width === 'string' ? MIN_BAR_WIDTH_FOR_COUNTS : (width ?? 0);
178
+
179
+ // Flip the labels to vertical text when the bar width is (roughly) less than the text width
180
+ // noinspection SuspiciousTypeOfGuard
181
+ const vertical = finalWidth < (value ?? '').toString().length * BAR_LABEL_APPROX_NUMBER_WIDTH;
182
+ // noinspection SuspiciousTypeOfGuard
183
+ const xPos = typeof x === 'number' ? x + finalWidth / 2 : x;
184
+
185
+ return (
186
+ <g transform={`translate(${xPos}, ${y})`}>
187
+ <text
188
+ textAnchor={vertical ? 'start' : 'middle'} // Anchor the start coordinate of the text at the start in vert. mode
189
+ dominantBaseline={vertical ? 'central' : undefined} // In vertical text mode, center the text over the bar
190
+ transform={vertical ? 'rotate(-90)' : undefined} // Make text vertical for narrow bars
191
+ letterSpacing={vertical ? -1 : undefined} // Compress text slightly in vertical mode, to better fit in margin
192
+ dy={vertical ? 0 : -1 * BAR_LABEL_SPACING}
193
+ dx={vertical ? BAR_LABEL_SPACING : 0}
194
+ fill={barCountFillMode === 'neutral' ? '#666666' : fill}
195
+ >
196
+ {/* Hide 0-count values to avoid a bunch of "0" spam in histograms with empty bars */}
197
+ {finalWidth < MIN_BAR_WIDTH_FOR_COUNTS || value === 0 ? '' : value}
198
+ </text>
199
+ </g>
200
+ );
201
+ };
202
+
138
203
  export default BaseBarChart;
@@ -3,10 +3,17 @@ import { HistogramProps } from '../../types/chartTypes';
3
3
  import { useChartTheme } from '../../ChartConfigProvider';
4
4
  import BaseBarChart from './BaseBarChart';
5
5
 
6
- const BentoHistogram = ({ colorTheme = 'default', ...params }: HistogramProps) => {
6
+ const BentoHistogram = ({ colorTheme = 'default', barCountFillMode, ...params }: HistogramProps) => {
7
7
  const { fill: chartFill, other: otherFill } = useChartTheme().histogram[colorTheme];
8
8
 
9
- return <BaseBarChart chartFill={chartFill} otherFill={otherFill} {...params} />;
9
+ return (
10
+ <BaseBarChart
11
+ chartFill={chartFill}
12
+ otherFill={otherFill}
13
+ barCountFillMode={barCountFillMode ?? 'match'} // For histograms, bar count text fill defaults to matching bar
14
+ {...params}
15
+ />
16
+ );
10
17
  };
11
18
 
12
19
  export default BentoHistogram;
@@ -79,6 +79,8 @@ export interface PieChartProps extends BaseCategoricalChartProps {
79
79
  maxLabelChars?: number;
80
80
  }
81
81
 
82
+ export type BarCountFillMode = 'match' | 'neutral';
83
+
82
84
  export interface BaseBarChartProps extends BaseCategoricalChartProps {
83
85
  chartFill: HexColor[];
84
86
  otherFill: HexColor;
@@ -86,6 +88,8 @@ export interface BaseBarChartProps extends BaseCategoricalChartProps {
86
88
  units: string;
87
89
  onClick?: BarProps['onClick'];
88
90
  onChartClick?: RechartsBarChartProps['onClick'];
91
+ showBarCounts?: boolean;
92
+ barCountFillMode?: BarCountFillMode; // Whether the bar count text fill should match the bar color, or be neutral.
89
93
  }
90
94
 
91
95
  export interface BarChartProps extends Omit<BaseBarChartProps, 'chartFill' | 'otherFill'> {
File without changes