Създаване на диаграма на Гант с React с помощта на Next.js

Диаграмата на Гант е инструмент за управление на проекти за координиране на сложни графици за големи или множество екипи. Използването на диаграма на Гант, която е базирана на JavaScript, има няколко предимства пред базираните на електронни таблици диаграми на Гант, като например:

  • Лесна интеграция в съществуващи табла за управление на проекти.
  • Споделяне на вашата диаграма онлайн.
  • Персонализиране на вашата диаграма, за да отговаря на вашите нужди.

В предишна статия описахме как да създадем основен компонент на диаграма на Гант с плъзгане и пускане с помощта на ванилен JavaScript. В тази статия ще направим същата основна диаграма на Гант с React, използвайки Next.js.

Ние също така ще създадем основна диаграма на Гант с помощта на нашата търговска „Bryntum Gantt Chart“ и ще разгледаме разликите между изграждането на ваша собствена диаграма спрямо използването на готово решение.

Основната диаграма на React Gantt, която ще създадем с помощта на Next.js, ще има следните характеристики:

  • Потребителят може да избере периода на планиране, като избере начална дата и крайна дата.
  • Ще можем да добавяме, изтриваме и редактираме задачи.
  • Продължителността на задачите може да се добавя и изтрива и ние ще можем да ги редактираме чрез плъзгане и пускане.

След като приключите, ще имате диаграма на Гант, която изглежда като тази, показана по-долу.

Можете да намерите кода за попълнената диаграма на Гант Next.js в нашето хранилище на GitHub.

Приготвяме се да започнем

Ще започнем този проект, като клонираме следното Next.js Gantt chart starter GitHub repository.

Папката .vscode включва някои настройки на VS Code и препоръки за разширение, както и настройки за ESLint и Prettier. ESLint и Prettier са добавени и конфигурирани да форматират вашия код при поставяне и при запазване. Ако не използвате VS Code като IDE, ще трябва да ги конфигурирате за вашата IDE. След като направите това, можете да изтриете тази папка.

Стартовото хранилище съдържа всички компоненти, от които се нуждаете, за да създадете диаграмата на Гант. Ще трябва да създадете състояние и да завършите кода за компонентите. Използваният код е подобен на нашата предишна статия, която обяснява как да направите ванилия JavaScript Gantt Chart.

Ако инсталирате зависимости npm install и стартирате локалния сървър за разработка с помощта на npm run dev, ще видите страница със заглавка „Gantt Tracker“.

Нека да разгледаме как е структуриран началният код на диаграмата на Гант.

Добавяне на стил с CSS

CSS, който ще използваме за диаграмата на Гант, е включен в началния код. Използвахме Styled JSX, който идва с Next.js, за да напишем компоненти със стил с обхват. Има някои глобални стилове в styles/globals.js. Тези глобални стилове се добавят към нашето приложение в компонента Layout в папката компоненти. Цялото приложение е обвито в този компонент Layout във файла _app.js, който е в папката pages.

Таговете ‹style jsx› в компонентите съдържат CSS, който е с обхват на компонента. Стилизираният JSX прави това, като прави имената на класовете уникални. В компонента GanttChart има някои CSS променливи за цвят, радиус на границата и височина на клетката, които ще използваме за диаграмата на Гант.

Помощни функции, помощници, константи и данни

Файлът fetchWrapper.js в папката utils съдържа функция за обвивка на API за извличане, която ще използваме, за да правим HTTP заявки към нашата крайна точка на API. Тази функция за обвивка е от статията на Kent C. Dodd „Заменете Axios с проста персонализирана обвивка за извличане“. Ще използваме тази функция за извличане на обвивка, за да извлечем примерните данни от диаграмата на Гант, които се намират във файла data.json в публичната папка.

Файлът dateFunctions.js в папката helpers съдържа помощни функции, които ще използваме за изчисления и форматиране на дати. И накрая, файлът constants.js в основната папка съдържа масив от месеци, който ще използваме за създаване на колоните на диаграмата на Гант и за попълване на избраните входни елементи за избор на диапазон от дати на нашата диаграма на Гант.

Сега нека започнем да създаваме компонента на диаграмата на Гант.

Добавяне на състояние

Първо, ще добавим състояние към компонента GanttChart. Ще добавим състояние за задачите, продължителността на задачите и времевия диапазон, които ще се показват на диаграмата на Гант. Ще използваме сини хоризонтални ленти през клетките, за да покажем продължителността на задачите.

