horizontal scroll custom handler has been added

This commit is contained in:
MaTeMaTuK committed 2021-05-03 10:23:24 +03:00
1 parent a2fb41a155
commit 33143f4b8c
12 files changed
+4390 -8589

No files matched your search

+2 -3
View File
@@ -1,6 +1,5 @@
.ganttVerticalContainer {
overflow-x: auto;
overflow-y: hidden;
overflow: hidden;
font-size: 0;
margin: 0;
padding: 0;
@@ -9,7 +8,7 @@
.horizontalContainer {
margin: 0;
padding: 0;
overflow-y: hidden;
overflow: hidden;
}
.wrapper {
+65 -35
View File
@@ -7,7 +7,7 @@ import { TaskGanttContentProps } from "./task-gantt-content";
import { TaskListHeaderDefault } from "../task-list/task-list-header";
import { TaskListTableDefault } from "../task-list/task-list-table";
import { StandardTooltipContent } from "../other/tooltip";
import { Scroll } from "../other/scroll";
import { VerticalScroll } from "../other/vertical-scroll";
import { TaskListProps, TaskList } from "../task-list/task-list";
import { TaskGantt } from "./task-gantt";
import { BarTask } from "../../types/bar-task";
@@ -15,6 +15,7 @@ import { convertToBarTasks } from "../../helpers/bar-helper";
import { GanttEvent } from "../../types/gantt-task-actions";
import { DateSetup } from "../../types/date-setup";
import styles from "./gantt.module.css";
import { HorizontalScroll } from "../other/horizontal-scroll";
export const Gantt: React.FunctionComponent<GanttProps> = ({
tasks,
@@ -54,12 +55,15 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
onSelect,
}) => {
const wrapperRef = useRef<HTMLDivElement>(null);
const taskListRef = useRef<HTMLDivElement>(null);
const verticalGanttContainerRef = useRef<HTMLDivElement>(null);
const [dateSetup, setDateSetup] = useState<DateSetup>(() => {
const [startDate, endDate] = ganttDateRange(tasks, viewMode);
return { viewMode, dates: seedDates(startDate, endDate, viewMode) };
});
const [taskHeight, setTaskHeight] = useState((rowHeight * barFill) / 100);
const [taskListWidth, setTaskListWidth] = useState(0);
const [barTasks, setBarTasks] = useState<BarTask[]>([]);
const [ganttEvent, setGanttEvent] = useState<GanttEvent>({
action: "",
@@ -165,27 +169,43 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
}
}, [rowHeight, barFill, taskHeight]);
useEffect(() => {
if (taskListRef.current) {
setTaskListWidth(taskListRef.current.offsetWidth);
}
}, [taskListRef]);
// scroll events
useEffect(() => {
const handleWheel = (event: WheelEvent) => {
event.preventDefault();
const newScrollY = scrollY + event.deltaY;
if (newScrollY < 0) {
setScrollY(0);
} else if (newScrollY > ganttFullHeight - ganttHeight) {
setScrollY(ganttFullHeight - ganttHeight);
if (event.shiftKey || event.deltaX) {
const scrollMove = event.deltaX ? event.deltaX : event.deltaY;
let newScrollX = scrollX + scrollMove;
if (newScrollX < 0) {
newScrollX = 0;
} else if (newScrollX > svgWidth) {
newScrollX = svgWidth;
}
setScrollX(newScrollX);
event.preventDefault();
} else {
setScrollY(newScrollY);
let newScrollY = scrollY + event.deltaY;
if (newScrollY < 0) {
newScrollY = 0;
} else if (newScrollY > ganttFullHeight - ganttHeight) {
newScrollY = ganttFullHeight - ganttHeight;
}
if (newScrollY !== scrollY) {
setScrollY(newScrollY);
event.preventDefault();
}
}
setIgnoreScrollEvent(true);
};
// subscribe if scroll is necessary
if (
wrapperRef.current &&
ganttHeight &&
ganttHeight < barTasks.length * rowHeight
) {
if (wrapperRef.current) {
wrapperRef.current.addEventListener("wheel", handleWheel, {
passive: false,
});
@@ -195,7 +215,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
wrapperRef.current.removeEventListener("wheel", handleWheel);
}
};
}, [wrapperRef.current, scrollY, ganttHeight, barTasks, rowHeight]);
}, [wrapperRef.current, scrollY, scrollX, ganttHeight, svgWidth]);
const handleScrollY = (event: SyntheticEvent<HTMLDivElement>) => {
if (scrollY !== event.currentTarget.scrollTop && !ignoreScrollEvent) {
@@ -330,34 +350,44 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
ganttHeight,
horizontalContainerClass: styles.horizontalContainer,
selectedTask,
taskListRef,
setSelectedTask: handleSelectedTask,
TaskListHeader,
TaskListTable,
};
return (
<div
className={styles.wrapper}
onKeyDown={handleKeyDown}
tabIndex={0}
ref={wrapperRef}
>
{listCellWidth && <TaskList {...tableProps} />}
<TaskGantt
gridProps={gridProps}
calendarProps={calendarProps}
barProps={barProps}
ganttHeight={ganttHeight}
scrollY={scrollY}
scrollX={scrollX}
<div>
<div
className={styles.wrapper}
onKeyDown={handleKeyDown}
tabIndex={0}
ref={wrapperRef}
// onWheel={handleWheel}
>
{listCellWidth && <TaskList {...tableProps} />}
<TaskGantt
gridProps={gridProps}
calendarProps={calendarProps}
barProps={barProps}
ganttHeight={ganttHeight}
scrollY={scrollY}
scrollX={scrollX}
verticalGanttContainerRef={verticalGanttContainerRef}
/>
<VerticalScroll
ganttFullHeight={ganttFullHeight}
ganttHeight={ganttHeight}
headerHeight={headerHeight}
scroll={scrollY}
onScroll={handleScrollY}
/>
</div>
<HorizontalScroll
svgWidth={svgWidth}
taskListWidth={taskListWidth}
scroll={scrollX}
onScroll={handleScrollX}
/>
<Scroll
ganttFullHeight={ganttFullHeight}
ganttHeight={ganttHeight}
headerHeight={headerHeight}
scroll={scrollY}
onScroll={handleScrollY}
/>
</div>
);
};
+8 -10
View File
@@ -1,4 +1,4 @@
import React, { useRef, useEffect, SyntheticEvent, useState } from "react";
import React, { useRef, useEffect, useState } from "react";
import { GridProps, Grid } from "../grid/grid";
import { CalendarProps, Calendar } from "../calendar/calendar";
import { TaskGanttContentProps, TaskGanttContent } from "./task-gantt-content";
@@ -11,7 +11,7 @@ export type TaskGanttProps = {
ganttHeight: number;
scrollY: number;
scrollX: number;
onScroll: (event: SyntheticEvent<HTMLDivElement>) => void;
verticalGanttContainerRef: React.RefObject<HTMLDivElement>;
};
export const TaskGantt: React.FC<TaskGanttProps> = ({
gridProps,
@@ -20,11 +20,10 @@ export const TaskGantt: React.FC<TaskGanttProps> = ({
ganttHeight,
scrollY,
scrollX,
onScroll,
verticalGanttContainerRef,
}) => {
const ganttSVGRef = useRef<SVGSVGElement>(null);
const horizontalContainerRef = useRef<HTMLDivElement>(null);
const verticalContainerRef = useRef<HTMLDivElement>(null);
const [displayXStartEndpoint, setDisplayXStartEndpoint] = useState({
start: 0,
end: 0,
@@ -38,21 +37,20 @@ export const TaskGantt: React.FC<TaskGanttProps> = ({
}, [scrollY]);
useEffect(() => {
if (verticalContainerRef.current) {
verticalContainerRef.current.scrollLeft = scrollX;
if (verticalGanttContainerRef.current) {
verticalGanttContainerRef.current.scrollLeft = scrollX;
setDisplayXStartEndpoint({
start: scrollX,
end: verticalContainerRef.current.clientWidth + scrollX,
end: verticalGanttContainerRef.current.clientWidth + scrollX,
});
}
// verticalContainerRef.current?.clientWidth need for resize window tracking
}, [scrollX, verticalContainerRef.current?.clientWidth]);
}, [scrollX, verticalGanttContainerRef.current?.clientWidth]);
return (
<div
className={styles.ganttVerticalContainer}
ref={verticalContainerRef}
onScroll={onScroll}
ref={verticalGanttContainerRef}
>
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -0,0 +1,4 @@
.scroll {
overflow: auto;
max-width: 100%;
}
@@ -0,0 +1,28 @@
import React, { SyntheticEvent, useRef, useEffect } from "react";
import styles from "./horizontal-scroll.module.css";
export const HorizontalScroll: React.FC<{
scroll: number;
svgWidth: number;
taskListWidth: number;
onScroll: (event: SyntheticEvent<HTMLDivElement>) => void;
}> = ({ scroll, svgWidth, taskListWidth, onScroll }) => {
const scrollRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollLeft = scroll;
}
}, [scroll]);
return (
<div
style={{ marginLeft: taskListWidth }}
className={styles.scroll}
onScroll={onScroll}
ref={scrollRef}
>
<div style={{ width: svgWidth, height: 1 }} />
</div>
);
};
@@ -1,7 +1,7 @@
import React, { SyntheticEvent, useRef, useEffect } from "react";
import styles from "./scroll.module.css";
import styles from "./vertical-scroll.module.css";
export const Scroll: React.FC<{
export const VerticalScroll: React.FC<{
scroll: number;
ganttHeight: number;
ganttFullHeight: number;
+3 -1
View File
@@ -12,6 +12,7 @@ export type TaskListProps = {
scrollY: number;
locale: string;
tasks: Task[];
taskListRef: React.RefObject<HTMLDivElement>;
horizontalContainerClass?: string;
selectedTask: BarTask | undefined;
setSelectedTask: (task: string) => void;
@@ -45,6 +46,7 @@ export const TaskList: React.FC<TaskListProps> = ({
setSelectedTask,
locale,
ganttHeight,
taskListRef,
horizontalContainerClass,
TaskListHeader,
TaskListTable,
@@ -75,7 +77,7 @@ export const TaskList: React.FC<TaskListProps> = ({
};
return (
<div>
<div ref={taskListRef}>
<TaskListHeader {...headerProps} />
<div
ref={horizontalContainerRef}
-1
View File
@@ -156,7 +156,6 @@ const convertToBar = (
barBackgroundColor: string,
barBackgroundSelectedColor: string
): BarTask => {
debugger;
const x1 = taskXCoordinate(task.start, dates, dateDelta, columnWidth);
let x2 = taskXCoordinate(task.end, dates, dateDelta, columnWidth);
const y = taskYCoordinate(index, rowHeight, taskHeight);