diff --git a/src/components/LBDashboard/BarGraphs/CompareGraphs.jsx b/src/components/LBDashboard/BarGraphs/CompareGraphs.jsx
index 3c8453582f..cd6ef111d7 100644
--- a/src/components/LBDashboard/BarGraphs/CompareGraphs.jsx
+++ b/src/components/LBDashboard/BarGraphs/CompareGraphs.jsx
@@ -94,6 +94,126 @@ const getVerticalAxes = (nameKey, tickColor, xLabel, yDomain, yTicks, valueForma
),
});
+const getChartAxes = ({
+ isHorizontal,
+ tickColor,
+ valueFormatter,
+ nameKey,
+ xLabel,
+ yLabel,
+ ...props
+}) =>
+ isHorizontal
+ ? getHorizontalAxes({
+ xDomain: props.xDomain,
+ xTicks: props.xTicks,
+ valueFormatter,
+ tickColor,
+ xLabel,
+ nameKey,
+ yCategoryWidth: props.yCategoryWidth,
+ yTickFormatter: props.yTickFormatter,
+ showYAxisTitle: props.showYAxisTitle,
+ yLabel,
+ })
+ : getVerticalAxes(
+ nameKey,
+ tickColor,
+ xLabel,
+ props.yDomain,
+ props.yTicks,
+ valueFormatter,
+ yLabel,
+ );
+
+const GraphHeader = ({ title, metricLabel, showMetricPill, headerChips, darkMode }) => (
+
+
{title}
+ {showMetricPill && (
+
+ {metricLabel}
+
+ )}
+
+
+ {headerChips.map((chip, index) => (
+
+
+ {chip.label}
+
+
+ {String(chip.value).toUpperCase()}
+
+
+ ))}
+
+
+);
+
+const NoDataMessage = ({ height, darkMode }) => (
+
+ No data available
+
+);
+
+const CompareChart = ({
+ data,
+ height,
+ isHorizontal,
+ margins,
+ gridColor,
+ axes,
+ valueKey,
+ barColor,
+ barSize,
+ valueFormatter,
+ tooltipLabel,
+ metricLabel,
+ title,
+ darkMode,
+}) => (
+
+
+
+ {axes.xAxis}
+ {axes.yAxis}
+
+ [valueFormatter(value), tooltipLabel || metricLabel || title]}
+ labelFormatter={label => `${label}`}
+ contentStyle={{
+ background: darkMode ? '#1c2541' : '#fff',
+ border: `1px solid ${darkMode ? '#3a506b' : '#ccc'}`,
+ color: darkMode ? '#e1e1e1' : '#333',
+ }}
+ itemStyle={{ color: darkMode ? '#e1e1e1' : '#333' }}
+ labelStyle={{ color: darkMode ? '#e1e1e1' : '#333', fontWeight: 600 }}
+ />
+
+
+
+
+
+
+);
+
export function CompareBarGraph({
title,
metricLabel,
@@ -106,7 +226,7 @@ export function CompareBarGraph({
xLabel,
yLabel,
barColor = '#3b82f6',
- valueFormatter = v => v,
+ valueFormatter = value => value,
headerChips = [],
xDomain,
yDomain,
@@ -116,7 +236,6 @@ export function CompareBarGraph({
height = 420,
yCategoryWidth = 70,
margins = { top: 16, right: 20, bottom: 46, left: 0 },
- maxBars,
showYAxisTitle = true,
yTickFormatter,
darkMode = false,
@@ -125,6 +244,22 @@ export function CompareBarGraph({
const tickColor = darkMode ? '#e1e1e1' : '#444';
const gridColor = darkMode ? '#3a506b' : '#e0e0e0';
+ const axes = getChartAxes({
+ isHorizontal,
+ tickColor,
+ valueFormatter,
+ nameKey,
+ xLabel,
+ yLabel,
+ xDomain,
+ yDomain,
+ xTicks,
+ yTicks,
+ yCategoryWidth,
+ yTickFormatter,
+ showYAxisTitle,
+ });
+
return (
- {/* Title row + chips */}
-
-
{title}
- {showMetricPill && (
-
- {metricLabel}
-
- )}
-
- {/* chips on the right */}
-
- {headerChips.map((c, i) => (
-
-
- {c.label}
-
-
- {String(c.value).toUpperCase()}
-
-
- ))}
-
-
+
- {/* chart */}
-
-
-
+ {data?.length ? (
+
-
- {isHorizontal
- ? (() => {
- const axes = getHorizontalAxes({
- xDomain,
- xTicks,
- valueFormatter,
- tickColor,
- xLabel,
- nameKey,
- yCategoryWidth,
- yTickFormatter,
- showYAxisTitle,
- yLabel,
- });
- return (
- <>
- {axes.xAxis}
- {axes.yAxis}
- >
- );
- })()
- : (() => {
- const axes = getVerticalAxes(
- nameKey,
- tickColor,
- xLabel,
- yDomain,
- yTicks,
- valueFormatter,
- yLabel,
- );
- return (
- <>
- {axes.xAxis}
- {axes.yAxis}
- >
- );
- })()}
-
- [valueFormatter(v), tooltipLabel || metricLabel || title]}
- labelFormatter={lbl => `${lbl}`}
- contentStyle={{
- background: darkMode ? '#1c2541' : '#fff',
- border: `1px solid ${darkMode ? '#3a506b' : '#ccc'}`,
- color: darkMode ? '#e1e1e1' : '#333',
- }}
- itemStyle={{ color: darkMode ? '#e1e1e1' : '#333' }}
- labelStyle={{ color: darkMode ? '#e1e1e1' : '#333', fontWeight: 600 }}
- />
-
-
-
-
-
+ height={height}
+ isHorizontal={isHorizontal}
+ margins={margins}
+ gridColor={gridColor}
+ axes={axes}
+ valueKey={valueKey}
+ barColor={barColor}
+ barSize={barSize}
+ valueFormatter={valueFormatter}
+ tooltipLabel={tooltipLabel}
+ metricLabel={metricLabel}
+ title={title}
+ darkMode={darkMode}
+ />
+ ) : (
+
+ )}
);
}
+GraphHeader.propTypes = {
+ title: PropTypes.string.isRequired,
+ metricLabel: PropTypes.string,
+ showMetricPill: PropTypes.bool.isRequired,
+ headerChips: PropTypes.arrayOf(
+ PropTypes.shape({
+ label: PropTypes.string.isRequired,
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
+ }),
+ ).isRequired,
+ darkMode: PropTypes.bool.isRequired,
+};
+
+NoDataMessage.propTypes = {
+ height: PropTypes.number.isRequired,
+ darkMode: PropTypes.bool.isRequired,
+};
+
+CompareChart.propTypes = {
+ data: PropTypes.arrayOf(PropTypes.object).isRequired,
+ height: PropTypes.number.isRequired,
+ isHorizontal: PropTypes.bool.isRequired,
+ margins: PropTypes.shape({
+ top: PropTypes.number,
+ right: PropTypes.number,
+ bottom: PropTypes.number,
+ left: PropTypes.number,
+ }).isRequired,
+ gridColor: PropTypes.string.isRequired,
+ axes: PropTypes.shape({
+ xAxis: PropTypes.node.isRequired,
+ yAxis: PropTypes.node.isRequired,
+ }).isRequired,
+ valueKey: PropTypes.string.isRequired,
+ barColor: PropTypes.string.isRequired,
+ barSize: PropTypes.number,
+ valueFormatter: PropTypes.func.isRequired,
+ tooltipLabel: PropTypes.string,
+ metricLabel: PropTypes.string,
+ title: PropTypes.string.isRequired,
+ darkMode: PropTypes.bool.isRequired,
+};
+
CompareBarGraph.propTypes = {
title: PropTypes.string.isRequired,
metricLabel: PropTypes.string,
@@ -272,7 +378,6 @@ CompareBarGraph.propTypes = {
bottom: PropTypes.number,
left: PropTypes.number,
}),
- maxBars: PropTypes.number,
showYAxisTitle: PropTypes.bool,
yTickFormatter: PropTypes.func,
darkMode: PropTypes.bool,
diff --git a/src/components/LBDashboard/LBDashboard.jsx b/src/components/LBDashboard/LBDashboard.jsx
index 4c1b5c8f85..7d30af966a 100644
--- a/src/components/LBDashboard/LBDashboard.jsx
+++ b/src/components/LBDashboard/LBDashboard.jsx
@@ -603,8 +603,8 @@ export function LBDashboard() {
{compareType === 'villages' && (
-
-
+
+
-
+
{loadingVillages && (
Loading villages…
@@ -636,10 +636,10 @@ export function LBDashboard() {
showYAxisTitle={true}
yTickFormatter={stripVillageWord}
yCategoryWidth={120}
- margins={{ top: 60, right: 110, bottom: 50, left: 20 }}
+ margins={{ top: 40, right: 40, bottom: 50, left: 40 }}
barSize={24}
maxBars={6}
- height={480}
+ height={420}
valueFormatter={valueFormatter}
darkMode={darkMode}
headerChips={[