angular-gantt-chart
Version:
This library can be used in Angular 2 application for creating responsive gantt chart. The chart component consists of inline SVG. The component accepts input data from child component using input decorator of Angular 2.
329 lines (321 loc) • 9.9 kB
text/typescript
import {Component, Input, OnInit} from '@angular/core';
import {Observable} from "rxjs";
export class GanttChartComponent {
defaultData: Object = {
"date": "2017-02-09",
"taskArray": [
{
"task": "Breakfast",
"startTime": "8:30am",
"endTime": "11:00am"
},
]
};
public chartOptions: Object;
public chartData: Object;
lineColor:string="#808080" ;//for setting color of line
labelColor:string="";
rectColor: string = "#87ceeb"; //for setting color of rectangle in SVG
mFlag: number = 0; //Neutralizing the mobile factors in desktop
dFlag: number = 1; //Neutralizing the dekstop factors in mobile
viewHeight: number; //setting the viewBox height property according to length of taskArray
startPos: number =200; //Start Poation of rectange and grid
xAxisGap:number=40;//gap between grid Lines
viewBox: string;
rectHeight: number = 35; //gap between two rectangle
finalTask: any[];
finalInterval: any[];
span: number;
ylabelAdjust:number=15;
heightSpan: number;
labelHeight: number = 35;
mobileRect: number = 0;
fontSize: string = "16px";
truncateLength: number = 10;
areaFacor: number = 11;
constructor() {
Observable.fromEvent(window, 'resize')
.debounceTime(100)
.subscribe((event) => {
this.reRender(event);
});
}
/**
* Represents a function to change viewBox propery of svg in mobile and dekstop
*/
reRender(event) {
var WindowWidth = event.currentTarget.innerWidth;
if (WindowWidth < 767) {
this.startPos = 10;
this.rectHeight = 70;
this.viewHeight = this.finalTask.length * this.rectHeight+20;
this.viewBox = "0 0 600 " + this.viewHeight;
this.labelHeight = 20;
this.ylabelAdjust=-10;
this.mobileRect = 30;
this.fontSize = "20px";
this.dFlag = 0;
this.mFlag = 1;
this.areaFacor = 11;
}
else {
this.startPos = 200;
this.viewHeight = this.finalTask.length * 35+20;
this.viewBox = "0 0 800 " + this.viewHeight;
this.labelHeight = 35;
this.mobileRect = 0;
this.rectHeight = 35;
this.fontSize = "16px";
this.dFlag = 1;
this.mFlag = 0;
this.areaFacor = 11;
this.ylabelAdjust=15;
}
if (WindowWidth < 450) {
this.fontSize = "28px";
this.areaFacor = 15;
}
}
ngOnInit() {
this.makeGanttChart(this.chartData, this.chartOptions);
var WindowWidth = window.innerWidth;
if (WindowWidth < 767) {
this.startPos = 10;
this.rectHeight = 70;
this.viewHeight = this.finalTask.length * this.rectHeight+20;
this.viewBox = "0 0 600 " + this.viewHeight;
this.labelHeight = 20;
this.dFlag = 0;
this.mFlag = 1;
this.mobileRect = 30;
this.fontSize = "20px";
this.areaFacor = 11;
this.ylabelAdjust=-10;
}
else {
this.viewHeight = this.finalTask.length * 35+20;
this.viewBox = "0 0 800 " + this.viewHeight;
}
if (WindowWidth < 450) {
this.fontSize = "28px";
this.areaFacor = 15;
}
}
/**
* Represents a function to convert 12 hour format timing to 24 hour format
*/
convertTo24Hour(time) {
var hours = parseInt(time.substr(0, 2));
if (time.indexOf('am') != -1 && hours == 12) {
time = time.replace('12', '0');
}
if (time.indexOf('am') != -1 && hours < 10) {
time = time.replace(time, '0' + time);
}
if (time.indexOf('pm') != -1 && hours < 12) {
time = time.replace(hours, (hours + 12));
}
return time.replace(/(am|pm)/, '');
}
findmaxTime(max, endTime) {
var time = endTime.split(":");
var HH = Number(time[0]);
var MM = Number(time[1]);
var time2 = HH + MM / 60;
if (max < time2) {
max = time2;
return max;
}
else {
return max;
}
}
findminTime(min, endTime) {
var time = endTime.split(":");
var HH = Number(time[0]);
var MM = Number(time[1]);
var time2 = HH + MM / 60;
if (min > time2) {
min = time2;
return min;
}
else {
return min;
}
}
findNumberOfTicks(min, max) {
var maxInterval = Math.ceil(max - min);
if (maxInterval < 5) {
var ticks = {
"noOfTicks": maxInterval * 4,
"tickWidth": 0.25
}
return ticks;
}
else if (maxInterval >= 5 && maxInterval <= 8) {
var ticks = {
"noOfTicks": maxInterval * 2,
"tickWidth": 0.5
}
return ticks;
}
else if (maxInterval > 16) {
var ticks = {
"noOfTicks": Math.ceil(maxInterval / 2),
"tickWidth": 2
}
return ticks;
}
else {
var ticks = {
"noOfTicks": maxInterval,
"tickWidth": 1
}
return ticks;
}
}
makeGanttChart(ganttChartData, options) {
if (options.rectColor !== undefined)
this.rectColor = options.rectColor;
if(options.lineColor!==undefined){
this.lineColor=options.lineColor;
}
if(options.labelColor!==undefined){
this.labelColor=options.labelColor;
}
if (ganttChartData.taskArray === undefined || ganttChartData.taskArray.length === 0)
this.convertTimeScaleToSpace(this.defaultData);
else
this.convertTimeScaleToSpace(ganttChartData);
}
convertTimeScaleToSpace(ganttChartData) {
var taskArray = [];
var taskarray2 = [];
var displayInterval = [];
var min = 23, max = 0;
var ticksObject: any;
var count = 0;
var hour;
var minute;
taskArray = ganttChartData.taskArray;
for (var task of taskArray) {
var taskObject: any = {};
var startTime24HourFormat = this.convertTo24Hour(task.startTime);
var endTime24HourFormat = this.convertTo24Hour(task.endTime);
var startTime = startTime24HourFormat.split(":");
var startPoint = Number(startTime[0]) + Number(startTime[1]) / 60;
var endTime = endTime24HourFormat.split(":");
var endPoint = Number(endTime[0]) + Number(endTime[1]) / 60;
var width = endPoint - startPoint;
taskObject = {
"taskLabel": task.task,
"startPoint": startPoint,
"width": width,
}
taskarray2.push(taskObject);
max = this.findmaxTime(max, endTime24HourFormat);
min = this.findminTime(min, startTime24HourFormat);
count++;
}
ticksObject = this.findNumberOfTicks(min, max);
for (var i = 0; i < count; i++) {
taskarray2[i].startPoint = taskarray2[i].startPoint - min;
}
this.finalTask = taskarray2;
/*X Axis Interval Display */
hour = Math.floor(min);
minute = (min - hour) * 60;
if (hour > 12) {
hour = hour - 12;
}
if (minute === 0) {
displayInterval.push(hour);
}
else {
displayInterval.push(hour + ":" + minute);
}
for (var i = 0; i < Number(ticksObject.noOfTicks); i++) {
if (Number(ticksObject.tickWidth) === 0.25) {
this.span = 4;
minute = minute + 15;
if (minute === 60) {
hour = hour + 1;
minute = 0;
}
}
else if (Number(ticksObject.tickWidth) == 0.50) {
this.span = 2;
minute = minute + 30;
if (minute == 60) {
hour = hour + 1;
minute = 0;
}
}
else if (Number(ticksObject.tickWidth) === 1) {
this.span = 1;
hour = hour + 1;
}
else if (Number(ticksObject.tickWidth) == 2) {
this.span = 0.5;
hour = hour + 2;
}
if (hour > 12) {
hour = hour - 12;
}
if (minute === 0) {
if (hour === 12) {
displayInterval.push(hour + "P");
} else
displayInterval.push(hour);
}
else {
if (hour === 12 && minute === 0) {
displayInterval.push(hour + "P");
} else
displayInterval.push(hour + ":" + minute);
}
}
this.finalInterval = displayInterval;
this.heightSpan = this.finalTask.length;
}
}