react-native-chart-kit
Version:
Beautiful React Native charts for dashboards, reports, and data-rich mobile apps.
88 lines (87 loc) • 3.7 kB
JavaScript
import { normalizeCartesianData } from "../../../core/index";
import { defaultFormatBarChartXLabel, defaultFormatBarChartYLabel } from "./modelUtils";
const pluralize = (count, singular, plural = `${singular}s`) => `${count} ${count === 1 ? singular : plural}`;
const resolveSeriesInput = (yKey, yKeys, series) => {
if (series && series.length > 0) {
return series;
}
if (yKeys && yKeys.length > 0) {
return yKeys.map((key) => ({ yKey: key }));
}
return yKey ? [{ yKey }] : [];
};
const getDefinedPoints = (table) => table.rows.flatMap((row) => table.columns.flatMap((column) => {
const value = row.values[column.key];
return typeof value === "number"
? [
{
formattedValue: row.formattedValues[column.key] ?? String(value),
raw: row.raw,
seriesLabel: column.label,
value,
xLabel: row.xLabel
}
]
: [];
}));
const getMinPoint = (points) => points.reduce((min, point) => (!min || point.value < min.value ? point : min), undefined);
const getMaxPoint = (points) => points.reduce((max, point) => (!max || point.value > max.value ? point : max), undefined);
const getPointLabel = ({ point, seriesCount }) => seriesCount > 1 ? `${point.seriesLabel} in ${point.xLabel}` : point.xLabel;
export const getBarChartDataTable = ({ data, formatXLabel = defaultFormatBarChartXLabel, formatYLabel = defaultFormatBarChartYLabel, series, xKey, yKey, yKeys }) => {
const seriesInput = resolveSeriesInput(yKey, yKeys, series);
const normalized = normalizeCartesianData({
data,
xKey,
series: seriesInput
});
return {
columns: normalized.series.map((item) => ({
key: item.key,
label: item.label
})),
rows: data.map((row, rowIndex) => {
const values = {};
const formattedValues = {};
normalized.series.forEach((seriesItem) => {
const value = seriesItem.points[rowIndex]?.value ?? null;
values[seriesItem.key] = value;
formattedValues[seriesItem.key] =
value === null ? "No value" : formatYLabel(value);
});
const x = normalized.series[0]?.points[rowIndex]?.x ?? rowIndex;
return {
index: rowIndex,
x,
xLabel: formatXLabel(x, rowIndex),
values,
formattedValues,
raw: row
};
})
};
};
export const getBarChartAccessibilitySummary = (input) => {
const table = getBarChartDataTable(input);
if (table.columns.length === 0 || table.rows.length === 0) {
return "Bar chart with no data.";
}
const points = getDefinedPoints(table);
if (points.length === 0) {
return `Bar chart with ${pluralize(table.rows.length, "category", "categories")} and no defined values.`;
}
const intro = table.columns.length === 1
? `Bar chart with ${pluralize(points.length, "bar")}.`
: `Bar chart with ${pluralize(table.columns.length, "series", "series")} across ${pluralize(table.rows.length, "category", "categories")}.`;
const minPoint = getMinPoint(points);
const maxPoint = getMaxPoint(points);
if (!minPoint || !maxPoint) {
return intro;
}
return `${intro} Highest value is ${getPointLabel({
point: maxPoint,
seriesCount: table.columns.length
})} at ${maxPoint.formattedValue}. Lowest value is ${getPointLabel({
point: minPoint,
seriesCount: table.columns.length
})} at ${minPoint.formattedValue}.`;
};