Импортирайте куките useState и useEffect в GanttChart.js:

Добавете следните променливи на състоянието и сетери към функцията GanttChart():

Ще получим данните за задачите и taskDurations от файла data.json, като направим заявка за извличане с помощта на обвивката за извличане на клиента. Импортирайте клиентската функция:

Добавете следната кука useEffect, за да извлечете данните:

След като данните бъдат извлечени, задачите и състоянието на taskDurations ще бъдат зададени. Ще можете да видите състоянието в раздела „Компоненти“ на „Инструменти за разработчици на React“.

Създаване на компонент диаграма на Гант

Компонентът на диаграмата на Гант ще бъде съставен от седем компонента, които ще намерите в папката "components/GanttChart". Във файла на началната страница index.js, който се намира в папката pages, ще импортираме основния файл GanttChart.js. Има и компонент AddButton, който се използва в компонентите AddTask и AddTaskDuration.

Импортирайте седемте компонента в GanttChart.js:

Сега ги добавете в ‹div› с id на gantt-container:

Компонентите Grid и Settings са обвивки, които прилагат някои CSS стилове към своите деца. За всеки от компонентите деструктурирайте предадените подпори. Например в компонента Tasks деструктурирайте задачи, setTasks и setTaskDurations, както следва:

Както и в компонента Разписание:

Направете същото за компонентите AddTask, AddTaskDuration и TimeRange.

Ако стартирате вашия локален сървър сега, трябва да видите следния основен скелет на нашето приложение в прозореца на вашия браузър:

Създаване на редове със задачи

Компонентът Tasks в момента изобразява три празни div реда. Под последния ред ‹div className=gantt-task-row›‹/div› добавете следния код, за да създадете нашите входове за задача:

Първо проверяваме дали tasks не е null, защото Next.js прави изобразяване от страна на сървъра. Състоянието на задачите се добавя след монтирането на компонента.

Създаваме елемент ‹input› за всяка задача със стойност, равна на името на задачата. Има бутон за изтриване за изтриване на елемента. Ще използваме атрибутите на данни, за да актуализираме състоянието на задачите, когато задача бъде редактирана или изтрита.

Правене на задачи за изтриване

Сега нека накараме бутоните за изтриване да работят. Първо добавете следното свойство към бутона за изтриване:

Сега добавете следната функция handleDelete:

Предаваме функция към setTaskDurations, за да получим предишната стойност на състоянието от аргумента на функцията. Получаваме идентификатора на задачата от атрибута data на бутона. След това актуализираме състоянието на задачите, като филтрираме задачата по id от състоянието на задачите, предадено като проп, и след това задаваме състоянието на задачите с помощта на setTasks. Също така актуализираме състоянието на tasksDurations, като премахваме всички продължителности на задачи, свързани с изтритата задача, и след това актуализираме състоянието. Това кара компонента Tasks да се изобрази повторно, което преминава в новото състояние.

Сега, ако щракнете върху бутона за изтриване, задачата ще бъде изтрита.

Правене на редактируеми задачи

Входните данни на задачата не могат да се редактират, нека поправим това. Добавете следното свойство onChange към задачата ‹input›:

Сега добавете следната функция onChange:

Получаваме стойността на входа и id за задачата. След това създаваме ново състояние на задачи, като филтрираме редактираната задача, създаваме нов обект на задача и след това актуализираме състоянието на задачите. Също така сортираме задачите по id, реда, в който са създадени. Когато добавим нови задачи по-късно в този урок, ще видим, че даденият id е число: най-скоро създадените задачи имат по-висок номер.

Сега опитайте да редактирате задачите във вашия сървър за разработка. Ще забележите, че въвеждането губи фокус, след като добавите или премахнете знак от него. Състоянието на задачите се актуализира, както можете да видите във вашите инструменти за разработка на React. Входът губи фокус, тъй като компонентът Tasks се изобразява отново всеки път, когато състоянието на задачите се актуализира.

Ще коригираме това, като използваме две референции, които ще ни позволят да фокусираме правилния вход при всяко повторно изобразяване. Добавете следните референтни обекти:

InputRef ще съдържа масив от нашите входни елементи. indexRef ще съдържа индекса на последния вход, който е бил променен. Референтните стойности ще се запазят след всяко повторно изобразяване.

Добавете следното свойство ref към задачата ‹input›:

Това ще зададе текущата стойност на inputRef. Масивът ще съдържа реф за всеки входен елемент.

