react-native-chart-kit
Version:
Beautiful React Native charts for dashboards, reports, and data-rich mobile apps.
72 lines (71 loc) • 3.39 kB
JavaScript
const defaultValueKey = "value";
const defaultLabelKey = "label";
const defaultColorKey = "color";
const defaultFormatPercentage = (value) => `${Math.round(value * 100)}%`;
const isObjectRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
const isObjectRowData = (data) => Array.isArray(data) && data.some(isObjectRecord);
const getStringValue = (value, fallback) => typeof value === "string" && value.length > 0 ? value : fallback;
const getProgressValue = (value) => {
if (typeof value === "number" && Number.isFinite(value)) {
return value;
}
return null;
};
const clampProgress = (value) => Math.min(Math.max(value, 0), 1);
const getLegacyRows = (data) => Array.isArray(data) ? { data, labels: undefined, colors: undefined } : data;
export const getProgressChartDataTable = ({ colorKey, colors, data, formatPercentage = defaultFormatPercentage, labelKey, labels, valueKey }) => {
const rows = isObjectRowData(data)
? data.map((item, index) => {
const value = getProgressValue(item[valueKey ?? defaultValueKey]);
const color = getStringValue(item[colorKey ?? defaultColorKey], colors?.[index]);
const row = {
formattedValue: value === null
? "No value"
: formatPercentage(clampProgress(value)),
index,
label: getStringValue(item[labelKey ?? defaultLabelKey], labels?.[index]) ?? `Ring ${index + 1}`,
raw: item,
value
};
if (color !== undefined) {
row.color = color;
}
return row;
})
: getLegacyRows(data).data.map((rawValue, index) => {
const value = getProgressValue(rawValue);
const color = getLegacyRows(data).colors?.[index] ?? colors?.[index];
const row = {
formattedValue: value === null
? "No value"
: formatPercentage(clampProgress(value)),
index,
label: getLegacyRows(data).labels?.[index] ??
labels?.[index] ??
`Ring ${index + 1}`,
value
};
if (color !== undefined) {
row.color = color;
}
return row;
});
const definedRows = rows.filter((row) => row.value !== null);
const average = definedRows.length > 0
? definedRows.reduce((sum, row) => sum + clampProgress(row.value ?? 0), 0) / definedRows.length
: 0;
return { average, rows };
};
export const getProgressChartAccessibilitySummary = (input) => {
const table = getProgressChartDataTable(input);
if (table.rows.length === 0) {
return "Progress chart with no rings.";
}
const definedRows = table.rows.filter((row) => row.value !== null);
if (definedRows.length === 0) {
return `Progress chart with ${table.rows.length} rings and no defined values.`;
}
const currentRow = definedRows[definedRows.length - 1];
const formatPercentage = input.formatPercentage ?? defaultFormatPercentage;
return `Progress chart with ${table.rows.length} rings. Average progress ${formatPercentage(table.average)}. Current ring ${currentRow?.label ?? "Ring"} is ${currentRow?.formattedValue ?? "No value"}.`;
};