mirror of
https://github.com/tenrok/vue-ganttastic.git
synced 2026-06-25 11:00:33 +03:00
feat: scrolling
This commit is contained in:
+6
-1
@@ -273,8 +273,13 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
drag(e) {
|
drag(e) {
|
||||||
|
const chart = document.querySelector('#g-gantt-chart')
|
||||||
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 =
|
||||||
|
chart.scrollLeft +
|
||||||
|
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
|
||||||
|
|||||||
+17
-14
@@ -21,7 +21,14 @@
|
|||||||
:highlighted-hours="highlightedHours"
|
:highlighted-hours="highlightedHours"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div id="g-gantt-rows-container">
|
<div
|
||||||
|
id="g-gantt-rows-container"
|
||||||
|
:style="{
|
||||||
|
width: `${
|
||||||
|
timeCount * 30 + parseInt(rowLabelWidth.replace('px', ''))
|
||||||
|
}px`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<slot />
|
<slot />
|
||||||
<!-- the g-gantt-row components go here -->
|
<!-- the g-gantt-row components go here -->
|
||||||
</div>
|
</div>
|
||||||
@@ -48,7 +55,7 @@ export default {
|
|||||||
chartStart: { type: String },
|
chartStart: { type: String },
|
||||||
chartEnd: { type: String },
|
chartEnd: { type: String },
|
||||||
hideTimeaxis: Boolean,
|
hideTimeaxis: Boolean,
|
||||||
rowLabelWidth: { type: String, default: '10%' },
|
rowLabelWidth: { type: String, default: '200px' },
|
||||||
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 },
|
||||||
@@ -188,7 +195,7 @@ export default {
|
|||||||
let movedBars = didSnapBack ? new Set() : this.movedBarsInDrag
|
let movedBars = didSnapBack ? new Set() : this.movedBarsInDrag
|
||||||
// Magnetic suction
|
// Magnetic suction
|
||||||
if (movedBars.size && this.isMagnetic) {
|
if (movedBars.size && this.isMagnetic) {
|
||||||
let { left, right/*, move*/ } = action
|
let { left, right /*, move*/ } = action
|
||||||
|
|
||||||
movedBars.forEach((bar) => {
|
movedBars.forEach((bar) => {
|
||||||
if (this.timeaxisMode === 'month_days') {
|
if (this.timeaxisMode === 'month_days') {
|
||||||
@@ -286,10 +293,8 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for (let side of ['left', 'right']) {
|
for (let side of ['left', 'right']) {
|
||||||
let [
|
let [totalGapDistance, bundleBarsOnPath] =
|
||||||
totalGapDistance,
|
this.countGapDistanceToNextImmobileBar(bar, null, side, false)
|
||||||
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
|
||||||
@@ -297,10 +302,8 @@ export default {
|
|||||||
barFromBundle.barConfig.bundle
|
barFromBundle.barConfig.bundle
|
||||||
).filter((otherBar) => otherBar !== barFromBundle)
|
).filter((otherBar) => otherBar !== barFromBundle)
|
||||||
otherBarsFromBundle.forEach((otherBar) => {
|
otherBarsFromBundle.forEach((otherBar) => {
|
||||||
let [
|
let [newGapDistance, newBundleBars] =
|
||||||
newGapDistance,
|
this.countGapDistanceToNextImmobileBar(otherBar, gapDist, side)
|
||||||
newBundleBars,
|
|
||||||
] = this.countGapDistanceToNextImmobileBar(otherBar, gapDist, side)
|
|
||||||
if (
|
if (
|
||||||
newGapDistance !== null &&
|
newGapDistance !== null &&
|
||||||
(newGapDistance < totalGapDistance || !totalGapDistance)
|
(newGapDistance < totalGapDistance || !totalGapDistance)
|
||||||
@@ -479,9 +482,9 @@ export default {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
#g-gantt-chart {
|
#g-gantt-chart {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
/* display: flex; */
|
||||||
flex-direction: column;
|
/* flex-direction: column; */
|
||||||
overflow-x: hidden;
|
overflow: auto;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-khtml-user-select: none;
|
-khtml-user-select: none;
|
||||||
|
|||||||
+4
-4
@@ -3,7 +3,7 @@
|
|||||||
class="g-grid-container"
|
class="g-grid-container"
|
||||||
:style="{
|
:style="{
|
||||||
left: rowLabelWidth,
|
left: rowLabelWidth,
|
||||||
width: `${100 - this.rowLabelWidth.replace('%', '')}%`,
|
width: `${getTimeCount() * 30}px`,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -23,7 +23,7 @@ import moment from 'moment'
|
|||||||
export default {
|
export default {
|
||||||
name: 'GGanttGrid',
|
name: 'GGanttGrid',
|
||||||
|
|
||||||
inject: ['ganttChartProps'],
|
inject: ['ganttChartProps', 'getTimeCount'],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
chartStart: { type: String },
|
chartStart: { type: String },
|
||||||
@@ -57,8 +57,8 @@ export default {
|
|||||||
.g-grid-container {
|
.g-grid-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 30%; /* must correspond to width of row title */
|
/* left: 30%; must correspond to width of row title */
|
||||||
width: 70%;
|
/* width: 70%; */
|
||||||
height: calc(100% - 23px);
|
height: calc(100% - 23px);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|||||||
+8
-3
@@ -85,7 +85,9 @@ export default {
|
|||||||
|
|
||||||
barsContainerStyle() {
|
barsContainerStyle() {
|
||||||
return {
|
return {
|
||||||
width: `${100 - this.ganttChartProps.rowLabelWidth.replace('%', '')}%`,
|
width: `${
|
||||||
|
100 /*- this.ganttChartProps.rowLabelWidth.replace('%', '')*/
|
||||||
|
}%`,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -193,19 +195,22 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
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;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
left: 0;
|
||||||
|
position: sticky;
|
||||||
}
|
}
|
||||||
|
|
||||||
.g-gantt-row > .g-gantt-row-bars-container {
|
.g-gantt-row > .g-gantt-row-bars-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
border-top: 1px solid #eaeaea;
|
border-top: 1px solid #eaeaea;
|
||||||
width: 70%;
|
/* width: 70%; */
|
||||||
border-bottom: 1px solid #eaeaea;
|
border-bottom: 1px solid #eaeaea;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
+24
-18
@@ -1,25 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="g-timeaxis">
|
<div
|
||||||
|
id="g-timeaxis"
|
||||||
|
:style="{
|
||||||
|
width: `${
|
||||||
|
getTimeCount() * 30 + parseInt(rowLabelWidth.replace('px', ''))
|
||||||
|
}px`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="g-timeaxis-empty-space"
|
class="g-timeaxis-empty-space"
|
||||||
:style="{ width: rowLabelWidth, background: themeColors.secondary }"
|
:style="{ minWidth: rowLabelWidth, background: themeColors.secondary }"
|
||||||
/>
|
/>
|
||||||
<div
|
<div class="g-timeaxis-days">
|
||||||
class="g-timeaxis-days"
|
|
||||||
:style="{ width: `${100 - rowLabelWidth.replace('%', '')}%` }"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
v-for="(point, index) in axisPoints"
|
v-for="(point, index) in axisPoints"
|
||||||
:key="point.text"
|
:key="point.text"
|
||||||
class="g-timeaxis-day"
|
class="g-timeaxis-day"
|
||||||
:style="{
|
:style="{
|
||||||
width: point.widthPercentage + '%',
|
|
||||||
background:
|
background:
|
||||||
index % 2 === 0 ? themeColors.primary : themeColors.secondary,
|
index % 2 === 0 ? themeColors.primary : themeColors.secondary,
|
||||||
color: themeColors.text,
|
color: themeColors.text,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div v-html="pointFormatted(point)||' '"></div>
|
<div v-html="pointFormatted(point) || ' '"></div>
|
||||||
<div
|
<div
|
||||||
:style="{ background: themeColors.ternary, color: themeColors.text }"
|
:style="{ background: themeColors.ternary, color: themeColors.text }"
|
||||||
>
|
>
|
||||||
@@ -28,7 +31,7 @@
|
|||||||
:key="childPoint.fullDatetime"
|
:key="childPoint.fullDatetime"
|
||||||
class="g-timeaxis-hour"
|
class="g-timeaxis-hour"
|
||||||
:style="{
|
:style="{
|
||||||
width: childPoint.widthPercentage + '%',
|
width: '30px',
|
||||||
background:
|
background:
|
||||||
index % 2 === 0 ? themeColors.primary : themeColors.secondary,
|
index % 2 === 0 ? themeColors.primary : themeColors.secondary,
|
||||||
color: themeColors.text,
|
color: themeColors.text,
|
||||||
@@ -55,7 +58,7 @@ import moment from 'moment'
|
|||||||
export default {
|
export default {
|
||||||
name: 'GGanttTimeaxis',
|
name: 'GGanttTimeaxis',
|
||||||
|
|
||||||
inject: ['ganttChartProps', 'getTimeUnit', 'getTimeFormat'],
|
inject: ['ganttChartProps', 'getTimeUnit', 'getTimeFormat', 'getTimeCount'],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
chartStart: String,
|
chartStart: String,
|
||||||
@@ -230,29 +233,32 @@ export default {
|
|||||||
.g-timeaxis-day,
|
.g-timeaxis-day,
|
||||||
.g-timeaxis-day > div {
|
.g-timeaxis-day > div {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
/* overflow: hidden; */
|
||||||
}
|
}
|
||||||
|
|
||||||
#g-timeaxis {
|
#g-timeaxis {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
/* width: 100%; */
|
||||||
height: 8%;
|
/* height: 8%; */
|
||||||
min-height: 75px;
|
/* min-height: 75px; */
|
||||||
background: white;
|
background: white;
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
box-shadow: 0px 1px 3px 2px rgba(50, 50, 50, 0.5);
|
box-shadow: 0px 1px 3px 2px rgba(50, 50, 50, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#g-timeaxis > .g-timeaxis-empty-space {
|
#g-timeaxis > .g-timeaxis-empty-space {
|
||||||
width: 20%; /* this has to be as wide as .ganttRowTitle in VGanttastic.css */
|
/* width: 20%; this has to be as wide as .ganttRowTitle in VGanttastic.css */
|
||||||
height: 100%;
|
min-height: 100%;
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
|
z-index: 5;
|
||||||
|
left: 0;
|
||||||
|
position: sticky;
|
||||||
}
|
}
|
||||||
|
|
||||||
#g-timeaxis > .g-timeaxis-days {
|
#g-timeaxis > .g-timeaxis-days {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 80%;
|
/* width: 80%; */
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +296,7 @@ export default {
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
width: 100%;
|
/* width: 100%; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.g-timeaxis-hour-pin {
|
.g-timeaxis-hour-pin {
|
||||||
|
|||||||
+6
-6
@@ -11,7 +11,7 @@
|
|||||||
timeaxisMode="day_hours"
|
timeaxisMode="day_hours"
|
||||||
:is-magnetic="isMagnetic"
|
:is-magnetic="isMagnetic"
|
||||||
:highlighted-hours="highlightedHours"
|
:highlighted-hours="highlightedHours"
|
||||||
:row-label-width="`${rowLabelWidth}%`"
|
:row-label-width="rowLabelWidth"
|
||||||
:row-height="rowHeight"
|
:row-height="rowHeight"
|
||||||
:theme="selectedTheme"
|
:theme="selectedTheme"
|
||||||
barStartKey="myStart"
|
barStartKey="myStart"
|
||||||
@@ -46,12 +46,12 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
chartStart: '2020-03-02 00:00',
|
chartStart: '2020-03-02 00:00',
|
||||||
chartEnd: '2020-03-04 00:00',
|
chartEnd: '2020-03-05 10:00',
|
||||||
pushOnOverlap: true,
|
pushOnOverlap: true,
|
||||||
isMagnetic: true,
|
isMagnetic: true,
|
||||||
grid: true,
|
grid: true,
|
||||||
rowHeight: 40,
|
rowHeight: 40,
|
||||||
rowLabelWidth: 15,
|
rowLabelWidth: '200px',
|
||||||
hideTimeaxis: false,
|
hideTimeaxis: false,
|
||||||
highlightOnHover: false,
|
highlightOnHover: false,
|
||||||
hours: [...Array(24).keys()],
|
hours: [...Array(24).keys()],
|
||||||
@@ -166,7 +166,7 @@ export default {
|
|||||||
color: 'white',
|
color: 'white',
|
||||||
backgroundColor: '#5effad',
|
backgroundColor: '#5effad',
|
||||||
pushOnOverlap: false,
|
pushOnOverlap: false,
|
||||||
zIndex: 3,
|
zIndex: 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -213,8 +213,8 @@ export default {
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
onDragend(e) {
|
onDragend(e) {
|
||||||
let {event, bar} = e
|
let { event, bar } = e
|
||||||
console.log('onDragend', {event: event.type, bar})
|
console.log('onDragend', { event: event.type, bar })
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user