react-native-chart-kit
Version:
Beautiful React Native charts for dashboards, reports, and data-rich mobile apps.
106 lines (105 loc) • 4.19 kB
JavaScript
const getSegmentCount = (data) => Math.max(data.legend.length, data.barColors.length, ...data.data.map((group) => group.length));
const clampRatio = (value, fallback) => {
if (typeof value !== "number" || !Number.isFinite(value)) {
return fallback;
}
return Math.max(0.05, Math.min(1, value));
};
const getLegacyTheme = ({ chartConfig, fallbackSeries }) => {
const background = chartConfig.backgroundColor ??
chartConfig.backgroundGradientFrom ??
chartConfig.backgroundGradientTo;
const plotBackground = chartConfig.backgroundGradientTo ??
chartConfig.backgroundGradientFrom ??
background;
const labelColor = chartConfig.labelColor?.(1);
const lineColor = chartConfig.propsForBackgroundLines?.stroke;
return {
...(background ? { background } : {}),
...(plotBackground ? { plotBackground } : {}),
...(lineColor ? { axis: lineColor, grid: lineColor } : {}),
...(labelColor ? { mutedText: labelColor, text: labelColor } : {}),
...(fallbackSeries.length > 0 ? { series: fallbackSeries } : {})
};
};
const formatStackedBarValue = ({ decimalPlaces, formatYLabel, value, yAxisLabel, yAxisSuffix }) => {
const fixed = value.toFixed(decimalPlaces);
const formatted = formatYLabel ? formatYLabel(fixed) : fixed;
return `${yAxisLabel ?? ""}${formatted}${yAxisSuffix ?? ""}`;
};
export const buildStackedBarChartCompatProps = ({ accessibilityLabel, barPercentage, chartConfig, data, decimalPlaces, formatYLabel, fromZero, height, hideLegend, percentile, preset, segments, style, testID, theme, width, withHorizontalLabels, withInnerLines, withVerticalLabels, yAxisLabel, yAxisSuffix }) => {
const segmentCount = getSegmentCount(data);
const yKeys = Array.from({ length: segmentCount }, (_, index) => `series${index}`);
const rows = data.data.map((group, groupIndex) => {
const row = {
label: data.labels[groupIndex] ?? String(groupIndex)
};
yKeys.forEach((key, segmentIndex) => {
row[key] = group[segmentIndex] ?? null;
});
return row;
});
const series = yKeys.map((key, index) => {
const color = data.barColors[index] ?? chartConfig.color?.(1, index);
return {
...(color ? { color } : {}),
key,
label: data.legend[index] ?? `Series ${index + 1}`,
yKey: key
};
});
const resolvedDecimalPlaces = decimalPlaces ?? chartConfig.decimalPlaces ?? (percentile ? 0 : 2);
const resolvedTheme = typeof theme === "object"
? theme
: getLegacyTheme({
chartConfig,
fallbackSeries: series
.map((item) => item.color)
.filter((color) => Boolean(color))
});
const resolvedBarRatio = clampRatio(barPercentage ?? chartConfig.barPercentage, 0.72);
const barChartProps = {
barRadius: Math.max(0, chartConfig.barRadius ?? 5),
barWidthRatio: resolvedBarRatio,
data: rows,
formatYLabel: (value) => formatStackedBarValue({
decimalPlaces: resolvedDecimalPlaces,
formatYLabel,
value,
yAxisLabel,
yAxisSuffix
}),
height,
legend: !hideLegend,
mode: percentile ? "stacked100" : "stacked",
series,
showHorizontalGridLines: withInnerLines ?? true,
showValuesOnTopOfBars: false,
showXAxisLabels: withVerticalLabels ?? true,
showYAxisLabels: withHorizontalLabels ?? true,
theme: resolvedTheme,
width,
xKey: "label",
yDomain: percentile
? [0, 100]
: fromZero
? { includeZero: true, min: 0, nice: true }
: { includeZero: true, nice: true }
};
if (accessibilityLabel) {
barChartProps.accessibilityLabel = accessibilityLabel;
}
if (preset) {
barChartProps.preset = preset;
}
if (testID) {
barChartProps.testID = testID;
}
if (segments) {
barChartProps.yTickCount = segments + 1;
}
return {
style,
barChartProps
};
};