fix many bugs as demo is built
This commit is contained in:
parent
f37fe4e80f
commit
0c6266e0fe
23
src/bar.js
23
src/bar.js
@ -166,8 +166,8 @@ export default class Bar {
|
||||
this.gantt.config.column_width;
|
||||
|
||||
let $date_highlight = document.createElement('div');
|
||||
$date_highlight.id = `highlight-${this.task.id}`;
|
||||
$date_highlight.classList.add('date-highlight');
|
||||
$date_highlight.classList.add(`highlight-${this.task.id}`);
|
||||
$date_highlight.style.height = this.height * 0.8 + 'px';
|
||||
$date_highlight.style.width = this.width + 'px';
|
||||
$date_highlight.style.top =
|
||||
@ -243,7 +243,7 @@ export default class Bar {
|
||||
|
||||
const bar = this.$bar;
|
||||
const handle_width = 8;
|
||||
if (!this.gantt.options.dates_readonly) {
|
||||
if (!this.gantt.options.readonly_dates) {
|
||||
createSVG('rect', {
|
||||
x: bar.getX() + bar.getWidth() + handle_width - 4,
|
||||
y: bar.getY() + 1,
|
||||
@ -266,7 +266,7 @@ export default class Bar {
|
||||
append_to: this.handle_group,
|
||||
});
|
||||
}
|
||||
if (!this.gantt.options.progress_readonly) {
|
||||
if (!this.gantt.options.readonly_progress) {
|
||||
const bar_progress = this.$bar_progress;
|
||||
this.$handle_progress = createSVG('circle', {
|
||||
cx: bar_progress.getEndX(),
|
||||
@ -299,8 +299,8 @@ export default class Bar {
|
||||
$.on(this.group, 'click', (e) => {
|
||||
if (!opened) {
|
||||
this.show_popup(e.offsetX || e.layerX);
|
||||
document.getElementById(
|
||||
`highlight-${task_id}`,
|
||||
this.gantt.$container.querySelector(
|
||||
`.highlight-${task_id}`,
|
||||
).style.display = 'block';
|
||||
} else {
|
||||
this.gantt.hide_popup();
|
||||
@ -315,8 +315,8 @@ export default class Bar {
|
||||
(e) =>
|
||||
(timeout = setTimeout(() => {
|
||||
this.show_popup(e.offsetX || e.layerX);
|
||||
document.getElementById(
|
||||
`highlight-${task_id}`,
|
||||
this.gantt.$container.querySelector(
|
||||
`.highlight-${task_id}`,
|
||||
).style.display = 'block';
|
||||
}, 200)),
|
||||
);
|
||||
@ -325,8 +325,9 @@ export default class Bar {
|
||||
clearTimeout(timeout);
|
||||
this.gantt.popup?.hide?.();
|
||||
|
||||
document.getElementById(`highlight-${task_id}`).style.display =
|
||||
'none';
|
||||
this.gantt.$container.querySelector(
|
||||
`.highlight-${task_id}`,
|
||||
).style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
@ -589,8 +590,8 @@ export default class Bar {
|
||||
!this.gantt.config.ignored_dates.find(
|
||||
(k) => k.getTime() === d.getTime(),
|
||||
) &&
|
||||
this.gantt.config.ignored_function &&
|
||||
!this.gantt.config.ignored_function(d)
|
||||
(!this.gantt.config.ignored_function ||
|
||||
!this.gantt.config.ignored_function(d))
|
||||
) {
|
||||
actual_duration_in_days++;
|
||||
}
|
||||
|
||||
@ -95,34 +95,33 @@ const DEFAULT_VIEW_MODES = [
|
||||
];
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
header_height: 65,
|
||||
column_width: 30,
|
||||
view_modes: DEFAULT_VIEW_MODES,
|
||||
bar_height: 30,
|
||||
bar_corner_radius: 3,
|
||||
arrow_curve: 5,
|
||||
padding: 18,
|
||||
view_mode: 'Day',
|
||||
auto_move_label: false,
|
||||
bar_corner_radius: 3,
|
||||
bar_height: 30,
|
||||
container_height: 400,
|
||||
column_width: 30,
|
||||
date_format: 'YYYY-MM-DD',
|
||||
move_dependencies: true,
|
||||
show_expected_progress: false,
|
||||
popup: null,
|
||||
popup_on: 'hover',
|
||||
language: 'en',
|
||||
readonly: false,
|
||||
progress_readonly: false,
|
||||
dates_readonly: false,
|
||||
scroll_to: 'start',
|
||||
lines: 'both',
|
||||
auto_move_label: true,
|
||||
today_button: true,
|
||||
view_mode_select: false,
|
||||
default_snap: '1d',
|
||||
extend_by_units: 7,
|
||||
holiday_highlight: {
|
||||
green: 'weekend',
|
||||
},
|
||||
header_height: 65,
|
||||
holiday_highlight: { '#fff7ed': 'weekend' },
|
||||
ignore: [],
|
||||
language: 'en',
|
||||
lines: 'both',
|
||||
move_dependencies: true,
|
||||
padding: 18,
|
||||
popup: null,
|
||||
popup_on: 'hover',
|
||||
readonly_progress: false,
|
||||
readonly_dates: false,
|
||||
readonly: false,
|
||||
scroll_to: 'start',
|
||||
show_expected_progress: false,
|
||||
today_button: true,
|
||||
view_mode: 'Day',
|
||||
view_mode_select: false,
|
||||
view_modes: DEFAULT_VIEW_MODES,
|
||||
};
|
||||
|
||||
export { DEFAULT_OPTIONS, DEFAULT_VIEW_MODES };
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
font-size: 12px;
|
||||
height: 500px;
|
||||
height: 300px;
|
||||
|
||||
& .popup-wrapper {
|
||||
position: absolute;
|
||||
@ -153,13 +153,14 @@
|
||||
position: absolute;
|
||||
background: var(--dark-blue);
|
||||
width: 1px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
& .current-date-highlight {
|
||||
background: var(--dark-blue);
|
||||
color: var(--text-light);
|
||||
padding: 4px 8px;
|
||||
border-radius: 200px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
102
src/index.js
102
src/index.js
@ -23,7 +23,13 @@ export default class Gantt {
|
||||
|
||||
// CSS Selector is passed
|
||||
if (typeof element === 'string') {
|
||||
element = document.querySelector(element);
|
||||
let el = document.querySelector(element);
|
||||
if (!el) {
|
||||
throw new ReferenceError(
|
||||
`CSS selector "${element}" could not be found in DOM`,
|
||||
);
|
||||
}
|
||||
element = el;
|
||||
}
|
||||
|
||||
// get the SVGElement
|
||||
@ -66,16 +72,10 @@ export default class Gantt {
|
||||
}
|
||||
|
||||
setup_options(options) {
|
||||
this.original_options = options;
|
||||
this.options = { ...DEFAULT_OPTIONS, ...options };
|
||||
const custom_mode = this.options.custom_view_modes
|
||||
? this.options.custom_view_modes.find(
|
||||
(m) => m.name === this.config.view_mode.name,
|
||||
)
|
||||
: null;
|
||||
if (custom_mode) this.options = { ...this.options, custom_mode };
|
||||
|
||||
this.config = {};
|
||||
|
||||
this.config.ignored_dates = [];
|
||||
this.config.ignored_positions = [];
|
||||
|
||||
@ -99,6 +99,11 @@ export default class Gantt {
|
||||
}
|
||||
}
|
||||
|
||||
update_options(options) {
|
||||
this.setup_options({ ...this.original_options, ...options });
|
||||
this.change_view_mode();
|
||||
}
|
||||
|
||||
setup_tasks(tasks) {
|
||||
this.tasks = tasks
|
||||
.map((task, i) => {
|
||||
@ -201,6 +206,7 @@ export default class Gantt {
|
||||
if (typeof mode === 'string') {
|
||||
mode = this.options.view_modes.find((d) => d.name === mode);
|
||||
}
|
||||
|
||||
this.config.view_mode = mode;
|
||||
this.update_view_scale(mode);
|
||||
this.setup_dates();
|
||||
@ -303,7 +309,7 @@ export default class Gantt {
|
||||
this.make_bars();
|
||||
this.make_arrows();
|
||||
this.map_arrows_on_bars();
|
||||
this.set_width();
|
||||
this.set_dimensions();
|
||||
this.set_scroll_position(this.options.scroll_to);
|
||||
}
|
||||
|
||||
@ -348,7 +354,7 @@ export default class Gantt {
|
||||
});
|
||||
|
||||
$.attr(this.$svg, {
|
||||
height: grid_height + this.options.padding + 100,
|
||||
height: grid_height + this.options.padding,
|
||||
width: '100%',
|
||||
});
|
||||
}
|
||||
@ -578,7 +584,7 @@ export default class Gantt {
|
||||
*
|
||||
* @returns Object containing the x-axis distance and date of the current date, or null if the current date is out of the gantt range.
|
||||
*/
|
||||
highlightToday(view_mode) {
|
||||
highlightToday() {
|
||||
const today = new Date();
|
||||
if (today < this.gantt_start || today > this.gantt_end) return null;
|
||||
const diff_in_units = date_utils.diff(
|
||||
@ -590,20 +596,25 @@ export default class Gantt {
|
||||
(diff_in_units / this.config.step) * this.config.column_width;
|
||||
const height =
|
||||
(this.options.bar_height + this.options.padding) *
|
||||
this.tasks.length;
|
||||
this.tasks.length +
|
||||
20 +
|
||||
this.options.padding / 2;
|
||||
const date = date_utils.format(
|
||||
today,
|
||||
this.config.view_mode.format_string,
|
||||
this.options.language,
|
||||
);
|
||||
this.$current_highlight = this.$current_highlight = this.create_el({
|
||||
top,
|
||||
console.log(this.$header.clientHeight);
|
||||
this.$current_highlight = this.create_el({
|
||||
top: this.options.header_height - 20,
|
||||
left,
|
||||
height,
|
||||
classes: 'current-highlight',
|
||||
append_to: this.$container,
|
||||
});
|
||||
let $today = document.getElementById(date.replaceAll(' ', '_'));
|
||||
let $today = this.$container.querySelector(
|
||||
'.date_' + date.replaceAll(' ', '_'),
|
||||
);
|
||||
if ($today) {
|
||||
$today.classList.add('current-date-highlight');
|
||||
$today.style.top = +$today.style.top.slice(0, -2) - 4 + 'px';
|
||||
@ -663,7 +674,7 @@ export default class Gantt {
|
||||
|
||||
create_el({ left, top, width, height, id, classes, append_to }) {
|
||||
let $el = document.createElement('div');
|
||||
$el.classList.add(classes);
|
||||
for (let cls of classes.split(' ')) $el.classList.add(cls);
|
||||
$el.style.top = top + 'px';
|
||||
$el.style.left = left + 'px';
|
||||
if (id) $el.id = id;
|
||||
@ -679,8 +690,7 @@ export default class Gantt {
|
||||
let $lower_text = this.create_el({
|
||||
left: date.lower_x,
|
||||
top: date.lower_y,
|
||||
id: date.formatted_date,
|
||||
classes: 'lower-text',
|
||||
classes: 'lower-text date_' + date.formatted_date,
|
||||
append_to: this.$lower_header,
|
||||
});
|
||||
|
||||
@ -799,14 +809,17 @@ export default class Gantt {
|
||||
}
|
||||
}
|
||||
|
||||
set_width() {
|
||||
const cur_width = this.$svg.getBoundingClientRect().width;
|
||||
set_dimensions() {
|
||||
const { width: cur_width, height } = this.$svg.getBoundingClientRect();
|
||||
const actual_width = this.$svg.querySelector('.grid .grid-row')
|
||||
? this.$svg.querySelector('.grid .grid-row').getAttribute('width')
|
||||
: 0;
|
||||
if (cur_width < actual_width) {
|
||||
this.$svg.setAttribute('width', actual_width);
|
||||
}
|
||||
this.$container.style.height =
|
||||
{ auto: height }[this.options.container_height] ||
|
||||
this.options.container_height + 'px';
|
||||
}
|
||||
|
||||
set_scroll_position(date) {
|
||||
@ -828,9 +841,43 @@ export default class Gantt {
|
||||
);
|
||||
const scroll_pos =
|
||||
(units_since_first_task / this.config.step) *
|
||||
this.config.column_width -
|
||||
this.config.column_width;
|
||||
parent_element.scrollTo({ left: scroll_pos, behavior: 'smooth' });
|
||||
|
||||
this.$side_header.style.left =
|
||||
this.$container.clientWidth +
|
||||
this.$container.scrollLeft -
|
||||
this.$side_header.clientWidth -
|
||||
5 +
|
||||
'px';
|
||||
|
||||
// Calculate current scroll position's upper text
|
||||
if (this.$current) this.$current.classList.remove('current-upper');
|
||||
|
||||
this.upperTexts = Array.from(
|
||||
this.$container.querySelectorAll('.upper-text'),
|
||||
);
|
||||
let currentDate = date_utils.add(
|
||||
this.gantt_start,
|
||||
this.$container.scrollLeft / this.config.column_width,
|
||||
this.config.unit,
|
||||
);
|
||||
let currentUpper = this.config.view_mode.upper_text(currentDate);
|
||||
let $el = this.upperTexts.find((el) => el.textContent === currentUpper);
|
||||
|
||||
// Recalculate
|
||||
currentDate = date_utils.add(
|
||||
this.gantt_start,
|
||||
(this.$container.scrollLeft + $el.clientWidth) /
|
||||
this.config.column_width,
|
||||
this.config.unit,
|
||||
);
|
||||
currentUpper = this.config.view_mode.upper_text(currentDate);
|
||||
$el = this.upperTexts.find((el) => el.textContent === currentUpper);
|
||||
|
||||
$el.classList.add('current-upper');
|
||||
$el.style.left = this.$container.scrollLeft + 'px';
|
||||
this.$current = $el;
|
||||
}
|
||||
|
||||
scroll_today() {
|
||||
@ -953,7 +1000,7 @@ export default class Gantt {
|
||||
});
|
||||
|
||||
$.on(this.$container, 'scroll', (e) => {
|
||||
let elements = document.querySelectorAll('.bar-wrapper');
|
||||
let elements = this.$container.querySelectorAll('.bar-wrapper');
|
||||
let localBars = [];
|
||||
const ids = [];
|
||||
let dx;
|
||||
@ -971,16 +1018,15 @@ export default class Gantt {
|
||||
this.$current.style.left = e.currentTarget.scrollLeft + 'px';
|
||||
|
||||
// Calculate current scroll position's upper text
|
||||
const upperTexts = Array.from(
|
||||
document.querySelectorAll('.upper-text'),
|
||||
);
|
||||
let currentDate = date_utils.add(
|
||||
this.gantt_start,
|
||||
e.currentTarget.scrollLeft / this.config.column_width,
|
||||
this.config.unit,
|
||||
);
|
||||
let currentUpper = this.config.view_mode.upper_text(currentDate);
|
||||
let $el = upperTexts.find((el) => el.textContent === currentUpper);
|
||||
let $el = this.upperTexts.find(
|
||||
(el) => el.textContent === currentUpper,
|
||||
);
|
||||
// Recalculate for smoother experience
|
||||
currentDate = date_utils.add(
|
||||
this.gantt_start,
|
||||
@ -989,7 +1035,7 @@ export default class Gantt {
|
||||
this.config.unit,
|
||||
);
|
||||
currentUpper = this.config.view_mode.upper_text(currentDate);
|
||||
$el = upperTexts.find((el) => el.textContent === currentUpper);
|
||||
$el = this.upperTexts.find((el) => el.textContent === currentUpper);
|
||||
|
||||
if ($el !== this.$current) {
|
||||
if (this.$current)
|
||||
@ -1047,7 +1093,7 @@ export default class Gantt {
|
||||
} else if (
|
||||
is_dragging &&
|
||||
!this.options.readonly &&
|
||||
!this.options.dates_readonly
|
||||
!this.options.readonly_dates
|
||||
) {
|
||||
bar.update_bar_position({ x: $bar.ox + $bar.finaldx });
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user