Във функцията onChange добавете следния ред:

Това ще настрои indexRef на индекса на последния редактиран вход.

Сега можем да използваме тези две препратки, за да фокусираме входа, който потребителят редактира. Добавете следната кука useEffect към компонента Tasks:

Този useEffect ще се изпълнява при всяко изобразяване. Той ще постави фокус върху входа, който е бил последно редактиран. Сега опитайте да редактирате задачите във вашия сървър за разработка. Въведеното ще поддържа фокуса, докато редактирате задачата.

Създаване на мрежата на диаграмата на Гант

Ще създадем решетката на диаграмата на Gant в компонента TimeTable. В горната част на файла TimeTable.js има някои обекти, включително ganttTimePeriod, които ще използваме за динамично CSS стилизиране. Ще създадем мрежата, като използваме код, подобен на този в предишната статия, която използва ванилен JavaScript. Ще създадем решетката ред по ред. Ще добавим лентите за продължителност на задачата към правилната начална клетка, като проверим свойството на задачата за продължителност на задачата и нейната начална дата.

Има някакъв начален код за създаване на редовете. Ще запълним масивите monthRows, dayRows и weekRows с React елементи за решетката на диаграмата на Гант и след това ще ги изобразим.

Заменете импортираните модули със следните модули:

Над връщането на компонента добавете следния for цикъл:

Това преминава през броя месеци в диапазона от време и създава редове за месец, седмица и ден. Стойността за numMonths е две. Ще можем да променим тази стойност, когато завършим кода на компонента TimeRange по-късно в урока. Използваме променливата месец и метода setMonth, за да увеличим стойността на месеца във всеки цикъл. Ние използваме тази стойност и масива от месеци от нашия файл с константи, за да добавим стилизирани React елементи с правилното име на месеца към масива monthRows.

Използваме вложен цикъл, за да създадем клетките dayRow и weekRow. Ние използваме методите на JavaScript Date, както и функциите getDaysInMonth и getDayOfWeek от нашия файл dateFunctions.

Ако прегледате приложението си сега, ще видите редове с година и месец, ден от месеца и ден от седмицата. Те ще бъдат позиционирани правилно, след като добавим клетките за дата за всяка задача.

Сега нека създадем клетките на реда на задачата и да добавим продължителността на задачата. Уверете се, че следните функции са импортирани от dataFunctions.js:

Добавете следния for цикъл под този, който сте добавили:

Преминаваме през всеки месец, както направихме в първия for цикъл, който добавихме. Използваме вложения for цикъл, за да създадем клетките. Атрибутите data-task и data-date се добавят към всяка клетка. Ще ги използваме, когато добавим функция за плъзгане и пускане към продължителността на задачите. За всяка клетка картографираме състоянието taskDurations и добавяме елемент ‹div› за продължителност на задачата като дете на клетката, ако идентификаторът на задачата и началната дата на клетката съвпадат със свойствата на задачата и началото на продължителността на задачата. Ширината на елемента за продължителност на задачата се определя чрез изчисляване на продължителността на продължителността на задачата с помощта на функцията dayDiff и след това умножаването й по 100% от ширината на клетката с помощта на CSS.

Сега ще видите редовете на задачите и продължителността на задачите във вашето приложение.

Продължителността на задачите се изтрива

