diff --git a/src/bar.js b/src/bar.js
index 87a262c..a3a6a5e 100644
--- a/src/bar.js
+++ b/src/bar.js
@@ -136,7 +136,6 @@ export default class Bar {
draw_progress_bar() {
if (this.invalid) return;
this.progress_width = this.calculate_progress_width();
-
this.$bar_progress = createSVG('rect', {
x: this.x,
y: this.y,
@@ -157,7 +156,7 @@ export default class Bar {
this.gantt.config.column_width;
let $date_highlight = this.gantt.create_el({
- classes: `date-highlight highlight-${this.task.id}`,
+ classes: `date-highlight hide highlight-${this.task.id}`,
width: this.width,
left: x,
});
@@ -172,11 +171,18 @@ export default class Bar {
const ignored_end = this.x + width;
const total_ignored_area =
this.gantt.config.ignored_positions.reduce((acc, val) => {
+ if (this.task._index === 2)
+ console.log('IN', val >= this.x, val < ignored_end);
return acc + (val >= this.x && val < ignored_end);
}, 0) * this.gantt.config.column_width;
let progress_width =
((width - total_ignored_area) * this.task.progress) / 100;
-
+ console.log(
+ this.task,
+ this.gantt.config.ignored_positions.reduce((acc, val) => {
+ return acc + (val >= this.x && val < ignored_end);
+ }, 0),
+ );
const progress_end = this.x + progress_width;
const total_ignored_progress =
this.gantt.config.ignored_positions.reduce((acc, val) => {
@@ -304,6 +310,22 @@ export default class Bar {
this.setup_click_event();
}
+ toggle_popup(e) {
+ if (
+ !this.gantt.popup ||
+ this.gantt.popup.parent.classList.contains('hide')
+ ) {
+ this.gantt.show_popup({
+ x: e.offsetX || e.layerX,
+ y: e.offsetY || e.layerY,
+ task: this.task,
+ target: this.$bar,
+ });
+ } else {
+ this.gantt.popup.hide();
+ }
+ }
+
setup_click_event() {
let task_id = this.task.id;
$.on(this.group, 'mouseover', (e) => {
@@ -316,40 +338,38 @@ export default class Bar {
});
if (this.gantt.options.popup_on === 'click') {
- let opened = false;
$.on(this.group, 'click', (e) => {
- if (!opened) {
- this.show_popup(e.offsetX || e.layerX);
- this.gantt.$container.querySelector(
- `.highlight-${task_id}`,
- ).style.display = 'block';
- } else {
- this.gantt.hide_popup();
- }
- opened = !opened;
+ console.log('CLICKED');
+ this.toggle_popup(e);
+ this.gantt.$container
+ .querySelector(`.highlight-${task_id}`)
+ .classList.toggle('hide');
});
} else {
- let timeout;
- $.on(
- this.group,
- 'mouseenter',
- (e) =>
- (timeout = setTimeout(() => {
- this.show_popup(e.offsetX || e.layerX);
- this.gantt.$container.querySelector(
- `.highlight-${task_id}`,
- ).style.display = 'block';
- }, 200)),
- );
-
- $.on(this.group, 'mouseleave', () => {
- clearTimeout(timeout);
- this.gantt.popup?.hide?.();
-
- this.gantt.$container.querySelector(
- `.highlight-${task_id}`,
- ).style.display = 'none';
- });
+ // let timeout;
+ // $.on(
+ // this.group,
+ // 'mouseenter',
+ // (e) =>
+ // (timeout = setTimeout(() => {
+ // this.gantt.show_popup({
+ // x: e.offsetX || e.layerX,
+ // y: e.offsetY || e.layerY,
+ // task: this.task,
+ // target: this.$bar,
+ // });
+ // this.gantt.$container.querySelector(
+ // `.highlight-${task_id}`,
+ // ).style.display = 'block';
+ // }, 200)),
+ // );
+ // $.on(this.group, 'mouseleave', () => {
+ // clearTimeout(timeout);
+ // this.gantt.popup?.hide?.();
+ // this.gantt.$container.querySelector(
+ // `.highlight-${task_id}`,
+ // ).style.display = 'none';
+ // });
}
$.on(this.group, 'click', () => {
@@ -363,36 +383,12 @@ export default class Bar {
}
this.group.classList.remove('active');
if (this.gantt.popup)
- this.gantt.popup.parent.classList.remove('hidden');
+ this.gantt.popup.parent.classList.remove('hide');
this.gantt.trigger_event('double_click', [this.task]);
});
}
- show_popup(x) {
- if (this.gantt.bar_being_dragged) return;
-
- const start_date = date_utils.format(
- this.task._start,
- 'MMM D',
- this.gantt.options.language,
- );
- const end_date = date_utils.format(
- date_utils.add(this.task._end, -1, 'second'),
- 'MMM D',
- this.gantt.options.language,
- );
-
- const subtitle = `${start_date} - ${end_date} (${this.actual_duration_in_days} days)
Progress: ${this.task.progress}`;
- this.gantt.show_popup({
- x,
- target_element: this.$bar,
- title: this.task.name,
- subtitle: subtitle,
- task: this.task,
- });
- }
-
update_bar_position({ x = null, width = null }) {
const bar = this.$bar;
@@ -541,7 +537,7 @@ export default class Bar {
if (progress < 0) return 0;
const total =
this.$bar.getWidth() -
- this.ignored_duration * this.gantt.config.column_width;
+ this.ignored_duration_raw * this.gantt.config.column_width;
return parseInt((progress / total) * 100, 10);
}
@@ -617,7 +613,8 @@ export default class Bar {
actual_duration_in_days++;
}
}
- this.actual_duration_in_days = actual_duration_in_days;
+ this.task.actual_duration = actual_duration_in_days;
+ this.task.ignored_duration = duration_in_days - actual_duration_in_days;
this.duration =
date_utils.convert_scales(
@@ -625,12 +622,13 @@ export default class Bar {
this.gantt.config.unit,
) / this.gantt.config.step;
- this.actual_duration =
+ this.actual_duration_raw =
date_utils.convert_scales(
actual_duration_in_days + 'd',
this.gantt.config.unit,
) / this.gantt.config.step;
- this.ignored_duration = this.duration - this.actual_duration;
+
+ this.ignored_duration_raw = this.duration - this.actual_duration_raw;
}
update_attr(element, attr, value) {
@@ -648,7 +646,7 @@ export default class Bar {
this.$expected_bar_progress.setAttribute(
'width',
this.gantt.config.column_width *
- this.actual_duration *
+ this.actual_duration_raw *
(this.expected_progress / 100) || 0,
);
}
diff --git a/src/defaults.js b/src/defaults.js
index b4e6d23..c10dd43 100644
--- a/src/defaults.js
+++ b/src/defaults.js
@@ -122,8 +122,47 @@ const DEFAULT_OPTIONS = {
lines: 'both',
move_dependencies: true,
padding: 18,
- popup: null,
- popup_on: 'hover',
+ popup: (ctx) => {
+ ctx.set_title(ctx.task.name);
+ if (ctx.task.description) ctx.set_subtitle(ctx.task.description);
+ else ctx.set_subtitle('');
+
+ const start_date = date_utils.format(
+ ctx.task._start,
+ 'MMM D',
+ ctx.chart.options.language,
+ );
+ const end_date = date_utils.format(
+ date_utils.add(ctx.task._end, -1, 'second'),
+ 'MMM D',
+ ctx.chart.options.language,
+ );
+
+ ctx.set_details(
+ `${start_date} - ${end_date} (${ctx.task.actual_duration} days${ctx.task.ignored_duration ? ' + ' + ctx.task.ignored_duration + ' excluded' : ''})
Progress: ${ctx.task.progress}%`,
+ );
+
+ ctx.add_action('Toggle Priority', (task, chart) => {
+ task.important = !task.important;
+ chart.refresh(
+ chart.tasks.map((t) => (t.id !== task.id ? t : task)),
+ );
+ });
+
+ ctx.add_action('+', (task, chart) => {
+ task.progress += (1 / task.actual_duration) * 100;
+ chart.refresh(
+ chart.tasks.map((t) => (t.id !== task.id ? t : task)),
+ );
+ });
+ ctx.add_action('-', (task, chart) => {
+ task.progress -= (1 / task.actual_duration) * 100;
+ chart.refresh(
+ chart.tasks.map((t) => (t.id !== task.id ? t : task)),
+ );
+ });
+ },
+ popup_on: 'click',
readonly_progress: false,
readonly_dates: false,
readonly: false,
diff --git a/src/index.js b/src/index.js
index d92ca4b..1d2e3fb 100644
--- a/src/index.js
+++ b/src/index.js
@@ -669,6 +669,7 @@ export default class Gantt {
make_grid_highlights() {
this.highlightHolidays();
+ this.config.ignored_positions = [];
const height =
(this.options.bar_height + this.options.padding) *
@@ -1028,7 +1029,7 @@ export default class Gantt {
bar_wrapper.classList.add('active');
- if (this.popup) this.popup.parent.classList.add('hidden');
+ if (this.popup) this.popup.hide();
x_on_start = e.offsetX || e.layerX;
y_on_start = e.offsetY || e.layerY;
@@ -1360,7 +1361,6 @@ export default class Gantt {
this.options.snap_at || this.config.view_mode.default_snap || '1d';
if (default_snap !== 'unit') {
- console.log(default_snap);
const { duration, scale } = date_utils.parse_duration(default_snap);
unit_length =
date_utils.convert_scales(this.config.view_mode.step, scale) /
@@ -1404,7 +1404,7 @@ export default class Gantt {
[...this.$svg.querySelectorAll('.bar-wrapper')].forEach((el) => {
el.classList.remove('active');
});
- if (this.popup) this.popup.parent.classList.remove('hidden');
+ if (this.popup) this.popup.parent.classList.remove('hide');
}
view_is(modes) {
@@ -1431,12 +1431,16 @@ export default class Gantt {
});
}
- show_popup(options) {
+ show_popup(opts) {
if (this.options.popup === false) return;
if (!this.popup) {
- this.popup = new Popup(this.$popup_wrapper, this.options.popup);
+ this.popup = new Popup(
+ this.$popup_wrapper,
+ this.options.popup,
+ this,
+ );
}
- this.popup.show(options);
+ this.popup.show(opts);
}
hide_popup() {
diff --git a/src/popup.js b/src/popup.js
index 56ea444..c9cda46 100644
--- a/src/popup.js
+++ b/src/popup.js
@@ -1,7 +1,9 @@
export default class Popup {
- constructor(parent, custom_html) {
+ constructor(parent, popup_func, gantt) {
this.parent = parent;
- this.custom_html = custom_html;
+ this.popup_func = popup_func;
+ this.gantt = gantt;
+
this.make();
}
@@ -9,55 +11,53 @@ export default class Popup {
this.parent.innerHTML = `