diff --git a/example/src/helper.tsx b/example/src/helper.tsx index b876feaec..e82f326ef 100644 --- a/example/src/helper.tsx +++ b/example/src/helper.tsx @@ -36,6 +36,10 @@ export function initTasks() { id: "Task 1", progress: 25, dependencies: ["Task 0"], + links: [{ + target: "Task 0", + type: "EndToStart" + }], type: "task", project: "ProjectSample", displayOrder: 3, @@ -47,6 +51,10 @@ export function initTasks() { id: "Task 2", progress: 10, dependencies: ["Task 1"], + links: [{ + target: "Task 1", + type: "StartToEnd" + }], type: "task", project: "ProjectSample", displayOrder: 4, @@ -58,6 +66,10 @@ export function initTasks() { id: "Task 3", progress: 2, dependencies: ["Task 2"], + links: [{ + target: "Task 2", + type: "EndToEnd" + }], type: "task", project: "ProjectSample", displayOrder: 5, @@ -70,6 +82,10 @@ export function initTasks() { type: "task", progress: 70, dependencies: ["Task 2"], + links: [{ + target: "Task 2", + type: "StartToStart" + }], project: "ProjectSample", displayOrder: 6, }, diff --git a/src/components/other/arrow.tsx b/src/components/other/arrow.tsx index 52e8f28b4..e2d8922ec 100644 --- a/src/components/other/arrow.tsx +++ b/src/components/other/arrow.tsx @@ -1,5 +1,6 @@ import React from "react"; import { BarTask } from "../../types/bar-task"; +import { Link } from "../../types/public-types"; type ArrowProps = { taskFrom: BarTask; @@ -45,6 +46,24 @@ export const Arrow: React.FC = ({ ); }; +const arrowToStart = ( + taskTo: BarTask, + taskToEndPosition: number, + ) => { + return `${taskTo.x1},${taskToEndPosition} + ${taskTo.x1 - 5},${taskToEndPosition - 5} + ${taskTo.x1 - 5},${taskToEndPosition + 5}`; +} + +const arrowToEnd = ( + task: BarTask, + taskToEndPosition: number, +) => { + return `${task.x2},${taskToEndPosition} + ${task.x2 + 5},${taskToEndPosition + 5} + ${task.x2 + 5},${taskToEndPosition - 5}`; +} + const drownPathAndTriangle = ( taskFrom: BarTask, taskTo: BarTask, @@ -62,16 +81,72 @@ const drownPathAndTriangle = ( ? arrowIndent : taskTo.x1 - taskFrom.x2 - arrowIndent; - const path = `M ${taskFrom.x2} ${taskFrom.y + taskHeight / 2} - h ${arrowIndent} - v ${(indexCompare * rowHeight) / 2} - ${taskFromHorizontalOffsetValue} - V ${taskToEndPosition} - h ${taskToHorizontalOffsetValue}`; + const endToStartPath = () => { + return `M ${taskFrom.x2} ${taskFrom.y + taskHeight / 2} + h ${arrowIndent} + v ${(indexCompare * rowHeight) / 2} + ${taskFromHorizontalOffsetValue} + V ${taskToEndPosition} + h ${taskToHorizontalOffsetValue}`; + } + + const startToEndPath = () => { + return `M ${taskFrom.x1} ${taskFrom.y + taskHeight / 2} + h ${-arrowIndent} + v ${(indexCompare * rowHeight) / 2} + H ${taskTo.x2 + arrowIndent} + V ${taskToEndPosition} + h ${-arrowIndent}`; + } + + const endToEndPath = () => { + return `M ${taskFrom.x2} ${taskFrom.y + taskHeight / 2} + h ${arrowIndent} + v ${(indexCompare * rowHeight) / 2} + ${taskFromEndPosition > taskTo.x2 + arrowIndent + 10 ? "" : `H ${taskTo.x2 + arrowIndent}`} + V ${taskToEndPosition} + h ${taskFromEndPosition < taskTo.x2 + ? -arrowIndent + : taskTo.x1 - taskFrom.x2 - arrowIndent}`; + } + + const startToStartPath = () => { + return `M ${taskFrom.x1} ${taskFrom.y + taskHeight / 2} + h ${-arrowIndent} + v ${(indexCompare * rowHeight) / 2} + ${taskFromHorizontalOffsetValue} + V ${taskToEndPosition} + h ${taskFromEndPosition > taskTo.x1 + ? arrowIndent + : taskTo.x2 - taskFrom.x1 - arrowIndent}`; + } + + // default endToStart + let trianglePoints = arrowToStart(taskTo, taskToEndPosition); + let path = endToStartPath(); + + if (taskTo?.links) { + const startToEnd = taskTo?.links.find((link: Link) => link.type === "StartToEnd"); + const endToEnd = taskTo?.links.find((link: Link) => link.type === "EndToEnd"); + const startToStart = taskTo?.links.find((link: Link) => link.type === "StartToStart"); + + if (startToEnd) { + trianglePoints = arrowToEnd(taskTo, taskToEndPosition); + path = startToEndPath(); + } + + if (endToEnd) { + trianglePoints = arrowToEnd(taskTo, taskToEndPosition); + path = endToEndPath(); + } + + if (startToStart) { + trianglePoints = arrowToStart(taskTo, taskToEndPosition); + path = startToStartPath(); + } + + } - const trianglePoints = `${taskTo.x1},${taskToEndPosition} - ${taskTo.x1 - 5},${taskToEndPosition - 5} - ${taskTo.x1 - 5},${taskToEndPosition + 5}`; return [path, trianglePoints]; }; diff --git a/src/helpers/other-helper.ts b/src/helpers/other-helper.ts index afd5a362e..e2c7c7a2a 100644 --- a/src/helpers/other-helper.ts +++ b/src/helpers/other-helper.ts @@ -33,12 +33,8 @@ export function removeHiddenTasks(tasks: Task[]) { function getChildren(taskList: Task[], task: Task) { let tasks: Task[] = []; - if (task.type !== "project") { - tasks = taskList.filter( - t => t.dependencies && t.dependencies.indexOf(task.id) !== -1 - ); - } else { - tasks = taskList.filter(t => t.project && t.project === task.id); + if (task.type === "project") { + tasks = taskList.filter(t => t.project && t.project === task.id); } var taskChildren: Task[] = []; tasks.forEach(t => { diff --git a/src/types/public-types.ts b/src/types/public-types.ts index f4c641a6b..44d3c55b2 100644 --- a/src/types/public-types.ts +++ b/src/types/public-types.ts @@ -9,6 +9,13 @@ export enum ViewMode { Year = "Year", } export type TaskType = "task" | "milestone" | "project"; + +export type LinkType = "EndToStart" | "EndToEnd" | "StartToStart" | "StartToEnd"; + +export interface Link { + target: string; + type: LinkType; +} export interface Task { id: string; type: TaskType; @@ -28,6 +35,7 @@ export interface Task { isDisabled?: boolean; project?: string; dependencies?: string[]; + links?: Array; hideChildren?: boolean; displayOrder?: number; }