2
0
mirror of https://github.com/tenrok/vue-ganttastic.git synced 2026-06-25 09:40:32 +03:00

refactor: remove hardcode format and unit of time

This commit is contained in:
yicone
2021-02-02 15:54:56 +08:00
parent 0b79d21097
commit ac56ec12d7
4 changed files with 686 additions and 514 deletions
+179 -95
View File
@@ -12,11 +12,8 @@
@contextmenu="onContextmenu($event)" @contextmenu="onContextmenu($event)"
> >
<div class="g-gantt-bar-label"> <div class="g-gantt-bar-label">
<slot <slot name="bar-label" :bar="bar">
name="bar-label" {{ barConfig.label || '' }}
:bar="bar"
>
{{barConfig.label || ""}}
</slot> </slot>
</div> </div>
<template v-if="barConfig.handles"> <template v-if="barConfig.handles">
@@ -33,14 +30,16 @@
> >
<div <div
class="color-indicator" class="color-indicator"
:style="{background: this.barStyle.background || this.barStyle.backgroundColor}" :style="{
background:
this.barStyle.background || this.barStyle.backgroundColor,
}"
/> />
{{bar[barStart] | TimeFilter}} {{ bar[barStart] }}
- -
{{bar[barEnd] | TimeFilter}} {{ bar[barEnd] }}
</div> </div>
</transition> </transition>
</div> </div>
</template> </template>
@@ -48,25 +47,27 @@
import moment from 'moment' import moment from 'moment'
export default { export default {
name: "GGanttBar", name: 'GGanttBar',
props: { props: {
bar: { type: Object }, bar: { type: Object },
barStart: { type: String }, // property name of the bar objects that represents the start datetime barStart: { type: String }, // property name of the bar objects that represents the start datetime
barEnd: { type: String }, // property name of the bar objects that represents the end datetime, barEnd: { type: String }, // property name of the bar objects that represents the end datetime,
barContainer: [Object, DOMRect], barContainer: [Object, DOMRect],
allBarsInRow: {type: Array} allBarsInRow: { type: Array },
}, },
inject: [ inject: [
"getHourCount", 'getTimeCount',
"ganttChartProps", 'ganttChartProps',
"initDragOfBarsFromBundle", 'initDragOfBarsFromBundle',
"moveBarsFromBundleOfPushedBar", 'moveBarsFromBundleOfPushedBar',
"setDragLimitsOfGanttBar", 'setDragLimitsOfGanttBar',
"onBarEvent", 'onBarEvent',
"onDragendBar", 'onDragendBar',
"getMinGapBetweenBars", 'getMinGapBetweenBars',
'getTimeUnit',
'getTimeFormat',
], ],
data() { data() {
@@ -83,6 +84,9 @@ export default {
// possible values: drag, dragByHandleLeft, dragByHandleRight, // possible values: drag, dragByHandleLeft, dragByHandleRight,
barStartBeforeDrag: null, barStartBeforeDrag: null,
barEndBeforeDrag: null, barEndBeforeDrag: null,
timeUnit: this.getTimeUnit(),
timeChildKey: this.getTimeUnit() === 'days' ? 'hours' : 'minutes',
timeFormat: this.getTimeFormat(),
} }
}, },
@@ -94,8 +98,8 @@ export default {
return moment(this.bar[this.barStart]) return moment(this.bar[this.barStart])
}, },
set(value) { set(value) {
this.bar[this.barStart] = moment(value).format("YYYY-MM-DD HH:mm:ss") this.bar[this.barStart] = moment(value).format(this.timeFormat)
} },
}, },
barEndMoment: { barEndMoment: {
@@ -103,16 +107,21 @@ export default {
return moment(this.bar[this.barEnd]) return moment(this.bar[this.barEnd])
}, },
set(value) { set(value) {
this.bar[this.barEnd] = moment(value).format("YYYY-MM-DD HH:mm:ss") this.bar[this.barEnd] = moment(value).format(this.timeFormat)
} },
}, },
barConfig() { barConfig() {
if (this.bar.ganttBarConfig) { if (this.bar.ganttBarConfig) {
return { return {
...this.bar.ganttBarConfig, ...this.bar.ganttBarConfig,
background: this.bar.ganttBarConfig.isShadow ? "grey" : this.bar.ganttBarConfig.background || this.bar.ganttBarConfig.backgroundColor, background: this.bar.ganttBarConfig.isShadow
opacity: this.bar.ganttBarConfig.isShadow ? "0.3" : this.bar.ganttBarConfig.opacity ? 'grey'
: this.bar.ganttBarConfig.background ||
this.bar.ganttBarConfig.backgroundColor,
opacity: this.bar.ganttBarConfig.isShadow
? '0.3'
: this.bar.ganttBarConfig.opacity,
} }
} }
return {} return {}
@@ -126,7 +135,7 @@ export default {
left: `${xStart}px`, left: `${xStart}px`,
width: `${xEnd - xStart}px`, width: `${xEnd - xStart}px`,
height: `${this.ganttChartProps.rowHeight - 6}px`, height: `${this.ganttChartProps.rowHeight - 6}px`,
zIndex: this.barConfig.zIndex || (this.isDragging ? 2 : 1) zIndex: this.barConfig.zIndex || (this.isDragging ? 2 : 1),
} }
}, },
@@ -143,16 +152,15 @@ export default {
chartEndMoment() { chartEndMoment() {
return moment(this.ganttChartProps.chartEnd) return moment(this.ganttChartProps.chartEnd)
} },
}, },
methods: { methods: {
onMouseenter(e) { onMouseenter(e) {
if (this.tooltipTimeout) { if (this.tooltipTimeout) {
clearTimeout(this.tooltipTimeout) clearTimeout(this.tooltipTimeout)
} }
this.tooltipTimeout = setTimeout(() => this.showTooltip = true, 800) this.tooltipTimeout = setTimeout(() => (this.showTooltip = true), 800)
this.onBarEvent({ event: e, type: e.type }, this) this.onBarEvent({ event: e, type: e.type }, this)
}, },
@@ -163,17 +171,23 @@ export default {
}, },
onContextmenu(e) { onContextmenu(e) {
const time = this.mapPositionToTime(e.clientX - this.barContainer.left).format("YYYY-MM-DD HH:mm:ss") const time = this.mapPositionToTime(
e.clientX - this.barContainer.left
).format(this.timeFormat)
this.onBarEvent({ event: e, type: e.type, time }, this) this.onBarEvent({ event: e, type: e.type, time }, this)
}, },
onClick(e) { onClick(e) {
const time = this.mapPositionToTime(e.clientX - this.barContainer.left).format("YYYY-MM-DD HH:mm:ss") const time = this.mapPositionToTime(
e.clientX - this.barContainer.left
).format(this.timeFormat)
this.onBarEvent({ event: e, type: e.type, time }, this) this.onBarEvent({ event: e, type: e.type, time }, this)
}, },
onDblclick(e) { onDblclick(e) {
const time = this.mapPositionToTime(e.clientX - this.barContainer.left).format("YYYY-MM-DD HH:mm:ss") const time = this.mapPositionToTime(
e.clientX - this.barContainer.left
).format(this.timeFormat)
this.onBarEvent({ event: e, type: e.type, time }, this) this.onBarEvent({ event: e, type: e.type, time }, this)
}, },
@@ -185,14 +199,19 @@ export default {
if (!this.barConfig.immobile && !this.barConfig.isShadow) { if (!this.barConfig.immobile && !this.barConfig.isShadow) {
this.setDragLimitsOfGanttBar(this) this.setDragLimitsOfGanttBar(this)
// initialize the dragging on next mousemove event: // initialize the dragging on next mousemove event:
window.addEventListener("mousemove", this.onFirstMousemove, {once: true}) window.addEventListener('mousemove', this.onFirstMousemove, {
once: true,
})
// if next mousemove happens after mouse up (if user just presses mouse button down, then up, without moving): // if next mousemove happens after mouse up (if user just presses mouse button down, then up, without moving):
window.addEventListener("mouseup", window.addEventListener(
() => window.removeEventListener("mousemove", this.onFirstMousemove), 'mouseup',
() => window.removeEventListener('mousemove', this.onFirstMousemove),
{ once: true } { once: true }
) )
} }
const time = this.mapPositionToTime(e.clientX - this.barContainer.left).format("YYYY-MM-DD HH:mm:ss") const time = this.mapPositionToTime(
e.clientX - this.barContainer.left
).format(this.timeFormat)
this.onBarEvent({ event: e, type: e.type, time }, this) this.onBarEvent({ event: e, type: e.type, time }, this)
}, },
@@ -206,31 +225,33 @@ export default {
/* --------------------------------------------------------- */ /* --------------------------------------------------------- */
/* ------------- METHODS FOR DRAGGING THE BAR -------------- */ /* ------------- METHODS FOR DRAGGING THE BAR -------------- */
/* --------------------------------------------------------- */ /* --------------------------------------------------------- */
initDrag(e){ // "e" must be the mousedown event initDrag(e) {
// "e" must be the mousedown event
this.isDragging = true this.isDragging = true
this.barStartBeforeDrag = this.bar[this.barStart] this.barStartBeforeDrag = this.bar[this.barStart]
this.barEndBeforeDrag = this.bar[this.barEnd] this.barEndBeforeDrag = this.bar[this.barEnd]
let barX = this.$refs["g-gantt-bar"].getBoundingClientRect().left let barX = this.$refs['g-gantt-bar'].getBoundingClientRect().left
this.cursorOffsetX = e.clientX - barX this.cursorOffsetX = e.clientX - barX
let mousedownType = e.target.className let mousedownType = e.target.className
switch (mousedownType) { switch (mousedownType) {
case "g-gantt-bar-handle-left": case 'g-gantt-bar-handle-left':
document.body.style.cursor = "w-resize" document.body.style.cursor = 'w-resize'
this.mousemoveCallback = this.dragByHandleLeft this.mousemoveCallback = this.dragByHandleLeft
break break
case "g-gantt-bar-handle-right": case 'g-gantt-bar-handle-right':
document.body.style.cursor = "w-resize" document.body.style.cursor = 'w-resize'
this.mousemoveCallback = this.dragByHandleRight this.mousemoveCallback = this.dragByHandleRight
break break
default: this.mousemoveCallback = this.drag default:
this.mousemoveCallback = this.drag
} }
window.addEventListener("mousemove", this.mousemoveCallback) window.addEventListener('mousemove', this.mousemoveCallback)
window.addEventListener("mouseup", this.endDrag) window.addEventListener('mouseup', this.endDrag)
}, },
drag(e) { drag(e) {
let barWidth = this.$refs["g-gantt-bar"].getBoundingClientRect().width let barWidth = this.$refs['g-gantt-bar'].getBoundingClientRect().width
let newXStart = (e.clientX-this.barContainer.left) - this.cursorOffsetX let newXStart = e.clientX - this.barContainer.left - this.cursorOffsetX
let newXEnd = newXStart + barWidth let newXEnd = newXStart + barWidth
if (this.isPosOutOfDragRange(newXStart, newXEnd)) { if (this.isPosOutOfDragRange(newXStart, newXEnd)) {
return return
@@ -238,13 +259,16 @@ export default {
this.barStartMoment = this.mapPositionToTime(newXStart) this.barStartMoment = this.mapPositionToTime(newXStart)
this.barEndMoment = this.mapPositionToTime(newXEnd) this.barEndMoment = this.mapPositionToTime(newXEnd)
this.manageOverlapping() this.manageOverlapping()
this.onBarEvent({event: e, type: "drag"}, this) this.onBarEvent({ event: e, type: 'drag' }, this)
}, },
dragByHandleLeft(e) { dragByHandleLeft(e) {
let newXStart = e.clientX - this.barContainer.left let newXStart = e.clientX - this.barContainer.left
let newStartMoment = this.mapPositionToTime(newXStart) let newStartMoment = this.mapPositionToTime(newXStart)
if(newStartMoment.isSameOrAfter(this.barEndMoment) || this.isPosOutOfDragRange(newXStart, null)){ if (
newStartMoment.isSameOrAfter(this.barEndMoment) ||
this.isPosOutOfDragRange(newXStart, null)
) {
return return
} }
this.barStartMoment = newStartMoment this.barStartMoment = newStartMoment
@@ -254,7 +278,10 @@ export default {
dragByHandleRight(e) { dragByHandleRight(e) {
let newXEnd = e.clientX - this.barContainer.left let newXEnd = e.clientX - this.barContainer.left
let newEndMoment = this.mapPositionToTime(newXEnd) let newEndMoment = this.mapPositionToTime(newXEnd)
if(newEndMoment.isSameOrBefore(this.barStartMoment) || this.isPosOutOfDragRange(null, newXEnd)){ if (
newEndMoment.isSameOrBefore(this.barStartMoment) ||
this.isPosOutOfDragRange(null, newXEnd)
) {
return return
} }
this.barEndMoment = newEndMoment this.barEndMoment = newEndMoment
@@ -269,10 +296,18 @@ export default {
if (xStart && xStart < 0) { if (xStart && xStart < 0) {
return true return true
} }
if(xStart && this.dragLimitLeft !== null && xStart < this.dragLimitLeft + this.getMinGapBetweenBars()){ if (
xStart &&
this.dragLimitLeft !== null &&
xStart < this.dragLimitLeft + this.getMinGapBetweenBars()
) {
return true return true
} }
if(xEnd && this.dragLimitRight !== null && xEnd > this.dragLimitRight - this.getMinGapBetweenBars()){ if (
xEnd &&
this.dragLimitRight !== null &&
xEnd > this.dragLimitRight - this.getMinGapBetweenBars()
) {
return true return true
} }
return false return false
@@ -282,9 +317,9 @@ export default {
this.isDragging = false this.isDragging = false
this.dragLimitLeft = null this.dragLimitLeft = null
this.dragLimitRight = null this.dragLimitRight = null
document.body.style.cursor = "auto" document.body.style.cursor = 'auto'
window.removeEventListener("mousemove", this.mousemoveCallback) window.removeEventListener('mousemove', this.mousemoveCallback)
window.removeEventListener("mouseup", this.endDrag) window.removeEventListener('mouseup', this.endDrag)
if (this.isMainBarOfDrag) { if (this.isMainBarOfDrag) {
this.onDragendBar(e, this) this.onDragendBar(e, this)
this.isMainBarOfDrag = false this.isMainBarOfDrag = false
@@ -297,7 +332,10 @@ export default {
}, },
manageOverlapping() { manageOverlapping() {
if(!this.ganttChartProps.pushOnOverlap || this.barConfig.pushOnOverlap === false){ if (
!this.ganttChartProps.pushOnOverlap ||
this.barConfig.pushOnOverlap === false
) {
return return
} }
let currentBar = this.bar let currentBar = this.bar
@@ -309,24 +347,44 @@ export default {
let overlapStartMoment = moment(overlapBar[this.barStart]) let overlapStartMoment = moment(overlapBar[this.barStart])
let overlapEndMoment = moment(overlapBar[this.barEnd]) let overlapEndMoment = moment(overlapBar[this.barEnd])
switch (overlapType) { switch (overlapType) {
case "left": case 'left':
minuteDiff = overlapEndMoment.diff(currentStartMoment, "minutes", true) + this.getMinGapBetweenBars() minuteDiff =
overlapBar[this.barEnd] = currentStartMoment.subtract(this.getMinGapBetweenBars(), "minutes", true).format("YYYY-MM-DD HH:mm:ss") overlapEndMoment.diff(
overlapBar[this.barStart] = overlapStartMoment.subtract(minuteDiff, "minutes", true).format("YYYY-MM-DD HH:mm:ss") currentStartMoment,
this.timeChildKey,
true
) + this.getMinGapBetweenBars()
overlapBar[this.barEnd] = currentStartMoment
.subtract(this.getMinGapBetweenBars(), this.timeChildKey, true)
.format(this.timeFormat)
overlapBar[this.barStart] = overlapStartMoment
.subtract(minuteDiff, this.timeChildKey, true)
.format(this.timeFormat)
break break
case "right": case 'right':
minuteDiff = currentEndMoment.diff(overlapStartMoment, "minutes", true) + this.getMinGapBetweenBars() minuteDiff =
overlapBar[this.barStart] = currentEndMoment.add(this.getMinGapBetweenBars(), "minutes", true).format("YYYY-MM-DD HH:mm:ss") currentEndMoment.diff(
overlapBar[this.barEnd] = overlapEndMoment.add(minuteDiff, "minutes", true).format("YYYY-MM-DD HH:mm:ss") overlapStartMoment,
this.timeChildKey,
true
) + this.getMinGapBetweenBars()
overlapBar[this.barStart] = currentEndMoment
.add(this.getMinGapBetweenBars(), this.timeChildKey, true)
.format(this.timeFormat)
overlapBar[this.barEnd] = overlapEndMoment
.add(minuteDiff, this.timeChildKey, true)
.format(this.timeFormat)
break break
default: default:
// eslint-disable-next-line // eslint-disable-next-line
console.warn("One bar is inside of the other one! This should never occur while push-on-overlap is active!") console.warn(
'One bar is inside of the other one! This should never occur while push-on-overlap is active!'
)
return return
} }
this.moveBarsFromBundleOfPushedBar(overlapBar, minuteDiff, overlapType) this.moveBarsFromBundleOfPushedBar(overlapBar, minuteDiff, overlapType)
currentBar = overlapBar; currentBar = overlapBar
({overlapBar, overlapType} = this.getOverlapBarAndType(overlapBar)) ;({ overlapBar, overlapType } = this.getOverlapBarAndType(overlapBar))
} }
}, },
@@ -334,19 +392,29 @@ export default {
let barStartMoment = moment(bar[this.barStart]) let barStartMoment = moment(bar[this.barStart])
let barEndMoment = moment(bar[this.barEnd]) let barEndMoment = moment(bar[this.barEnd])
let overlapLeft, overlapRight, overlapInBetween let overlapLeft, overlapRight, overlapInBetween
let overlapBar = this.allBarsInRow.find(otherBar => { let overlapBar = this.allBarsInRow.find((otherBar) => {
if(otherBar === bar || otherBar.ganttBarConfig.pushOnOverlap === false){ if (
otherBar === bar ||
otherBar.ganttBarConfig.pushOnOverlap === false
) {
return false return false
} }
let otherBarStart = moment(otherBar[this.barStart]) let otherBarStart = moment(otherBar[this.barStart])
let otherBarEnd = moment(otherBar[this.barEnd]) let otherBarEnd = moment(otherBar[this.barEnd])
overlapLeft = barStartMoment.isBetween(otherBarStart, otherBarEnd) overlapLeft = barStartMoment.isBetween(otherBarStart, otherBarEnd)
overlapRight = barEndMoment.isBetween(otherBarStart, otherBarEnd) overlapRight = barEndMoment.isBetween(otherBarStart, otherBarEnd)
overlapInBetween = otherBarStart.isBetween(barStartMoment, barEndMoment) overlapInBetween =
|| otherBarEnd.isBetween(barStartMoment, barEndMoment) otherBarStart.isBetween(barStartMoment, barEndMoment) ||
otherBarEnd.isBetween(barStartMoment, barEndMoment)
return overlapLeft || overlapRight || overlapInBetween return overlapLeft || overlapRight || overlapInBetween
}) })
let overlapType = overlapLeft ? "left" : (overlapRight ? "right" : (overlapInBetween ? "between" : null)) let overlapType = overlapLeft
? 'left'
: overlapRight
? 'right'
: overlapInBetween
? 'between'
: null
return { overlapBar, overlapType } return { overlapBar, overlapType }
}, },
@@ -354,17 +422,33 @@ export default {
// so that bars from its bundle also get pushed // so that bars from its bundle also get pushed
moveBarByMinutesAndPush(minuteCount, direction) { moveBarByMinutesAndPush(minuteCount, direction) {
switch (direction) { switch (direction) {
case "left": case 'left':
this.barStartMoment = moment(this.barStartMoment).subtract(minuteCount, "minutes", true) this.barStartMoment = moment(this.barStartMoment).subtract(
this.barEndMoment = moment(this.barEndMoment).subtract(minuteCount, "minutes", true) minuteCount,
this.timeChildKey,
true
)
this.barEndMoment = moment(this.barEndMoment).subtract(
minuteCount,
this.timeChildKey,
true
)
break break
case "right": case 'right':
this.barStartMoment = moment(this.barStartMoment).add(minuteCount, "minutes", true) this.barStartMoment = moment(this.barStartMoment).add(
this.barEndMoment = moment(this.barEndMoment).add(minuteCount, "minutes", true) minuteCount,
this.timeChildKey,
true
)
this.barEndMoment = moment(this.barEndMoment).add(
minuteCount,
this.timeChildKey,
true
)
break break
default: default:
// eslint-disable-next-line // eslint-disable-next-line
console.warn("wrong direction in moveBarByMinutesAndPush") console.warn('wrong direction in moveBarByMinutesAndPush')
return return
} }
this.manageOverlapping() this.manageOverlapping()
@@ -374,22 +458,20 @@ export default {
/* ------- MAPPING POSITION TO TIME (AND VICE VERSA) ------- */ /* ------- MAPPING POSITION TO TIME (AND VICE VERSA) ------- */
/* --------------------------------------------------------- */ /* --------------------------------------------------------- */
mapTimeToPosition(time) { mapTimeToPosition(time) {
let hourDiffFromStart = moment(time).diff(this.chartStartMoment, "hour", true) let timeDiffFromStart = moment(time).diff(
return (hourDiffFromStart / this.getHourCount()) * this.barContainer.width this.chartStartMoment,
this.timeUnit,
true
)
return (timeDiffFromStart / this.getTimeCount()) * this.barContainer.width
}, },
mapPositionToTime(xPos) { mapPositionToTime(xPos) {
let hourDiffFromStart = (xPos/this.barContainer.width)*this.getHourCount() let timeDiffFromStart =
return this.chartStartMoment.clone().add(hourDiffFromStart, "hours") (xPos / this.barContainer.width) * this.getTimeCount()
return this.chartStartMoment.clone().add(timeDiffFromStart, this.timeUnit)
}, },
}, },
filters:{
TimeFilter(value){
return moment(value).format("HH:mm")
}
}
} }
</script> </script>
@@ -425,7 +507,8 @@ export default {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.g-gantt-bar > .g-gantt-bar-handle-left, .g-gantt-bar > .g-gantt-bar-handle-right { .g-gantt-bar > .g-gantt-bar-handle-left,
.g-gantt-bar > .g-gantt-bar-handle-right {
position: absolute; position: absolute;
width: 10px; width: 10px;
height: 100%; height: 100%;
@@ -452,7 +535,7 @@ export default {
background: black; background: black;
color: white; color: white;
z-index: 3; z-index: 3;
font-size: 0.70em; font-size: 0.7em;
padding: 3px; padding: 3px;
border-radius: 3px; border-radius: 3px;
transition: opacity 0.2s; transition: opacity 0.2s;
@@ -482,17 +565,18 @@ export default {
} }
.fade-enter-active { .fade-enter-active {
animation: fade-in .3s; animation: fade-in 0.3s;
} }
.fade-leave-active { .fade-leave-active {
animation: fade-in .3s reverse; animation: fade-in 0.3s reverse;
} }
@keyframes fade-in { @keyframes fade-in {
from { from {
opacity: 0; opacity: 0;
} to { }
to {
opacity: 1; opacity: 1;
} }
} }
+167 -88
View File
@@ -22,9 +22,9 @@
/> />
<div id="g-gantt-rows-container"> <div id="g-gantt-rows-container">
<slot/> <!-- the g-gantt-row components go here --> <slot />
<!-- the g-gantt-row components go here -->
</div> </div>
</div> </div>
</template> </template>
@@ -37,64 +37,67 @@ import GGanttRow from './GGanttRow.vue'
import GGanttBar from './GGanttBar.vue' import GGanttBar from './GGanttBar.vue'
export default { export default {
name: 'GGanttChart',
name: "GGanttChart",
components: { components: {
GGanttTimeaxis, GGanttTimeaxis,
GGanttGrid GGanttGrid,
}, },
props: { props: {
chartStart: {type: String, default: moment().startOf("day").format("YYYY-MM-DD HH:mm:ss")}, chartStart: { type: String },
chartEnd: {type: String, default: moment().startOf("day").add(12,"hours").format("YYYY-MM-DD HH:mm:ss")}, chartEnd: { type: String },
hideTimeaxis: Boolean, hideTimeaxis: Boolean,
rowLabelWidth: {type: String, default: "10%"}, rowLabelWidth: { type: String, default: '10%' },
rowHeight: { type: Number, default: 40 }, rowHeight: { type: Number, default: 40 },
locale: {type: String, default: "en"}, locale: { type: String, default: 'en' },
theme: { type: String }, theme: { type: String },
grid: { type: Boolean }, grid: { type: Boolean },
highlightedHours: { type: Array, default: () => [] }, highlightedHours: { type: Array, default: () => [] },
width: {type: String, default: "100%"}, // the total width of the entire ganttastic component in % width: { type: String, default: '100%' }, // the total width of the entire ganttastic component in %
pushOnOverlap: { type: Boolean }, pushOnOverlap: { type: Boolean },
snapBackOnOverlap: { type: Boolean }, snapBackOnOverlap: { type: Boolean },
minGapBetweenBars: { minGapBetweenBars: {
type: Number, type: Number,
default: 0 default: 0,
}, },
defaultBarLength: { type: Number, default: 1 }, defaultBarLength: { type: Number, default: 1 },
// ["month_days", "day_hours"] // ["month_days", "day_hours"]
timeaxisMode: {type: String, default: "month_days"} timeaxisMode: { type: String, default: 'month_days' },
}, },
data() { data() {
return { return {
timemarkerOffset: 0, timemarkerOffset: 0,
movedBarsInDrag: new Set() movedBarsInDrag: new Set(),
timeUnit: this.timeaxisMode === 'month_days' ? 'days' : 'hours',
timeFormat:
this.timeaxisMode === 'month_days' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm',
} }
}, },
computed: { computed: {
timeCount() {
hourCount(){
let momentChartStart = moment(this.chartStart) let momentChartStart = moment(this.chartStart)
let momentChartEnd = moment(this.chartEnd) let momentChartEnd = moment(this.chartEnd)
return Math.floor(momentChartEnd.diff(momentChartStart, "hour", true)) return Math.floor(momentChartEnd.diff(momentChartStart, this.timeUnit, true))
}, },
themeColors() { themeColors() {
return GanttasticThemeColors[this.theme] || GanttasticThemeColors.default return GanttasticThemeColors[this.theme] || GanttasticThemeColors.default
}, },
}, },
methods: { methods: {
getGanttBarChildrenList() { getGanttBarChildrenList() {
let ganttBarChildren = [] let ganttBarChildren = []
let ganttRowChildrenList = this.$children.filter(childComp => childComp.$options.name === GGanttRow.name) let ganttRowChildrenList = this.$children.filter(
ganttRowChildrenList.forEach(row => { (childComp) => childComp.$options.name === GGanttRow.name
let ganttBarChildrenOfRow = row.$children.filter(childComp => childComp.$options.name === GGanttBar.name) )
ganttRowChildrenList.forEach((row) => {
let ganttBarChildrenOfRow = row.$children.filter(
(childComp) => childComp.$options.name === GGanttBar.name
)
ganttBarChildren.push(...ganttBarChildrenOfRow) ganttBarChildren.push(...ganttBarChildrenOfRow)
}) })
return ganttBarChildren return ganttBarChildren
@@ -104,15 +107,23 @@ export default {
if (bundleId === undefined || bundleId === null) { if (bundleId === undefined || bundleId === null) {
return [] return []
} }
return this.getGanttBarChildrenList().filter(ganttBarChild => ganttBarChild.barConfig.bundle === bundleId) return this.getGanttBarChildrenList().filter(
(ganttBarChild) => ganttBarChild.barConfig.bundle === bundleId
)
}, },
initDragOfBarsFromBundle(gGanttBar, e) { initDragOfBarsFromBundle(gGanttBar, e) {
gGanttBar.initDrag(e) gGanttBar.initDrag(e)
this.movedBarsInDrag.add(gGanttBar.bar) this.movedBarsInDrag.add(gGanttBar.bar)
if(gGanttBar.barConfig.bundle !== null && gGanttBar.barConfig.bundle !== undefined){ if (
this.getGanttBarChildrenList().forEach(ganttBarChild => { gGanttBar.barConfig.bundle !== null &&
if(ganttBarChild.barConfig.bundle === gGanttBar.barConfig.bundle && ganttBarChild !== gGanttBar){ gGanttBar.barConfig.bundle !== undefined
) {
this.getGanttBarChildrenList().forEach((ganttBarChild) => {
if (
ganttBarChild.barConfig.bundle === gGanttBar.barConfig.bundle &&
ganttBarChild !== gGanttBar
) {
ganttBarChild.initDrag(e) ganttBarChild.initDrag(e)
this.movedBarsInDrag.add(ganttBarChild.bar) this.movedBarsInDrag.add(ganttBarChild.bar)
} }
@@ -126,8 +137,11 @@ export default {
if (bundleId === undefined || bundleId === null) { if (bundleId === undefined || bundleId === null) {
return return
} }
this.getGanttBarChildrenList().forEach(ganttBarChild => { this.getGanttBarChildrenList().forEach((ganttBarChild) => {
if(ganttBarChild.barConfig.bundle === bundleId && ganttBarChild.bar !== pushedBar){ if (
ganttBarChild.barConfig.bundle === bundleId &&
ganttBarChild.bar !== pushedBar
) {
ganttBarChild.moveBarByMinutesAndPush(minuteDiff, overlapType) ganttBarChild.moveBarByMinutesAndPush(minuteDiff, overlapType)
this.movedBarsInDrag.add(ganttBarChild.bar) this.movedBarsInDrag.add(ganttBarChild.bar)
} }
@@ -135,7 +149,10 @@ export default {
}, },
shouldSnapBackBar(ganttBar) { shouldSnapBackBar(ganttBar) {
if(this.snapBackOnOverlap && ganttBar.barConfig.pushOnOverlap !== false){ if (
this.snapBackOnOverlap &&
ganttBar.barConfig.pushOnOverlap !== false
) {
let { overlapBar } = ganttBar.getOverlapBarAndType(ganttBar.bar) let { overlapBar } = ganttBar.getOverlapBarAndType(ganttBar.bar)
return !!overlapBar return !!overlapBar
} }
@@ -144,9 +161,12 @@ export default {
snapBackBundleIfNeeded(ganttBar) { snapBackBundleIfNeeded(ganttBar) {
let barsFromBundle = this.getBarsFromBundle(ganttBar.barConfig.bundle) let barsFromBundle = this.getBarsFromBundle(ganttBar.barConfig.bundle)
if(this.shouldSnapBackBar(ganttBar) || barsFromBundle.some(gBar => this.shouldSnapBackBar(gBar))){ if (
this.shouldSnapBackBar(ganttBar) ||
barsFromBundle.some((gBar) => this.shouldSnapBackBar(gBar))
) {
ganttBar.snapBack() ganttBar.snapBack()
barsFromBundle.forEach(gBar => gBar.snapBack()) barsFromBundle.forEach((gBar) => gBar.snapBack())
return true return true
} }
return false return false
@@ -160,7 +180,7 @@ export default {
let didSnapBack = this.snapBackBundleIfNeeded(ganttBar) let didSnapBack = this.snapBackBundleIfNeeded(ganttBar)
let movedBars = didSnapBack ? new Set() : this.movedBarsInDrag let movedBars = didSnapBack ? new Set() : this.movedBarsInDrag
this.movedBarsInDrag = new Set() this.movedBarsInDrag = new Set()
this.$emit("dragend-bar", {event: e, bar: ganttBar.bar, movedBars}) this.$emit('dragend-bar', { event: e, bar: ganttBar.bar, movedBars })
}, },
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@@ -174,33 +194,54 @@ export default {
if (!this.pushOnOverlap || bar.barConfig.pushOnOverlap === false) { if (!this.pushOnOverlap || bar.barConfig.pushOnOverlap === false) {
return return
} }
for(let side of ["left", "right"]){ for (let side of ['left', 'right']) {
let [totalGapDistance, bundleBarsOnPath] = this.countGapDistanceToNextImmobileBar(bar, null, side, false) let [
totalGapDistance,
bundleBarsOnPath,
] = this.countGapDistanceToNextImmobileBar(bar, null, side, false)
for (let i = 0; i < bundleBarsOnPath.length; i++) { for (let i = 0; i < bundleBarsOnPath.length; i++) {
let barFromBundle = bundleBarsOnPath[i].bar let barFromBundle = bundleBarsOnPath[i].bar
let gapDist = bundleBarsOnPath[i].gapDistance let gapDist = bundleBarsOnPath[i].gapDistance
let otherBarsFromBundle = this.getBarsFromBundle(barFromBundle.barConfig.bundle).filter(otherBar => otherBar !== barFromBundle) let otherBarsFromBundle = this.getBarsFromBundle(
otherBarsFromBundle.forEach(otherBar => { barFromBundle.barConfig.bundle
let [newGapDistance, newBundleBars] = this.countGapDistanceToNextImmobileBar(otherBar, gapDist, side) ).filter((otherBar) => otherBar !== barFromBundle)
if(newGapDistance !== null && (newGapDistance < totalGapDistance || !totalGapDistance)){ otherBarsFromBundle.forEach((otherBar) => {
let [
newGapDistance,
newBundleBars,
] = this.countGapDistanceToNextImmobileBar(otherBar, gapDist, side)
if (
newGapDistance !== null &&
(newGapDistance < totalGapDistance || !totalGapDistance)
) {
totalGapDistance = newGapDistance totalGapDistance = newGapDistance
} }
newBundleBars.forEach(newBundleBar => { newBundleBars.forEach((newBundleBar) => {
if(!bundleBarsOnPath.find(barAndGap => barAndGap.bar === newBundleBar.bar)){ if (
!bundleBarsOnPath.find(
(barAndGap) => barAndGap.bar === newBundleBar.bar
)
) {
bundleBarsOnPath.push(newBundleBar) bundleBarsOnPath.push(newBundleBar)
} }
}) })
}) })
} }
if(totalGapDistance != null && side === "left"){ if (totalGapDistance != null && side === 'left') {
bar.dragLimitLeft = bar.$refs['g-gantt-bar'].offsetLeft - totalGapDistance bar.dragLimitLeft =
} else if(totalGapDistance != null && side === "right"){ bar.$refs['g-gantt-bar'].offsetLeft - totalGapDistance
bar.dragLimitRight = bar.$refs['g-gantt-bar'].offsetLeft+ bar.$refs['g-gantt-bar'].offsetWidth + totalGapDistance } else if (totalGapDistance != null && side === 'right') {
bar.dragLimitRight =
bar.$refs['g-gantt-bar'].offsetLeft +
bar.$refs['g-gantt-bar'].offsetWidth +
totalGapDistance
} }
} }
// all bars from the bundle of the clicked bar need to have the same drag limit: // all bars from the bundle of the clicked bar need to have the same drag limit:
let barsFromBundleOfClickedBar = this.getBarsFromBundle(bar.barConfig.bundle) let barsFromBundleOfClickedBar = this.getBarsFromBundle(
barsFromBundleOfClickedBar.forEach(barFromBundle => { bar.barConfig.bundle
)
barsFromBundleOfClickedBar.forEach((barFromBundle) => {
barFromBundle.dragLimitLeft = bar.dragLimitLeft barFromBundle.dragLimitLeft = bar.dragLimitLeft
barFromBundle.dragLimitRight = bar.dragLimitRight barFromBundle.dragLimitRight = bar.dragLimitRight
}) })
@@ -209,77 +250,110 @@ export default {
// returns the gap distance to the next immobile bar // returns the gap distance to the next immobile bar
// in the row where the given bar (parameter) is (added to gapDistanceSoFar) // in the row where the given bar (parameter) is (added to gapDistanceSoFar)
// and a list of all bars on that path that belong to a bundle // and a list of all bars on that path that belong to a bundle
countGapDistanceToNextImmobileBar(bar, gapDistanceSoFar, side="left", ignoreShadows = true){ countGapDistanceToNextImmobileBar(
let bundleBarsAndGapDist = bar.barConfig.bundle ? [{bar, gapDistance: gapDistanceSoFar}] : [] bar,
gapDistanceSoFar,
side = 'left',
ignoreShadows = true
) {
let bundleBarsAndGapDist = bar.barConfig.bundle
? [{ bar, gapDistance: gapDistanceSoFar }]
: []
let currentBar = bar let currentBar = bar
let nextBar = this.getNextGanttBar(currentBar, side) let nextBar = this.getNextGanttBar(currentBar, side)
// left side: // left side:
if(side === "left"){ if (side === 'left') {
while (nextBar) { while (nextBar) {
let nextBarOffsetRight = nextBar.$refs['g-gantt-bar'].offsetLeft + nextBar.$refs['g-gantt-bar'].offsetWidth let nextBarOffsetRight =
gapDistanceSoFar += currentBar.$refs['g-gantt-bar'].offsetLeft - nextBarOffsetRight nextBar.$refs['g-gantt-bar'].offsetLeft +
if(nextBar.barConfig.immobile || (nextBar.barConfig.isShadow && !ignoreShadows)){ nextBar.$refs['g-gantt-bar'].offsetWidth
gapDistanceSoFar +=
currentBar.$refs['g-gantt-bar'].offsetLeft - nextBarOffsetRight
if (
nextBar.barConfig.immobile ||
(nextBar.barConfig.isShadow && !ignoreShadows)
) {
return [gapDistanceSoFar, bundleBarsAndGapDist] return [gapDistanceSoFar, bundleBarsAndGapDist]
} else if (nextBar.barConfig.bundle) { } else if (nextBar.barConfig.bundle) {
bundleBarsAndGapDist.push({bar: nextBar, gapDistance: gapDistanceSoFar}) bundleBarsAndGapDist.push({
bar: nextBar,
gapDistance: gapDistanceSoFar,
})
} }
currentBar = nextBar currentBar = nextBar
nextBar = this.getNextGanttBar(nextBar, "left") nextBar = this.getNextGanttBar(nextBar, 'left')
} }
} }
if(side === "right"){ if (side === 'right') {
while (nextBar) { while (nextBar) {
let currentBarOffsetRight = currentBar.$refs['g-gantt-bar'].offsetLeft + currentBar.$refs['g-gantt-bar'].offsetWidth let currentBarOffsetRight =
gapDistanceSoFar += nextBar.$refs['g-gantt-bar'].offsetLeft - currentBarOffsetRight currentBar.$refs['g-gantt-bar'].offsetLeft +
if(nextBar.barConfig.immobile || (nextBar.barConfig.isShadow && !ignoreShadows)){ currentBar.$refs['g-gantt-bar'].offsetWidth
gapDistanceSoFar +=
nextBar.$refs['g-gantt-bar'].offsetLeft - currentBarOffsetRight
if (
nextBar.barConfig.immobile ||
(nextBar.barConfig.isShadow && !ignoreShadows)
) {
return [gapDistanceSoFar, bundleBarsAndGapDist] return [gapDistanceSoFar, bundleBarsAndGapDist]
} else if (nextBar.barConfig.bundle) { } else if (nextBar.barConfig.bundle) {
bundleBarsAndGapDist.push({bar: nextBar, gapDistance: gapDistanceSoFar}) bundleBarsAndGapDist.push({
bar: nextBar,
gapDistance: gapDistanceSoFar,
})
} }
currentBar = nextBar currentBar = nextBar
nextBar = this.getNextGanttBar(nextBar, "right") nextBar = this.getNextGanttBar(nextBar, 'right')
} }
} }
return [null, bundleBarsAndGapDist] return [null, bundleBarsAndGapDist]
}, },
getNextGanttBar(bar, side="left"){ getNextGanttBar(bar, side = 'left') {
let allBarsLeftOrRight = [] let allBarsLeftOrRight = []
if(side === "left"){ if (side === 'left') {
allBarsLeftOrRight = bar.$parent.$children.filter(gBar => { allBarsLeftOrRight = bar.$parent.$children.filter((gBar) => {
return gBar.$options.name === GGanttBar.name return (
&& gBar.$parent === bar.$parent gBar.$options.name === GGanttBar.name &&
&& gBar.$refs['g-gantt-bar'] gBar.$parent === bar.$parent &&
&& gBar.$refs['g-gantt-bar'].offsetLeft < bar.$refs['g-gantt-bar'].offsetLeft gBar.$refs['g-gantt-bar'] &&
&& gBar.barConfig.pushOnOverlap !== false gBar.$refs['g-gantt-bar'].offsetLeft <
bar.$refs['g-gantt-bar'].offsetLeft &&
gBar.barConfig.pushOnOverlap !== false
)
}) })
} else { } else {
allBarsLeftOrRight = bar.$parent.$children.filter(gBar => { allBarsLeftOrRight = bar.$parent.$children.filter((gBar) => {
return gBar.$options.name === GGanttBar.name return (
&& gBar.$parent === bar.$parent gBar.$options.name === GGanttBar.name &&
&& gBar.$refs['g-gantt-bar'] gBar.$parent === bar.$parent &&
&& gBar.$refs['g-gantt-bar'].offsetLeft > bar.$refs['g-gantt-bar'].offsetLeft gBar.$refs['g-gantt-bar'] &&
&& gBar.barConfig.pushOnOverlap !== false gBar.$refs['g-gantt-bar'].offsetLeft >
bar.$refs['g-gantt-bar'].offsetLeft &&
gBar.barConfig.pushOnOverlap !== false
)
}) })
} }
if (allBarsLeftOrRight.length > 0) { if (allBarsLeftOrRight.length > 0) {
return allBarsLeftOrRight.reduce( return allBarsLeftOrRight.reduce((bar1, bar2) => {
(bar1, bar2) => { let bar1Dist = Math.abs(
let bar1Dist = Math.abs(bar1.$refs['g-gantt-bar'].offsetLeft - bar.$refs['g-gantt-bar'].offsetLeft) bar1.$refs['g-gantt-bar'].offsetLeft -
let bar2Dist = Math.abs(bar2.$refs['g-gantt-bar'].offsetLeft - bar.$refs['g-gantt-bar'].offsetLeft) bar.$refs['g-gantt-bar'].offsetLeft
return bar1Dist < bar2Dist ? bar1 : bar2
},
allBarsLeftOrRight[0]
) )
let bar2Dist = Math.abs(
bar2.$refs['g-gantt-bar'].offsetLeft -
bar.$refs['g-gantt-bar'].offsetLeft
)
return bar1Dist < bar2Dist ? bar1 : bar2
}, allBarsLeftOrRight[0])
} else { } else {
return null return null
} }
} },
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
}, },
// all child components of GGanttChart may have access to // all child components of GGanttChart may have access to
@@ -288,21 +362,26 @@ export default {
return { return {
getChartStart: () => this.chartStart, getChartStart: () => this.chartStart,
getChartEnd: () => this.chartEnd, getChartEnd: () => this.chartEnd,
getHourCount: () => this.hourCount, getTimeCount: () => this.timeCount,
ganttChartProps: this.$props, ganttChartProps: this.$props,
getThemeColors: () => this.themeColors, getThemeColors: () => this.themeColors,
initDragOfBarsFromBundle: (bundleId, e) => this.initDragOfBarsFromBundle(bundleId, e), initDragOfBarsFromBundle: (bundleId, e) =>
moveBarsFromBundleOfPushedBar: (bar, minuteDiff, overlapType) => this.moveBarsFromBundleOfPushedBar(bar, minuteDiff, overlapType), this.initDragOfBarsFromBundle(bundleId, e),
setDragLimitsOfGanttBar : (ganttBar) => this.setDragLimitsOfGanttBar(ganttBar), moveBarsFromBundleOfPushedBar: (bar, minuteDiff, overlapType) =>
this.moveBarsFromBundleOfPushedBar(bar, minuteDiff, overlapType),
setDragLimitsOfGanttBar: (ganttBar) =>
this.setDragLimitsOfGanttBar(ganttBar),
onBarEvent: (e, ganttBar) => this.onBarEvent(e, ganttBar), onBarEvent: (e, ganttBar) => this.onBarEvent(e, ganttBar),
onDragendBar: (e, ganttBar) => this.onDragendBar(e, ganttBar), onDragendBar: (e, ganttBar) => this.onDragendBar(e, ganttBar),
shouldSnapBackOnOverlap: () => this.snapBackOnOverlap, shouldSnapBackOnOverlap: () => this.snapBackOnOverlap,
snapBackBundle: (ganttBar) => this.snapBackBundle(ganttBar), snapBackBundle: (ganttBar) => this.snapBackBundle(ganttBar),
getMinGapBetweenBars: () => this.minGapBetweenBars, getMinGapBetweenBars: () => this.minGapBetweenBars,
getDefaultBarLength: () => this.defaultBarLength, getDefaultBarLength: () => this.defaultBarLength,
getTimeaxisMode:() => this.timeaxisMode getTimeaxisMode: () => this.timeaxisMode,
} getTimeUnit: () => this.timeUnit,
getTimeFormat: () => this.timeFormat
} }
},
} }
</script> </script>
+54 -45
View File
@@ -5,10 +5,7 @@
:style="{ height: `${$parent.rowHeight}px` }" :style="{ height: `${$parent.rowHeight}px` }"
v-on="$listeners" v-on="$listeners"
> >
<div <div class="g-gantt-row-label" :style="rowLabelStyle">
class="g-gantt-row-label"
:style="rowLabelStyle"
>
<slot name="label"> <slot name="label">
{{ label }} {{ label }}
</slot> </slot>
@@ -35,10 +32,7 @@
:all-bars-in-row="bars" :all-bars-in-row="bars"
> >
<template #bar-label="{ bar }"> <template #bar-label="{ bar }">
<slot <slot name="bar-label" :bar="bar" />
name="bar-label"
:bar="bar"
/>
</template> </template>
</g-gantt-bar> </g-gantt-bar>
</div> </div>
@@ -50,15 +44,14 @@ import GGanttBar from './GGanttBar.vue'
import moment from 'moment' import moment from 'moment'
export default { export default {
name: 'GGanttRow',
name: "GGanttRow",
components: { components: {
GGanttBar GGanttBar,
}, },
props: { props: {
label: {type: String, default: "Row"}, label: { type: String, default: 'Row' },
bars: { type: Array, default: () => [] }, bars: { type: Array, default: () => [] },
barStart: { type: String, required: true }, // property name of the bar objects that represents the start datetime barStart: { type: String, required: true }, // property name of the bar objects that represents the start datetime
barEnd: { type: String, required: true }, // property name of the bar objects that represents the end datetime, barEnd: { type: String, required: true }, // property name of the bar objects that represents the end datetime,
@@ -66,28 +59,31 @@ export default {
}, },
inject: [ inject: [
"ganttChartProps", 'ganttChartProps',
"getThemeColors", 'getThemeColors',
"getHourCount", 'getTimeCount',
"getChartStart", 'getChartStart',
"getChartEnd", 'getChartEnd',
"getDefaultBarLength" 'getDefaultBarLength',
'getTimeUnit',
'getTimeFormat',
], ],
data() { data() {
return { return {
barContainer: {} barContainer: {},
timeUnit: this.getTimeUnit(),
timeFormat: this.getTimeFormat(),
} }
}, },
computed: { computed: {
rowLabelStyle() { rowLabelStyle() {
return { return {
width: this.ganttChartProps.rowLabelWidth, width: this.ganttChartProps.rowLabelWidth,
height: this.ganttChartProps.rowHeight, height: this.ganttChartProps.rowHeight,
background: this.$parent.themeColors.ternary, background: this.$parent.themeColors.ternary,
color: this.$parent.themeColors.text color: this.$parent.themeColors.text,
} }
}, },
@@ -96,72 +92,86 @@ export default {
width: `${100 - this.ganttChartProps.rowLabelWidth.replace('%', '')}%`, width: `${100 - this.ganttChartProps.rowLabelWidth.replace('%', '')}%`,
} }
}, },
}, },
mounted() { mounted() {
this.barContainer = this.$refs.barContainer.getBoundingClientRect() this.barContainer = this.$refs.barContainer.getBoundingClientRect()
window.addEventListener("resize", this.onWindowResize) window.addEventListener('resize', this.onWindowResize)
}, },
methods: { methods: {
onDragover(e) { onDragover(e) {
e.preventDefault() // enables dropping content on row e.preventDefault() // enables dropping content on row
if (this.highlightOnHover) { if (this.highlightOnHover) {
console.log({backgroundColor: this.$refs["g-gantt-row"].style.backgroundColor }) console.log({
this.$refs["g-gantt-row"].style.backgroundColor = this.getThemeColors().hoverHighlight backgroundColor: this.$refs['g-gantt-row'].style.backgroundColor,
console.log({backgroundColor: this.$refs["g-gantt-row"].style.backgroundColor }) })
this.$refs[
'g-gantt-row'
].style.backgroundColor = this.getThemeColors().hoverHighlight
console.log({
backgroundColor: this.$refs['g-gantt-row'].style.backgroundColor,
})
} }
}, },
onDragleave() { onDragleave() {
this.$refs["g-gantt-row"].style.backgroundColor = null this.$refs['g-gantt-row'].style.backgroundColor = null
}, },
onDrop(e) { onDrop(e) {
let barContainer = this.$refs.barContainer.getBoundingClientRect() let barContainer = this.$refs.barContainer.getBoundingClientRect()
let xPos = e.clientX - barContainer.left let xPos = e.clientX - barContainer.left
let hourDiffFromStart = (xPos/barContainer.width) * this.getHourCount() let timeDiffFromStart = (xPos / barContainer.width) * this.getTimeCount()
let time = moment(this.getChartStart()).add(hourDiffFromStart, "hours") let time = moment(this.getChartStart()).add(
let bar = this.bars.find(bar => time.isBetween(bar[this.barStart], bar[this.barEnd])) timeDiffFromStart,
this.$emit("drop", {event: e, bar, time: time.format("YYYY-MM-DD HH:mm:ss")}) this.timeUnit
)
let bar = this.bars.find((bar) =>
time.isBetween(bar[this.barStart], bar[this.barEnd])
)
this.$emit('drop', { event: e, bar, time: time.format(this.timeFormat) })
}, },
onDoubleClick(e) { onDoubleClick(e) {
let barContainer = this.$refs.barContainer.getBoundingClientRect() let barContainer = this.$refs.barContainer.getBoundingClientRect()
let xPos = e.clientX - barContainer.left let xPos = e.clientX - barContainer.left
let hourDiffFromStart = (xPos/barContainer.width) * this.getHourCount() let timeDiffFromStart = (xPos / barContainer.width) * this.getTimeCount()
let time = moment(this.getChartStart()).add(hourDiffFromStart, "hours") let time = moment(this.getChartStart()).add(
let bar = {}; timeDiffFromStart,
bar[this.barStart] = time.format("YYYY-MM-DD HH:mm:ss") this.timeUnit
bar[this.barEnd] = time.add(this.getDefaultBarLength(), "hours").format("YYYY-MM-DD HH:mm:ss") )
let bar = {}
bar[this.barStart] = time
bar[this.barEnd] = time.add(this.getDefaultBarLength(), this.timeUnit)
bar.ganttBarConfig = { handles: true } bar.ganttBarConfig = { handles: true }
this.bars.push(bar) this.bars.push(bar)
}, },
onMouseover() { onMouseover() {
if (this.highlightOnHover) { if (this.highlightOnHover) {
this.$refs["g-gantt-row"].style.backgroundColor = this.getThemeColors().hoverHighlight this.$refs[
'g-gantt-row'
].style.backgroundColor = this.getThemeColors().hoverHighlight
} }
}, },
onMouseleave() { onMouseleave() {
this.$refs["g-gantt-row"].style.backgroundColor = null this.$refs['g-gantt-row'].style.backgroundColor = null
}, },
onWindowResize() { onWindowResize() {
// re-initialize the barContainer DOMRect variable, which will trigger re-rendering in the gantt bars // re-initialize the barContainer DOMRect variable, which will trigger re-rendering in the gantt bars
this.barContainer = this.$refs.barContainer.getBoundingClientRect() this.barContainer = this.$refs.barContainer.getBoundingClientRect()
} },
}, },
watch: { watch: {
'ganttChartProps.rowLabelWidth': function () { 'ganttChartProps.rowLabelWidth': function () {
this.barContainer = this.$refs.barContainer.getBoundingClientRect() this.barContainer = this.$refs.barContainer.getBoundingClientRect()
} },
} },
} }
</script> </script>
@@ -178,7 +188,7 @@ export default {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 20%; width: 20%;
background: #E8E8E8; background: #e8e8e8;
color: #424242; color: #424242;
font-size: 0.9em; font-size: 0.9em;
z-index: 3; z-index: 3;
@@ -192,5 +202,4 @@ export default {
width: 70%; width: 70%;
border-bottom: 1px solid #eaeaea; border-bottom: 1px solid #eaeaea;
} }
</style> </style>
+7 -7
View File
@@ -55,7 +55,7 @@ import moment from 'moment'
export default { export default {
name: 'GGanttTimeaxis', name: 'GGanttTimeaxis',
inject: ['getTimeaxisMode'], inject: ['getTimeaxisMode', 'getTimeUnit', 'getTimeFormat'],
props: { props: {
chartStart: String, chartStart: String,
@@ -74,6 +74,8 @@ export default {
hourFontSize: '11px', hourFontSize: '11px',
dayFormat: 'MM-DD', // ISO 8601 dayFormat: 'MM-DD', // ISO 8601
mode: this.getTimeaxisMode(), mode: this.getTimeaxisMode(),
timeUnit: this.getTimeUnit(),
timeFormat: this.getTimeFormat()
} }
}, },
@@ -100,8 +102,7 @@ export default {
let end = moment(this.chartEnd) let end = moment(this.chartEnd)
this.childPointCount = Math.floor(end.diff(start, 'day', true)) this.childPointCount = Math.floor(end.diff(start, 'day', true))
while (start.isBefore(end)) { while (start.isBefore(end)) {
let dayCountOfMonth = let dayCountOfMonth = start.isSame(end, 'month')
start.isSame(end, 'day')
? end.date() ? end.date()
: start.daysInMonth() - start.date() + 1 : start.daysInMonth() - start.date() + 1
let widthPercentage = (dayCountOfMonth / this.childPointCount) * 100 let widthPercentage = (dayCountOfMonth / this.childPointCount) * 100
@@ -119,8 +120,7 @@ export default {
let end = moment(this.chartEnd) let end = moment(this.chartEnd)
this.childPointCount = Math.floor(end.diff(start, 'hour', true)) this.childPointCount = Math.floor(end.diff(start, 'hour', true))
while (start.isBefore(end)) { while (start.isBefore(end)) {
let hourCountOfDay = let hourCountOfDay = start.isSame(end, 'day')
start.isSame(end, 'day')
? end.hour() ? end.hour()
: 24 - start.hour() : 24 - start.hour()
@@ -144,7 +144,7 @@ export default {
for (let i = 0; i <= endDay - startDay; i++) { for (let i = 0; i <= endDay - startDay; i++) {
let day = { let day = {
text: datetimeMoment.format('D'), text: datetimeMoment.format('D'),
fullDatetime: datetimeMoment.format('YYYY-MM-DD'), // ISO 8601 fullDatetime: datetimeMoment.format(this.timeFormat),
} }
axisMonthObject.ganttDays.push(day) axisMonthObject.ganttDays.push(day)
datetimeMoment.add(1, 'day') datetimeMoment.add(1, 'day')
@@ -163,7 +163,7 @@ export default {
for (let i = 0; i <= endHour - startHour; i++) { for (let i = 0; i <= endHour - startHour; i++) {
let hour = { let hour = {
text: datetimeMoment.format('HH'), text: datetimeMoment.format('HH'),
fullDatetime: datetimeMoment.format('YYYY-MM-DD HH:mm'), // ISO 8601 fullDatetime: datetimeMoment.format(this.timeFormat),
} }
axisDayObject.ganttHours.push(hour) axisDayObject.ganttHours.push(hour)
datetimeMoment.add(1, 'hour') datetimeMoment.add(1, 'hour')