Skip to content

fix: keep month-view bar end positions consistent within the rendered month bucket#611

Open
brandonetter wants to merge 5 commits intofrappe:masterfrom
brandonetter:fix/month-view-same-end-alignment
Open

fix: keep month-view bar end positions consistent within the rendered month bucket#611
brandonetter wants to merge 5 commits intofrappe:masterfrom
brandonetter:fix/month-view-same-end-alignment

Conversation

@brandonetter
Copy link
Copy Markdown

@brandonetter brandonetter commented Mar 20, 2026

Summary

  • Fix Month view bar positioning so tasks with the same end date render to the same visual end position.
  • Fix Month view editing and dragging to match this more precise positioning

The bug was reproducible with tasks that all ended on the same date but started on different month boundaries like 2025-07-31, 2025-09-30, 2025-10-31, and 2024-02-29. In Month view, those bars did not share the same rendered right edge.

Example Screenshot from Current:

image

Example fixed Screenshot:

image

Root Cause

Month-view bar rendering was mixing two different coordinate models:

  • bar start position used month-diff based placement
  • bar width used a separate day-based approximation

That meant bars with the same end date could still land at different visual end positions.

Fix

For Month view only:

  • compute bar x with a consistent month-bucket fractional position
  • compute bar duration/width from the same coordinate model
  • align the date-range highlight overlay with the bar's actual x

This keeps the rendered end position stable and keeps dates like 2026-03-19 inside the March bucket rather than spilling into April.

Verification

Added focused regression coverage for Month view to verify:

  • tasks with the same end date render to the same right edge
  • identical date ranges render identically
  • a 2026-03-19 end renders within the March bucket

Notes

This PR intentionally is narrow to fix the month rendering issue without changing any other behavior.

It does not change Month-view drag/resize date reverse-mapping, which remains approximate.

Full changes could be made if the maintainer wants, but I really just needed this for something I'm working on and didn't want to start diving into the entire codebase here. LMK 👍

PR Handles fix to x position math with helpers to make future month_view changes easier.

@safwansamsudeen
Copy link
Copy Markdown
Collaborator

@brandonetter can you give me the exact code to test this before/after?

Thanks for this.

@brandonetter
Copy link
Copy Markdown
Author

@brandonetter can you give me the exact code to test this before/after?

Thanks for this.

Sure thing. Probably the easiest way to test without changing anything would be

  1. Open index.html
  2. Paste this into the dev console:
const existing = document.getElementById('month-repro');
if (existing) existing.remove();

const host = document.createElement('div');
host.id = 'month-repro';
host.style.margin = '24px';
document.body.prepend(host);

const tasks = [
  { id: 'same-end-1', name: 'Ends Mar 24 from Jul 31', start: '2025-07-31', end: '2026-03-24' },
  { id: 'same-end-2', name: 'Ends Mar 24 from Dec 23', start: '2024-12-23', end: '2026-03-24' },
  { id: 'same-end-3', name: 'Ends Mar 24 from Jan 31', start: '2025-01-31', end: '2026-03-24' },
  { id: 'same-end-4', name: 'Ends Mar 24 from Feb 28', start: '2025-02-28', end: '2026-03-24' },
  { id: 'same-end-5', name: 'Ends Mar 24 from Aug 31', start: '2025-08-31', end: '2026-03-24' },
  { id: 'same-end-6', name: 'Ends Mar 24 from Sep 30', start: '2025-09-30', end: '2026-03-24' },
  { id: 'same-end-7', name: 'Ends Mar 24 from Oct 31', start: '2025-10-31', end: '2026-03-24' },
  { id: 'leap-check', name: 'Ends Mar 24 from Feb 29', start: '2024-02-29', end: '2026-03-24' },
  { id: 'control-a', name: 'Control A', start: '2026-01-01', end: '2026-03-24' },
  { id: 'control-b', name: 'Control B', start: '2026-01-01', end: '2026-03-24' },
];

const chart = new Gantt(host, tasks, {
  view_mode: 'Month',
  scroll_to: '2025-12-01',
  container_height: 420,
});

window.measureMonthRepro = () =>
  [...host.querySelectorAll('.bar-wrapper')].map((wrapper) => {
    const bar = wrapper.querySelector('.bar');
    return {
      id: wrapper.dataset.id,
      endX: +(
        Number(bar.getAttribute('x')) +
        Number(bar.getAttribute('width'))
      ).toFixed(2),
    };
  });

requestAnimationFrame(() =>
  requestAnimationFrame(() => {
    console.table(window.measureMonthRepro());
    console.log(
      'unique endX count =',
      new Set(window.measureMonthRepro().map((r) => r.endX)).size,
    );
  }),
);

Running that in the browser on master:
image

Running that after building on this branch should show the fix:
image

I could push an example into the index.html page into this branch if you'd like.

@brandonetter
Copy link
Copy Markdown
Author

Added date_from_x helper and fixed the drag/drop resize on months.

Should be easy now to use this math to put in the final changes on #607

prettier formatting issue
not relevant to current codebase or needs/style
@brandonetter
Copy link
Copy Markdown
Author

Removed prettier formatting changes and removed the test file- as it isn't really relevant or a big part of this repo and just introduced bulk to a PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants