rtl experiment

This commit is contained in:
MaTeMaTuK 2021-06-28 23:15:53 +03:00
parent e4a2cc02dc
commit 6c51146f91
11 changed files with 106 additions and 49 deletions

View File

@ -64,17 +64,20 @@ const App = () => {
isChecked={isChecked} isChecked={isChecked}
/> />
<h3>Gantt With Unlimited Height</h3> <h3>Gantt With Unlimited Height</h3>
<Gantt <div dir="rtl">
tasks={tasks} <Gantt
viewMode={view} tasks={tasks}
onDateChange={onTaskChange} viewMode={view}
onDelete={onTaskDelete} onDateChange={onTaskChange}
onProgressChange={onProgressChange} onDelete={onTaskDelete}
onDoubleClick={onDblClick} onProgressChange={onProgressChange}
onSelect={onSelect} onDoubleClick={onDblClick}
listCellWidth={isChecked ? "155px" : ""} onSelect={onSelect}
columnWidth={columnWidth} listCellWidth={isChecked ? "155px" : ""}
/> columnWidth={columnWidth}
rtl={true}
/>
</div>
<h3>Gantt With Limited Height</h3> <h3>Gantt With Limited Height</h3>
<Gantt <Gantt
tasks={tasks} tasks={tasks}

View File

@ -38,6 +38,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
projectBackgroundSelectedColor = "#f7bb53", projectBackgroundSelectedColor = "#f7bb53",
milestoneBackgroundColor = "#f1c453", milestoneBackgroundColor = "#f1c453",
milestoneBackgroundSelectedColor = "#f29e4c", milestoneBackgroundSelectedColor = "#f29e4c",
rtl = false,
handleWidth = 8, handleWidth = 8,
timeStep = 300000, timeStep = 300000,
arrowColor = "grey", arrowColor = "grey",
@ -83,7 +84,10 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
// task change events // task change events
useEffect(() => { useEffect(() => {
const [startDate, endDate] = ganttDateRange(tasks, viewMode); const [startDate, endDate] = ganttDateRange(tasks, viewMode);
const newDates = seedDates(startDate, endDate, viewMode); let newDates = seedDates(startDate, endDate, viewMode);
if (rtl) {
newDates = newDates.reverse();
}
setDateSetup({ dates: newDates, viewMode }); setDateSetup({ dates: newDates, viewMode });
setBarTasks( setBarTasks(
convertToBarTasks( convertToBarTasks(
@ -94,6 +98,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
taskHeight, taskHeight,
barCornerRadius, barCornerRadius,
handleWidth, handleWidth,
rtl,
barProgressColor, barProgressColor,
barProgressSelectedColor, barProgressSelectedColor,
barBackgroundColor, barBackgroundColor,
@ -124,6 +129,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
projectBackgroundSelectedColor, projectBackgroundSelectedColor,
milestoneBackgroundColor, milestoneBackgroundColor,
milestoneBackgroundSelectedColor, milestoneBackgroundSelectedColor,
rtl,
]); ]);
useEffect(() => { useEffect(() => {
@ -344,6 +350,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
fontSize, fontSize,
arrowIndent, arrowIndent,
svgWidth, svgWidth,
rtl,
setGanttEvent, setGanttEvent,
setFailedTask, setFailedTask,
setSelectedTask: handleSelectedTask, setSelectedTask: handleSelectedTask,
@ -415,6 +422,7 @@ export const Gantt: React.FunctionComponent<GanttProps> = ({
svgWidth={svgWidth} svgWidth={svgWidth}
taskListWidth={taskListWidth} taskListWidth={taskListWidth}
scroll={scrollX} scroll={scrollX}
rtl={rtl}
onScroll={handleScrollX} onScroll={handleScrollX}
/> />
</div> </div>

View File

@ -26,6 +26,7 @@ export type TaskGanttContentProps = {
arrowIndent: number; arrowIndent: number;
fontSize: string; fontSize: string;
fontFamily: string; fontFamily: string;
rtl: boolean;
setGanttEvent: (value: GanttEvent) => void; setGanttEvent: (value: GanttEvent) => void;
setFailedTask: (value: BarTask | null) => void; setFailedTask: (value: BarTask | null) => void;
setSelectedTask: (taskId: string) => void; setSelectedTask: (taskId: string) => void;
@ -45,6 +46,7 @@ export const TaskGanttContent: React.FC<TaskGanttContentProps> = ({
arrowIndent, arrowIndent,
fontFamily, fontFamily,
fontSize, fontSize,
rtl,
setGanttEvent, setGanttEvent,
setFailedTask, setFailedTask,
setSelectedTask, setSelectedTask,
@ -85,7 +87,8 @@ export const TaskGanttContent: React.FC<TaskGanttContentProps> = ({
ganttEvent.changedTask, ganttEvent.changedTask,
xStep, xStep,
timeStep, timeStep,
initEventX1Delta initEventX1Delta,
rtl
); );
if (isChanged) { if (isChanged) {
setGanttEvent({ action: ganttEvent.action, changedTask }); setGanttEvent({ action: ganttEvent.action, changedTask });
@ -108,7 +111,8 @@ export const TaskGanttContent: React.FC<TaskGanttContentProps> = ({
changedTask, changedTask,
xStep, xStep,
timeStep, timeStep,
initEventX1Delta initEventX1Delta,
rtl
); );
const isNotLikeOriginal = const isNotLikeOriginal =

View File

@ -5,8 +5,9 @@ export const HorizontalScroll: React.FC<{
scroll: number; scroll: number;
svgWidth: number; svgWidth: number;
taskListWidth: number; taskListWidth: number;
rtl: boolean;
onScroll: (event: SyntheticEvent<HTMLDivElement>) => void; onScroll: (event: SyntheticEvent<HTMLDivElement>) => void;
}> = ({ scroll, svgWidth, taskListWidth, onScroll }) => { }> = ({ scroll, svgWidth, taskListWidth, rtl, onScroll }) => {
const scrollRef = useRef<HTMLDivElement>(null); const scrollRef = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
@ -17,7 +18,11 @@ export const HorizontalScroll: React.FC<{
return ( return (
<div <div
style={{ marginLeft: taskListWidth }} style={{
margin: rtl
? `0px ${taskListWidth}px 0px 0px`
: `0px 0px 0px ${taskListWidth}px`,
}}
className={styles.scroll} className={styles.scroll}
onScroll={onScroll} onScroll={onScroll}
ref={scrollRef} ref={scrollRef}

View File

@ -7,6 +7,8 @@ type BarDisplayProps = {
width: number; width: number;
height: number; height: number;
isSelected: boolean; isSelected: boolean;
/* progress start point */
progressX: number;
progressWidth: number; progressWidth: number;
barCornerRadius: number; barCornerRadius: number;
styles: { styles: {
@ -23,6 +25,7 @@ export const BarDisplay: React.FC<BarDisplayProps> = ({
width, width,
height, height,
isSelected, isSelected,
progressX,
progressWidth, progressWidth,
barCornerRadius, barCornerRadius,
styles, styles,
@ -49,7 +52,7 @@ export const BarDisplay: React.FC<BarDisplayProps> = ({
className={style.barBackground} className={style.barBackground}
/> />
<rect <rect
x={x} x={progressX}
width={progressWidth} width={progressWidth}
y={y} y={y}
height={height} height={height}

View File

@ -1,8 +1,5 @@
import React from "react"; import React from "react";
import { import { getProgressPoint } from "../../../helpers/bar-helper";
progressWithByParams,
getProgressPoint,
} from "../../../helpers/bar-helper";
import { BarDisplay } from "./bar-display"; import { BarDisplay } from "./bar-display";
import { BarProgressHandle } from "./bar-progress-handle"; import { BarProgressHandle } from "./bar-progress-handle";
import { TaskItemProps } from "../task-item"; import { TaskItemProps } from "../task-item";
@ -15,9 +12,8 @@ export const BarSmall: React.FC<TaskItemProps> = ({
onEventStart, onEventStart,
isSelected, isSelected,
}) => { }) => {
const progressWidth = progressWithByParams(task.x1, task.x2, task.progress);
const progressPoint = getProgressPoint( const progressPoint = getProgressPoint(
progressWidth + task.x1, task.progressWidth + task.x1,
task.y, task.y,
task.height task.height
); );
@ -28,7 +24,8 @@ export const BarSmall: React.FC<TaskItemProps> = ({
y={task.y} y={task.y}
width={task.x2 - task.x1} width={task.x2 - task.x1}
height={task.height} height={task.height}
progressWidth={progressWidth} progressX={task.progressX}
progressWidth={task.progressWidth}
barCornerRadius={task.barCornerRadius} barCornerRadius={task.barCornerRadius}
styles={task.styles} styles={task.styles}
isSelected={isSelected} isSelected={isSelected}

View File

@ -1,8 +1,5 @@
import React from "react"; import React from "react";
import { import { getProgressPoint } from "../../../helpers/bar-helper";
progressWithByParams,
getProgressPoint,
} from "../../../helpers/bar-helper";
import { BarDisplay } from "./bar-display"; import { BarDisplay } from "./bar-display";
import { BarDateHandle } from "./bar-date-handle"; import { BarDateHandle } from "./bar-date-handle";
import { BarProgressHandle } from "./bar-progress-handle"; import { BarProgressHandle } from "./bar-progress-handle";
@ -16,9 +13,8 @@ export const Bar: React.FC<TaskItemProps> = ({
onEventStart, onEventStart,
isSelected, isSelected,
}) => { }) => {
const progressWidth = progressWithByParams(task.x1, task.x2, task.progress);
const progressPoint = getProgressPoint( const progressPoint = getProgressPoint(
progressWidth + task.x1, task.progressWidth + task.x1,
task.y, task.y,
task.height task.height
); );
@ -30,7 +26,8 @@ export const Bar: React.FC<TaskItemProps> = ({
y={task.y} y={task.y}
width={task.x2 - task.x1} width={task.x2 - task.x1}
height={task.height} height={task.height}
progressWidth={progressWidth} progressX={task.progressX}
progressWidth={task.progressWidth}
barCornerRadius={task.barCornerRadius} barCornerRadius={task.barCornerRadius}
styles={task.styles} styles={task.styles}
isSelected={isSelected} isSelected={isSelected}

View File

@ -1,5 +1,4 @@
import React from "react"; import React from "react";
import { progressWithByParams } from "../../../helpers/bar-helper";
import { TaskItemProps } from "../task-item"; import { TaskItemProps } from "../task-item";
import styles from "./project.module.css"; import styles from "./project.module.css";
@ -10,7 +9,6 @@ export const Project: React.FC<TaskItemProps> = ({ task, isSelected }) => {
const processColor = isSelected const processColor = isSelected
? task.styles.progressSelectedColor ? task.styles.progressSelectedColor
: task.styles.progressColor; : task.styles.progressColor;
const progressWidth = progressWithByParams(task.x1, task.x2, task.progress);
const projectWith = task.x2 - task.x1; const projectWith = task.x2 - task.x1;
const projectLeftTriangle = [ const projectLeftTriangle = [
@ -43,8 +41,8 @@ export const Project: React.FC<TaskItemProps> = ({ task, isSelected }) => {
className={styles.projectBackground} className={styles.projectBackground}
/> />
<rect <rect
x={task.x1} x={task.progressX}
width={progressWidth} width={task.progressWidth}
y={task.y} y={task.y}
height={task.height} height={task.height}
ry={task.barCornerRadius} ry={task.barCornerRadius}

View File

@ -10,6 +10,7 @@ export const convertToBarTasks = (
taskHeight: number, taskHeight: number,
barCornerRadius: number, barCornerRadius: number,
handleWidth: number, handleWidth: number,
rtl: boolean,
barProgressColor: string, barProgressColor: string,
barProgressSelectedColor: string, barProgressSelectedColor: string,
barBackgroundColor: string, barBackgroundColor: string,
@ -37,6 +38,7 @@ export const convertToBarTasks = (
taskHeight, taskHeight,
barCornerRadius, barCornerRadius,
handleWidth, handleWidth,
rtl,
barProgressColor, barProgressColor,
barProgressSelectedColor, barProgressSelectedColor,
barBackgroundColor, barBackgroundColor,
@ -75,6 +77,7 @@ const convertToBarTask = (
taskHeight: number, taskHeight: number,
barCornerRadius: number, barCornerRadius: number,
handleWidth: number, handleWidth: number,
rtl: boolean,
barProgressColor: string, barProgressColor: string,
barProgressSelectedColor: string, barProgressSelectedColor: string,
barBackgroundColor: string, barBackgroundColor: string,
@ -114,6 +117,7 @@ const convertToBarTask = (
taskHeight, taskHeight,
barCornerRadius, barCornerRadius,
handleWidth, handleWidth,
rtl,
projectProgressColor, projectProgressColor,
projectProgressSelectedColor, projectProgressSelectedColor,
projectBackgroundColor, projectBackgroundColor,
@ -131,6 +135,7 @@ const convertToBarTask = (
taskHeight, taskHeight,
barCornerRadius, barCornerRadius,
handleWidth, handleWidth,
rtl,
barProgressColor, barProgressColor,
barProgressSelectedColor, barProgressSelectedColor,
barBackgroundColor, barBackgroundColor,
@ -151,13 +156,35 @@ const convertToBar = (
taskHeight: number, taskHeight: number,
barCornerRadius: number, barCornerRadius: number,
handleWidth: number, handleWidth: number,
rtl: boolean,
barProgressColor: string, barProgressColor: string,
barProgressSelectedColor: string, barProgressSelectedColor: string,
barBackgroundColor: string, barBackgroundColor: string,
barBackgroundSelectedColor: string barBackgroundSelectedColor: string
): BarTask => { ): BarTask => {
const x1 = taskXCoordinate(task.start, dates, dateDelta, columnWidth); let x1: number;
let x2 = taskXCoordinate(task.end, dates, dateDelta, columnWidth); let x2: number;
if (rtl) {
x2 = taskXCoordinate(task.start, dates, dateDelta, columnWidth);
x1 = taskXCoordinate(task.end, dates, dateDelta, columnWidth);
} else {
x1 = taskXCoordinate(task.start, dates, dateDelta, columnWidth);
x2 = taskXCoordinate(task.end, dates, dateDelta, columnWidth);
}
let typeInternal: TaskTypeInternal = task.type;
if (typeInternal === "task" && x2 - x1 < handleWidth * 2) {
typeInternal = "smalltask";
x2 = x1 + handleWidth * 2;
}
const progressWidth = progressWithByParams(x1, x2, task.progress);
let progressX: number;
if (rtl) {
progressX = x2 - progressWidth;
} else {
progressX = x1;
}
const y = taskYCoordinate(index, rowHeight, taskHeight); const y = taskYCoordinate(index, rowHeight, taskHeight);
const styles = { const styles = {
@ -167,11 +194,6 @@ const convertToBar = (
progressSelectedColor: barProgressSelectedColor, progressSelectedColor: barProgressSelectedColor,
...task.styles, ...task.styles,
}; };
let typeInternal: TaskTypeInternal = task.type;
if (typeInternal === "task" && x2 - x1 < handleWidth * 2) {
typeInternal = "smalltask";
x2 = x1 + handleWidth * 2;
}
return { return {
...task, ...task,
typeInternal, typeInternal,
@ -179,6 +201,8 @@ const convertToBar = (
x2, x2,
y, y,
index, index,
progressX,
progressWidth,
barCornerRadius, barCornerRadius,
handleWidth, handleWidth,
height: taskHeight, height: taskHeight,
@ -199,7 +223,7 @@ const convertToMilestone = (
handleWidth: number, handleWidth: number,
milestoneBackgroundColor: string, milestoneBackgroundColor: string,
milestoneBackgroundSelectedColor: string milestoneBackgroundSelectedColor: string
) => { ): BarTask => {
const x = taskXCoordinate(task.start, dates, dateDelta, columnWidth); const x = taskXCoordinate(task.start, dates, dateDelta, columnWidth);
const y = taskYCoordinate(index, rowHeight, taskHeight); const y = taskYCoordinate(index, rowHeight, taskHeight);
@ -221,6 +245,8 @@ const convertToMilestone = (
x2, x2,
y, y,
index, index,
progressX: 0,
progressWidth: 0,
barCornerRadius, barCornerRadius,
handleWidth, handleWidth,
typeInternal: task.type, typeInternal: task.type,
@ -281,9 +307,7 @@ export const progressByProgressWidth = (
const progressPercent = Math.round((progressWidth * 100) / barWidth); const progressPercent = Math.round((progressWidth * 100) / barWidth);
if (progressPercent >= 100) return 100; if (progressPercent >= 100) return 100;
else if (progressPercent <= 0) return 0; else if (progressPercent <= 0) return 0;
else { else return progressPercent;
return progressPercent;
}
}; };
const progressByX = (x: number, task: BarTask) => { const progressByX = (x: number, task: BarTask) => {
@ -364,7 +388,8 @@ export const handleTaskBySVGMouseEvent = (
selectedTask: BarTask, selectedTask: BarTask,
xStep: number, xStep: number,
timeStep: number, timeStep: number,
initEventX1Delta: number initEventX1Delta: number,
rtl: boolean
): { isChanged: boolean; changedTask: BarTask } => { ): { isChanged: boolean; changedTask: BarTask } => {
let result: { isChanged: boolean; changedTask: BarTask }; let result: { isChanged: boolean; changedTask: BarTask };
switch (selectedTask.type) { switch (selectedTask.type) {
@ -385,7 +410,8 @@ export const handleTaskBySVGMouseEvent = (
selectedTask, selectedTask,
xStep, xStep,
timeStep, timeStep,
initEventX1Delta initEventX1Delta,
rtl
); );
break; break;
} }
@ -398,7 +424,8 @@ const handleTaskBySVGMouseEventForBar = (
selectedTask: BarTask, selectedTask: BarTask,
xStep: number, xStep: number,
timeStep: number, timeStep: number,
initEventX1Delta: number initEventX1Delta: number,
rtl: boolean
): { isChanged: boolean; changedTask: BarTask } => { ): { isChanged: boolean; changedTask: BarTask } => {
const changedTask: BarTask = { ...selectedTask }; const changedTask: BarTask = { ...selectedTask };
let isChanged = false; let isChanged = false;
@ -406,6 +433,18 @@ const handleTaskBySVGMouseEventForBar = (
case "progress": case "progress":
changedTask.progress = progressByX(svgX, selectedTask); changedTask.progress = progressByX(svgX, selectedTask);
isChanged = changedTask.progress !== selectedTask.progress; isChanged = changedTask.progress !== selectedTask.progress;
if (isChanged) {
changedTask.progressWidth = progressWithByParams(
changedTask.x1,
changedTask.x2,
changedTask.progress
);
if (rtl) {
changedTask.progressX = changedTask.x2 - changedTask.progressWidth;
} else {
changedTask.progressX = changedTask.x1;
}
}
break; break;
case "start": { case "start": {
const newX1 = startByX(svgX, xStep, selectedTask); const newX1 = startByX(svgX, xStep, selectedTask);

View File

@ -7,6 +7,8 @@ export interface BarTask extends Task {
x2: number; x2: number;
y: number; y: number;
height: number; height: number;
progressX: number;
progressWidth: number;
barCornerRadius: number; barCornerRadius: number;
handleWidth: number; handleWidth: number;
barChildren: number[]; barChildren: number[];

View File

@ -65,6 +65,7 @@ export interface DisplayOption {
* Specifies the month name language. Able formats: ISO 639-2, Java Locale * Specifies the month name language. Able formats: ISO 639-2, Java Locale
*/ */
locale?: string; locale?: string;
rtl?: boolean;
} }
export interface StylingOption { export interface StylingOption {