Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,28 @@ export default class Bar {
}

compute_duration() {
// For hour-level precision, calculate duration directly in the configured unit
if (
['Hour', 'Quarter Day', 'Half Day'].includes(
this.gantt.config.view_mode.name,
)
) {
this.duration =
date_utils.diff(
this.task._end,
this.task._start,
this.gantt.config.unit,
) / this.gantt.config.step;

// For hour-level views, we don't need to worry about ignored dates/weekends
this.actual_duration_raw = this.duration;
this.ignored_duration_raw = 0;
this.task.actual_duration = this.duration;
this.task.ignored_duration = 0;
return;
}

// Original day-based calculation for day-level and above views
let actual_duration_in_days = 0,
duration_in_days = 0;
for (
Expand Down
18 changes: 15 additions & 3 deletions src/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,31 @@ const DEFAULT_OPTIONS = {
if (ctx.task.description) ctx.set_subtitle(ctx.task.description);
else ctx.set_subtitle('');

const is_hour_level = ['Hour', 'Quarter Day', 'Half Day'].includes(
ctx.chart.config.view_mode.name,
);
const date_format = is_hour_level ? 'MMM D HH:mm' : 'MMM D';

const start_date = date_utils.format(
ctx.task._start,
'MMM D',
date_format,
ctx.chart.options.language,
);
const end_date = date_utils.format(
date_utils.add(ctx.task._end, -1, 'second'),
'MMM D',
date_format,
ctx.chart.options.language,
);

const duration_unit = is_hour_level ? 'hours' : 'days';
const duration_value = is_hour_level
? Math.round(
date_utils.diff(ctx.task._end, ctx.task._start, 'hour') * 100,
) / 100
: ctx.task.actual_duration;

ctx.set_details(
`${start_date} - ${end_date} (${ctx.task.actual_duration} days${ctx.task.ignored_duration ? ' + ' + ctx.task.ignored_duration + ' excluded' : ''})<br/>Progress: ${Math.floor(ctx.task.progress * 100) / 100}%`,
`${start_date} - ${end_date} (${duration_value} ${duration_unit}${ctx.task.ignored_duration ? ' + ' + ctx.task.ignored_duration + ' excluded' : ''})<br/>Progress: ${Math.floor(ctx.task.progress * 100) / 100}%`,
);
},
popup_on: 'click',
Expand Down
24 changes: 20 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,18 @@ export default class Gantt {
// cache index
task._index = i;

// if hours is not set, assume the last day is full day
// e.g: 2018-09-09 becomes 2018-09-09 23:59:59
// Only extend to full day if we're in day-level view modes and no time was specified
// For hour-level granularity, preserve the exact end time
const task_end_values = date_utils.get_date_values(task._end);
if (task_end_values.slice(3).every((d) => d === 0)) {
const is_hour_level_view = [
'Hour',
'Quarter Day',
'Half Day',
].includes(this.options.view_mode);
if (
task_end_values.slice(3).every((d) => d === 0) &&
!is_hour_level_view
) {
task._end = date_utils.add(task._end, 24, 'hour');
}

Expand Down Expand Up @@ -323,7 +331,15 @@ export default class Gantt {
}
this.config.date_format =
this.config.view_mode.date_format || this.options.date_format;
this.gantt_start.setHours(0, 0, 0, 0);

// Only reset hours for day-level and above views
if (
!['Hour', 'Quarter Day', 'Half Day'].includes(
this.config.view_mode.name,
)
) {
this.gantt_start.setHours(0, 0, 0, 0);
}
}

setup_date_values() {
Expand Down