fix: bar chart uses analysis_summary from each day's status records
X-axis: animals with valid field data on that day. Bars: Success / Failure / Total from status.analysis_summary for that day. Each day shows its own session metrics. Animals without analysis_summary or with total=0 are excluded from the chart. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -38,7 +38,7 @@ function todayStr() {
|
||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
function makeStatus(animalId, date, customFields = {}, vitals = null) {
|
||||
function makeStatus(animalId, date, customFields = {}, vitals = null, analysisSummary = null) {
|
||||
return {
|
||||
id: `s-${animalId}-${date}`,
|
||||
animal_id: animalId,
|
||||
@@ -48,6 +48,7 @@ function makeStatus(animalId, date, customFields = {}, vitals = null) {
|
||||
treatment: null,
|
||||
notes: null,
|
||||
custom_fields: customFields,
|
||||
analysis_summary: analysisSummary,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -248,10 +249,11 @@ describe('day click modal', () => {
|
||||
// ── Bar chart (inside day modal) ──────────────────────────────────────────────
|
||||
|
||||
describe('bar chart inside day modal', () => {
|
||||
it('renders bar chart with that day\'s numeric field values', async () => {
|
||||
it('renders session metrics bar chart when analysis_summary has data', async () => {
|
||||
const dateStr = todayStr();
|
||||
const summary = { total: 18, counts: { Success: 5, Failure: 13 }, success_rate: 0.28 };
|
||||
const statuses = [
|
||||
makeStatus('a1000000-0000-0000-0000-000000000001', dateStr, { 'ww000000-0000-0000-0000-000000000099': '325' }),
|
||||
makeStatus('a1000000-0000-0000-0000-000000000001', dateStr, { 'ww000000-0000-0000-0000-000000000099': '325' }, null, summary),
|
||||
];
|
||||
render(
|
||||
<ExperimentCalendar experimentId={EXP_ID} template={TEMPLATE} allStatuses={statuses} animals={ANIMALS} />,
|
||||
@@ -262,31 +264,16 @@ describe('bar chart inside day modal', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('omits animals with empty or non-numeric field value from bar chart', async () => {
|
||||
it('hides bar chart when no animal has analysis_summary with total > 0', async () => {
|
||||
const dateStr = todayStr();
|
||||
// Rat A has numeric weight; Rat B has empty weight — Rat B excluded from chart but shown in day list
|
||||
const statuses = [
|
||||
makeStatus('a1000000-0000-0000-0000-000000000001', dateStr, { 'ww000000-0000-0000-0000-000000000099': '325' }),
|
||||
makeStatus('a2000000-0000-0000-0000-000000000002', dateStr, {}),
|
||||
];
|
||||
render(
|
||||
<ExperimentCalendar experimentId={EXP_ID} template={TEMPLATE} allStatuses={statuses} animals={ANIMALS} />,
|
||||
);
|
||||
fireEvent.click(screen.getByTestId(`day-${dateStr}`));
|
||||
await waitFor(() => screen.getByRole('dialog'));
|
||||
expect(screen.getByTestId('bar-chart')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('hides bar chart when no animals have a numeric value for the selected field that day', async () => {
|
||||
const dateStr = todayStr();
|
||||
// vitals is text — no bar chart
|
||||
const statuses = [makeStatus('a1000000-0000-0000-0000-000000000001', dateStr, {}, 'HR 72')];
|
||||
render(
|
||||
<ExperimentCalendar experimentId={EXP_ID} template={TEMPLATE} allStatuses={statuses} animals={ANIMALS} />,
|
||||
);
|
||||
fireEvent.change(screen.getByTestId('field-select'), { target: { value: 'vitals' } });
|
||||
fireEvent.click(screen.getByTestId(`day-${dateStr}`));
|
||||
await waitFor(() => screen.getByRole('dialog'));
|
||||
expect(screen.queryByTestId('bar-chart')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user