{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "tags": [],
    "ExecuteTime": {
     "start_time": "2023-04-06T09:21:56.063886Z",
     "end_time": "2023-04-06T09:21:56.106234Z"
    }
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "from datetime import datetime\n",
    "sys.path.append('../../src')\n",
    "from pjplan import Task, DefaultScheduler, WBS, DhtmlxGantt, DhtmlxGanttColumn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Sample project"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-04-06T09:21:56.088235Z",
     "end_time": "2023-04-06T09:21:56.140232Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "\u001B[92mID   NAME       RESOURCE   ESTIMATE   SPENT   START             END               PREDECESSORS \u001B[0m\n\u001B[94m     Task 1     Tester     40         0       06.04.2023 00:00  13.04.2023 00:00  []           \u001B[0m\n\u001B[94m     Task 2     Tester     20         0       13.04.2023 00:00  17.04.2023 12:00  [1]          \u001B[0m\n\u001B[94m     Task 3     -          150        0       17.04.2023 12:00  12.05.2023 06:00  []           \u001B[0m\n\u001B[96m        Task 4  -          100        0       17.04.2023 12:00  04.05.2023 00:00  [2]          \u001B[0m\n\u001B[96m        Task 5  -          50         0       04.05.2023 00:00  12.05.2023 06:00  [2]          \u001B[0m\n\u001B[94m     Task 6     -          32         0       12.05.2023 06:00  18.05.2023 06:00  []           \u001B[0m\n\u001B[96m        Task 7  -          16         0       12.05.2023 06:00  16.05.2023 06:00  [5]          \u001B[0m\n\u001B[96m        Task 9  -          16         0       16.05.2023 06:00  18.05.2023 06:00  [7]          \u001B[0m"
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "with WBS() as prj:\n",
    "    prj // Task(1, 'Task 1', estimate=40, resource='Tester')\n",
    "    prj // Task(2, 'Task 2', predecessors=[prj[1]], estimate=20, resource='Tester')\n",
    "    with prj // Task(3, 'Task 3') as t:\n",
    "        t // Task(4, 'Task 4', predecessors=[prj[2]], estimate=100)\n",
    "        t // Task(5, 'Task 5', predecessors=[prj[2]], estimate=50)\n",
    "    with prj // Task(6, 'Task 6') as t:\n",
    "        t // Task(7, 'Task 7', predecessors=[prj[5]], estimate=16)\n",
    "        t // Task(8, 'Task 9', predecessors=[prj[7]], estimate=16)\n",
    "plan, usage = DefaultScheduler(datetime.now()).calc(prj)\n",
    "plan"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Simple gantt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-04-06T09:21:56.097237Z",
     "end_time": "2023-04-06T09:21:56.141232Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "<pjplan.viz.dhtmlx.gantt.DhtmlxGantt at 0x2581ddda830>",
      "text/html": "<iframe srcdoc=\"&lt;html&gt;\n&lt;meta charset=&quot;utf-8&quot;&gt;\n&lt;body&gt;\n&lt;script src=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.js?v=7.1.13&quot;&gt;&lt;/script&gt;\n&lt;link rel=&quot;stylesheet&quot; href=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.css?v=7.1.13&quot;&gt;\n&lt;style&gt;\n    html, body {\n        padding: 0px;\n        margin: 0px;\n        height: 100%;\n    }\n\n    .gantt_side_content.gantt_link_crossing {\n        top:0\n    }\n\n    \n&lt;/style&gt;\n&lt;div id=&quot;gantt_here&quot; style=&#x27;width:100%; height:100%;&#x27;&gt;&lt;/div&gt;\n&lt;script&gt;\n\n    gantt.plugins({\n        marker: true,\n        grouping: true\n    });\n\n    gantt.ext.zoom.init({\n        minColumnWidth: 80,\n        maxColumnWidth: 150,\n        levels: [\n            [\n                {unit: &quot;year&quot;, format: &quot;%Y&quot;, step: 1},\n                {unit: &quot;month&quot;, format: &quot;%M&quot;, step: 1},\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %Y&quot;, step: 1},\n                {\n                    unit: &quot;week&quot;, step: 1, format: function (date) {\n                        var dateToStr = gantt.date.date_to_str(&quot;%d.%m&quot;);\n                        var endDate = gantt.date.add(date, -6, &quot;day&quot;);\n                        return dateToStr(date) + &quot; - &quot; + dateToStr(endDate);\n                    }\n                }\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %y&quot;, step: 1},\n                {unit: &quot;day&quot;, format: &quot;%d&quot;, step: 1}\n            ]\n        ],\n        useKey: &quot;ctrlKey&quot;,\n        trigger: &quot;wheel&quot;,\n        element: function () {\n            return gantt.$root.querySelector(&quot;.gantt_task&quot;);\n        }\n    });\n\n    gantt.ext.zoom.setLevel(2)\n\n    gantt.config.min_column_width = 20;\n    gantt.config.auto_types = true;\n\n    if (true) {\n        gantt.addMarker({\n            start_date: new Date(),\n            css: &quot;today&quot;,\n        });\n    }\n\n    gantt.config.columns = [];\n\n    gantt.config.row_height = 25;\n\n    (function () {\n        gantt.config.font_width_ratio = 7;\n        gantt.templates.leftside_text = function leftSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;left&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.rightside_text = function rightSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;right&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.task_text = function taskTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;center&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n\n        function getTaskFitValue(task) {\n            var taskStartPos = gantt.posFromDate(task.start_date),\n                taskEndPos = gantt.posFromDate(task.end_date);\n\n            var width = taskEndPos - taskStartPos;\n            var textWidth = (task.text || &quot;&quot;).length * gantt.config.font_width_ratio;\n\n            if (width &lt; textWidth) {\n                var ganttLastDate = gantt.getState().max_date;\n                var ganttEndPos = gantt.posFromDate(ganttLastDate);\n                if (ganttEndPos - taskEndPos &lt; textWidth) {\n                    return &quot;left&quot;\n                } else {\n                    return &quot;right&quot;\n                }\n            } else {\n                return &quot;center&quot;;\n            }\n        }\n    })();\n\n    gantt.templates.task_class = function (start, end, task) {\n        return task.css_class;\n    };\n\n    gantt.config.readonly = true;\n\n    gantt.init(&quot;gantt_here&quot;);\n\n    gantt.parse({\n  &quot;data&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;text&quot;: &quot;Task 1&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;06-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 1&quot;,\n      &quot;start&quot;: &quot;2023-04-06 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;40&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;text&quot;: &quot;Task 2&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 2&quot;,\n      &quot;start&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;20&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;text&quot;: &quot;Task 3&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 3&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;150&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;text&quot;: &quot;Task 6&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 6&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;32&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    }\n  ],\n  &quot;links&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;source&quot;: 1,\n      &quot;target&quot;: 2,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 9,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    }\n  ]\n});\n\n&lt;/script&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n\" width=\"100%\" height=\"300\" style=\"border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>"
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "DhtmlxGantt(plan, height=300)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Sidebar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-04-06T09:21:56.112233Z",
     "end_time": "2023-04-06T09:21:56.159953Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "<pjplan.viz.dhtmlx.gantt.DhtmlxGantt at 0x2581ddda380>",
      "text/html": "<iframe srcdoc=\"&lt;html&gt;\n&lt;meta charset=&quot;utf-8&quot;&gt;\n&lt;body&gt;\n&lt;script src=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.js?v=7.1.13&quot;&gt;&lt;/script&gt;\n&lt;link rel=&quot;stylesheet&quot; href=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.css?v=7.1.13&quot;&gt;\n&lt;style&gt;\n    html, body {\n        padding: 0px;\n        margin: 0px;\n        height: 100%;\n    }\n\n    .gantt_side_content.gantt_link_crossing {\n        top:0\n    }\n\n    \n&lt;/style&gt;\n&lt;div id=&quot;gantt_here&quot; style=&#x27;width:100%; height:100%;&#x27;&gt;&lt;/div&gt;\n&lt;script&gt;\n\n    gantt.plugins({\n        marker: true,\n        grouping: true\n    });\n\n    gantt.ext.zoom.init({\n        minColumnWidth: 80,\n        maxColumnWidth: 150,\n        levels: [\n            [\n                {unit: &quot;year&quot;, format: &quot;%Y&quot;, step: 1},\n                {unit: &quot;month&quot;, format: &quot;%M&quot;, step: 1},\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %Y&quot;, step: 1},\n                {\n                    unit: &quot;week&quot;, step: 1, format: function (date) {\n                        var dateToStr = gantt.date.date_to_str(&quot;%d.%m&quot;);\n                        var endDate = gantt.date.add(date, -6, &quot;day&quot;);\n                        return dateToStr(date) + &quot; - &quot; + dateToStr(endDate);\n                    }\n                }\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %y&quot;, step: 1},\n                {unit: &quot;day&quot;, format: &quot;%d&quot;, step: 1}\n            ]\n        ],\n        useKey: &quot;ctrlKey&quot;,\n        trigger: &quot;wheel&quot;,\n        element: function () {\n            return gantt.$root.querySelector(&quot;.gantt_task&quot;);\n        }\n    });\n\n    gantt.ext.zoom.setLevel(2)\n\n    gantt.config.min_column_width = 20;\n    gantt.config.auto_types = true;\n\n    if (true) {\n        gantt.addMarker({\n            start_date: new Date(),\n            css: &quot;today&quot;,\n        });\n    }\n\n    gantt.config.columns = [{&quot;name&quot;: &quot;text&quot;, &quot;tree&quot;: true, &quot;width&quot;: 200, &quot;resize&quot;: true, &quot;label&quot;: &quot;Name&quot;}];\n\n    gantt.config.row_height = 25;\n\n    (function () {\n        gantt.config.font_width_ratio = 7;\n        gantt.templates.leftside_text = function leftSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;left&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.rightside_text = function rightSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;right&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.task_text = function taskTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;center&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n\n        function getTaskFitValue(task) {\n            var taskStartPos = gantt.posFromDate(task.start_date),\n                taskEndPos = gantt.posFromDate(task.end_date);\n\n            var width = taskEndPos - taskStartPos;\n            var textWidth = (task.text || &quot;&quot;).length * gantt.config.font_width_ratio;\n\n            if (width &lt; textWidth) {\n                var ganttLastDate = gantt.getState().max_date;\n                var ganttEndPos = gantt.posFromDate(ganttLastDate);\n                if (ganttEndPos - taskEndPos &lt; textWidth) {\n                    return &quot;left&quot;\n                } else {\n                    return &quot;right&quot;\n                }\n            } else {\n                return &quot;center&quot;;\n            }\n        }\n    })();\n\n    gantt.templates.task_class = function (start, end, task) {\n        return task.css_class;\n    };\n\n    gantt.config.readonly = true;\n\n    gantt.init(&quot;gantt_here&quot;);\n\n    gantt.parse({\n  &quot;data&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;text&quot;: &quot;Task 1&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;06-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 1&quot;,\n      &quot;start&quot;: &quot;2023-04-06 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;40&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;text&quot;: &quot;Task 2&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 2&quot;,\n      &quot;start&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;20&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;text&quot;: &quot;Task 3&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 3&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;150&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;text&quot;: &quot;Task 6&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 6&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;32&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    }\n  ],\n  &quot;links&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;source&quot;: 1,\n      &quot;target&quot;: 2,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 9,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    }\n  ]\n});\n\n&lt;/script&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n\" width=\"100%\" height=\"300\" style=\"border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>"
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "DhtmlxGantt(\n",
    "    plan,\n",
    "    height=300,\n",
    "    columns=[\n",
    "        DhtmlxGanttColumn(field='name', width=200, tree=True, label='Name')\n",
    "    ]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Custom bar styles"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-04-06T09:21:56.131233Z",
     "end_time": "2023-04-06T09:21:56.159953Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "<pjplan.viz.dhtmlx.gantt.DhtmlxGantt at 0x2581ddd9300>",
      "text/html": "<iframe srcdoc=\"&lt;html&gt;\n&lt;meta charset=&quot;utf-8&quot;&gt;\n&lt;body&gt;\n&lt;script src=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.js?v=7.1.13&quot;&gt;&lt;/script&gt;\n&lt;link rel=&quot;stylesheet&quot; href=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.css?v=7.1.13&quot;&gt;\n&lt;style&gt;\n    html, body {\n        padding: 0px;\n        margin: 0px;\n        height: 100%;\n    }\n\n    .gantt_side_content.gantt_link_crossing {\n        top:0\n    }\n\n    .dhtmlx_bar_0{background:red!important;}\n\n&lt;/style&gt;\n&lt;div id=&quot;gantt_here&quot; style=&#x27;width:100%; height:100%;&#x27;&gt;&lt;/div&gt;\n&lt;script&gt;\n\n    gantt.plugins({\n        marker: true,\n        grouping: true\n    });\n\n    gantt.ext.zoom.init({\n        minColumnWidth: 80,\n        maxColumnWidth: 150,\n        levels: [\n            [\n                {unit: &quot;year&quot;, format: &quot;%Y&quot;, step: 1},\n                {unit: &quot;month&quot;, format: &quot;%M&quot;, step: 1},\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %Y&quot;, step: 1},\n                {\n                    unit: &quot;week&quot;, step: 1, format: function (date) {\n                        var dateToStr = gantt.date.date_to_str(&quot;%d.%m&quot;);\n                        var endDate = gantt.date.add(date, -6, &quot;day&quot;);\n                        return dateToStr(date) + &quot; - &quot; + dateToStr(endDate);\n                    }\n                }\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %y&quot;, step: 1},\n                {unit: &quot;day&quot;, format: &quot;%d&quot;, step: 1}\n            ]\n        ],\n        useKey: &quot;ctrlKey&quot;,\n        trigger: &quot;wheel&quot;,\n        element: function () {\n            return gantt.$root.querySelector(&quot;.gantt_task&quot;);\n        }\n    });\n\n    gantt.ext.zoom.setLevel(2)\n\n    gantt.config.min_column_width = 20;\n    gantt.config.auto_types = true;\n\n    if (true) {\n        gantt.addMarker({\n            start_date: new Date(),\n            css: &quot;today&quot;,\n        });\n    }\n\n    gantt.config.columns = [];\n\n    gantt.config.row_height = 25;\n\n    (function () {\n        gantt.config.font_width_ratio = 7;\n        gantt.templates.leftside_text = function leftSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;left&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.rightside_text = function rightSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;right&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.task_text = function taskTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;center&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n\n        function getTaskFitValue(task) {\n            var taskStartPos = gantt.posFromDate(task.start_date),\n                taskEndPos = gantt.posFromDate(task.end_date);\n\n            var width = taskEndPos - taskStartPos;\n            var textWidth = (task.text || &quot;&quot;).length * gantt.config.font_width_ratio;\n\n            if (width &lt; textWidth) {\n                var ganttLastDate = gantt.getState().max_date;\n                var ganttEndPos = gantt.posFromDate(ganttLastDate);\n                if (ganttEndPos - taskEndPos &lt; textWidth) {\n                    return &quot;left&quot;\n                } else {\n                    return &quot;right&quot;\n                }\n            } else {\n                return &quot;center&quot;;\n            }\n        }\n    })();\n\n    gantt.templates.task_class = function (start, end, task) {\n        return task.css_class;\n    };\n\n    gantt.config.readonly = true;\n\n    gantt.init(&quot;gantt_here&quot;);\n\n    gantt.parse({\n  &quot;data&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;text&quot;: &quot;Task 1&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;06-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: &quot;dhtmlx_bar_0&quot;,\n      &quot;name&quot;: &quot;Task 1&quot;,\n      &quot;start&quot;: &quot;2023-04-06 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;40&quot;,\n      &quot;spent&quot;: &quot;0&quot;,\n      &quot;gantt_bar_style&quot;: &quot;{&#x27;background&#x27;: &#x27;red&#x27;}&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;text&quot;: &quot;Task 2&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: &quot;dhtmlx_bar_0&quot;,\n      &quot;name&quot;: &quot;Task 2&quot;,\n      &quot;start&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;20&quot;,\n      &quot;spent&quot;: &quot;0&quot;,\n      &quot;gantt_bar_style&quot;: &quot;{&#x27;background&#x27;: &#x27;red&#x27;}&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;text&quot;: &quot;Task 3&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 3&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;150&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;text&quot;: &quot;Task 6&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 6&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;32&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    }\n  ],\n  &quot;links&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;source&quot;: 1,\n      &quot;target&quot;: 2,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 9,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    }\n  ]\n});\n\n&lt;/script&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n\" width=\"100%\" height=\"300\" style=\"border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>"
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p = plan.clone()\n",
    "p.tasks(resource='Tester').gantt_bar_style = {\n",
    "    'background': 'red'\n",
    "}\n",
    "DhtmlxGantt(p, height=300)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Collapse children"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "start_time": "2023-04-06T09:21:56.143233Z",
     "end_time": "2023-04-06T09:21:56.159953Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "<pjplan.viz.dhtmlx.gantt.DhtmlxGantt at 0x2581ddf2e30>",
      "text/html": "<iframe srcdoc=\"&lt;html&gt;\n&lt;meta charset=&quot;utf-8&quot;&gt;\n&lt;body&gt;\n&lt;script src=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.js?v=7.1.13&quot;&gt;&lt;/script&gt;\n&lt;link rel=&quot;stylesheet&quot; href=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.css?v=7.1.13&quot;&gt;\n&lt;style&gt;\n    html, body {\n        padding: 0px;\n        margin: 0px;\n        height: 100%;\n    }\n\n    .gantt_side_content.gantt_link_crossing {\n        top:0\n    }\n\n    \n&lt;/style&gt;\n&lt;div id=&quot;gantt_here&quot; style=&#x27;width:100%; height:100%;&#x27;&gt;&lt;/div&gt;\n&lt;script&gt;\n\n    gantt.plugins({\n        marker: true,\n        grouping: true\n    });\n\n    gantt.ext.zoom.init({\n        minColumnWidth: 80,\n        maxColumnWidth: 150,\n        levels: [\n            [\n                {unit: &quot;year&quot;, format: &quot;%Y&quot;, step: 1},\n                {unit: &quot;month&quot;, format: &quot;%M&quot;, step: 1},\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %Y&quot;, step: 1},\n                {\n                    unit: &quot;week&quot;, step: 1, format: function (date) {\n                        var dateToStr = gantt.date.date_to_str(&quot;%d.%m&quot;);\n                        var endDate = gantt.date.add(date, -6, &quot;day&quot;);\n                        return dateToStr(date) + &quot; - &quot; + dateToStr(endDate);\n                    }\n                }\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %y&quot;, step: 1},\n                {unit: &quot;day&quot;, format: &quot;%d&quot;, step: 1}\n            ]\n        ],\n        useKey: &quot;ctrlKey&quot;,\n        trigger: &quot;wheel&quot;,\n        element: function () {\n            return gantt.$root.querySelector(&quot;.gantt_task&quot;);\n        }\n    });\n\n    gantt.ext.zoom.setLevel(2)\n\n    gantt.config.min_column_width = 20;\n    gantt.config.auto_types = true;\n\n    if (true) {\n        gantt.addMarker({\n            start_date: new Date(),\n            css: &quot;today&quot;,\n        });\n    }\n\n    gantt.config.columns = [{&quot;name&quot;: &quot;text&quot;, &quot;tree&quot;: true, &quot;width&quot;: 200, &quot;resize&quot;: true, &quot;label&quot;: &quot;Name&quot;}];\n\n    gantt.config.row_height = 25;\n\n    (function () {\n        gantt.config.font_width_ratio = 7;\n        gantt.templates.leftside_text = function leftSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;left&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.rightside_text = function rightSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;right&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.task_text = function taskTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;center&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n\n        function getTaskFitValue(task) {\n            var taskStartPos = gantt.posFromDate(task.start_date),\n                taskEndPos = gantt.posFromDate(task.end_date);\n\n            var width = taskEndPos - taskStartPos;\n            var textWidth = (task.text || &quot;&quot;).length * gantt.config.font_width_ratio;\n\n            if (width &lt; textWidth) {\n                var ganttLastDate = gantt.getState().max_date;\n                var ganttEndPos = gantt.posFromDate(ganttLastDate);\n                if (ganttEndPos - taskEndPos &lt; textWidth) {\n                    return &quot;left&quot;\n                } else {\n                    return &quot;right&quot;\n                }\n            } else {\n                return &quot;center&quot;;\n            }\n        }\n    })();\n\n    gantt.templates.task_class = function (start, end, task) {\n        return task.css_class;\n    };\n\n    gantt.config.readonly = true;\n\n    gantt.init(&quot;gantt_here&quot;);\n\n    gantt.parse({\n  &quot;data&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;text&quot;: &quot;Task 1&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;06-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 1&quot;,\n      &quot;start&quot;: &quot;2023-04-06 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;40&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;text&quot;: &quot;Task 2&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 2&quot;,\n      &quot;start&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;20&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;text&quot;: &quot;Task 3&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 3&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;150&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;text&quot;: &quot;Task 6&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 6&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;32&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    }\n  ],\n  &quot;links&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;source&quot;: 1,\n      &quot;target&quot;: 2,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 9,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    }\n  ]\n});\n\n&lt;/script&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n\" width=\"100%\" height=\"300\" style=\"border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>"
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p = plan.clone()\n",
    "p.tasks(parent_id=0).gantt_open=False\n",
    "DhtmlxGantt(p, height=300, columns=[DhtmlxGanttColumn(field='name', width=200, tree=True, label='Name')])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Scales"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "ExecuteTime": {
     "start_time": "2023-04-06T09:21:56.159953Z",
     "end_time": "2023-04-06T09:21:56.234622Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "<pjplan.viz.dhtmlx.gantt.DhtmlxGantt at 0x2581ddf3a90>",
      "text/html": "<iframe srcdoc=\"&lt;html&gt;\n&lt;meta charset=&quot;utf-8&quot;&gt;\n&lt;body&gt;\n&lt;script src=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.js?v=7.1.13&quot;&gt;&lt;/script&gt;\n&lt;link rel=&quot;stylesheet&quot; href=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.css?v=7.1.13&quot;&gt;\n&lt;style&gt;\n    html, body {\n        padding: 0px;\n        margin: 0px;\n        height: 100%;\n    }\n\n    .gantt_side_content.gantt_link_crossing {\n        top:0\n    }\n\n    \n&lt;/style&gt;\n&lt;div id=&quot;gantt_here&quot; style=&#x27;width:100%; height:100%;&#x27;&gt;&lt;/div&gt;\n&lt;script&gt;\n\n    gantt.plugins({\n        marker: true,\n        grouping: true\n    });\n\n    gantt.ext.zoom.init({\n        minColumnWidth: 80,\n        maxColumnWidth: 150,\n        levels: [\n            [\n                {unit: &quot;year&quot;, format: &quot;%Y&quot;, step: 1},\n                {unit: &quot;month&quot;, format: &quot;%M&quot;, step: 1},\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %Y&quot;, step: 1},\n                {\n                    unit: &quot;week&quot;, step: 1, format: function (date) {\n                        var dateToStr = gantt.date.date_to_str(&quot;%d.%m&quot;);\n                        var endDate = gantt.date.add(date, -6, &quot;day&quot;);\n                        return dateToStr(date) + &quot; - &quot; + dateToStr(endDate);\n                    }\n                }\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %y&quot;, step: 1},\n                {unit: &quot;day&quot;, format: &quot;%d&quot;, step: 1}\n            ]\n        ],\n        useKey: &quot;ctrlKey&quot;,\n        trigger: &quot;wheel&quot;,\n        element: function () {\n            return gantt.$root.querySelector(&quot;.gantt_task&quot;);\n        }\n    });\n\n    gantt.ext.zoom.setLevel(1)\n\n    gantt.config.min_column_width = 20;\n    gantt.config.auto_types = true;\n\n    if (true) {\n        gantt.addMarker({\n            start_date: new Date(),\n            css: &quot;today&quot;,\n        });\n    }\n\n    gantt.config.columns = [];\n\n    gantt.config.row_height = 25;\n\n    (function () {\n        gantt.config.font_width_ratio = 7;\n        gantt.templates.leftside_text = function leftSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;left&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.rightside_text = function rightSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;right&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.task_text = function taskTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;center&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n\n        function getTaskFitValue(task) {\n            var taskStartPos = gantt.posFromDate(task.start_date),\n                taskEndPos = gantt.posFromDate(task.end_date);\n\n            var width = taskEndPos - taskStartPos;\n            var textWidth = (task.text || &quot;&quot;).length * gantt.config.font_width_ratio;\n\n            if (width &lt; textWidth) {\n                var ganttLastDate = gantt.getState().max_date;\n                var ganttEndPos = gantt.posFromDate(ganttLastDate);\n                if (ganttEndPos - taskEndPos &lt; textWidth) {\n                    return &quot;left&quot;\n                } else {\n                    return &quot;right&quot;\n                }\n            } else {\n                return &quot;center&quot;;\n            }\n        }\n    })();\n\n    gantt.templates.task_class = function (start, end, task) {\n        return task.css_class;\n    };\n\n    gantt.config.readonly = true;\n\n    gantt.init(&quot;gantt_here&quot;);\n\n    gantt.parse({\n  &quot;data&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;text&quot;: &quot;Task 1&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;06-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 1&quot;,\n      &quot;start&quot;: &quot;2023-04-06 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;40&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;text&quot;: &quot;Task 2&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 2&quot;,\n      &quot;start&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;20&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;text&quot;: &quot;Task 3&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 3&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;150&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;text&quot;: &quot;Task 6&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 6&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;32&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    }\n  ],\n  &quot;links&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;source&quot;: 1,\n      &quot;target&quot;: 2,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 9,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    }\n  ]\n});\n\n&lt;/script&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n\" width=\"100%\" height=\"300\" style=\"border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>"
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p = plan.clone()\n",
    "DhtmlxGantt(p, height=300, scale='month')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    },
    "tags": [],
    "ExecuteTime": {
     "start_time": "2023-04-06T09:21:56.209424Z",
     "end_time": "2023-04-06T09:21:56.234622Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": "<pjplan.viz.dhtmlx.gantt.DhtmlxGantt at 0x2581ddd9fc0>",
      "text/html": "<iframe srcdoc=\"&lt;html&gt;\n&lt;meta charset=&quot;utf-8&quot;&gt;\n&lt;body&gt;\n&lt;script src=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.js?v=7.1.13&quot;&gt;&lt;/script&gt;\n&lt;link rel=&quot;stylesheet&quot; href=&quot;https://storage.yandexcloud.net/gymboss-test/gantt/gantt/dhtmlxgantt.css?v=7.1.13&quot;&gt;\n&lt;style&gt;\n    html, body {\n        padding: 0px;\n        margin: 0px;\n        height: 100%;\n    }\n\n    .gantt_side_content.gantt_link_crossing {\n        top:0\n    }\n\n    \n&lt;/style&gt;\n&lt;div id=&quot;gantt_here&quot; style=&#x27;width:100%; height:100%;&#x27;&gt;&lt;/div&gt;\n&lt;script&gt;\n\n    gantt.plugins({\n        marker: true,\n        grouping: true\n    });\n\n    gantt.ext.zoom.init({\n        minColumnWidth: 80,\n        maxColumnWidth: 150,\n        levels: [\n            [\n                {unit: &quot;year&quot;, format: &quot;%Y&quot;, step: 1},\n                {unit: &quot;month&quot;, format: &quot;%M&quot;, step: 1},\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %Y&quot;, step: 1},\n                {\n                    unit: &quot;week&quot;, step: 1, format: function (date) {\n                        var dateToStr = gantt.date.date_to_str(&quot;%d.%m&quot;);\n                        var endDate = gantt.date.add(date, -6, &quot;day&quot;);\n                        return dateToStr(date) + &quot; - &quot; + dateToStr(endDate);\n                    }\n                }\n            ],\n            [\n                {unit: &quot;month&quot;, format: &quot;%M %y&quot;, step: 1},\n                {unit: &quot;day&quot;, format: &quot;%d&quot;, step: 1}\n            ]\n        ],\n        useKey: &quot;ctrlKey&quot;,\n        trigger: &quot;wheel&quot;,\n        element: function () {\n            return gantt.$root.querySelector(&quot;.gantt_task&quot;);\n        }\n    });\n\n    gantt.ext.zoom.setLevel(0)\n\n    gantt.config.min_column_width = 20;\n    gantt.config.auto_types = true;\n\n    if (true) {\n        gantt.addMarker({\n            start_date: new Date(),\n            css: &quot;today&quot;,\n        });\n    }\n\n    gantt.config.columns = [];\n\n    gantt.config.row_height = 25;\n\n    (function () {\n        gantt.config.font_width_ratio = 7;\n        gantt.templates.leftside_text = function leftSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;left&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.rightside_text = function rightSideTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;right&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n        gantt.templates.task_text = function taskTextTemplate(start, end, task) {\n            if (getTaskFitValue(task) === &quot;center&quot;) {\n                return task.text;\n            }\n            return &quot;&quot;;\n        };\n\n        function getTaskFitValue(task) {\n            var taskStartPos = gantt.posFromDate(task.start_date),\n                taskEndPos = gantt.posFromDate(task.end_date);\n\n            var width = taskEndPos - taskStartPos;\n            var textWidth = (task.text || &quot;&quot;).length * gantt.config.font_width_ratio;\n\n            if (width &lt; textWidth) {\n                var ganttLastDate = gantt.getState().max_date;\n                var ganttEndPos = gantt.posFromDate(ganttLastDate);\n                if (ganttEndPos - taskEndPos &lt; textWidth) {\n                    return &quot;left&quot;\n                } else {\n                    return &quot;right&quot;\n                }\n            } else {\n                return &quot;center&quot;;\n            }\n        }\n    })();\n\n    gantt.templates.task_class = function (start, end, task) {\n        return task.css_class;\n    };\n\n    gantt.config.readonly = true;\n\n    gantt.init(&quot;gantt_here&quot;);\n\n    gantt.parse({\n  &quot;data&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;text&quot;: &quot;Task 1&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;06-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 1&quot;,\n      &quot;start&quot;: &quot;2023-04-06 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;40&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;text&quot;: &quot;Task 2&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;13-04-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;resource&quot;: &quot;Tester&quot;,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 2&quot;,\n      &quot;start&quot;: &quot;2023-04-13 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;20&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;text&quot;: &quot;Task 3&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 3&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;150&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;text&quot;: &quot;Task 4&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;17-04-2023 12:00&quot;,\n      &quot;end_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 4&quot;,\n      &quot;start&quot;: &quot;2023-04-17 12:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;100&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;text&quot;: &quot;Task 5&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;04-05-2023 00:00&quot;,\n      &quot;end_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 3,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 5&quot;,\n      &quot;start&quot;: &quot;2023-05-04 00:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;50&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;text&quot;: &quot;Task 6&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 0,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 6&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;32&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;text&quot;: &quot;Task 7&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;12-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 7&quot;,\n      &quot;start&quot;: &quot;2023-05-12 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;text&quot;: &quot;Task 9&quot;,\n      &quot;type&quot;: &quot;task&quot;,\n      &quot;start_date&quot;: &quot;16-05-2023 06:00&quot;,\n      &quot;end_date&quot;: &quot;18-05-2023 06:00&quot;,\n      &quot;resource&quot;: null,\n      &quot;open&quot;: &quot;true&quot;,\n      &quot;parent&quot;: 6,\n      &quot;progress&quot;: 0.0,\n      &quot;css_class&quot;: null,\n      &quot;name&quot;: &quot;Task 9&quot;,\n      &quot;start&quot;: &quot;2023-05-16 06:00:00&quot;,\n      &quot;end&quot;: &quot;2023-05-18 06:00:00&quot;,\n      &quot;milestone&quot;: &quot;False&quot;,\n      &quot;estimate&quot;: &quot;16&quot;,\n      &quot;spent&quot;: &quot;0&quot;\n    }\n  ],\n  &quot;links&quot;: [\n    {\n      &quot;id&quot;: 1,\n      &quot;source&quot;: 1,\n      &quot;target&quot;: 2,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 2,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 3,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 4,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 4,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 5,\n      &quot;source&quot;: 2,\n      &quot;target&quot;: 5,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 6,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 7,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 8,\n      &quot;source&quot;: 5,\n      &quot;target&quot;: 7,\n      &quot;type&quot;: &quot;0&quot;\n    },\n    {\n      &quot;id&quot;: 9,\n      &quot;source&quot;: 7,\n      &quot;target&quot;: 8,\n      &quot;type&quot;: &quot;0&quot;\n    }\n  ]\n});\n\n&lt;/script&gt;\n&lt;/body&gt;\n&lt;/html&gt;\n\" width=\"100%\" height=\"300\" style=\"border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>"
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p = plan.clone()\n",
    "DhtmlxGantt(p, height=300, scale='year')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
