diff --git a/src/defaults.js b/src/defaults.js index d10c721..b4e6d23 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -50,7 +50,7 @@ const DEFAULT_VIEW_MODES = [ }, { name: 'Day', - padding: '14d', + padding: '1m', format_string: 'YYYY-MM-DD', step: '1d', lower_text: (d, ld, lang) => diff --git a/src/index.js b/src/index.js index 2e4fa27..d92ca4b 100644 --- a/src/index.js +++ b/src/index.js @@ -361,6 +361,12 @@ export default class Gantt { classes: 'extras', append_to: this.$container, }); + this.$adjust = this.create_el({ + classes: 'adjust hide', + append_to: this.$extras, + type: 'button', + }); + this.$adjust.innerHTML = '←'; } make_grid() { @@ -710,8 +716,8 @@ export default class Gantt { if (!highlightDimensions) return; } - create_el({ left, top, width, height, id, classes, append_to }) { - let $el = document.createElement('div'); + create_el({ left, top, width, height, id, classes, append_to, type }) { + let $el = document.createElement(type || 'div'); for (let cls of classes.split(' ')) $el.classList.add(cls); $el.style.top = top + 'px'; $el.style.left = left + 'px'; @@ -1138,9 +1144,46 @@ export default class Gantt { this.$current = $el; } - Array.prototype.forEach.call(elements, function (el, i) { - ids.push(el.getAttribute('data-id')); - }); + x_on_scroll_start = e.currentTarget.scrollLeft; + let min_start, max_end, max_start; + if (elements.length) { + let { x, width } = elements[0].getBBox(); + min_start = x; + max_start = x; + max_end = x + width; + Array.prototype.forEach.call(elements, function (el, i) { + ids.push(el.getAttribute('data-id')); + let { x, width } = el.getBBox(); + if (x < min_start) min_start = x; + if (x > max_start) max_start = x; + if (x + width > max_end) max_end = x + width; + }); + } + + if (x_on_scroll_start > max_end + 100) { + this.$adjust.innerHTML = '←'; + this.$adjust.classList.remove('hide'); + this.$adjust.onclick = () => { + this.$container.scrollTo({ + left: max_start, + behavior: 'smooth', + }); + }; + } else if ( + x_on_scroll_start + e.currentTarget.offsetWidth < + min_start - 100 + ) { + this.$adjust.innerHTML = '→'; + this.$adjust.classList.remove('hide'); + this.$adjust.onclick = () => { + this.$container.scrollTo({ + left: min_start, + behavior: 'smooth', + }); + }; + } else { + this.$adjust.classList.add('hide'); + } if (dx) { localBars = ids.map((id) => this.get_bar(id)); @@ -1153,8 +1196,6 @@ export default class Gantt { }); } } - - x_on_scroll_start = e.currentTarget.scrollLeft; }); $.on(this.$svg, 'mousemove', (e) => { diff --git a/src/styles/gantt.css b/src/styles/gantt.css index 582134e..9fdb2a6 100644 --- a/src/styles/gantt.css +++ b/src/styles/gantt.css @@ -170,6 +170,26 @@ opacity: 100; } } + + & .extras { + position: sticky; + left: 0px; + + & .adjust { + position: absolute; + left: 8px; + top: calc(var(--gv-grid-height) - 60px); + background-color: rgba(0, 0, 0, 0.7); + color: white; + border: none; + padding: 8px; + border-radius: 3px; + } + } + + .hide { + display: none; + } } .gantt { @@ -312,8 +332,4 @@ } } } - - & .hide { - display: none; - } }