diff --git a/README.md b/README.md index 0372946..95ba896 100644 --- a/README.md +++ b/README.md @@ -151,13 +151,12 @@ Pull requests are warmly welcomed, while every major change or proposal ought to 1. Clone the project 2. Install the Vue CLI service, if you don't already have it installed: ``` - npm install -g @vue/cli - npm install -g @vue/cli-service-global + npm install -g @vue/cli ``` 3. `App.vue` is a dedicated Vue SFC where all Vue-Ganttastic features can be played around with and tested out. Get it running using: ``` - npm run serve + npm run serve ``` ## Dependencies diff --git a/lib/components/GGanttBar.vue b/lib/components/GGanttBar.vue index 9dc0347..7d1b40a 100644 --- a/lib/components/GGanttBar.vue +++ b/lib/components/GGanttBar.vue @@ -35,7 +35,10 @@ this.barStyle.background || this.barStyle.backgroundColor }" /> - {{ barStartText }} - {{ barEndText }} +
+
{{ bar.tooltip }}
+
{{ barStartText }} - {{ barEndText }}
+
@@ -55,13 +58,12 @@ export default { inject: [ 'getTimeCount', - 'ganttChartProps', + 'getChartProps', 'initDragOfBarsFromBundle', 'moveBarsFromBundleOfPushedBar', 'setDragLimitsOfGanttBar', 'onBarEvent', 'onDragendBar', - 'getMinGapBetweenBars', 'getTimeUnit', 'getTimeFormat' ], @@ -77,19 +79,49 @@ export default { cursorOffsetX: 0, mousemoveCallback: null, // gets initialized when starting to drag, possible values: drag, dragByHandleLeft, dragByHandleRight, barStartBeforeDrag: null, - barEndBeforeDrag: null, - timeUnit: this.getTimeUnit(), - timeChildKey: - this.ganttChartProps.precision === 'month' ? 'hours' : 'minutes', - timeChildFormat: - this.ganttChartProps.precision === 'month' ? 'MM-DD' : 'HH:mm', - timeFormat: this.getTimeFormat(), - barStartKey: this.ganttChartProps.barStartKey, - barEndKey: this.ganttChartProps.barEndKey + barEndBeforeDrag: null } }, computed: { + chartProps() { + return this.getChartProps() + }, + + minGapBetweenBars() { + return this.chartProps.minGapBetweenBars + }, + + timeChildKey() { + return this.chartProps.precision === 'month' ? 'hours' : 'minutes' + }, + + timeChildFormat() { + return this.chartProps.precision === 'month' + ? 'DD.MM.YYYY' + : 'DD.MM.YYYY HH:mm' + }, + + barStartKey() { + return this.chartProps.barStartKey + }, + + barEndKey() { + return this.chartProps.barEndKey + }, + + timeCount() { + return this.getTimeCount() + }, + + timeUnit() { + return this.getTimeUnit() + }, + + timeFormat() { + return this.getTimeFormat() + }, + barStartMoment: { get() { return moment(this.bar[this.barStartKey], this.timeFormat) @@ -146,7 +178,7 @@ export default { ...(this.barConfig || {}), left: `${xStart}px`, width: `${xEnd - xStart}px`, - height: `${this.ganttChartProps.rowHeight - 6}px`, + height: `${this.chartProps.rowHeight - 6}px`, zIndex: this.barConfig.zIndex || (this.isDragging ? 2 : 1) } }, @@ -154,16 +186,16 @@ export default { tooltipStyle() { return { left: this.barStyle.left, - top: `${this.ganttChartProps.rowHeight}px` + top: `${this.chartProps.rowHeight}px` } }, chartStartMoment() { - return moment(this.ganttChartProps.chartStart) + return moment(this.chartProps.chartStart) }, chartEndMoment() { - return moment(this.ganttChartProps.chartEnd) + return moment(this.chartProps.chartEnd) } }, @@ -328,26 +360,26 @@ export default { if ( newXStart && this.dragLimitLeft !== null && - newXStart < this.dragLimitLeft + this.getMinGapBetweenBars() + newXStart < this.dragLimitLeft + this.minGapBetweenBars ) { return true } if ( newXEnd && this.dragLimitRight !== null && - newXEnd > this.dragLimitRight - this.getMinGapBetweenBars() + newXEnd > this.dragLimitRight - this.minGapBetweenBars ) { return true } - if ( - moment(this.bar[this.barStartKey]).isAfter(this.barStartBeforeDrag) && - moment(this.bar[this.barStartKey]) - .add(1, this.timeUnit) - .isAfter(this.bar[this.barEndBeforeDrag]) - ) { - return true - } + // if ( + // moment(this.bar[this.barStartKey]).isAfter(this.barStartBeforeDrag) && + // moment(this.bar[this.barStartKey]) + // .add(1, this.timeUnit) + // .isAfter(this.bar[this.barEndBeforeDrag]) + // ) { + // return true + // } const isSqueezeToLeft = newXStart && @@ -419,7 +451,7 @@ export default { manageOverlapping() { if ( - !this.ganttChartProps.pushOnOverlap || + !this.chartProps.pushOnOverlap || this.barConfig.pushOnOverlap === false ) { return @@ -439,9 +471,9 @@ export default { currentStartMoment, this.timeChildKey, true - ) + this.getMinGapBetweenBars() + ) + this.minGapBetweenBars overlapBar[this.barEndKey] = currentStartMoment - .subtract(this.getMinGapBetweenBars(), this.timeChildKey, true) + .subtract(this.minGapBetweenBars, this.timeChildKey, true) .format(this.timeFormat) overlapBar[this.barStartKey] = overlapStartMoment .subtract(minuteDiff, this.timeChildKey, true) @@ -453,9 +485,9 @@ export default { overlapStartMoment, this.timeChildKey, true - ) + this.getMinGapBetweenBars() + ) + this.minGapBetweenBars overlapBar[this.barStartKey] = currentEndMoment - .add(this.getMinGapBetweenBars(), this.timeChildKey, true) + .add(this.minGapBetweenBars, this.timeChildKey, true) .format(this.timeFormat) overlapBar[this.barEndKey] = overlapEndMoment .add(minuteDiff, this.timeChildKey, true) @@ -556,14 +588,12 @@ export default { this.timeUnit, true ) - let pos = - (timeDiffFromStart / this.getTimeCount()) * this.barContainer.width + let pos = (timeDiffFromStart / this.timeCount) * this.barContainer.width return pos }, mapPositionToTime(xPos) { - let timeDiffFromStart = - (xPos / this.barContainer.width) * this.getTimeCount() + let timeDiffFromStart = (xPos / this.barContainer.width) * this.timeCount if (this.timeUnit === 'days') { let duration = moment.duration(timeDiffFromStart, 'days') timeDiffFromStart = duration.asHours() diff --git a/lib/components/GGanttChart.vue b/lib/components/GGanttChart.vue index e04745b..6d55b1f 100644 --- a/lib/components/GGanttChart.vue +++ b/lib/components/GGanttChart.vue @@ -459,10 +459,8 @@ export default { // the following values by using Vue's "inject" option: provide() { return { - getChartStart: () => this.chartStart, - getChartEnd: () => this.chartEnd, getTimeCount: () => this.timeCount, - ganttChartProps: this.$props, + getChartProps: () => this.$props, getThemeColors: () => this.themeColors, initDragOfBarsFromBundle: (bundleId, e) => this.initDragOfBarsFromBundle(bundleId, e), @@ -473,10 +471,6 @@ export default { onBarEvent: (e, ganttBar) => this.onBarEvent(e, ganttBar), onDragendBar: (e, ganttBar, action) => this.onDragendBar(e, ganttBar, action), - shouldSnapBackOnOverlap: () => this.snapBackOnOverlap, - snapBackBundle: ganttBar => this.snapBackBundle(ganttBar), - getMinGapBetweenBars: () => this.minGapBetweenBars, - getDefaultBarLength: () => this.defaultBarLength, getTimeUnit: () => this.timeUnit, getTimeFormat: () => this.timeFormat } diff --git a/lib/components/GGanttRow.vue b/lib/components/GGanttRow.vue index 940d702..9841ff2 100644 --- a/lib/components/GGanttRow.vue +++ b/lib/components/GGanttRow.vue @@ -2,7 +2,7 @@
@@ -23,8 +23,8 @@ @@ -54,30 +54,55 @@ export default { }, inject: [ + 'getChartProps', 'getThemeColors', 'getTimeCount', - 'getChartStart', - 'getChartEnd', - 'getDefaultBarLength', 'getTimeUnit', 'getTimeFormat' ], data() { return { - barContainer: {}, - timeUnit: this.getTimeUnit(), - timeFormat: this.getTimeFormat() + barContainer: {} } }, computed: { + themeColors() { + return this.getThemeColors() + }, + + defaultBarLength() { + return this.chartProps.defaultBarLength + }, + + chartProps() { + return this.getChartProps() + }, + + timeUnit() { + return this.getTimeUnit() + }, + + timeFormat() { + return this.getTimeFormat() + }, + + timeCount() { + return this.getTimeCount() + }, + + chartStart() { + return this.chartProps.chartStart + }, + rowLabelStyle() { return { - width: `${this.$parent.rowLabelWidth}px`, - // height: `${this.$parent.rowHeight}px`, - background: this.$parent.themeColors.ternary, - color: this.$parent.themeColors.text + width: `${this.chartProps.rowLabelWidth}px`, + background: this.themeColors.ternary, + color: this.themeColors.text, + borderTop: `1px solid ${this.themeColors.rowLabelBorder}`, + borderBottom: `1px solid ${this.themeColors.rowLabelBorder}` } } }, @@ -96,7 +121,7 @@ export default { e.preventDefault() // enables dropping content on row if (this.highlightOnHover) { this.$refs['g-gantt-row'].style.backgroundColor = - this.getThemeColors().hoverHighlight + this.themeColors.hoverHighlight } }, @@ -107,42 +132,36 @@ export default { onDrop(e) { let barContainer = this.$refs.barContainer.getBoundingClientRect() let xPos = e.clientX - barContainer.left - let timeDiffFromStart = (xPos / barContainer.width) * this.getTimeCount() - let time = moment(this.getChartStart()).add( - timeDiffFromStart, - this.timeUnit - ) + let timeDiffFromStart = (xPos / barContainer.width) * this.timeCount + let time = moment(this.chartStart).add(timeDiffFromStart, this.timeUnit) let bar = this.bars.find(bar => time.isBetween( - bar[this.$parent.barStartKey], - bar[this.$parent.barEndKey] + bar[this.chartProps.barStartKey], + bar[this.chartProps.barEndKey] ) ) this.$emit('drop', { event: e, bar, time: time.format(this.timeFormat) }) }, onDoubleClick(e) { - if (!this.$parent.mayAdd) return + if (!this.chartProps.mayAdd) return let barContainer = this.$refs.barContainer.getBoundingClientRect() let xPos = e.clientX - barContainer.left let timeDiffFromStart = Math.floor( - (xPos / barContainer.width) * this.getTimeCount() - ) - let time = moment(this.getChartStart()).add( - timeDiffFromStart, - this.timeUnit + (xPos / barContainer.width) * this.timeCount ) + let time = moment(this.chartStart).add(timeDiffFromStart, this.timeUnit) let bar = {} - bar[this.$parent.barStartKey] = time.format() - bar[this.$parent.barEndKey] = time - .add(this.getDefaultBarLength(), this.timeUnit) + bar[this.chartProps.barStartKey] = time.format() + bar[this.chartProps.barEndKey] = time + .add(this.defaultBarLength, this.timeUnit) .format() bar.ganttBarConfig = { handles: true } this.bars.push(bar) this.bars.sort((first, second) => - moment(first[this.$parent.barStartKey]).diff( - second[this.$parent.barStartKey] + moment(first[this.chartProps.barStartKey]).diff( + second[this.chartProps.barStartKey] ) ) }, @@ -150,7 +169,7 @@ export default { onMouseover() { if (this.highlightOnHover) { this.$refs['g-gantt-row'].style.backgroundColor = - this.getThemeColors().hoverHighlight + this.themeColors.hoverHighlight } }, @@ -167,7 +186,11 @@ export default { }, watch: { - '$parent.rowLabelWidth': function () { + 'chartProps.rowLabelWidth': function () { + this.barContainer = this.$refs.barContainer.getBoundingClientRect() + }, + + 'chartProps.gridSize': function () { this.barContainer = this.$refs.barContainer.getBoundingClientRect() } } diff --git a/lib/components/GGanttTimeaxis.vue b/lib/components/GGanttTimeaxis.vue index c2bc7e7..d4c51d8 100644 --- a/lib/components/GGanttTimeaxis.vue +++ b/lib/components/GGanttTimeaxis.vue @@ -88,6 +88,9 @@ export default { }, chartEnd() { this.initAxis() + }, + gridSize() { + this.onWindowResize() } }, diff --git a/lib/components/GanttasticThemeColors.js b/lib/components/GanttasticThemeColors.js index bb98429..f5db04d 100644 --- a/lib/components/GanttasticThemeColors.js +++ b/lib/components/GanttasticThemeColors.js @@ -1,11 +1,12 @@ export default { default: { primary: '#eeeeee', - secondary: '#E0E0E0', - ternary: '#F5F5F5', + secondary: '#e0e0e0', + ternary: '#f5f5f5', hoverHighlight: 'rgba(204, 216, 219, 0.5)', text: '#404040', - background: 'white' + background: 'white', + rowLabelBorder: '#eaeaea' }, creamy: { @@ -14,7 +15,8 @@ export default { ternary: '#fff6f0', hoverHighlight: 'rgba(230, 221, 202, 0.5)', text: '#542d05', - background: 'white' + background: 'white', + rowLabelBorder: '#eaeaea' }, crimson: { @@ -23,7 +25,8 @@ export default { ternary: '#db4f56', hoverHighlight: 'rgba(196, 141, 141, 0.5)', text: 'white', - background: 'white' + background: 'white', + rowLabelBorder: '#eaeaea' }, dark: { @@ -33,7 +36,8 @@ export default { hoverHighlight: 'rgba(159, 160, 161, 0.5)', text: 'white', background: '#525252', - toast: '#1f1f1f' + toast: '#1f1f1f', + rowLabelBorder: '#eaeaea' }, flare: { @@ -42,7 +46,8 @@ export default { ternary: '#5e5145', hoverHighlight: 'rgba(196, 141, 141, 0.5)', text: 'white', - background: 'white' + background: 'white', + rowLabelBorder: '#eaeaea' }, fuchsia: { @@ -51,7 +56,8 @@ export default { ternary: '#ff7da6', hoverHighlight: 'rgba(196, 141, 141, 0.5)', text: 'white', - background: 'white' + background: 'white', + rowLabelBorder: '#eaeaea' }, grove: { @@ -60,16 +66,18 @@ export default { ternary: '#72b585', hoverHighlight: 'rgba(160, 219, 171, 0.5)', text: 'white', - background: 'white' + background: 'white', + rowLabelBorder: '#eaeaea' }, 'material-blue': { - primary: '#0D47A1', - secondary: '#1565C0', + primary: '#0d47a1', + secondary: '#1565c0', ternary: '#42a5f5', hoverHighlight: 'rgba(110, 165, 196, 0.5)', text: 'white', - background: 'white' + background: 'white', + rowLabelBorder: '#eaeaea' }, sky: { @@ -78,7 +86,8 @@ export default { ternary: '#d6f7ff', hoverHighlight: 'rgba(193, 202, 214, 0.5)', text: '#022c47', - background: 'white' + background: 'white', + rowLabelBorder: '#eaeaea' }, slumber: { @@ -88,15 +97,17 @@ export default { hoverHighlight: 'rgba(179, 162, 127, 0.5)', text: '#ffe0b3', background: '#38383b', - toast: '#1f1f1f' + toast: '#1f1f1f', + rowLabelBorder: '#eaeaea' }, vue: { primary: '#258a5d', - secondary: '#41B883', - ternary: '#35495E', + secondary: '#41b883', + ternary: '#35495e', hoverHighlight: 'rgba(160, 219, 171, 0.5)', text: 'white', - background: 'white' + background: 'white', + rowLabelBorder: '#384d63' } } diff --git a/lib/scss/vue-ganttastic.scss b/lib/scss/vue-ganttastic.scss index d240333..f4db4c3 100644 --- a/lib/scss/vue-ganttastic.scss +++ b/lib/scss/vue-ganttastic.scss @@ -9,7 +9,7 @@ -moz-user-select: none; -ms-user-select: none; user-select: none; - padding-bottom: 23px; + padding-bottom: 34px; border: 1px solid #eaeaea; box-sizing: border-box; } @@ -147,6 +147,8 @@ position: sticky; padding: 0 10px; box-sizing: border-box; + border-top: 1px solid #eaeaea; + border-bottom: 1px solid #eaeaea; } .g-gantt-row > .g-gantt-row-label > * { @@ -157,7 +159,7 @@ .g-gantt-row > .g-gantt-row-bars-container { position: relative; - /* border-top: 1px solid #eaeaea; */ + border-top: 1px solid #eaeaea; border-bottom: 1px solid #eaeaea; flex: 1; } diff --git a/package-lock.json b/package-lock.json index 71f5da5..48991c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@tenrok/vue-ganttastic", - "version": "0.10.13", + "version": "0.10.14", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@tenrok/vue-ganttastic", - "version": "0.10.13", + "version": "0.10.14", "license": "MIT", "dependencies": { "vue": "^2.6.12" diff --git a/package.json b/package.json index fce4cd4..8f6de8e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tenrok/vue-ganttastic", - "version": "0.10.13", + "version": "0.10.14", "description": "A simple and customizable Gantt chart component for Vue.js", "keywords": [ "gantt", diff --git a/src/App.vue b/src/App.vue index ed87a04..4ccab73 100644 --- a/src/App.vue +++ b/src/App.vue @@ -93,6 +93,7 @@ export default { myStart: '2020-03-03 18:00', myEnd: '2020-03-03 23:00', label: 'Immobile', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#404040', @@ -104,6 +105,7 @@ export default { myStart: '2020-03-03 04:00', myEnd: '2020-03-03 15:00', label: 'Bar', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#2e74a3', @@ -119,6 +121,7 @@ export default { myStart: '2020-03-02 09:00', myEnd: '2020-03-02 18:00', label: 'Bar', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#de3b26', @@ -129,6 +132,7 @@ export default { myStart: '2020-03-03 04:00', myEnd: '2020-03-03 15:00', label: 'We belong together ^', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#2e74a3', @@ -139,6 +143,7 @@ export default { myStart: '2020-03-03 18:00', myEnd: '2020-03-03 22:00', label: 'Bar', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#aa34a3' } } ] @@ -150,6 +155,7 @@ export default { myStart: '2020-03-02 09:00', myEnd: '2020-03-02 18:00', label: 'We belong together ^', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#de3b26', @@ -160,6 +166,7 @@ export default { myStart: '2020-03-02 22:30', myEnd: '2020-03-03 05:00', label: 'With handles!', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#a23def', @@ -170,6 +177,7 @@ export default { myStart: '2020-03-02 01:00', myEnd: '2020-03-02 07:00', label: 'Bar', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#5effad', @@ -181,6 +189,7 @@ export default { myStart: '2020-03-03 14:00', myEnd: '2020-03-03 20:00', label: 'Woooow!', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', background: @@ -196,6 +205,7 @@ export default { myStart: '2020-03-03 06:30', myEnd: '2020-03-03 20:00', label: 'Bar', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#d18aaf', @@ -206,6 +216,7 @@ export default { myStart: '2020-03-02 00:30', myEnd: '2020-03-03 01:00', label: 'Rectangular', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#f2840f', @@ -247,6 +258,7 @@ export default { start: '2020-03-05 00:00', end: '2020-03-10 23:59', label: 'Bar', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#2e74a3', @@ -262,6 +274,7 @@ export default { start: '2020-03-02 00:00', end: '2020-03-09 23:59', label: 'We belong together ^', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#2e74a3', @@ -272,6 +285,7 @@ export default { start: '2020-03-24 00:00', end: '2020-03-26 23:00', label: 'Bar', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#de3b26' @@ -286,6 +300,7 @@ export default { start: '2020-03-15 00:00', end: '2020-03-18 23:59', label: 'Bar', + tooltip: 'Bar tooltip', ganttBarConfig: { color: 'white', backgroundColor: '#408e2f'