{"id":4243,"date":"2017-09-08T19:45:39","date_gmt":"2017-09-08T15:45:39","guid":{"rendered":"https:\/\/dhtmlx.com\/blog\/?p=4243"},"modified":"2023-05-05T12:58:51","modified_gmt":"2023-05-05T09:58:51","slug":"using-d3-visualize-workload-dhtmlxgantt","status":"publish","type":"post","link":"https:\/\/dhtmlx.com\/blog\/using-d3-visualize-workload-dhtmlxgantt\/","title":{"rendered":"Using D3 to Visualize Workload in dhtmlxGantt"},"content":{"rendered":"<p>Gantt charts are essential for project management. They are very helpful when you need to see the sequencing of all tasks, the overall timeline of a project and plan deadlines. To further improve planning functionality, you can visualize daily amounts of work for each person. It allows distributing workload in a more effective way. D3 is one of those useful tools that make visualizing data happier. So I\u2019ll show you how to expand your <a href=\"https:\/\/dhtmlx.com\/docs\/products\/dhtmlxGantt\/\" target=\"_blank\" rel=\"noopener noreferrer\">dhtmlxGantt chart<\/a> with D3. As a result, the app will also display working hours for every employee on specific dates. You can <a href=\"https:\/\/github.com\/DHTMLX\/demo-gantt-d3\" target=\"_blank\" rel=\"noopener noreferrer\">get the demo from GitHub<\/a> and <a href=\"https:\/\/dhtmlx.github.io\/demo-gantt-d3\/index_4.html\" target=\"_blank\" rel=\"noopener noreferrer\">view it online<\/a>.<\/p>\n<h2>Initializing Gantt<\/h2>\n<p>Let\u2019s plan the layout of the app first. The layout will consist of two parts: the Gantt chart and the extra chart for the workload. The second chart will have two columns, just like the Gantt itself. The first column will display a list of all the employees. The second column will display a number of hours for each employee. In fact, it will be an extension for the Gantt timescale and will provide additional information about employees.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2017\/09\/gantt01d.png\" alt=\"dhtmlx gantt chart initialization\" \/><\/p>\n<p>Let\u2019s begin with <a href=\"https:\/\/docs.dhtmlx.com\/gantt\/desktop__howtostart_guides.html\" target=\"_blank\" rel=\"noopener noreferrer\">initializing the Gantt chart<\/a>. Next, I\u2019ll add two panels for displaying workload and create a single <em>div<\/em> for the app:<\/p>\n<div class=\"codecolorer-container html4strict default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"html4strict codecolorer\"><span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">'widget'<\/span>&gt;<\/span><br \/>\n&nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">id<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">'gantt_block'<\/span>&gt;&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">'workload_users'<\/span>&gt;<\/span>Users list<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n&nbsp; <span class=\"sc2\">&lt;<span class=\"kw2\">div<\/span> <span class=\"kw3\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">'workload_jobs'<\/span>&gt;<\/span>Tasks list<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">div<\/span>&gt;<\/span><br \/>\n<br \/>\n<span class=\"sc2\">&lt;<span class=\"kw2\">script<\/span> <span class=\"kw3\">type<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">&quot;text\/javascript&quot;<\/span>&gt;<\/span><br \/>\n&nbsp; gantt.init(&quot;gantt_block&quot;);<br \/>\n&nbsp; gantt.load(&quot;data.json&quot;);<br \/>\n<span class=\"sc2\">&lt;<span class=\"sy0\">\/<\/span><span class=\"kw2\">script<\/span>&gt;<\/span><\/div><\/div>\n<p>For correct rendering, don\u2019t forget to remove space around the app:<\/p>\n<div class=\"codecolorer-container css default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"css codecolorer\">html<span class=\"sy0\">,<\/span> body <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; <span class=\"kw1\">padding<\/span><span class=\"sy0\">:<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">margin<\/span><span class=\"sy0\">:<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>Let\u2019s style the layout of the app. According to the design, there should be two rows and two columns. So, I\u2019ll create a grid layout for the app:<\/p>\n<div class=\"codecolorer-container css default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"css codecolorer\">.widget<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; <span class=\"kw1\">display<\/span><span class=\"sy0\">:<\/span> grid<span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">grid-template-columns<\/span><span class=\"sy0\">:<\/span> <span class=\"re3\">420px<\/span> 1fr<span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">grid-template-rows<\/span><span class=\"sy0\">:<\/span> <span class=\"re3\">400px<\/span> <span class=\"re3\">200px<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>The Gantt chart will span 2 columns in the first row:<\/p>\n<div class=\"codecolorer-container css default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"css codecolorer\"><span class=\"re0\">#gantt_block<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; <span class=\"kw1\">grid-column<\/span><span class=\"sy0\">:<\/span> <span class=\"nu0\">1<\/span> \/ <span class=\"nu0\">3<\/span><span class=\"sy0\">;<\/span> <span class=\"coMULTI\">\/* from col 1 to 3 (excl) *\/<\/span><br \/>\n&nbsp; <span class=\"kw1\">grid-row<\/span><span class=\"sy0\">:<\/span> <span class=\"nu0\">1<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">height<\/span><span class=\"sy0\">:<\/span> <span class=\"re3\">380px<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>And finally, here\u2019s the place for the future chart of workload in the second row:<\/p>\n<div class=\"codecolorer-container css default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"css codecolorer\">.workload_users<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; <span class=\"kw1\">grid-column<\/span><span class=\"sy0\">:<\/span> <span class=\"nu0\">1<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">grid-row<\/span><span class=\"sy0\">:<\/span> <span class=\"nu0\">2<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n.workload_jobs<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; <span class=\"kw1\">grid-column<\/span><span class=\"sy0\">:<\/span> <span class=\"nu0\">2<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">grid-row<\/span><span class=\"sy0\">:<\/span> <span class=\"nu0\">2<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">overflow<\/span><span class=\"sy0\">:<\/span> <span class=\"kw2\">hidden<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p><a href=\"https:\/\/dhtmlx.github.io\/demo-gantt-d3\/index_0.html\" target=\"_blank\" rel=\"noopener noreferrer\">Live demo >><\/a><\/p>\n<h2>Adding List of Users<\/h2>\n<p>Next step is adding info about the employees on the project. Apart from the workload chart, employees\u2019 names will be displayed in the gantt grid and will serve as options for assigning tasks.<\/p>\n<p>Let\u2019s create the list of employees:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">serverList<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;users&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">&#91;<\/span><br \/>\n&nbsp; <span class=\"br0\">&#123;<\/span> label<span class=\"sy0\">:<\/span><span class=\"st0\">&quot;Not Assigned&quot;<\/span><span class=\"sy0\">,<\/span> key<span class=\"sy0\">:<\/span><span class=\"nu0\">0<\/span><span class=\"sy0\">,<\/span> job<span class=\"sy0\">:<\/span><span class=\"st0\">&quot; },<br \/>\n&nbsp; { label:&quot;<\/span>John Doe<span class=\"st0\">&quot;, &nbsp; &nbsp; key:1, job:&quot;<\/span>Developer<span class=\"st0\">&quot; },<br \/>\n&nbsp; \/\/others<br \/>\n]);<\/span><\/div><\/div>\n<p>In the real app, you can load the same data from a server-side.<\/p>\n<p>To display a list of names in the gantt grid, let\u2019s reconfigure the grid. By default there are four columns, I\u2019ll leave three of them (the Task name, the Start date and the Add columns) and add the column for owners of tasks:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">config<\/span>.<span class=\"me1\">columns<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><br \/>\n&nbsp; <span class=\"br0\">&#123;<\/span>name<span class=\"sy0\">:<\/span><span class=\"st0\">&quot;text&quot;<\/span><span class=\"sy0\">,<\/span> label<span class=\"sy0\">:<\/span><span class=\"st0\">&quot;Task name&quot;<\/span><span class=\"sy0\">,<\/span> tree<span class=\"sy0\">:<\/span><span class=\"kw2\">true<\/span><span class=\"sy0\">,<\/span> width<span class=\"sy0\">:<\/span><span class=\"nu0\">170<\/span> <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; <span class=\"br0\">&#123;<\/span>name<span class=\"sy0\">:<\/span><span class=\"st0\">&quot;owner&quot;<\/span><span class=\"sy0\">,<\/span> align<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;center&quot;<\/span><span class=\"sy0\">,<\/span> template<span class=\"sy0\">:<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span>item<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">return<\/span> gantt.<span class=\"me1\">getLabel<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'assignedTo'<\/span><span class=\"sy0\">,<\/span> item.<span class=\"me1\">assignedTo<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span> width<span class=\"sy0\">:<\/span> <span class=\"nu0\">120<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; <span class=\"br0\">&#123;<\/span>name<span class=\"sy0\">:<\/span><span class=\"st0\">&quot;start_date&quot;<\/span><span class=\"sy0\">,<\/span> align<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;center&quot;<\/span><span class=\"sy0\">,<\/span> width<span class=\"sy0\">:<\/span> <span class=\"nu0\">90<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; <span class=\"br0\">&#123;<\/span>name<span class=\"sy0\">:<\/span><span class=\"st0\">&quot;add&quot;<\/span><span class=\"sy0\">,<\/span> width<span class=\"sy0\">:<\/span><span class=\"nu0\">40<\/span><span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>The contents of the <em>Owner<\/em> column are taken from the <em>assignedTo<\/em> property in the tasks data. Unlike the default columns, this column also needs a header, so let\u2019s provide it:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">locale<\/span>.<span class=\"me1\">labels<\/span>.<span class=\"me1\">column_owner<\/span> <span class=\"sy0\">=<\/span> <span class=\"st0\">&quot;Owner&quot;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Now it\u2019s time to enable assigning tasks to specific employees. Let\u2019s reconfigure the <em>Edit<\/em> form (aka the <em>lightbox<\/em>). By default, the lightbox has two sections: task description and time period. Let\u2019s also add a section for choosing a person for the task:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">config<\/span>.<span class=\"me1\">lightbox<\/span>.<span class=\"me1\">sections<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><br \/>\n&nbsp; <span class=\"br0\">&#123;<\/span>name<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;description&quot;<\/span><span class=\"sy0\">,<\/span> height<span class=\"sy0\">:<\/span> <span class=\"nu0\">38<\/span><span class=\"sy0\">,<\/span> map_to<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;text&quot;<\/span><span class=\"sy0\">,<\/span> type<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;textarea&quot;<\/span><span class=\"sy0\">,<\/span> focus<span class=\"sy0\">:<\/span> <span class=\"kw2\">true<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; <span class=\"br0\">&#123;<\/span>name<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;owner&quot;<\/span><span class=\"sy0\">,<\/span> height<span class=\"sy0\">:<\/span> <span class=\"nu0\">22<\/span><span class=\"sy0\">,<\/span> map_to<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;assignedTo&quot;<\/span><span class=\"sy0\">,<\/span> type<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;select&quot;<\/span><span class=\"sy0\">,<\/span> options<span class=\"sy0\">:<\/span> gantt.<span class=\"me1\">serverList<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;users&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; <span class=\"br0\">&#123;<\/span>name<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;time&quot;<\/span><span class=\"sy0\">,<\/span> type<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;duration&quot;<\/span><span class=\"sy0\">,<\/span> map_to<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;auto&quot;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Employees are selected from the user list that I added previously.<\/p>\n<p>Just like in the case of the grid area, the new section needs a name:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">locale<\/span>.<span class=\"me1\">labels<\/span>.<span class=\"me1\">section_owner<\/span> <span class=\"sy0\">=<\/span> <span class=\"st0\">&quot;Owner&quot;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Okay, the Gantt shows the names, and the lightbox is up and ready to serve:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2017\/09\/gantt02b.png\" alt=\"dhtmlx Gantt chart configuring lightbox and user list\" \/><\/p>\n<p><a href=\"https:\/\/dhtmlx.github.io\/demo-gantt-d3\/index_1.html\" target=\"_blank\" rel=\"noopener noreferrer\">Live demo >><\/a><\/p>\n<h2>Adding the Method to Get Workload per Day<\/h2>\n<p>The Gantt is configured and it\u2019s time to work on the workload chart. First thing, I need to provide the data for the chart. The list of users is ready, and I need to calculate individual working hours.<\/p>\n<p>Let\u2019s define the function that will return a table with numbers &#8212; an object with arrays with working hours per day for each assignee.<\/p>\n<p>The function will create the <em>data<\/em> object with zero filled arrays. The length of each array equals to the number of days in the Gantt timescale:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> getJobData<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"kw1\">var<\/span> state <span class=\"sy0\">=<\/span> gantt.<span class=\"me1\">getState<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">var<\/span> users <span class=\"sy0\">=<\/span> gantt.<span class=\"me1\">serverList<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;users&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"kw1\">var<\/span> data <span class=\"sy0\">=<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"kw1\">var<\/span> line <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"kw1\">var<\/span> d <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span>state.<span class=\"me1\">min_date<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; while <span class=\"br0\">&#40;<\/span>d <span class=\"sy0\">&lt;<\/span> state.<span class=\"me1\">max_date<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp;line.<span class=\"me1\">push<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp;d.<span class=\"me1\">setDate<\/span><span class=\"br0\">&#40;<\/span>d.<span class=\"me1\">getDate<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">+<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp;<span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp;<span class=\"kw1\">for<\/span> <span class=\"br0\">&#40;<\/span><span class=\"kw1\">var<\/span> i <span class=\"sy0\">=<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">;<\/span> i <span class=\"sy0\">&lt;<\/span> users.<span class=\"me1\">length<\/span><span class=\"sy0\">;<\/span> i<span class=\"sy0\">++<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; data<span class=\"br0\">&#91;<\/span>users<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span>.<span class=\"me1\">key<\/span><span class=\"br0\">&#93;<\/span> <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><span class=\"br0\">&#93;<\/span>.<span class=\"me1\">concat<\/span><span class=\"br0\">&#40;<\/span>line<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"co1\">\/\/data generating logic<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"kw1\">return<\/span> data<span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>The table is created, and now I need to fill the table with correct working hours per person. Let\u2019s iterate through all the tasks and add working hours to people, to whom the tasks are assigned. I\u2019ll add 8 hours for each day of the task duration:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">eachTask<\/span><span class=\"br0\">&#40;<\/span>task <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; <br \/>\n&nbsp; &nbsp;<span class=\"kw1\">var<\/span> t <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span>task.<span class=\"me1\">start_date<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp;<span class=\"kw1\">var<\/span> line <span class=\"sy0\">=<\/span> data<span class=\"br0\">&#91;<\/span>task.<span class=\"me1\">assignedTo<\/span> <span class=\"sy0\">||<\/span> <span class=\"nu0\">0<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp;while <span class=\"br0\">&#40;<\/span>t <span class=\"sy0\">&lt;<\/span> task.<span class=\"me1\">end_date<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp;i <span class=\"sy0\">=<\/span> <span class=\"kw4\">Math<\/span>.<span class=\"me1\">round<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span>t <span class=\"sy0\">-<\/span> state.<span class=\"me1\">min_date<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">\/<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">1000<\/span><span class=\"sy0\">*<\/span><span class=\"nu0\">60<\/span><span class=\"sy0\">*<\/span><span class=\"nu0\">60<\/span><span class=\"sy0\">*<\/span><span class=\"nu0\">24<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp;line<span class=\"br0\">&#91;<\/span>i<span class=\"br0\">&#93;<\/span> <span class=\"sy0\">+=<\/span> <span class=\"nu0\">8<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp;t.<span class=\"me1\">setDate<\/span><span class=\"br0\">&#40;<\/span>t.<span class=\"me1\">getDate<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">+<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp;<span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp;<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Then let\u2019s make sure that projects and milestones are excluded from calculations. I\u2019ll add this check at the beginning of the <em>eachTask<\/em> method:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">&nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>task.<span class=\"me1\">type<\/span> <span class=\"sy0\">===<\/span> <span class=\"st0\">&quot;project&quot;<\/span> &nbsp;<span class=\"sy0\">||<\/span> task.<span class=\"me1\">type<\/span> <span class=\"sy0\">===<\/span> <span class=\"st0\">&quot;milestone&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">return<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Now I can load the data and calculate the workload:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">load<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;data.json&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; console.<span class=\"me1\">log<\/span><span class=\"br0\">&#40;<\/span>getJobData<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p><a href=\"https:\/\/dhtmlx.github.io\/demo-gantt-d3\/index_2.html\" target=\"_blank\" rel=\"noopener noreferrer\">Live demo >><\/a><\/p>\n<h2>Visualizing Workload<\/h2>\n<p>Let\u2019s move on to the chart itself. There\u2019s going to be a list of employees on the left, just below the gantt grid. Let\u2019s use D3 and create the list:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> renderD3Diagram<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n<br \/>\n&nbsp; d3.<span class=\"me1\">select<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.workload_users&quot;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">selectAll<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.eachPerson&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp;.<span class=\"me1\">data<\/span><span class=\"br0\">&#40;<\/span>gantt.<span class=\"me1\">serverList<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;users&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp;.<span class=\"me1\">enter<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">append<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;div&quot;<\/span><span class=\"br0\">&#41;<\/span> &nbsp; &nbsp; &nbsp;<span class=\"co1\">\/\/append a new div<\/span><br \/>\n&nbsp; &nbsp;.<span class=\"me1\">text<\/span><span class=\"br0\">&#40;<\/span>item <span class=\"sy0\">=&gt;<\/span> item.<span class=\"me1\">label<\/span><span class=\"br0\">&#41;<\/span> &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/add the text from data<\/span><br \/>\n&nbsp; &nbsp;.<span class=\"me1\">attr<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;class&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;eachPerson&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span> &nbsp; <span class=\"co1\">\/\/add class to div<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n&nbsp; <span class=\"co1\">\/\/...chart<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>Next, I\u2019ll style the list with CSS, and here\u2019s what I\u2019ll have:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2017\/09\/gantt03b.png\" alt=\"gantt chart user list\" \/><\/p>\n<p>Next, let\u2019s draw the chart itself. Chart lines will represent each employee and will consist of boxes for every day in the Gantt timescale. Let\u2019s divide the task into subtasks:<\/p>\n<ul>\n<li>load data<\/li>\n<li>paint the chart<\/li>\n<li>paint a line for each person<\/li>\n<li>paint a box for each day of the project duration<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2017\/09\/gantt04_crb.png\" alt=\"gantt chart visualizing workload d3 examples\" \/><\/p>\n<p>Let\u2019s begin:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> renderD3Diagram<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; <span class=\"kw1\">var<\/span> data <span class=\"sy0\">=<\/span> getJobData<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"co1\">\/\/user list<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"kw1\">var<\/span> line <span class=\"sy0\">=<\/span> d3.<span class=\"me1\">select<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.workload_jobs&quot;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">selectAll<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.eachPerson&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; .<span class=\"me1\">data<\/span><span class=\"br0\">&#40;<\/span>gantt.<span class=\"me1\">serverList<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;users&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"co1\">\/\/...add new lines and paint them<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>New <em>div<\/em> elements can be added by <em>line.enter().append(&#8220;div&#8221;)<\/em>. After a line is created, it needs painting:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> paintLine<span class=\"br0\">&#40;<\/span>line<span class=\"sy0\">,<\/span> data<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; <span class=\"kw1\">var<\/span> boxes <span class=\"sy0\">=<\/span> line<br \/>\n&nbsp; &nbsp;.<span class=\"me1\">style<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;width&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">&#40;<\/span>data<span class=\"br0\">&#91;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#93;<\/span>.<span class=\"me1\">length<\/span> <span class=\"sy0\">*<\/span> <span class=\"nu0\">72<\/span> <span class=\"sy0\">+<\/span> <span class=\"nu0\">20<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">+<\/span><span class=\"st0\">&quot;px&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp;.<span class=\"me1\">attr<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;class&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;eachPerson&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp;.<span class=\"me1\">selectAll<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.eachDay&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp;.<span class=\"me1\">data<\/span><span class=\"br0\">&#40;<\/span>item <span class=\"sy0\">=&gt;<\/span> data<span class=\"br0\">&#91;<\/span>item.<span class=\"me1\">key<\/span><span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp;<span class=\"co1\">\/\/...add new boxes and paint them<\/span><br \/>\n&nbsp; <br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>To paint new lines, you need to call the <strong>paintLine()<\/strong> function with the following parameters:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">&nbsp; <span class=\"co1\">\/\/...add new lines and paint them<\/span><br \/>\n&nbsp; paintLine<span class=\"br0\">&#40;<\/span>line.<span class=\"me1\">enter<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">append<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;div&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span> data<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Like lines, boxes are added by <em>boxes.enter().append(&#8220;div&#8221;)<\/em>. To paint each box you need to render the working hours:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> markBoxes<span class=\"br0\">&#40;<\/span>boxes<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; boxes.<span class=\"me1\">text<\/span><span class=\"br0\">&#40;<\/span>a <span class=\"sy0\">=&gt;<\/span> a<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp;.<span class=\"me1\">attr<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;class&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;eachDay&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>By analogy with <em>paintLine()<\/em>, <strong>markBoxes()<\/strong> should be called with a newly created <strong>div<\/strong> as a parameter for rendering a new box:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">&nbsp; <span class=\"co1\">\/\/...add new boxes and paint them<\/span><br \/>\n&nbsp; markBoxes<span class=\"br0\">&#40;<\/span>boxes.<span class=\"me1\">enter<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">append<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;div&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Next, I need to style the chart with CSS. The main point of styling is to set <em>display: inline<\/em> for each box and set size. Besides, it\u2019ll be good to color each box according to the amount of work. Add a few lines of code to <strong>markBoxes()<\/strong>:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">&nbsp; .<span class=\"me1\">style<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;background&quot;<\/span><span class=\"sy0\">,<\/span> data <span class=\"sy0\">=&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp;<span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>data <span class=\"sy0\">==<\/span> <span class=\"nu0\">0<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw1\">return<\/span> &nbsp;<span class=\"st0\">&quot;#80fa80&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp;<span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>data <span class=\"sy0\">&lt;=<\/span> <span class=\"nu0\">8<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw1\">return<\/span> &nbsp;<span class=\"st0\">&quot;#fafa80&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp;<span class=\"kw1\">return<\/span> <span class=\"st0\">&quot;#fa8080&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><\/div><\/div>\n<p>After everything is done, you can load the data and draw the chart:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">load<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;data.json&quot;<\/span><span class=\"sy0\">,<\/span> renderD3Diagram<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p><img decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2017\/09\/gantt04b.png\" alt=\"dhtmlx gantt chart d3.js visualizing workload\" \/><\/p>\n<p><a href=\"https:\/\/dhtmlx.github.io\/demo-gantt-d3\/index_3.html\" target=\"_blank\" rel=\"noopener noreferrer\">Live demo >><\/a><\/p>\n<h2>Making Visualization Dynamic<\/h2>\n<p>The app is almost ready. If the timescale is long like in this case, you need to scroll the Gantt. And it\u2019s natural to expect that the lower chart with working hours will be scrolled with the Gantt. Let\u2019s link chart scroll to Gantt scroll and attach a corresponding event:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">attachEvent<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;onGanttScroll&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"kw1\">function<\/span><span class=\"br0\">&#40;<\/span>left<span class=\"sy0\">,<\/span> top<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp;<span class=\"kw1\">var<\/span> state <span class=\"sy0\">=<\/span> gantt.<span class=\"me1\">getScrollState<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp;document.<span class=\"me1\">querySelector<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.workload_jobs&quot;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">scrollLeft<\/span> <span class=\"sy0\">=<\/span> state.<span class=\"me1\">x<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Good, the UI of the app is complete. However, there\u2019s still one problem: if you try adding tasks and assigning them, the workload won\u2019t update. Let\u2019s add a few lines of code that will redraw the chart on every change of data in the Gantt. First, let\u2019s complete <strong>renderD3Diagram()<\/strong> and add code for rendering already existing lines before painting new ones:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> renderD3Diagram<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; <span class=\"co1\">\/\/...old code<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"co1\">\/\/redraw the existing lines<\/span><br \/>\n&nbsp; paintLine<span class=\"br0\">&#40;<\/span>line<span class=\"sy0\">,<\/span> data<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"co1\">\/\/add new lines and paint them<\/span><br \/>\n&nbsp; paintLine<span class=\"br0\">&#40;<\/span>line.<span class=\"me1\">enter<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">append<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;div&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span> data<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>And let\u2019s do the same for repainting the existing boxes:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> paintLine<span class=\"br0\">&#40;<\/span>line<span class=\"sy0\">,<\/span> data<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; <span class=\"co1\">\/\/...old code<\/span><br \/>\n<br \/>\n&nbsp; <span class=\"co1\">\/\/repaint the existing boxes<\/span><br \/>\n&nbsp; markBoxes<span class=\"br0\">&#40;<\/span>boxes<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; <span class=\"co1\">\/\/add new boxes and paint them<\/span><br \/>\n&nbsp; markBoxes<span class=\"br0\">&#40;<\/span>boxes.<span class=\"me1\">enter<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">append<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;div&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>Finally, let\u2019s attach corresponding events:<\/p>\n<div class=\"codecolorer-container javascript default codecolorer-noborder\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">attachEvent<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;onAfterTaskAdd&quot;<\/span><span class=\"sy0\">,<\/span> renderD3Diagram<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\ngantt.<span class=\"me1\">attachEvent<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;onAfterTaskUpdate&quot;<\/span><span class=\"sy0\">,<\/span> renderD3Diagram<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\ngantt.<span class=\"me1\">attachEvent<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;onAfterTaskDelete&quot;<\/span><span class=\"sy0\">,<\/span> renderD3Diagram<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p><img decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2017\/09\/gantt05b.png\" alt=\"dhtmlx gantt chart template ready\" \/><\/p>\n<p><a href=\"https:\/\/dhtmlx.github.io\/demo-gantt-d3\/index_4.html\" target=\"_blank\" rel=\"noopener noreferrer\">Live demo >><\/a><\/p>\n<h2>Conclusion<\/h2>\n<p>Gantt charts are well-known means of visualizing the workflow. You can make them even more effective and add other features, like the <a href=\"https:\/\/dhtmlx.github.io\/demo-gantt-d3\/index_4.html\" target=\"_blank\" rel=\"noopener noreferrer\">chart for daily workload<\/a> of every employee involved in the project. You can download <a href=\"https:\/\/github.com\/DHTMLX\/demo-gantt-d3\" target=\"_blank\" rel=\"noreferrer noopener\">the source code from GitHub<\/a>. <a href=\"https:\/\/github.com\/d3\/d3\/wiki\/Tutorials\" target=\"_blank\" rel=\"noopener noreferrer\">D3<\/a> helps create amazing and useful things. Have great ideas on further improvements for Gantt or other UI components? Let me know in the comments. I hope the article will inspire great ideas and help you with your projects.<\/p>\n<p><em>Written by Asta Vebraite, a tech writer at DHTMLX.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Gantt charts are essential for project management. They are very helpful when you need to see the sequencing of all tasks, the overall timeline of a project and plan &#8230;<\/p>\n","protected":false},"author":101011,"featured_media":4273,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,71,1,38],"tags":[33,20,14],"class_list":["post-4243","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-posts-for-codeproject-com","category-tutorials","category-uncategorized","category-visible","tag-all-posts","tag-gantt","tag-tips"],"_links":{"self":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/4243","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/users\/101011"}],"replies":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/comments?post=4243"}],"version-history":[{"count":1,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/4243\/revisions"}],"predecessor-version":[{"id":11366,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/4243\/revisions\/11366"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media\/4273"}],"wp:attachment":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media?parent=4243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/categories?post=4243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/tags?post=4243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}