{"id":12017,"date":"2024-01-04T16:30:56","date_gmt":"2024-01-04T13:30:56","guid":{"rendered":"https:\/\/dhtmlx.com\/blog\/?p=12017"},"modified":"2026-09-15T14:18:37","modified_gmt":"2026-09-15T11:18:37","slug":"building-custom-javascript-gantt-chart-dhtmlx","status":"publish","type":"post","link":"https:\/\/dhtmlx.com\/blog\/building-custom-javascript-gantt-chart-dhtmlx\/","title":{"rendered":"Building a Custom JavaScript Gantt Chart with DHTMLX"},"content":{"rendered":"<p>When you claim that your product comes with advanced customization capabilities, be sure that customers will give it a harsh test. This rule is certainly applicable to DHTMLX Gantt. Our support team receives many requests on how to implement certain appearance customizations in our <a href=\"https:\/\/dhtmlx.com\/docs\/products\/\" rel=\"noopener\" target=\"_blank\">JavaScript Gantt component<\/a>. <\/p>\n<p>We combined several popular requests into one case and would like to show you how these customizations are implemented in practice.<\/p>\n<h5>Use Case: JavaScript Gantt Chart with Custom Project Tasks, Resources, Icons, and More<\/h5>\n<p>DHTMLX Gantt comes with a comprehensive API that enables you to adjust the default view of our JavaScript component to your liking and any HTML elements to the timeline as in the example below:<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2024\/01\/imageedit_2_4829481022-1024x259.png\" alt=\"DHTMLX Gantt Customization\" width=\"1024\" height=\"259\" class=\"alignnone size-large wp-image-12018\" srcset=\"https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2024\/01\/imageedit_2_4829481022-1024x259.png 1024w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2024\/01\/imageedit_2_4829481022-300x76.png 300w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2024\/01\/imageedit_2_4829481022-768x194.png 768w, https:\/\/dhtmlx.com\/blog\/wp-content\/uploads\/2024\/01\/imageedit_2_4829481022.png 1148w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><br \/>\n<a href=\"https:\/\/snippet.dhtmlx.com\/ioxpgp6v?mode=wide\" rel=\"noopener\" target=\"_blank\">Check the code snippet ><\/a><\/p>\n<p>This JavaScript Gantt chart includes numerous customizations delivered with DHTMLX Gantt. Here, we changed the look of project tasks, specified resources in the grid as well as in the timeline, added the ability to show task names and resource images inside task bars, highlighted weekends and regular tasks belonging to a particular project, and placed custom icons on top of tasks.<\/p>\n<p>Such customizations will make it much easier for end-users to manage the workflow and keep track of resource distribution. So without further ado, let us provide you with more details on how to add such features to your Gantt project.<\/p>\n<h5>Project Task Bars with Custom Brackets<\/h5>\n<p>In Gantt charts, it can be useful to display projects with special brackets (triangles) that indicate the projects\u2019 start and end dates. By default, DHTMLX Gantt shows all tasks (including projects) as rectangles, and there is no such built-in feature for emphasizing the timeframe in project tasks. However, the rich API of our Gantt allows you to add such elements to a web project.<\/p>\n<p>For instance, it can be done via <strong>gantt.config.type_renderers<\/strong>. Using this config, you can completely redefine the appearance of tasks. We also have an <a href=\"https:\/\/docs.dhtmlx.com\/gantt\/samples\/?sample=%2704_customization\/17_classic_gantt_look.html%27&#038;filter=%27classic%27\" rel=\"noopener\" target=\"_blank\">official sample<\/a> on the subject. This option offers plenty of customization opportunities, but it also causes some inconvenience. The thing is that when creating custom elements, you\u2019ll have to manually add HTML-elements with particular classes and properties or event handlers for some existing Gantt features such as handlers for adding dependencies or a progress bar, otherwise they won\u2019t work. <\/p>\n<p>But don\u2019t worry, there are two other ways to solve this task. The first one of them is to use an additional layer that allows displaying any HTML elements in the Gantt timeline. <\/p>\n<p>Another more convenient approach for adding custom brackets is to apply CSS. You can do it using <strong>::before<\/strong> and <strong>::after<\/strong> pseudo-elements.<\/p>\n<p>They will have the following common styles:<\/p>\n<div class=\"codecolorer-container css default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"css codecolorer\"><span class=\"re1\">.gantt_project<\/span><span class=\"sy0\">::<\/span><span class=\"kw5\">before<\/span><span class=\"sy0\">,<\/span><br \/>\n<span class=\"re1\">.gantt_project<\/span><span class=\"sy0\">::<\/span><span class=\"kw5\">after<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">content<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">position<\/span><span class=\"sy0\">:<\/span> <span class=\"kw2\">absolute<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">top<\/span><span class=\"sy0\">:<\/span> <span class=\"re3\">100%<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">background-color<\/span><span class=\"sy0\">:<\/span> <span class=\"kw4\">transparent<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">border-style<\/span><span class=\"sy0\">:<\/span> <span class=\"kw2\">solid<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>Custom brackets are drawn with the <strong>border<\/strong> property, but you need to add the <strong>border-width<\/strong> parameter in the style rules:<\/p>\n<div class=\"codecolorer-container css default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"css codecolorer\"><span class=\"re1\">.gantt_project<\/span><span class=\"sy0\">::<\/span><span class=\"kw5\">before<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">left<\/span><span class=\"sy0\">:<\/span> <span class=\"re3\">-1px<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">border-width<\/span><span class=\"sy0\">:<\/span> <span class=\"re3\">0px<\/span> <span class=\"re3\">0px<\/span> <span class=\"kw3\">var<\/span><span class=\"br0\">&#40;<\/span><span class=\"re4\">--gantt-bracket-height<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw3\">var<\/span><span class=\"br0\">&#40;<\/span><span class=\"re4\">--gantt-bracket-width<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n<br \/>\n<span class=\"re1\">.gantt_project<\/span><span class=\"sy0\">::<\/span><span class=\"kw5\">after<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">right<\/span><span class=\"sy0\">:<\/span> <span class=\"re3\">0px<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">border-width<\/span><span class=\"sy0\">:<\/span> <span class=\"re3\">0px<\/span> <span class=\"kw3\">var<\/span><span class=\"br0\">&#40;<\/span><span class=\"re4\">--gantt-bracket-width<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw3\">var<\/span><span class=\"br0\">&#40;<\/span><span class=\"re4\">--gantt-bracket-height<\/span><span class=\"br0\">&#41;<\/span> <span class=\"re3\">0px<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>Since each project will have a different color, you will need to generate styles based on the project colors. For this purpose, iterate through each task and see if it is a project and has the <strong>color<\/strong> parameter. If so, you should add styles to the <strong>::before<\/strong> and <strong>::after<\/strong> pseudo-elements. The name of the class will be the following combination: &#8220;task + task ID&#8221;.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> dynamicStyle <span class=\"sy0\">=<\/span> document.<span class=\"me1\">createElement<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'style'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\ngantt.<span class=\"me1\">eachTask<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>task.<span class=\"me1\">type<\/span> <span class=\"sy0\">==<\/span> gantt.<span class=\"me1\">config<\/span>.<span class=\"me1\">types<\/span>.<span class=\"me1\">project<\/span> <span class=\"sy0\">&amp;&amp;<\/span> task.<span class=\"me1\">color<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; dynamicStyle.<span class=\"me1\">innerHTML<\/span> <span class=\"sy0\">+=<\/span> `<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; .<span class=\"me1\">task_<\/span>$<span class=\"br0\">&#123;<\/span>task.<span class=\"me1\">id<\/span><span class=\"br0\">&#125;<\/span>.<span class=\"me1\">gantt_project<\/span><span class=\"sy0\">::<\/span>before<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; border<span class=\"sy0\">-<\/span>color<span class=\"sy0\">:<\/span> transparent transparent transparent $<span class=\"br0\">&#123;<\/span>task.<span class=\"me1\">color<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; .<span class=\"me1\">task_<\/span>$<span class=\"br0\">&#123;<\/span>task.<span class=\"me1\">id<\/span><span class=\"br0\">&#125;<\/span>.<span class=\"me1\">gantt_project<\/span><span class=\"sy0\">::<\/span>after <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; border<span class=\"sy0\">-<\/span>color<span class=\"sy0\">:<\/span> transparent $<span class=\"br0\">&#123;<\/span>task.<span class=\"me1\">color<\/span><span class=\"br0\">&#125;<\/span> transparent transparent<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; `<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><br \/>\ndocument.<span class=\"me1\">body<\/span>.<span class=\"me1\">appendChild<\/span><span class=\"br0\">&#40;<\/span>dynamicStyle<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>It is also necessary to apply the <strong>task_class<\/strong> template to return a custom class, in which you need to check the task type. If it is a project type, add <strong>classic_project<\/strong> to the variable. Also, check whether the task has the <strong>color<\/strong> property, and if so, add task + task ID to the variable. After that, you should return a variable with all custom class names.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">templates<\/span>.<span class=\"me1\">task_class<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>start<span class=\"sy0\">,<\/span> end<span class=\"sy0\">,<\/span> task<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>task.<span class=\"me1\">type<\/span> <span class=\"sy0\">==<\/span> gantt.<span class=\"me1\">config<\/span>.<span class=\"me1\">types<\/span>.<span class=\"me1\">project<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; let css <span class=\"sy0\">=<\/span> <span class=\"st0\">&quot;classic_project&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>task.<span class=\"me1\">color<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; css <span class=\"sy0\">+=<\/span> ` task_$<span class=\"br0\">&#123;<\/span>task.<span class=\"me1\">id<\/span><span class=\"br0\">&#125;<\/span>`<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> css<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>There is one more condition to make everything work smoothly. It is the height of project elements. By default, task bars can be stretched to almost the entire available row height. It means that you need to reduce the height of the task bar to show corners in the project bar. You can do it using the bar_height parameter that should be specified for projects.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"st0\">&quot;row_height&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"nu0\">40<\/span><span class=\"sy0\">,<\/span> <br \/>\n<span class=\"st0\">&quot;bar_height&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"nu0\">20<\/span><span class=\"sy0\">,<\/span><\/div><\/div>\n<p><em>Please note, that if you don\u2019t do that, brackets in project tasks will extend beyond the task boundaries and will be displayed on the row below.<\/em><\/p>\n<h5>Assigning Resources to Tasks<\/h5>\n<p>The next feature is the ability to assign resources (in our case employees) to tasks. Our Gantt is known for wide <a href=\"https:\/\/docs.dhtmlx.com\/gantt\/desktop__resource_management.html\" rel=\"noopener\" target=\"_blank\">resource management<\/a> capabilities, including a <a href=\"https:\/\/docs.dhtmlx.com\/gantt\/samples\/?sample=%2711_resources\/07_assign_multiple_resources.html%27&#038;filter=%27%27\" rel=\"noopener\" target=\"_blank\">separate resource panel<\/a>. <\/p>\n<p>But if you need a simpler configuration with individual elements, you can work with resources in a <a href=\"https:\/\/docs.dhtmlx.com\/gantt\/samples\/?sample=%2711_resources\/01_assigning_resources.html%27&#038;filter=%27resource%27\" rel=\"noopener\" target=\"_blank\">simplified form<\/a>.<\/p>\n<p>In our demo, we have an array, where names and photos of employees are specified. It is implied that such data can be loaded from the server.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> resourceData <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#123;<\/span> <span class=\"st0\">&quot;key&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;1&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;label&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;John&quot;<\/span> <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#123;<\/span> <span class=\"st0\">&quot;key&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;2&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;label&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;Mike&quot;<\/span> <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#123;<\/span> <span class=\"st0\">&quot;key&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;3&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;label&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;Anna&quot;<\/span> <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#123;<\/span> <span class=\"st0\">&quot;key&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;4&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;label&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;Bill&quot;<\/span> <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#123;<\/span> <span class=\"st0\">&quot;key&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;5&quot;<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">&quot;label&quot;<\/span><span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;Floe&quot;<\/span> <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><br \/>\n<span class=\"br0\">&#93;<\/span><\/div><\/div>\n<p>Our Gantt has a lightbox section that enables you to assign several resources to one task and specify the resource value (hours, days, materials, etc.). To make it work properly, you need to specify an array with resources in the <strong>options<\/strong> parameter.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"br0\">&#123;<\/span> name<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;resources&quot;<\/span><span class=\"sy0\">,<\/span> type<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;resources&quot;<\/span><span class=\"sy0\">,<\/span> map_to<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;owners&quot;<\/span><span class=\"sy0\">,<\/span> options<span class=\"sy0\">:<\/span> resourceData<span class=\"sy0\">,<\/span> default_value<span class=\"sy0\">:<\/span> <span class=\"nu0\">8<\/span> <span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span><\/div><\/div>\n<p>If the simple Gantt configuration is used (<strong><a href=\"https:\/\/docs.dhtmlx.com\/gantt\/api__gantt_resources_config.html\" rel=\"noopener\" target=\"_blank\">gantt.config.resources<\/a><\/strong>) and resources are loaded from the server using the <strong>load()<\/strong> or <strong>parse()<\/strong> method, Gantt will automatically add the necessary parameters to the lightbox section.<\/p>\n<p>When using the custom configuration, the array must contain objects with the <strong>key<\/strong> and <strong>label<\/strong> parameters.<\/p>\n<p>In our demo, we also show resources (photos of employees) assigned to tasks in the grid section. To do that, you need to use the <strong>template<\/strong> function of the column configuration, in which the value of the <strong>getOwnerPics<\/strong> function will be returned.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">name<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;owners&quot;<\/span><span class=\"sy0\">,<\/span> label<span class=\"sy0\">:<\/span> <span class=\"st0\">&quot;Owners&quot;<\/span><span class=\"sy0\">,<\/span> resize<span class=\"sy0\">:<\/span> <span class=\"kw2\">true<\/span><span class=\"sy0\">,<\/span> width<span class=\"sy0\">:<\/span> <span class=\"nu0\">75<\/span><span class=\"sy0\">,<\/span> template<span class=\"sy0\">:<\/span> <span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">return<\/span> getOwnerPics<span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>In this function, it is necessary to use the <strong>owners<\/strong> task property, where assigned resources are indicated. If there are assignments, you should add the resource ID to a separate <strong>owners<\/strong> array. <\/p>\n<p>The next step is to iterate through the array with the resource data. If the resource ID is in the <strong>owners<\/strong> array, take the property with the photo and add it to the <strong>images<\/strong> variable. After that, you return this variable containing all photos of employees.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">function<\/span> getOwnerPics<span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; let images <span class=\"sy0\">=<\/span> <span class=\"st0\">&quot;&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> owners <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#40;<\/span>task.<span class=\"me1\">owners<\/span> <span class=\"sy0\">||<\/span> <span class=\"br0\">&#91;<\/span><span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">forEach<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>el<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; owners.<span class=\"me1\">push<\/span><span class=\"br0\">&#40;<\/span>el.<span class=\"me1\">resource_id<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; resourceData.<span class=\"me1\">forEach<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>resource<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>owners.<span class=\"me1\">indexOf<\/span><span class=\"br0\">&#40;<\/span>resource.<span class=\"me1\">key<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">&gt;<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; images <span class=\"sy0\">+=<\/span> <span class=\"st0\">&quot; &quot;<\/span> <span class=\"sy0\">+<\/span> resource.<span class=\"me1\">img<\/span> <span class=\"sy0\">||<\/span> <span class=\"st0\">&quot;&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">return<\/span> images<span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<h5>Task Names and Resources inside Task Bars<\/h5>\n<p>If you take a look at our Gantt demo, you can see that some task bars are displayed with task names and resource images inside them. If they do not fit in there, these elements will be displayed to the right of the task bar.<\/p>\n<p>To determine if the task name and employee\u2019s image can be placed inside the task bar, you are required to apply the <strong>detectOverflow<\/strong> function. In this function, you first use the <strong>getTaskPosition()<\/strong> method to get the coordinates of the task bar. Since you need only the width of the task bar, take the <strong>width<\/strong> parameter from the object returned by the <strong>getTaskPosition()<\/strong> method.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> taskWidth <span class=\"sy0\">=<\/span> gantt.<span class=\"me1\">getTaskPosition<\/span><span class=\"br0\">&#40;<\/span>task<span class=\"sy0\">,<\/span> task.<span class=\"me1\">start_date<\/span><span class=\"sy0\">,<\/span> task.<span class=\"me1\">end_date<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">width<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Then it is required to create the canvas element. Use the <strong>getComputedStyle()<\/strong> method to find out the font family and font size of the text that is usually displayed in the task bar. After that, specify these parameters in the <strong>context<\/strong> element and use the <strong>measureText()<\/strong> method to determine the text width.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> canvas <span class=\"sy0\">=<\/span> document.<span class=\"me1\">createElement<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'canvas'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">const<\/span> context <span class=\"sy0\">=<\/span> canvas.<span class=\"me1\">getContext<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;2d&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">const<\/span> bar <span class=\"sy0\">=<\/span> document.<span class=\"me1\">querySelector<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;.gantt_task_content&quot;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>bar<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> fontFamily <span class=\"sy0\">=<\/span> getComputedStyle<span class=\"br0\">&#40;<\/span>bar<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#91;<\/span><span class=\"st0\">'font-family'<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> fontSize <span class=\"sy0\">=<\/span> getComputedStyle<span class=\"br0\">&#40;<\/span>bar<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#91;<\/span><span class=\"st0\">'font-size'<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; context.<span class=\"me1\">font<\/span> <span class=\"sy0\">=<\/span> fontSize <span class=\"sy0\">+<\/span> <span class=\"st0\">' '<\/span> <span class=\"sy0\">+<\/span> fontFamily<span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"kw1\">const<\/span> textWidth <span class=\"sy0\">=<\/span> context.<span class=\"me1\">measureText<\/span><span class=\"br0\">&#40;<\/span>task.<span class=\"me1\">text<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">width<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Now it is time to add photos to the task bar. You have to specify the width of these photos to do that. In our demo, the width of images is adjusted to the height of task bars, so you can use the value of the <strong>gantt.config.row_height<\/strong> config. But if the width of the elements is different, you\u2019ll need to set a new value. The width value must be multiplied by the number of resources assigned to a given task.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> ownersWidth <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span>task.<span class=\"me1\">owners<\/span> <span class=\"sy0\">||<\/span> <span class=\"br0\">&#91;<\/span><span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">length<\/span> <span class=\"sy0\">*<\/span> gantt.<span class=\"me1\">config<\/span>.<span class=\"me1\">row_height<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Now, it is necessary to sum up the width values of text and images. If the resulting value is greater than the width of the task bar, you return true. It means that the content (text + photo) won\u2019t be included in the task bar.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>textWidth <span class=\"sy0\">+<\/span> ownersWidth <span class=\"sy0\">&gt;<\/span> taskWidth<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">return<\/span> <span class=\"kw2\">true<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>If <strong>detectOverflow<\/strong> returns <em>false<\/em>, the <strong>task_text<\/strong> template contains the following condition. If the task type is a project, you will simply return the task text. If it is a regular task, return an HTML element with the task text and employees\u2019 photos that you can get from the <strong>getOwnerPics<\/strong> function.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">templates<\/span>.<span class=\"me1\">task_text<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>start<span class=\"sy0\">,<\/span> end<span class=\"sy0\">,<\/span> task<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>detectOverflow<span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> <span class=\"st0\">&quot;&quot;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">else<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>task.<span class=\"me1\">type<\/span> <span class=\"sy0\">==<\/span> gantt.<span class=\"me1\">config<\/span>.<span class=\"me1\">types<\/span>.<span class=\"me1\">project<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> task.<span class=\"me1\">text<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">else<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> `<span class=\"sy0\">&lt;<\/span>span style<span class=\"sy0\">=<\/span><span class=\"st0\">&quot;vertical-align: top&quot;<\/span> <span class=\"sy0\">&gt;<\/span>$<span class=\"br0\">&#123;<\/span>task.<span class=\"me1\">text<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy0\">&lt;\/<\/span>span<span class=\"sy0\">&gt;<\/span>$<span class=\"br0\">&#123;<\/span>getOwnerPics<span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#125;<\/span>`<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>In the <strong>rightside_text<\/strong> template, use the <strong>detectOverflow<\/strong> function for tasks with the &#8220;task&#8221; type. If this function returns <em>true<\/em>, you should return an HTML element with the task text and employees\u2019 images from the <strong>getOwnerPics<\/strong> function.<\/p>\n<p>In DHTMLX Gantt, it is possible to use only one template. You can&#8217;t specify different templates multiple times and expect them to work properly. So you have to add all the code inside one template:<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">templates<\/span>.<span class=\"me1\">rightside_text<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>start<span class=\"sy0\">,<\/span> end<span class=\"sy0\">,<\/span> task<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>task.<span class=\"me1\">type<\/span> <span class=\"sy0\">==<\/span> gantt.<span class=\"me1\">config<\/span>.<span class=\"me1\">types<\/span>.<span class=\"me1\">project<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> `<span class=\"sy0\">&lt;<\/span>div <span class=\"kw5\">class<\/span><span class=\"sy0\">=<\/span><span class=\"st0\">'project-right'<\/span> style<span class=\"sy0\">=<\/span><span class=\"st0\">&quot;${getTriangleStyles(task, &quot;<\/span>right<span class=\"st0\">&quot;)}&quot;<\/span><span class=\"sy0\">&gt;&lt;\/<\/span>div<span class=\"sy0\">&gt;<\/span>`<br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>detectOverflow<span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> `<span class=\"sy0\">&lt;<\/span>span style<span class=\"sy0\">=<\/span><span class=\"st0\">&quot;vertical-align: top&quot;<\/span> <span class=\"sy0\">&gt;<\/span>$<span class=\"br0\">&#123;<\/span>task.<span class=\"me1\">text<\/span><span class=\"br0\">&#125;<\/span><span class=\"sy0\">&lt;\/<\/span>span<span class=\"sy0\">&gt;<\/span>$<span class=\"br0\">&#123;<\/span>getOwnerPics<span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#125;<\/span>`<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">return<\/span> <span class=\"st0\">&quot;&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<h5>Highlighting Project\u2019s Tasks and Weekends<\/h5>\n<p>When managing projects via a JavaScript Gantt chart built with DHTMLX, it can be useful to be able to highlight groups of tasks belonging to separate projects as well as weekends. <\/p>\n<p>Let&#8217;s start by highlighting the project&#8217;s tasks. To enable this feature, you need to apply an additional layer that is drawn depending on the task coordinates. But before that, check if the task type is a project.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">addTaskLayer<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &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><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><\/div><\/div>\n<p>Use the <strong>getTaskPosition()<\/strong> method to get the project coordinates. The topmost coordinate is already known &#8211; the <strong>top<\/strong> parameter in the <strong>sizes<\/strong> object.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> sizes <span class=\"sy0\">=<\/span> gantt.<span class=\"me1\">getTaskPosition<\/span><span class=\"br0\">&#40;<\/span>task<span class=\"sy0\">,<\/span> task.<span class=\"me1\">start_date<\/span><span class=\"sy0\">,<\/span> task.<span class=\"me1\">end_date<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Add the leftmost task coordinates to the <strong>left<\/strong> array and the rightmost coordinates to the <strong>right<\/strong> array, then iterate through each subtask of the project and add these coordinates. Also, increase the <strong>height<\/strong> parameter in the <strong>sizes<\/strong> object depending on the coordinates of the subtask.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> left <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span>sizes.<span class=\"me1\">left<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"kw1\">const<\/span> right <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span>sizes.<span class=\"me1\">left<\/span> <span class=\"sy0\">+<\/span> sizes.<span class=\"me1\">width<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">;<\/span><br \/>\ngantt.<span class=\"me1\">eachTask<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>child<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">const<\/span> childSizes <span class=\"sy0\">=<\/span> gantt.<span class=\"me1\">getTaskPosition<\/span><span class=\"br0\">&#40;<\/span>child<span class=\"sy0\">,<\/span> child.<span class=\"me1\">start_date<\/span><span class=\"sy0\">,<\/span> child.<span class=\"me1\">end_date<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; left.<span class=\"me1\">push<\/span><span class=\"br0\">&#40;<\/span>childSizes.<span class=\"me1\">left<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; right.<span class=\"me1\">push<\/span><span class=\"br0\">&#40;<\/span>childSizes.<span class=\"me1\">left<\/span> <span class=\"sy0\">+<\/span> childSizes.<span class=\"me1\">width<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>sizes.<span class=\"me1\">height<\/span> <span class=\"sy0\">&lt;<\/span> childSizes.<span class=\"me1\">top<\/span> <span class=\"sy0\">+<\/span> childSizes.<span class=\"me1\">height<\/span><span class=\"br0\">&#41;<\/span> sizes.<span class=\"me1\">height<\/span> <span class=\"sy0\">=<\/span> childSizes.<span class=\"me1\">top<\/span> <span class=\"sy0\">+<\/span> childSizes.<span class=\"me1\">height<\/span> <span class=\"sy0\">-<\/span> sizes.<span class=\"me1\">top<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy0\">,<\/span> task.<span class=\"me1\">id<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>After iterating through all the tasks, you have to sort the <strong>left<\/strong> array to get the minimum value, and then add it to the <strong>left<\/strong> parameter of the <strong>sizes<\/strong> object.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">sizes.<span class=\"me1\">left<\/span> <span class=\"sy0\">=<\/span> left.<span class=\"me1\">sort<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span>a<span class=\"sy0\">,<\/span> b<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> a <span class=\"sy0\">-<\/span> b<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#91;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#93;<\/span><\/div><\/div>\n<p>Next, sort the <strong>right<\/strong> array, but don&#8217;t add the rightmost value to the <strong>right<\/strong> parameter of the <strong>sizes<\/strong> object. Instead, subtract the leftmost coordinate from the resulting value to get the width of the rectangle.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> mostRight <span class=\"sy0\">=<\/span> right.<span class=\"me1\">sort<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#40;<\/span>a<span class=\"sy0\">,<\/span> b<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">=&gt;<\/span> a <span class=\"sy0\">-<\/span> b<span class=\"br0\">&#41;<\/span>.<span class=\"me1\">reverse<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#91;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#93;<\/span><br \/>\nsizes.<span class=\"me1\">width<\/span> <span class=\"sy0\">=<\/span> mostRight <span class=\"sy0\">-<\/span> sizes.<span class=\"me1\">left<\/span><\/div><\/div>\n<p>Then, you need to create an HTML element and take its coordinates from the <strong>sizes<\/strong> object. In styles, specify the color from the project&#8217;s <strong>color<\/strong> parameter. If you do not specify the color, it will be set to gray by default.<\/p>\n<p>When it comes to highlighting weekends, you should apply the <strong>timeline_cell_class<\/strong> template. Here, you should check if there is a date in the array with weekends, and if so, return a custom class name.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> weekends <span class=\"sy0\">=<\/span> <span class=\"br0\">&#91;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sy0\">+<\/span><span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">2025<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">11<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">24<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sy0\">+<\/span><span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">2025<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">11<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">25<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sy0\">+<\/span><span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">2025<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">11<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">31<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; <span class=\"sy0\">+<\/span><span class=\"kw1\">new<\/span> <span class=\"kw4\">Date<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">2026<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">,<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">,<\/span><br \/>\n<span class=\"br0\">&#93;<\/span><br \/>\n<br \/>\ngantt.<span class=\"me1\">templates<\/span>.<span class=\"me1\">timeline_cell_class<\/span> <span class=\"sy0\">=<\/span> <span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>task<span class=\"sy0\">,<\/span> date<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>weekends.<span class=\"me1\">indexOf<\/span><span class=\"br0\">&#40;<\/span><span class=\"sy0\">+<\/span>date<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">&gt;<\/span> <span class=\"sy0\">-<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> <span class=\"st0\">&quot;weekend&quot;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<h5>Custom Icons on Top of Tasks<\/h5>\n<p>And finally, we want to share with you how to display custom icons on top of tasks. An easy way to do that is to make use of the <strong>addTaskLayer()<\/strong> method. With this method, you can check if the task has the <strong>icon<\/strong> parameter, which will indicate whether the task has a custom icon. It is a custom <a href=\"https:\/\/docs.dhtmlx.com\/gantt\/desktop__task_properties.html\" rel=\"noopener\" target=\"_blank\">task property<\/a> that we added to our demo project.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\">gantt.<span class=\"me1\">addTaskLayer<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">function<\/span> <span class=\"br0\">&#40;<\/span>task<span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &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><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><\/div><\/div>\n<p>After that, let\u2019s take the coordinates of the task using the <strong>getTaskPosition()<\/strong> method. Then, create an HTML element, specify an image from an array with icons depending on the <strong>icon<\/strong> parameter, and set styles.<\/p>\n<div class=\"codecolorer-container javascript default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"javascript codecolorer\"><span class=\"kw1\">const<\/span> sizes <span class=\"sy0\">=<\/span> gantt.<span class=\"me1\">getTaskPosition<\/span><span class=\"br0\">&#40;<\/span>task<span class=\"sy0\">,<\/span> task.<span class=\"me1\">end_date<\/span><span class=\"sy0\">,<\/span> task.<span class=\"me1\">end_date<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">const<\/span> img <span class=\"sy0\">=<\/span> document.<span class=\"me1\">createElement<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">'img'<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nimg.<span class=\"me1\">src<\/span> <span class=\"sy0\">=<\/span> icons<span class=\"br0\">&#91;<\/span>task.<span class=\"me1\">icon<\/span> <span class=\"sy0\">-<\/span> <span class=\"nu0\">1<\/span><span class=\"br0\">&#93;<\/span><br \/>\nimg.<span class=\"me1\">style<\/span> <span class=\"sy0\">=<\/span> `<br \/>\n&nbsp; &nbsp; left<span class=\"sy0\">:<\/span> $<span class=\"br0\">&#123;<\/span>sizes.<span class=\"me1\">left<\/span> <span class=\"sy0\">-<\/span> <span class=\"nu0\">10<\/span><span class=\"br0\">&#125;<\/span>px<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; width<span class=\"sy0\">:<\/span> 30px<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; top<span class=\"sy0\">:<\/span> $<span class=\"br0\">&#123;<\/span>sizes.<span class=\"me1\">top<\/span><span class=\"br0\">&#125;<\/span>px<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; height<span class=\"sy0\">:<\/span> 30px<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; margin<span class=\"sy0\">-<\/span>top<span class=\"sy0\">:<\/span> 2px<span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<br \/>\n&nbsp; &nbsp; position<span class=\"sy0\">:<\/span> absolute<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; border<span class=\"sy0\">-<\/span>radius<span class=\"sy0\">:<\/span> 2px<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; color<span class=\"sy0\">:<\/span> white<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; opacity<span class=\"sy0\">:<\/span> <span class=\"nu0\">0.9<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; z<span class=\"sy0\">-<\/span>index<span class=\"sy0\">:<\/span><span class=\"nu0\">1<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; pointer<span class=\"sy0\">-<\/span>events<span class=\"sy0\">:<\/span> none<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br \/>\n<span class=\"kw1\">return<\/span> img<span class=\"sy0\">;<\/span><\/div><\/div>\n<p>That\u2019s it. Following the instructions above, you can implement the key custom Gantt features like in our <a href=\"https:\/\/snippet.dhtmlx.com\/ioxpgp6v?mode=wide\" rel=\"noopener\" target=\"_blank\">sample<\/a> and add them to your project.<\/p>\n<h5>Wrapping Up<\/h5>\n<p>Delivering a Gantt app is never a trifling matter, especially if it must include numerous customizations. We hope that this blog post will be one more useful addition to your arsenal of Gantt customization options and, if necessary, you\u2019ll easily integrate similar features into your app. Ready to share your unique Gantt customization scenarios? Send your ideas to us and we might choose it for one of our future articles.<\/p>\n<h5>Related Materials:<\/h5>\n<ul>\n<li><a href=\"https:\/\/dhtmlx.com\/blog\/building-jira-like-project-roadmap-dhtmlx-gantt\/\" rel=\"noopener\" target=\"_blank\">Building a Jira-Like Project Roadmap with DHTMLX Gantt<\/a><\/li>\n<li><a href=\"https:\/\/dhtmlx.com\/blog\/deep-dhtmlx-gantt-customization-project-roadmap-split-tasks-milestones-organized-via-swimlanes\/\" rel=\"noopener\" target=\"_blank\">Deep DHTMLX Gantt Customization: Project Roadmap with Split Tasks and Milestones Organized via Swimlanes<\/a><\/li>\n<li><a href=\"https:\/\/dhtmlx.com\/blog\/deep-dhtmlx-gantt-customization-tasks-month-marker-grid\/\" rel=\"noopener\" target=\"_blank\">Deep DHTMLX Gantt Customization: New Looks of Tasks, Month Marker, and Customized Grid<\/a><\/li>\n<li><a href=\"https:\/\/snippet.dhtmlx.com\/eq70o558?tag=gantt&#038;mode=wide\" rel=\"noopener\" target=\"_blank\">200+ Code Snippets with DHTMLX Gantt<\/a><\/li>\n<li><a href=\"https:\/\/docs.dhtmlx.com\/gantt\/\" rel=\"noopener\" target=\"_blank\">DHTMLX Gantt Documentation<\/a><\/li>\n<li><a href=\"https:\/\/docs.dhtmlx.com\/gantt\/demos\/\" rel=\"noopener\" target=\"_blank\">100+ DHTMLX Gantt Samples<\/a><\/li>\n<li><a href=\"https:\/\/dhtmlx.com\/docs\/products\/dhtmlxGantt\/download.shtml\" rel=\"noopener\" target=\"_blank\">30-day Free Trial Version<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>When you claim that your product comes with advanced customization capabilities, be sure that customers will give it a harsh test. This rule is certainly applicable to DHTMLX Gantt. &#8230;<\/p>\n","protected":false},"author":101014,"featured_media":12025,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[71],"tags":[33,20],"class_list":["post-12017","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-all-posts","tag-gantt"],"_links":{"self":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/12017","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\/101014"}],"replies":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/comments?post=12017"}],"version-history":[{"count":5,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/12017\/revisions"}],"predecessor-version":[{"id":15883,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/posts\/12017\/revisions\/15883"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media\/12025"}],"wp:attachment":[{"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/media?parent=12017"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/categories?post=12017"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dhtmlx.com\/blog\/wp-json\/wp\/v2\/tags?post=12017"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}