UNPKG

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
/* ========================================================= * 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&auml;kuu", "Hein&auml;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