Сега нека да направим продължителността на задачите ни изтриваема, като натиснете бутона за изтриване, когато продължителността на задачата е на фокус. Добавете следното свойство към елемента за продължителност на задачата, който е ‹div›, който се връща, където са картографирани taskDurations (taskDurations.map((el, i) =› {):

Сега нека създадем функцията deleteTaskDuration под двата цикъла for:

React SyntheticEvent и идентификаторът на продължителността на задачата се предават във функцията deleteTaskDuration. Ако се натисне клавишът „Delete“ или „Backspace“, се създава нов обект на състояние чрез филтриране на изтритата задача от състоянието taskDurations и състоянието се актуализира.

Добавяне на функционалност за плъзгане и пускане към продължителността на задачите

Нека добавим функционалност за плъзгане и пускане към продължителността на задачите, за да променим позицията на елементите за продължителност на задачата в мрежата. Добавете следното състояние и неговия сетер:

Състоянието taskDurationElDraggedId ще следи идентификатора на продължителността на задачата, който в момента се плъзга. Сега добавете следната функция под функцията deleteTaskDuration:

Тази функция ще обработва настройката на състоянието taskDurationElDraggedId.

Сега променете върнатата продължителност на задачата ‹div› елемент на следното:

Задаваме свойството за плъзгане на елемента ‹div› за продължителност на задачата на true. Разбира се, не се нуждаем от това свойство, за да работи нашето плъзгане и пускане, но е добро за UX, защото създава „призрачен“ образ на елемента за продължителност на задачата, прикрепен към курсора на мишката, докато се плъзга. След това извикваме функцията handleDragStart и предаваме идентификатора на продължителността на задачата като аргумент, когато започва плъзгането на продължителността на задачата. Също така намалихме непрозрачността на продължителността на задачата, докато плъзгаме.

Освен това, докато плъзгате, ще видите идентификационния номер на продължителността на задачата в конзолата на инструментите за разработка.

Добавете следното свойство към клетката на реда на задачите, която има свойство на задача за данни:

Добавяме атрибута onDrop, за да дефинираме манипулатора на събитието drop за всяка клетка в зоната за плъзгане и пускане на мрежата, която е областта на клетките на задачите. Пускането на елемент върху клетка ще задейства извикване на функция onTaskDuration. Нека дефинираме функцията onTaskDurationDrop. Добавете следните редове под функцията handleDragStart:

Предотвратяваме добавянето на продължителност на задача върху друга продължителност на задача, като проверяваме дали целевата клетка има атрибут за плъзгане. След това актуализираме състоянието на taskDuration. Първо намираме задачата, която е била влачена и пусната, и я премахваме от копие на състоянието taskDurations. След това създаваме нова продължителност на задачата и я добавяме към копираното състояние. Използваме това копирано и модифицирано състояние, за да актуализираме състоянието.

Ако сега се опитате да плъзнете продължителност на задача, ще видите, че курсорът ще се обърне към иконата „неразрешено“. Това е така, защото плъзгането и пускането на елемент вътре в друг елемент е деактивирано по подразбиране. За да премахнете това поведение по подразбиране в нашата зона за плъзгане и пускане, добавете следното свойство към елемента ‹div› с идентификатор gantt-time-period-cell-container:

След като плъзгането и пускането работи, нека формулярът „Добавяне на задача“ работи.

Функциониране на формуляра „Добавяне на задача“.

В компонента AddTask формулярът има входен елемент с манипулатор на събитие onChange, който актуализира задачата за локална променлива на състоянието. Изпращането на формуляра ще извика функцията handleSubmit. Трябва да завършим тази функция, като актуализираме състоянието на задачите, използвайки предадената подложка setTasks.

Задайте новото състояние на задачите, като добавите следния инструмент за настройка на състоянието над setTask(‘’):

Създаваме нова задача и я добавяме към копие на състоянието, newState, и след това я връщаме от setState, за да заменим състоянието с новото състояние.

За да определим новия идентификатор на задача, използваме метода за намаляване, за да намерим най-големия текущ идентификатор на задача и след това добавяме такъв към него, за да създадем идентификатора за новата задача. Стойностите на идентификатора на задачата са числа, които представляват реда, в който са създадени. Задачите са сортирани по техния id.

Вече ще можете да добавяте задачи към вашата диаграма на Гант. Когато добавите задача, диаграмата на Гант се изобразява отново, показвайки новото състояние на задачите.

Функциониране на формуляра „Добавяне на продължителност на задачата“.

Компонентът AddTaskDuration е частично създаден за вас, както беше компонентът AddTask. Трябва да преминем през състоянието на предадените задачи и да попълним входа „Кои задачи“ ‹избор›. Също така трябва да актуализираме състоянието taskDuration, като използваме подавания в setTaskDurations инструмент за настройка на състоянието.

Формата има три входа: вход ‹select› за избор на задачата, за която е продължителността на задачата, и два входа за дата за избор на начална и крайна дата на продължителността на задачата. Състоянието на формуляра се управлява с помощта на трите локални променливи на състоянието, task, startDate и endDate, както и техните настройки за състояние. Функцията onChange управлява актуализирането на локалното състояние при промяна на входна стойност.

Първо, нека попълним входа на задачите ‹select› с елементи ‹option› за всяка задача. Добавете следния код вътре във входа ‹select› с идентификатор на select-task:

Сега ще видите, че менюто ‹select› е попълнено с всички имена на задачи. Ако добавите задача, ще видите, че тя е добавена към менюто ‹select›, докато компонентът GanttChart се изобразява повторно.

За да накарате функцията handleSubmit да работи, добавете следните редове към нея под e.preventDefault():

Ако не е избрана задача, се връщаме. След това създаваме нова продължителност на задачата, използвайки локалното състояние и времеви печат за „id“. След това задаваме състоянието `taskDurations` с помощта на `setTaskDurations`, като връщаме нов масив от предадената функция.

Вече ще можете да добавяте нови продължителности на задачи към вашата диаграма на Гант.

Функциониране на „Периода на проследяване“.

За да завършим кода за компонента TimeRange, трябва да дадем на всеки елемент ‹select› правилната стойност, използвайки предаденото състояние timeRange. След това трябва да актуализираме това състояние във функцията за обработка onChange.

Заменете реквизитите за стойност на четирите елемента ‹select› със следните реквизити за стойност:

Сега добавете следните редове към функцията onChange, под реда const { value, id } = e.target;:

Когато стойността на един от входовете ‹select› се промени, актуализираме състоянието timeRange. Това кара компонента GanttChart да се изобрази отново, което ще покаже актуализирания времеви диапазон.

Завършихме нашата основна диаграма на Гант, но процесът беше малко досаден и вероятно без грешки. Сега нека създадем диаграма на Гант, използвайки нашия компонент Bryntum Gantt за сравнение.

Използване на Bryntum Gantt с Next.js

За да инсталирате Bryntum Gantt с npm, просто трябва да инсталирате две библиотеки с нулеви външни зависимости. Ако не сте запознати с продуктите на Bryntum, можете да следвате ръководството тук.

Нека импортираме компонента Bryntum Gantt. В папката с компоненти създайте файл Gantt.js и добавете следните редове:

Ще използваме импортирания компонент BryntumGantt. Ще предадем конфигурационен файл като подпори, за да определим как изглежда диаграмата на Гант и откъде получава данни. Можете също така да подадете реф., ако е необходимо.

Трябва да импортираме компонента BryntumGantt динамично. Създайте друг компонент, наречен GanttInstance.js, и добавете следния код:

В главната папка на проекта създайте файл ganttConfig.js и добавете следния код:

Предаваме статичната конфигурация от ganttConfig.js към компонента Gantt. Това включва свойството columns за създаване на колони на диаграмата на Гант за задачите. Можете да научите повече за опциите за конфигурация в Bryntum docs.

Ние динамично импортираме компонента Gantt със ssr, зададен на false. Докато компонентът се зарежда, показваме зареждащ компонент, който връща таг ‹p› със съобщението „Зарежда се...“. Предадохме сетера за състояние setGanttLoadedStatus в контекстна стойност. След това получихме контекстната стойност, използвайки useContext в зареждащия компонент, за да зададем състоянието isGanttLoaded.

Функцията за почистване useEffect на зареждащия компонент задава състоянието isGanttLoaded на компонента GanttInstance на true, когато зареждащият компонент се демонтира. Почистването на ефекта се случва, когато динамично заредената диаграма на Bryntum Gantt е импортирана. Това задейства useEffect вътре в компонента GanttInstance, който задава състоянието на проекта към обекта, който ще използваме за нашата конфигурация на диаграмата на Гант.

Ние конфигурираме проекта със свойството transport за попълване на хранилищата за данни на диаграмата на Гант. Конфигурирахме URL адреса за зареждане на данни, използвайки свойството load. Източникът на данни за url е JSON файл в публичната папка на стартовото хранилище. Можете също така да конфигурирате транспорта за синхронизиране на промените в данните към конкретен URL адрес. За повече информация можете да прочетете следното ръководство в нашите документи: Обвързване на данни на Bryntum Gantt.

Нека създадем страница, за да видим нашата диаграма на Bryntum Gantt. В папката на страниците създайте файл с име bryntum.js и добавете следните редове към него:

Ние импортираме нашия компонент GanttInstance и CSS за темата Bryntum Gantt Stockholm, която е една от петте налични теми. Можете да видите демонстрация, показваща различните теми тук. Можете също да създавате персонализирани теми. В тази демонстрация можете също да научите за различните компоненти на диаграмата на Гант, като щракнете върху бутона „Научете“ в горния десен ъгъл.

Компонентът GanttInstance е обвит в ‹div› с клас контейнер. Даваме му височина 100vh, така че диаграмата на Гант да запълни целия екран.

Във вашето приложение отидете до маршрута на bryntum, като отидете на следния url: http://localhost:3000/bryntum. Сега ще видите диаграмата на Bryntum Gantt.

Този основен пример за компонента Bryntum Gantt има повече функции по подразбиране от диаграмата на Гант, която създадохме. Характеристиките включват:

  • Сгъваеми групи задачи.
  • Пренареждане на задачите с плъзгане и пускане.
  • Добавяне, редактиране, копиране и изтриване на задачи. Щракнете с десния бутон върху задача, за да видите изскачащо меню с тези действия.
  • Продължителност на задачите с възможност за плъзгане.
  • Продължителност на задачата с възможност за повторно оразмеряване. Задръжте курсора на мишката върху лявата или дясната страна на продължителността на задачата, която е зелена, докато курсорът се промени на икона за преоразмеряване. След това щракнете и задръжте, докато местите мишката наляво или надясно.

Изпробвайте някои от тези функции в приложението си.

Сравняване на диаграмите на vanilla JS, React и Bryntum Gantt

Нека сравним диаграмата на Гант, която създадохме, с основния пример на диаграмата на Гант на Bryntum, както и тази с ванилен JavaScript, която създадохме в предишна статия.

Разбиването на диаграмата на React Gantt на различни компоненти, организирането на кода и управлението на състоянието беше по-лесно, отколкото когато се използва ванилен JavaScript. React управлява състоянието декларативно, което го прави по-лесно. Ванилната диаграма на Gantt на JavaScript изискваше много директни манипулации на DOM, избиране на DOM елементи и добавяне на събития към тях. Кодът на диаграмата на ванилен JavaScript Gantt и диаграмата на React Gantt са доста сходни, но тъй като използвахме Next.js, трябваше да вземем под внимание SSR.

Диаграмата на Bryntum Gantt беше лесна за настройка, въпреки че има някакъв труден код за динамично импортиране на компонента, тъй като е само от страна на клиента. Диаграмата на Bryntum Gantt има много персонализиран API, за който можете да научите в документите за API. Можете да видите всички налични функции тук и да видите разширена демонстрация на диаграма на React Gantt тук. Разширената демонстрация включва функции като подчертаване на критични пътища, избор на тема и отмяна или повторение на действия.

Диаграмата на Bryntum Gantt е изградена с чист JavaScript/ES6+ и използва много бърз механизъм за изобразяване. Неговата производителност е страхотна дори при големи набори от данни. Можете да тествате това сами: Върнете се към вашия локален сървър за разработка и задайте периода на проследяване в персонализирания Gantt на неговия максимален диапазон и добавете нова задача. Ще забележите, че добавянето на новата задача отнема няколко секунди. Това е така, защото има много клетки за изобразяване. Опитайте това и с живия пример на ванилия JavaScript Gantt от предишната статия. Ще забележите същото.

Сега променете диапазона от дати на проекта в диаграмата, която сте създали с компонента Bryntum Gantt. Направете диапазона от дати 1000 години и след това добавете задача. Няма забележима разлика в производителността.

Следващи стъпки

Има много начини, по които можете да добавите или подобрите компонента на диаграмата на Гант, както е описано в раздела „Следващи стъпки“ на нашата „предишна статия“, където използвахме ванилен JavaScript, за да създадем диаграма на Гант. За разлика от диаграмата на Gantt в JavaScript, не е нужно да се притеснявате за дезинфекция на задачата и данните за продължителността на задачата с React.

Можете да подобрите диаграмата на Гант, като добавите проверка на входа. Управлението на състоянието може също да се подобри чрез предотвратяване на ненужни повторни рендери. Компонентът TimeTable изобразява таблицата с помощта на много вложени цикли. Минимизирането на броя на вложените цикли би подобрило производителността.

Изграждане или купуване?

Тази статия ви дава отправна точка за изграждане на ваша собствена диаграма на React Gantt с помощта на Next.js. Ако вместо това търсите да купите готово, изпитано в битки решение, което просто работи, вижте някои примери за нашия Bryntum Gantt. С компонента Bryntum Gantt можете:

  • Планирайте задачи, като използвате зависимости и ограничения.
  • Използвайте календари за проекти, задачи и ресурси.
  • Използвайте повтарящи се и фиксирани интервали от време.
  • Персонализирайте изобразяването и стила.
  • Персонализирайте потребителското изживяване чрез много различни типове колони и редактори на задачи.
  • Справете се с обширни набори от данни и настройка на производителността.

Имаме и форум за поддръжка и предлагаме професионални услуги.