javascriptgantt
Version:
An open source JavaScript Gantt. This library provides a powerful set of tools and functionalities to create interactive Gantt charts for project management.
1,970 lines (1,918 loc) • 311 kB
JavaScript
/* =========================================================
* Created by Sunil Solanki
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ========================================================= */
(function (global) {
class javascriptgantt {
#arrangeData = true;
#ganttHeight = 0;
#debounceTimers = new Map();
#searchedData = undefined;
#dateFormat = {
month_full: [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
],
month_short: [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
],
day_full: [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
],
day_short: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
};
constructor(element, options, templates) {
this.element = element;
this.initializeOptions(options);
this.initTemplates(templates);
this.handleFullScreenChangeSafari =
this.handleFullScreenChangeSafari.bind(this);
this.handleFullScreenChange = this.handleFullScreenChange.bind(this);
this.handleResizeWindow = this.handleResizeWindow.bind(this);
this.init();
}
// initialize Options
initializeOptions(opt = {}) {
this.options = {
date_format: opt.date_format,
columns: opt.columns || [],
rightGrid: opt.rightGrid,
data: opt.data || [],
collapse: opt.collapse !== false,
fullWeek: opt.fullWeek !== false,
todayMarker: opt.todayMarker !== false,
weekends: opt.weekends || [],
startDate: opt.startDate,
endDate: opt.endDate,
zoomLevel: opt.zoomLevel || "day",
zoomConfig: opt.zoomConfig || {
levels: [{ unit: "day", step: 1, format: "%d" }],
},
scales: opt.scales || [{ unit: "day", step: 1, format: "%d" }],
minColWidth: 80,
openedTasks: [],
selectedRow: "",
weekStart: opt.weekStart || 1,
scale_height: opt.scale_height || 30,
row_height: opt.row_height || 50,
sidebarWidth: opt.sidebarWidth || 400,
customMarker: opt.customMarker || [],
fullCell: opt.fullCell !== false,
taskColor: opt.taskColor || false,
taskOpacity: opt.taskOpacity || 0.8,
addLinks: opt.addLinks || false,
exportApi: opt.exportApi,
updateLinkOnDrag: opt.updateLinkOnDrag !== false,
splitTask: opt.splitTask || false,
links: opt.links || [],
selectAreaOnDrag: opt.selectAreaOnDrag || false,
taskProgress: opt.taskProgress || true,
mouseScroll: opt.mouseScroll || false,
ctrlKeyRequiredForMouseScroll:
opt.ctrlKeyRequiredForMouseScroll !== false,
sort: opt.sort || false,
dropArea: opt.dropArea !== false,
i18n: {
hi: {
month_full: [
"जनवरी",
"फ़रवरी",
"मार्च",
"अप्रैल",
"मई",
"जून",
"जुलाई",
"अगस्त",
"सितंबर",
"अक्टूबर",
"नवंबर",
"दिसंबर",
],
month_short: [
"जनवरी",
"फ़रवरी",
"मार्च",
"अप्रैल",
"मई",
"जून",
"जुलाई",
"अगस्त",
"सितंबर",
"अक्टूबर",
"नवंबर",
"दिसंबर",
],
day_full: [
"रविवार",
"सोमवार",
"मंगलवार",
"बुधवार",
"गुरुवार",
"शुक्रवार",
"शनिवार",
],
day_short: ["रवि", "सोम", "मंगल", "बुध", "गुरु", "शुक्र", "शनि"],
label: {
description: "विवरण",
},
buttons: {
save: "जमा करे",
cancel: "रद्द करे",
delete: "मिटाये",
},
},
en: {
month_full: [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
],
month_short: [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
],
day_full: [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
],
day_short: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
label: {
description: "Description",
},
buttons: {
save: "Save",
cancel: "Cancel",
delete: "Delete",
},
},
fr: {
month_full: [
"Janvier",
"Février",
"Mars",
"Avril",
"Mai",
"Juin",
"Juillet",
"Août",
"Septembre",
"Octobre",
"Novembre",
"Décembre",
],
month_short: [
"Jan",
"Fév",
"Mar",
"Avr",
"Mai",
"Juin",
"Juil",
"Aoû",
"Sep",
"Oct",
"Nov",
"Déc",
],
day_full: [
"Dimanche",
"Lundi",
"Mardi",
"Mercredi",
"Jeudi",
"Vendredi",
"Samedi",
],
day_short: ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"],
label: {
description: "Description",
},
buttons: {
save: "Sauvegarder",
cancel: "Annuler",
delete: "Effacer",
},
},
de: {
month_full: [
"Januar",
"Februar",
"März ",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September ",
"Oktober",
"November ",
"Dezember",
],
month_short: [
"Jan",
"Feb",
"Mär",
"Apr",
"Mai",
"Jun",
"Jul",
"Aug",
"Sep",
"Okt",
"Nov",
"Dez",
],
day_full: [
"Sonntag",
"Montag",
"Dienstag",
"Mittwoch",
"Donnerstag",
"Freitag",
"Samstag",
],
day_short: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
label: {
description: "Beschreibung",
},
buttons: {
save: "Speichern",
cancel: "Abbrechen",
delete: "Löschen",
},
},
ja: {
month_full: [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
],
month_short: [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月",
],
day_full: [
"日曜日",
"月曜日",
"火曜日",
"水曜日",
"木曜日",
"金曜日",
"土曜日",
],
day_short: ["太陽", "月", "火", "結婚した", "木", "金", "土"],
label: {
description: "説明",
},
buttons: {
save: "保存する",
cancel: "キャンセル",
delete: "削除",
},
},
ar: {
month_full: [
"كانون الثاني",
"شباط",
"آذار",
"نيسان",
"أيار",
"حزيران",
"تموز",
"آب",
"أيلول",
"تشرين الأول",
"تشرين الثاني",
"كانون الأول",
],
month_short: [
"يناير",
"فبراير",
"مارس",
"أبريل",
"مايو",
"يونيو",
"يوليو",
"أغسطس",
"سبتمبر",
"أكتوبر",
"نوفمبر",
"ديسمبر",
],
day_full: [
"الأحد",
"الأثنين",
"ألثلاثاء",
"الأربعاء",
"ألحميس",
"ألجمعة",
"السبت",
],
day_short: [
"احد",
"اثنين",
"ثلاثاء",
"اربعاء",
"خميس",
"جمعة",
"سبت",
],
label: {
description: "وصف",
},
buttons: {
save: "يحفظ",
cancel: "يلغي",
delete: "يمسح",
},
},
be: {
month_full: [
"Студзень",
"Люты",
"Сакавік",
"Красавік",
"Maй",
"Чэрвень",
"Ліпень",
"Жнівень",
"Верасень",
"Кастрычнік",
"Лістапад",
"Снежань",
],
month_short: [
"Студз",
"Лют",
"Сак",
"Крас",
"Maй",
"Чэр",
"Ліп",
"Жнів",
"Вер",
"Каст",
"Ліст",
"Снеж",
],
day_full: [
"Нядзеля",
"Панядзелак",
"Аўторак",
"Серада",
"Чацвер",
"Пятніца",
"Субота",
],
day_short: ["Нд", "Пн", "Аўт", "Ср", "Чцв", "Пт", "Сб"],
label: {
description: "Апісанне",
},
buttons: {
save: "Захаваць",
cancel: "Адмяніць",
delete: "Выдаліць",
},
},
ca: {
month_full: [
"Gener",
"Febrer",
"Març",
"Abril",
"Maig",
"Juny",
"Juliol",
"Agost",
"Setembre",
"Octubre",
"Novembre",
"Desembre",
],
month_short: [
"Gen",
"Feb",
"Mar",
"Abr",
"Mai",
"Jun",
"Jul",
"Ago",
"Set",
"Oct",
"Nov",
"Des",
],
day_full: [
"Diumenge",
"Dilluns",
"Dimarts",
"Dimecres",
"Dijous",
"Divendres",
"Dissabte",
],
day_short: ["Dg", "Dl", "Dm", "Dc", "Dj", "Dv", "Ds"],
label: {
description: "Descripció",
},
buttons: {
save: "Desa",
cancel: "Cancel · lar",
delete: "Suprimeix",
},
},
cn: {
month_full: [
"一月",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月",
],
month_short: [
"简",
"二月",
"三月",
"四月",
"可能",
"君",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月",
],
day_full: [
"星期日",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
],
day_short: [
"太阳",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六",
],
label: {
description: "描述",
},
buttons: {
save: "节省",
cancel: "取消",
delete: "删除",
},
},
hr: {
month_full: [
"Siječanj",
"Veljača",
"Ožujak",
"Travanj",
"Svibanj",
"Lipanj",
"Srpanj",
"Kolovoz",
"Rujan",
"Listopad",
"Studeni",
"Prosinac",
],
month_short: [
"Sij",
"Velj",
"Ožu",
"Tra",
"Svi",
"Lip",
"Srp",
"Kol",
"Ruj",
"Lis",
"Stu",
"Pro",
],
day_full: [
"Nedjelja",
"Ponedjeljak",
"Utorak",
"Srijeda",
"Četvrtak",
"Petak",
"Subota",
],
day_short: ["Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"],
label: {
description: "Opis",
},
buttons: {
save: "Uštedjeti",
cancel: "Otkazati",
delete: "Izbrisati",
},
},
cs: {
month_full: [
"Leden",
"Únor",
"Březen",
"Duben",
"Květen",
"Červen",
"Červenec",
"Srpen",
"Září",
"Říjen",
"Listopad",
"Prosinec",
],
month_short: [
"Led",
"Ún",
"Bře",
"Dub",
"Kvě",
"Čer",
"Čec",
"Srp",
"Září",
"Říj",
"List",
"Pro",
],
day_full: [
"Neděle",
"Pondělí",
"Úterý",
"Středa",
"Čtvrtek",
"Pátek",
"Sobota",
],
day_short: ["Ne", "Po", "Út", "St", "Čt", "Pá", "So"],
label: {
description: "Popis",
},
buttons: {
save: "Uložit",
cancel: "zrušení",
delete: "Vymazat",
},
},
da: {
month_full: [
"Januar",
"Februar",
"Mars",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Desember",
],
month_short: [
"Jan",
"Feb",
"Mar",
"Apr",
"Mai",
"Jun",
"Jul",
"Aug",
"Sep",
"Okt",
"Nov",
"Des",
],
day_full: [
"Søndag",
"Mandag",
"Tirsdag",
"Onsdag",
"Torsdag",
"Fredag",
"Lørdag",
],
day_short: ["Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"],
label: {
description: "Beskrivelse",
},
buttons: {
save: "Gemme",
cancel: "Afbestille",
delete: "Slet",
},
},
nl: {
month_full: [
"Januari",
"Februari",
"Maart",
"April",
"Mei",
"Juni",
"Juli",
"Augustus",
"September",
"Oktober",
"November",
"December",
],
month_short: [
"Jan",
"Feb",
"mrt",
"Apr",
"Mei",
"Jun",
"Jul",
"Aug",
"Sep",
"Okt",
"Nov",
"Dec",
],
day_full: [
"Zondag",
"Maandag",
"Dinsdag",
"Woensdag",
"Donderdag",
"Vrijdag",
"Zaterdag",
],
day_short: ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za"],
label: {
description: "Beschrijving",
},
buttons: {
save: "Redden",
cancel: "Annuleren",
delete: "Verwijderen",
},
},
fi: {
month_full: [
"Tammikuu",
"Helmikuu",
"Maaliskuu",
"Huhtikuu",
"Toukokuu",
"Kesäkuu",
"Heinäkuu",
"Elokuu",
"Syyskuu",
"Lokakuu",
"Marraskuu",
"Joulukuu",
],
month_short: [
"Tam",
"Hel",
"Maa",
"Huh",
"Tou",
"Kes",
"Hei",
"Elo",
"Syy",
"Lok",
"Mar",
"Jou",
],
day_full: [
"Sunnuntai",
"Maanantai",
"Tiistai",
"Keskiviikko",
"Torstai",
"Perjantai",
"Lauantai",
],
day_short: ["Su", "Ma", "Ti", "Ke", "To", "Pe", "La"],
label: {
description: "Kuvaus",
},
buttons: {
save: "Tallentaa",
cancel: "Peruuttaa",
delete: "Poistaa",
},
},
el: {
month_full: [
"Ιανουάριος",
"Φεβρουάριος",
"Μάρτιος",
"Απρίλιος",
"Μάϊος",
"Ιούνιος",
"Ιούλιος",
"Αύγουστος",
"Σεπτέμβριος",
"Οκτώβριος",
"Νοέμβριος",
"Δεκέμβριος",
],
month_short: [
"ΙΑΝ",
"ΦΕΒ",
"ΜΑΡ",
"ΑΠΡ",
"ΜΑΙ",
"ΙΟΥΝ",
"ΙΟΥΛ",
"ΑΥΓ",
"ΣΕΠ",
"ΟΚΤ",
"ΝΟΕ",
"ΔΕΚ",
],
day_full: [
"Κυριακή",
"Δευτέρα",
"Τρίτη",
"Τετάρτη",
"Πέμπτη",
"Παρασκευή",
"Κυριακή",
],
day_short: ["ΚΥ", "ΔΕ", "ΤΡ", "ΤΕ", "ΠΕ", "ΠΑ", "ΣΑ"],
label: {
description: "Περιγραφή",
},
buttons: {
save: "Αποθηκεύσετε",
cancel: "Ματαίωση",
delete: "Διαγράφω",
},
},
hu: {
month_full: [
"Január",
"Február",
"Március",
"Április",
"Május",
"Június",
"Július",
"Augusztus",
"Szeptember",
"Október",
"November",
"December",
],
month_short: [
"Jan",
"Feb",
"Már",
"Ápr",
"Máj",
"Jún",
"Júl",
"Aug",
"Sep",
"Okt",
"Nov",
"Dec",
],
day_full: [
"Vasárnap",
"Hétfõ",
"Kedd",
"Szerda",
"Csütörtök",
"Péntek",
"szombat",
],
day_short: ["Va", "Hé", "Ke", "Sze", "Csü", "Pé", "Szo"],
label: {
description: "Leírás",
},
buttons: {
save: "Megment",
cancel: "Megszünteti",
delete: "Töröl",
},
},
id: {
month_full: [
"Januari",
"Februari",
"Maret",
"April",
"Mei",
"Juni",
"Juli",
"Agustus",
"September",
"Oktober",
"November",
"Desember",
],
month_short: [
"Jan",
"Feb",
"Mar",
"Apr",
"Mei",
"Jun",
"Jul",
"Ags",
"Sep",
"Okt",
"Nov",
"Des",
],
day_full: [
"Minggu",
"Senin",
"Selasa",
"Rabu",
"Kamis",
"Jumat",
"Sabtu",
],
day_short: ["Ming", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"],
label: {
description: "Keterangan",
},
buttons: {
save: "Menyimpan",
cancel: "Membatalkan",
delete: "Menghapus",
},
},
it: {
month_full: [
"Gennaio",
"Febbraio",
"Marzo",
"Aprile",
"Maggio",
"Giugno",
"Luglio",
"Agosto",
"Settembre",
"Ottobre",
"Novembre",
"Dicembre",
],
month_short: [
"Gen",
"Feb",
"Mar",
"Apr",
"Mag",
"Giu",
"Lug",
"Ago",
"Set",
"Ott",
"Nov",
"Dic",
],
day_full: [
"Domenica",
"Lunedì",
"Martedì",
"Mercoledì",
"Giovedì",
"Venerdì",
"Sabato",
],
day_short: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"],
label: {
description: "Descrizione",
},
buttons: {
save: "Salva",
cancel: "Annulla",
delete: "Eliminare",
},
},
kr: {
month_full: [
"1월",
"2월",
"3월",
"4월",
"5월",
"6월",
"7월",
"8월",
"9월",
"10월",
"11월",
"12월",
],
month_short: [
"1월",
"2월",
"3월",
"4월",
"5월",
"6월",
"7월",
"8월",
"9월",
"10월",
"11월",
"12월",
],
day_full: [
"일요일",
"월요일",
"화요일",
"수요일",
"목요일",
"금요일",
"토요일",
],
day_short: ["일", "월", "화", "수", "목", "금", "토"],
label: {
description: "설명",
},
buttons: {
save: "구하다",
cancel: "취소",
delete: "삭제",
},
},
fa: {
month_full: [
"ژانویه",
"فوریه",
"مارس",
"آوریل",
"مه",
"ژوئن",
"ژوئیه",
"اوت",
"سپتامبر",
"اکتبر",
"نوامبر",
"دسامبر",
],
month_short: [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
],
day_full: [
"يکشنبه",
"دوشنبه",
"سهشنبه",
"چهارشنبه",
"پنجشنبه",
"جمعه",
"شنبه",
],
day_short: ["ی", "د", "س", "چ", "پ", "ج", "ش"],
label: {
description: "شرح",
},
buttons: {
save: "صرفه جویی",
cancel: "لغو کنید",
delete: "حذف",
},
},
pl: {
month_full: [
"Styczeń",
"Luty",
"Marzec",
"Kwiecień",
"Maj",
"Czerwiec",
"Lipiec",
"Sierpień",
"Wrzesień",
"Październik",
"Listopad",
"Grudzień",
],
month_short: [
"Sty",
"Lut",
"Mar",
"Kwi",
"Maj",
"Cze",
"Lip",
"Sie",
"Wrz",
"Paź",
"Lis",
"Gru",
],
day_full: [
"Niedziela",
"Poniedziałek",
"Wtorek",
"Środa",
"Czwartek",
"Piątek",
"Sobota",
],
day_short: ["Nie", "Pon", "Wto", "Śro", "Czw", "Pią", "Sob"],
label: {
description: "Opis",
},
buttons: {
save: "Ratować",
cancel: "Anulować",
delete: "Usuwać",
},
},
pt: {
month_full: [
"Janeiro",
"Fevereiro",
"Março",
"Abril",
"Maio",
"Junho",
"Julho",
"Agosto",
"Setembro",
"Outubro",
"Novembro",
"Dezembro",
],
month_short: [
"Jan",
"Fev",
"Mar",
"Abr",
"Mai",
"Jun",
"Jul",
"Ago",
"Set",
"Out",
"Nov",
"Dez",
],
day_full: [
"Domingo",
"Segunda",
"Terça",
"Quarta",
"Quinta",
"Sexta",
"Sábado",
],
day_short: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"],
label: {
description: "Descrição",
},
buttons: {
save: "Salvar",
cancel: "Cancelar",
delete: "Excluir",
},
},
ro: {
month_full: [
"Ianuarie",
"Februarie",
"Martie",
"Aprilie",
"Mai",
"Iunie",
"Iulie",
"August",
"Septembrie",
"Octombrie",
"November",
"December",
],
month_short: [
"Ian",
"Feb",
"Mar",
"Apr",
"Mai",
"Iun",
"Iul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
],
day_full: [
"Duminica",
"Luni",
"Marti",
"Miercuri",
"Joi",
"Vineri",
"Sambata",
],
day_short: ["Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sa"],
label: {
description: "Descriere",
},
buttons: {
save: "Salvați",
cancel: "Anulare",
delete: "Șterge",
},
},
ru: {
month_full: [
"Январь",
"Февраль",
"Март",
"Апрель",
"Maй",
"Июнь",
"Июль",
"Август",
"Сентябрь",
"Oктябрь",
"Ноябрь",
"Декабрь",
],
month_short: [
"Янв",
"Фев",
"Maр",
"Aпр",
"Maй",
"Июн",
"Июл",
"Aвг",
"Сен",
"Окт",
"Ноя",
"Дек",
],
day_full: [
"Воскресенье",
"Понедельник",
"Вторник",
"Среда",
"Четверг",
"Пятница",
"Суббота",
],
day_short: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"],
label: {
description: "Описание",
},
buttons: {
save: "Сохранять",
cancel: "Отмена",
delete: "Удалить",
},
},
si: {
month_full: [
"Januar",
"Februar",
"Marec",
"April",
"Maj",
"Junij",
"Julij",
"Avgust",
"September",
"Oktober",
"November",
"December",
],
month_short: [
"Jan",
"Feb",
"Mar",
"Apr",
"Maj",
"Jun",
"Jul",
"Aug",
"Sep",
"Okt",
"Nov",
"Dec",
],
day_full: [
"Nedelja",
"Ponedeljek",
"Torek",
"Sreda",
"Četrtek",
"Petek",
"Sobota",
],
day_short: ["Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob"],
label: {
description: "Opis",
},
buttons: {
save: "Shrani",
cancel: "Prekliči",
delete: "Izbriši",
},
},
es: {
month_full: [
"Enero",
"Febrero",
"Marzo",
"Abril",
"Mayo",
"Junio",
"Julio",
"Agosto",
"Septiembre",
"Octubre",
"Noviembre",
"Diciembre",
],
month_short: [
"Ene",
"Feb",
"Mar",
"Abr",
"May",
"Jun",
"Jul",
"Ago",
"Sep",
"Oct",
"Nov",
"Dic",
],
day_full: [
"Domingo",
"Lunes",
"Martes",
"Miércoles",
"Jueves",
"Viernes",
"Sábado",
],
day_short: ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"],
label: {
description: "Descripción",
},
buttons: {
save: "Ahorrar",
cancel: "Cancelar",
delete: "Borrar",
},
},
sv: {
month_full: [
"Januari",
"Februari",
"Mars",
"April",
"Maj",
"Juni",
"Juli",
"Augusti",
"September",
"Oktober",
"November",
"December",
],
month_short: [
"Jan",
"Feb",
"Mar",
"Apr",
"Maj",
"Jun",
"Jul",
"Aug",
"Sep",
"Okt",
"Nov",
"Dec",
],
day_full: [
"Söndag",
"Måndag",
"Tisdag",
"Onsdag",
"Torsdag",
"Fredag",
"Lördag",
],
day_short: ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"],
label: {
description: "Beskrivning",
},
buttons: {
save: "Spara",
cancel: "Annullera",
delete: "Radera",
},
},
tr: {
month_full: [
"Ocak",
"Şubat",
"Mart",
"Nisan",
"Mayıs",
"Haziran",
"Temmuz",
"Ağustos",
"Eylül",
"Ekim",
"Kasım",
"Aralık",
],
month_short: [
"Oca",
"Şub",
"Mar",
"Nis",
"May",
"Haz",
"Tem",
"Ağu",
"Eyl",
"Eki",
"Kas",
"Ara",
],
day_full: [
"Pazar",
"Pazartesi",
"Salı",
"Çarşamba",
"Perşembe",
"Cuma",
"Cumartesi",
],
day_short: ["Paz", "Pzt", "Sal", "Çar", "Per", "Cum", "Cmt"],
label: {
description: "Tanım",
},
buttons: {
save: "Kaydetmek",
cancel: "İptal etmek",
delete: "Silmek",
},
},
ua: {
month_full: [
"Січень",
"Лютий",
"Березень",
"Квітень",
"Травень",
"Червень",
"Липень",
"Серпень",
"Вересень",
"Жовтень",
"Листопад",
"Грудень",
],
month_short: [
"Січ",
"Лют",
"Бер",
"Кві",
"Тра",
"Чер",
"Лип",
"Сер",
"Вер",
"Жов",
"Лис",
"Гру",
],
day_full: [
"Неділя",
"Понеділок",
"Вівторок",
"Середа",
"Четвер",
"П'ятниця",
"Субота",
],
day_short: ["Нед", "Пон", "Вів", "Сер", "Чет", "Птн", "Суб"],
label: {
description: "опис",
},
buttons: {
save: "зберегти",
cancel: "Скасувати",
delete: "Видалити",
},
},
he: {
month_full: [
"ינואר",
"פברואר",
"מרץ",
"אפריל",
"מאי",
"יוני",
"יולי",
"אוגוסט",
"ספטמבר",
"אוקטובר",
"נובמבר",
"דצמבר",
],
month_short: [
"ינואר",
"פברואר",
"מרץ",
"אפריל",
"מאי",
"יוני",
"יולי",
"אוגוסט",
"ספטמבר",
"אוקטובר",
"נובמבר",
"דצמבר",
],
day_full: [
"יוֹם רִאשׁוֹן",
"יוֹם שֵׁנִי",
"יוֹם שְׁלִישִׁי",
"יום רביעי",
"יוֹם חֲמִישִׁי",
"יוֹם שִׁישִׁי",
"יום שבת",
],
day_short: [
"שמש",
"יום שני",
"ג'",
"היינו עושים",
"יום ה'",
"שישי",
"ישב",
],
label: {
description: "תיאור",
},
buttons: {
save: "להציל",
cancel: "לְבַטֵל",
delete: "לִמְחוֹק",
},
},
no: {
month_full: [
"januar",
"februar",
"mars",
"april",
"Kan",
"juni",
"juli",
"august",
"september",
"oktober",
"november",
"desember",
],
month_short: [
"Jan",
"feb",
"Mar",
"apr",
"Kan",
"jun",
"jul",
"august",
"sep",
"okt",
"nov",
"des",
],
day_full: [
"søndag",
"Monday",
"tirsdag",
"onsdag",
"Torsdag",
"fredag",
"lørdag",
],
day_short: ["Søn", "man", "tirs", "ons", "tor", "fre", "Lør"],
label: {
description: "Beskrivelse",
},
buttons: {
save: "Lagre",
cancel: "Avbryt",
delete: "Slett",
},
},
sk: {
month_full: [
"Január",
"február",
"marec",
"apríl",
"máj",
"jún",
"júl",
"august",
"september",
"október",
"november",
"december",
],
month_short: [
"Jan",
"Feb",
"Mar",
"Apr",
"máj",
"Jun",
"júl",
"Aug",
"Sep",
"október",
"Nov",
"Dec",
],
day_full: [
"Nedeľa",
"pondelok",
"utorok",
"streda",
"štvrtok",
"piatok",
"sobota",
],
day_short: ["Ne", "Po", "Ut", "St", "Št", "Pia", "So"],
label: {
description: "Popis",
},
buttons: {
save: "Uložiť",
cancel: "Zrušiť",
delete: "Odstrániť",
},
},
},
localLang: opt.localLang || "en",
currentLanguage: {},
};
}
// initialize templates
initTemplates(templ = {}) {
this.templates = {
tooltip_text:
templ.tooltip_text ||
((start, end, task) =>
`<b>Task:</b> ${task.text}<br/><b>Start date:</b> ${start}<br/><b>End date:</b> ${end}`),
taskbar_text: templ.taskbar_text || ((start, end, task) => task.text),
task_drag: templ.task_drag || true,
grid_folder: templ.grid_folder || "",
grid_file: templ.grid_file || "",
grid_blank: templ.grid_blank || "",
showLightBox: templ.showLightBox || undefined,
grid_header_class: templ.grid_header_class || undefined,
grid_row_class: templ.grid_row_class || undefined,
task_class: templ.task_class || undefined,
task_row_class: templ.task_row_class || undefined,
scale_cell_class: templ.scale_cell_class || undefined,
grid_cell_class: templ.grid_cell_class || undefined,
timeline_cell_class: templ.timeline_cell_class || undefined,
};
}
/**
* Get an array of dates between the range of startDate and endDate.
* @param {Date} startDate - The start date of the range.
* @param {Date} endDate - The end date of the range.
* @param {boolean} [filterWeekends=true] - Whether to filter out weekends from the date range.
* @returns {Array<number>} - An array of dates (timestamps) between the start and end dates.
*/
getDates(startDate, endDate, filterWeekends = true) {
// Convert to timestamps and normalize to start of the day
const start = new Date(startDate).setHours(0, 0, 0, 0);
const end = new Date(endDate).setHours(0, 0, 0, 0);
const weekday = this.#dateFormat.day_short;
// Array to hold the dates
const dates = [];
// Loop through each date from start to end
for (
let currentDate = start;
currentDate <= end;
currentDate += 86400000
) {
const dayName = weekday[new Date(currentDate).getDay()];
// if fullWeek is false then don't push weekends date in dates array
if (
filterWeekends &&
!this.options.fullWeek &&
this.options.weekends.includes(dayName)
) {
continue;
}
dates.push(currentDate);
}
return dates;
}
init() {
this.options.currentLanguage = this.options.i18n[this.options.localLang];
/*for Safari below v16 */
document.removeEventListener(
"webkitfullscreenchange",
this.handleFullScreenChangeSafari
);
document.addEventListener(
"webkitfullscreenchange",
this.handleFullScreenChangeSafari
);
// Listen for the fullscreenchange event
document.removeEventListener(
"fullscreenchange",
this.handleFullScreenChange
);
document.addEventListener(
"fullscreenchange",
this.handleFullScreenChange
);
window.removeEventListener("resize", this.handleResizeWindow);
window.addEventListener("resize", this.handleResizeWindow);
this.createTooltip();
if (this.templates?.showLightBox !== false) {
this.createLightbox();
}
}
handleResizeWindow(event) {
if (
this.calculateTimeLineWidth("updated") !==
this.calculateTimeLineWidth("current")
) {
this.updateBody();
}
// handle custom event
this.dispatchEvent("onResize", { event });
}
handleFullScreenChangeSafari() {
// Check if full screen mode has been exited
if (!document.webkitIsFullScreen) {
this.element.classList.remove("js-gantt-fullScreen");
this.exitFullScreen(true);
}
}
handleFullScreenChange() {
// Check if full screen mode has been exited
if (!document.fullscreenElement) {
this.element.classList.remove("js-gantt-fullScreen");
this.exitFullScreen(true);
}
}
/**
* Method to render the gantt chart.
* @param {HTMLElement} element - gantt html element (optional).
*/
render(ele = this.element) {
if (
this.options.weekStart > 6 ||
typeof this.options.weekStart !== "number"
) {
let message =
this.options.weekStart > 6
? "enter week start between 0 to 6"
: "type of week start should be number!";
this.toastr("Error", message, "error");
}
if (!this.options.date_format) {
this.toastr(
"Error",
`date_format is ${this.options.date_format}, please provide a valid date format of your data date format`,
"error"
);
}
this.element = ele;
const options = this.options;
this.options.currentLanguage = this.options.i18n[this.options.localLang];
this.zoomInit("initial");
// create a copy of the data
if (this.#arrangeData) {
this.originalData = [...this.options.data];
}
const originalData = this.originalData;
const { date_format } = options;
// process task start and end date
const processDate = (date) => {
const parsedDate = new Date(date);
if (isNaN(parsedDate) && date_format) {
return this.getDateTimeComponents(date);
} else if (!isNaN(parsedDate) && !parsedDate.getHours()) {
return this.stripTime(parsedDate);
}
return date;
};
function createNestedTree(
flatArray,
parentIdKey = "parent",
idKey = "id"
) {
const tree = [];
const map = {};
flatArray.forEach((item, i) => {
if (originalData[i].start_date !== undefined) {
originalData[i].start_date = processDate(
originalData[i].start_date
);
}
if (originalData[i].end_date !== undefined) {
originalData[i].end_date = processDate(originalData[i].end_date);
}
const id = item[idKey];
const parentId = item[parentIdKey];
map[id] = { ...item, children: map[id] ? map[id].children : [] };
if (!parentId) {
tree.push(map[id]);
} else {
map[parentId] = map[parentId] || { children: [] };
map[parentId].children.push(map[id]);
}
});
return tree;
}
this.options.data = createNestedTree(this.originalData);
// calculate and add duration and start and end date in all data objects
this.updateTaskDuration();
this.#arrangeData = false;
if (!this.options.startDate || !this.options.endDate) {
const { startDate, endDate } = this.getStartAndEndDate();
this.options.startDate = this.options.startDate || startDate;
this.options.endDate = this.options.endDate || endDate;
}
const startDateTimestamp = this.stripTime(options.startDate).getTime();
const endDateTimestamp = this.stripTime(options.endDate).getTime();
if (
!this.dates ||
startDateTimestamp != this.dates[0] ||
endDateTimestamp != this.dates[this.dates.length - 1]
) {
this.dates = this.getDates(options.startDate, options.endDate);
}
// set all task expanded initially if collapse is false
if (!options.collapse && !options?.openedTasks?.length) {
this.options.openedTasks = this.originalData.map((task) => task?.id);
}
if (this.fullScreen === true) {
this.element.classList.add("js-gantt-fullScreen");
}
const jsGanttLayout = document.createElement("div");
jsGanttLayout.classList.add("js-gantt-layout", "js-gantt-d-flex");
jsGanttLayout.id = "js-gantt-layout";
this.createSidebar(jsGanttLayout);
const timeline = document.createElement("div");
timeline.classList.add("js-gantt-timeline-cell");
timeline.id = "js-gantt-timeline-cell";
this.createTimelineScale(timeline);
this.createTimelineBody(timeline, jsGanttLayout, true);
if (options?.rightGrid) {
let newGridOptions = { ...options };
newGridOptions.columns = options.rightGrid;
this.createRightSidebar(newGridOptions, jsGanttLayout);
}
const verScroll =
this.element.querySelector(".js-gantt-ver-scroll")?.scrollTop || 0;
const horScroll =
this.element.querySelector(".js-gantt-hor-scroll")?.scrollLeft || 0;
// append js-gantt-layout in element
const layout = this.element.querySelector("#js-gantt-layout");
if (layout) {
layout.replaceWith(jsGanttLayout);
} else {
this.element.append(jsGanttLayout);
}
this.createScrollbar(jsGanttLayout, verScroll || 0, horScroll || 0);
const timelineDataContainer = this.element.querySelector(
"#js-gantt-timeline-data"
);
if (!this.markerArea) {
const markerArea = document.createElement("div");
markerArea.classList.add("js-gantt-marker-area");
this.markerArea = markerArea;
// add all markers
for (let marker of this.options.customMarker) {
if (this.outOfGanttRange(marker?.start_date)) continue;
this.addMarkerToGantt(marker);
}
if (options.tod