
Hi, my name is Zhenya, and I'm just one of the inhabitants of the JavaScript universe who wants to share with you interesting experience in frontend development, namely how to customize the Gantt chart.
, . , :
. .
, . β . , , JavaScript .
, . :
JavaScript DHTMLX Gantt. , , β .
β :
β .
, GPL GPLv2 , (TLDRlegal). , β / front-end/ , . , , . - , .
DHTMLX JavaScript . , , .
.

DHTMLX Gantt :
, . DHTMLX Gantt, β color picker, . .
HTML5 JavaScript, .
. JS CSS , , ( ):
<!DOCTYPE html>
<html>
<head>
<script src="codebase/dhtmlxgantt.js"></script>
<link href="codebase/dhtmlxgantt.css" rel="stylesheet">
</head>
<body>
<div id="gantt_here" style='width:100vw; height:100vh;'></div>
<script>
window.addEventListener("DOMContentLoaded",() => {
gantt.init("gantt_here");
});
</script>
</body>
</html>
HTML js , , , . 1 ( ) 2 ( ). , , ( ):
gantt.parse({
data: [
{
id: 1, text: " ", start_date: "01-05-2020", duration: 18, open: true
},
{
id: 2, text: " ", start_date: "02-05-2020", duration: 4, parent: 1
},
{
id: 3, text: " ", start_date: "07-05-2020", duration: 5, parent: 1
}
],
links: [
{id: 1, source: 1, target: 2, type: "1"},
{id: 2, source: 2, target: 3, type: "0"}
]
});
});

.
Inline Editors
: , , .
, editor
:
gantt.config.columns = [
{name: "text", tree: true, width: '*', resize: true, editor: textEditor},
{name: "start_date", align: "center", resize: true, editor: dateEditor},
{name: "duration", align: "center", editor: durationEditor},
{name: "add", width: 44}
];
type
, , map_to
, , . , , :
const textEditor = {type: "text", map_to: "text"};
const dateEditor = {type: "date", map_to: "start_date", min: new Date(2020, 0, 1),
max: new Date(2021, 0, 1)};
const durationEditor = {type: "number", map_to: "duration", min:0, max: 100};
.
, .
, : (select) (color picker). , -colorpicker.
, HTML5 input color
, .
. :
gantt.config.editor_types.custom_editor = {
show: (id, column, config, placeholder) => {
placeholder.innerHTML `<div><input type='text' name='${column.name}'></div>`;
},
hide: () => {
},
set_value: (value, id, column, node) => {
},
get_value: (id, column, node) => {
},
is_changed: (value, id, column, node) => {
},
is_valid: (value, id, column, node) => {
return true/false;
},
save: (id, column, node) => {
},
focus: (node) => {
}
}
, :
show
, color:
gantt.config.editor_types.color = {
show: (id, column, config, placeholder) => {
placeholder.innerHTML = `<div><input type='color' name='${column.name}'></div>`;
},
hide
, , , :
hide: () => {},
β set_value
get_value
:
set_value: (value, id, column, node) => {
const input = node.querySelector("input");
input.value = value
},
get_value: (id, column, node) => {
const input = node.querySelector("input");
return input.value;
},
, task
. , , .
is_changed
. , , :
is_changed: (value, id, column, node) => {
const input = node.querySelector("input");
return input.value !== value;
},
, , true, . true , false .
is_valid
, false, , :
is_valid: (value, id, column, node) => {
const input = node.querySelector("input");
return !!input.value;
},
save
, , , .
focus
:
focus: node => {
const input = node.querySelector("input");
input.focus();
},
.
.
. type , ( type: βcolorβ).
const textEditor = {type: "text", map_to: "text"};
const dateEditor = {type: "date", map_to: "start_date", min: new Date(2020, 0, 1),
max: new Date(2021, 0, 1)};
const durationEditor = {type: "number", map_to: "duration", min:0, max: 100};
const colorEditor = {type: "color", map_to: "color"};
gantt.config.columns = [
{name: "text", tree: true, width: '*', resize: true, editor: textEditor},
{name: "start_date", align: "center", resize: true, editor: dateEditor},
{name: "duration", align: "center", editor: durationEditor},
{name: "color", align: "center", editor: colorEditor},
{name: "add", width: 44}
];
color
, . , , β , color:"#FF0000":
{
id: 2, text: " ", start_date: "02-05-2020", duration: 4, parent: 1, color:"#FF0000"
},

, , βcolorβ . :
gantt.config.columns = [
{name: "text", tree: true, width: '*', resize: true, editor: textEditor},
{name: "start_date", align: "center", resize: true, editor: dateEditor},
{name: "duration", align: "center", editor: durationEditor},
{name: "color", align: "center", label:"Color", editor: colorEditor, template:
(task) => {
return `<div class='task-color-cell' style='background:${task.color}'></div>`
}
},
{name: "add", width: 44}
];
, div . css , :
.task-color-cell{
margin:10%;
width:20px;
height:20px;
border:1px solid #cecece;
display:inline-block;
border-radius:20px;
}

: https://plnkr.co/edit/yGWtLzoELPrhJV2K?preview
Color Picker
DHTMLX Gantt , , jquery Spectrum.
:
<!DOCTYPE html>
<html>
<head>
<script src="https://docs.dhtmlx.com/gantt/codebase/dhtmlxgantt.js"></script>
<link rel="stylesheet"href="https://docs.dhtmlx.com/gantt/codebase/dhtmlxgantt.css">
<script
src="http://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="http://bgrins.imtqy.com/spectrum/spectrum.js"></script>
<link rel="stylesheet" href="http://bgrins.imtqy.com/spectrum/spectrum.css">
<script src="script.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="gantt_here"></div>
</body>
</html>
. let editor, . , , input .
show
. , .
: editor.spectrum("show")
show, . , show
placeholder- . -, color picker , placeholder .
document.addEventListener("DOMContentLoaded", function(event) {
let editor;
gantt.config.editor_types.color = {
show: (id, column, config, placeholder) => {
placeholder.innerHTML = `<div><input type='color' name='${column.name}'></div>`;
editor = $(placeholder).find("input").spectrum({
change:() => {
gantt.ext.inlineEditors.save();
}
});
setTimeout(() => {
editor.spectrum("show");
})
}
Next, I defined the βhideβ method - the destructor will be called when the editor is closed:
hide: () => {
if(editor){
editor.spectrum("destroy");
editor = null;
}
The remaining methods are not too different from the original implementation. You just need to change the way you get the values ββfrom the control:
set_value: (value, id, column, node) => {
editor.spectrum("set", value);
},
get_value: (id, column, node) => {
return editor.spectrum("get").toHexString();
},
is_changed: function (value, id, column, node) {
const newValue = this.get_value(id, column, node);
return newValue !== value;
},
is_valid: function (value, id, column, node) {
const newValue = this.get_value(id, column, node);
return !!newValue;
},
focus:(node) => {
editor.spectrum("show");
}

After that, everything should work as expected!
And this is a link to my example with the built-in Color Picker .
I hope this article helps you in adjusting the color of tasks in the Gantt chart.