Building a Scheduler app with React.js and DlhSoft Gantt chart components
step by step guide — shouldn’t take more than 15 minutes!
Happy New Year, everyone! Let’s start 2023 with a 10-minute mini-tutorial showing how you can create a small resource scheduling app using React.js and DlhSoft’s Gantt Chart Hyper Library for JavaScript, which — of course — comes with easy-to-use React extensions as well.
First thing first — setting up the development environment. We’ll assume you have already installed npm and therefore npx on your system (one good way to get them is by using nvm — this method doesn’t require sudo, by the way) and that you have a text editor available for editing your source code — be that Visual Studio Code, vim, or even Xcode or TextEdit, and, of course, a browser available for running local things live, too.
Start by creating a new React app (currently version 18.2) in your projects folder of choice. On a Mac, we prefer using the old-fashion Developer folder, ourselves. Run these commands in the Terminal:
cd Developer
npx create-react-app schedule-react-app
This may take a minute or two, may trigger some warnings (to which you could come back to later), but it should succeed: a folder would be created with the specified name and including the entire structure needed for developing a nice React app:
cd schedule-react-app
ls
README.md package-lock.json public
node_modules package.json src
You can start the app if you wish, just to test everything works well, by running this command that will build the project, start hosting the Web app locally, and then open it in your browser, too:
npm start
Let’s continue by doing what the app instructs us too: we can edit src/App.js file and prepare to show up a Schedule chart component rather than the React’s logo there.
return (
<div>
<h1>Scheduler</h1>
<ScheduleChartView items={resources} settings={settings} license={license}
change={onItemChanged}>
…
</ScheduleChartView>
</div>
);
Of course, this code won’t work as is. We need to get and import the right module to be able to use ScheduleChartView (and back it up with the JavaScript it is internally based on), and we need to define items, settings, and so on. Let’s do these things one by one — don’t worry, none of them would take too long.
Back in the Terminal window, run this command to download DlhSoft’s Gantt Chart Hyper Library package (note that a fully detailed tutorial for this part is available here, under Get DlhSoft components section):
npm install http://DlhSoft.com/Packages/DlhSoft.GanttChartHyperLibrary.tar
This will put a bunch of JavaScript and related files in node_modules/DlhSoft.GanttChartHyperLibrary subfolder. You need to copy some of them from there to src and public folders as indicated below:
cp node_modules/DlhSoft.GanttChartHyperLibrary/*.HTML.Controls.js public
cp node_modules/DlhSoft.GanttChartHyperLibrary/*.React.Components.jsx src
Specifically, the React component extension modules should be placed in src folder, for them to be used at project build time, while the core JavaScript functionality should just be made available in the server side hosting folder, public.
Of course, the public JavaScript needs to be loaded somehow, to be available at runtime. That can be done “classically”, by adding these script references to public/index.html, under <html>/<head>:
<script src="DlhSoft.Data.HTML.Controls.js"></script>
<script src="DlhSoft.ProjectData.GanttChart.HTML.Controls.js"></script>
And for the React part, you would simply need to import the appropriate modules directly at the top of src/App.js:
import { ScheduleChartView } from './DlhSoft.ProjectData.GanttChart.React.Components';
Now back to the ScheduleChartView instance. Let’s define some placeholder values for items — bound to resources variable, settings, license, and onItemChanged (function) arguments it requires. Just above the return statement in App.js, add these lines of code:
let resource1 = { content: 'Resource 1' };
let resource2 = { content: 'Resource 2' };
let resources = [ resource1, resource2 ];
let settings = { };
let license = '…';
function onItemChanged(resource, propertyName, isDirect, isFinal) {
console.log(propertyName + ' changed for ' + resource.content + '.');
}
Of course, this above will just show two rows in a Schedule chart, and no Gantt chart bars at all. It’s time to load the data from a database — or just generate some mock values like we’ll do below — and configure the settings appropriately.
We’ll assume our resources are actually represented by a team of developers, and that their work is to be done in January 2023. The Gantt chart items to present in the app — movable between developers too (such as to ensure the deadline is met and skills are properly balanced) — are programming tasks in a project. Some, having specific dependency constraints, as well:
let resource1 = { content: 'Diane' };
let resource2 = { content: 'John' };
…
let resources = [resource1, resource2, …];
let task1_1 = { content: 'Web-Based To-Do List App', start: new Date(2023, 1-1, 2, 8), finish: new Date(2023, 1-1, 3, 16) };
let task1_2 = { content: 'Restaurant Review Forum', start: new Date(2023, 1-1, 5, 8), finish: new Date(2023, 1-1, 6, 16) };
let task1_3 = { content: 'Real-Time Chat Room', start: new Date(2023, 1-1, 10, 8), finish: new Date(2023, 1-1, 12, 16) };
let task2_1 = { content: 'E-Commerce Site for Handmade Goods', start: new Date(2023, 1-1, 4, 8), finish: new Date(2023, 1-1, 6, 16) };
let task2_2 = { content: 'Online Course Platform', start: new Date(2023, 1-1, 9, 8), finish: new Date(2023, 1-1, 12, 16) };
…
resource1.ganttChartItems = [ task1_1, task1_2, task1_3 ];
resource2.ganttChartItems = [ task2_1, task2_2 ];
…
task1_2.predecessors = [ { item: task1_1 } ];
task2_2.predecessors = [ { item: task1_2 }, { item: task2_1 } ];
…
let settings = {
gridWidth: '120px',
timelineStart: new Date(2023, 1-1, 1),
timelineFinish: new Date(2023, 2-1, 1),
currentTime: new Date(2023, 1-1, 1, 12),
itemHeight: 32,
hourWidth: 7.5,
isTaskCompletionReadOnly: true,
areStandardTaskLabelsVisible: true,
standardBarStyle: 'fill: #d9d2e980; stroke: #005c9e;',
standardLabelStyle: 'color: #333; background: #d9d2e9;',
areTaskPredecessorsReadOnly: true,
areTaskDependenciesVisible: true,
areTaskDependencyConstraintsEnabled: true,
isMouseWheelZoomEnabled: false,
alternativeItemStyle: 'background-color: #f0f0f080',
alternativeChartItemStyle: 'fill: #f4f4f480'
};
Finally, let’s also update src/App.css to remove the original App styles, and just add a margin for the document’s body instead:
body {
margin: 10px;
}
And, if you want, you can improve the user interface by using a separate theme that you can download from our Demo app:
mkdir temp
cd temp
curl https://dlhsoft.com/GanttChartHyperLibrary/Demos/Samples/JavaScript/GanttChartView/MainFeatures.zip -o MainFeatures.zip
unzip MainFeatures.zip MainFeatures/themes.js
cp MainFeatures/themes.js ../public
cd ..
rm -rd temp
… and edit public/index.html again to add the reference to themes.js:
<script src="themes.js"></script>
… then call initializeGanttChartTheme in your src/App.js code, just before returning the output. Notice the window addressing call that allows bypassing React rules and accessing the external JavaScript call:
window['initializeGanttChartTheme'](settings, 'Generic-blue');
And now, we’re really ready to roll!
By the way, the end user can reschedule tasks to start on different days or at different times by dragging them horizontally, and assign them to different resources by dragging them vertically, after hovering their bar bottom areas.
For reference purposes, here is the entire git repo. Feel free to copy and adapt the code into your own app, and enjoy!