|
|
@@ -0,0 +1,1000 @@
|
|
|
+(function(){
|
|
|
+
|
|
|
+var apiUrl = "https://export.dhtmlx.com/gantt";
|
|
|
+
|
|
|
+var templates = [
|
|
|
+ "leftside_text",
|
|
|
+ "rightside_text",
|
|
|
+ "task_text",
|
|
|
+ "progress_text",
|
|
|
+ "task_class"
|
|
|
+];
|
|
|
+
|
|
|
+function xdr(url, pack, cb){
|
|
|
+ if (gantt.env.isIE){
|
|
|
+ gantt.env.isIE = false;
|
|
|
+ gantt.ajax.post(url, pack, cb);
|
|
|
+ gantt.env.isIE = true;
|
|
|
+ } else {
|
|
|
+ gantt.ajax.post(url, pack, cb);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function defaults(obj, std){
|
|
|
+ for (var key in std)
|
|
|
+ if (!obj[key])
|
|
|
+ obj[key] = std[key];
|
|
|
+ return obj;
|
|
|
+}
|
|
|
+
|
|
|
+//compatibility for new versions of gantt
|
|
|
+if(!gantt.ajax){
|
|
|
+ if(window.dhtmlxAjax){
|
|
|
+ gantt.ajax = window.dhtmlxAjax;
|
|
|
+ }else if(window.dhx4){
|
|
|
+ gantt.ajax = window.dhx4.ajax;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function mark_columns(base){
|
|
|
+ var columns = base.config.columns;
|
|
|
+ if (columns)
|
|
|
+ for (var i = 0; i < columns.length; i++) {
|
|
|
+ if (columns[i].template)
|
|
|
+ columns[i].$template = true;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+function add_export_methods(gantt){
|
|
|
+ var color_box = null;
|
|
|
+ var color_hash = {};
|
|
|
+
|
|
|
+ function get_styles(css){
|
|
|
+ if (!color_box){
|
|
|
+ var color_box = document.createElement("DIV");
|
|
|
+ color_box.style.cssText = "position:absolute; display:none;";
|
|
|
+ document.body.appendChild(color_box);
|
|
|
+ }
|
|
|
+ if (color_hash[css])
|
|
|
+ return color_hash[css];
|
|
|
+
|
|
|
+ color_box.className = css;
|
|
|
+ return (color_hash[css] = get_color(color_box, "color")+";"+get_color(color_box, "backgroundColor"));
|
|
|
+ }
|
|
|
+
|
|
|
+ gantt._getWorktimeSettings = function() {
|
|
|
+
|
|
|
+ var defaultWorkTimes = {
|
|
|
+ hours : [0, 24],
|
|
|
+ dates : {0:true, 1:true, 2:true, 3:true, 4:true, 5:true, 6:true}
|
|
|
+ };
|
|
|
+
|
|
|
+ var time;
|
|
|
+ if(!gantt.config.work_time){
|
|
|
+ time = defaultWorkTimes;
|
|
|
+ }else{
|
|
|
+ var wTime = gantt._working_time_helper;
|
|
|
+ if (wTime && wTime.get_calendar) {
|
|
|
+ time = wTime.get_calendar();
|
|
|
+ } else if (wTime) {
|
|
|
+ time = {
|
|
|
+ hours : wTime.hours,
|
|
|
+ dates : wTime.dates
|
|
|
+ };
|
|
|
+ } else if (gantt.config.worktimes && gantt.config.worktimes.global) {
|
|
|
+ time = {
|
|
|
+ hours : gantt.config.worktimes.global.hours,
|
|
|
+ dates : gantt.config.worktimes.global.dates
|
|
|
+ };
|
|
|
+ } else {
|
|
|
+ time = defaultWorkTimes;
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ return time;
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt.exportToPDF = function(config){
|
|
|
+ if (config && config.raw){
|
|
|
+ config = defaults(config, {
|
|
|
+ name:"gantt.pdf", data:this._serialize_html()
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ config = defaults((config || {}), {
|
|
|
+ name:"gantt.pdf",
|
|
|
+ data:this._serialize_all(),
|
|
|
+ config:this.config
|
|
|
+ });
|
|
|
+ fix_columns(gantt, config.config.columns);
|
|
|
+ }
|
|
|
+
|
|
|
+ config.version = this.version;
|
|
|
+ this._send_to_export(config, "pdf");
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt.exportToPNG = function(config){
|
|
|
+ if (config && config.raw){
|
|
|
+ config = defaults(config, {
|
|
|
+ name:"gantt.png", data:this._serialize_html()
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ config = defaults((config || {}), {
|
|
|
+ name:"gantt.png",
|
|
|
+ data:this._serialize_all(),
|
|
|
+ config:this.config
|
|
|
+ });
|
|
|
+ fix_columns(gantt, config.config.columns);
|
|
|
+ }
|
|
|
+
|
|
|
+ config.version = this.version;
|
|
|
+ this._send_to_export(config, "png");
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt.exportToICal = function(config){
|
|
|
+ config = defaults((config || {}), {
|
|
|
+ name:"gantt.ical",
|
|
|
+ data:this._serialize_plain().data,
|
|
|
+ version:this.version
|
|
|
+ });
|
|
|
+ this._send_to_export(config, "ical");
|
|
|
+ };
|
|
|
+
|
|
|
+ function eachTaskTimed(start, end){
|
|
|
+ return function(code, parent, master){
|
|
|
+ parent = parent || this.config.root_id;
|
|
|
+ master = master || this;
|
|
|
+
|
|
|
+ var branch = this.getChildren(parent);
|
|
|
+ if (branch)
|
|
|
+ for (var i=0; i<branch.length; i++){
|
|
|
+ var item = this._pull[branch[i]];
|
|
|
+ if ((!start || item.end_date > start) && (!end || item.start_date < end))
|
|
|
+ code.call(master, item);
|
|
|
+
|
|
|
+ if (this.hasChild(item.id))
|
|
|
+ this.eachTask(code, item.id, master);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ gantt.exportToExcel = function(config){
|
|
|
+ config = config || {};
|
|
|
+
|
|
|
+ var tasks, dates;
|
|
|
+ var state, scroll;
|
|
|
+ if (config.start || config.end){
|
|
|
+ state = this.getState();
|
|
|
+ dates = [ this.config.start_date, this.config.end_date ];
|
|
|
+ scroll = this.getScrollState();
|
|
|
+ var convert = this.date.str_to_date(this.config.date_format);
|
|
|
+ tasks = this.eachTask;
|
|
|
+
|
|
|
+ if (config.start)
|
|
|
+ this.config.start_date = convert(config.start);
|
|
|
+ if (config.end)
|
|
|
+ this.config.end_date = convert(config.end);
|
|
|
+
|
|
|
+ this.render();
|
|
|
+ this.eachTask = eachTaskTimed(this.config.start_date, this.config.end_date);
|
|
|
+ }
|
|
|
+
|
|
|
+ this._no_progress_colors =config.visual === "base-colors";
|
|
|
+
|
|
|
+ config = defaults(config, {
|
|
|
+ name:"gantt.xlsx",
|
|
|
+ title:"Tasks",
|
|
|
+ data:this._serialize_table(config).data,
|
|
|
+ columns:this._serialize_columns({ rawDates: true }),
|
|
|
+ version:this.version
|
|
|
+ });
|
|
|
+
|
|
|
+ if (config.visual)
|
|
|
+ config.scales = this._serialize_scales(config);
|
|
|
+
|
|
|
+ this._send_to_export(config, "excel");
|
|
|
+
|
|
|
+ if (config.start || config.end){
|
|
|
+ this.config.start_date = state.min_date;
|
|
|
+ this.config.end_date = state.max_date;
|
|
|
+ this.eachTask = tasks;
|
|
|
+
|
|
|
+ this.render();
|
|
|
+ this.scrollTo(scroll.x, scroll.y);
|
|
|
+
|
|
|
+ this.config.start_date = dates[0];
|
|
|
+ this.config.end_date = dates[1];
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt.exportToJSON = function(config){
|
|
|
+ config = defaults((config || {}), {
|
|
|
+ name:"gantt.json",
|
|
|
+ data:this._serialize_all(),
|
|
|
+ config: this.config,
|
|
|
+ columns:this._serialize_columns(),
|
|
|
+ worktime : gantt._getWorktimeSettings(),
|
|
|
+ version:this.version
|
|
|
+ });
|
|
|
+ this._send_to_export(config, "json");
|
|
|
+ };
|
|
|
+
|
|
|
+ function sendImportAjax(config){
|
|
|
+ var url = config.server || apiUrl;
|
|
|
+ var store = config.store || 0;
|
|
|
+ var formData = config.data;
|
|
|
+ var callback = config.callback;
|
|
|
+
|
|
|
+ formData.append("type", "excel-parse");
|
|
|
+ formData.append("data", JSON.stringify({
|
|
|
+ sheet: config.sheet || 0
|
|
|
+ }));
|
|
|
+
|
|
|
+ if(store)
|
|
|
+ formData.append("store", store);
|
|
|
+
|
|
|
+ var xhr = new XMLHttpRequest();
|
|
|
+ xhr.onreadystatechange = function (e) {
|
|
|
+ if(xhr.readyState == 4 && xhr.status == 0){// network error
|
|
|
+ if(callback){
|
|
|
+ callback(null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ xhr.onload = function() {
|
|
|
+ var fail = xhr.status > 400;
|
|
|
+ var info = null;
|
|
|
+
|
|
|
+ if (!fail){
|
|
|
+ try{
|
|
|
+ info = JSON.parse(xhr.responseText);
|
|
|
+ }catch(e){}
|
|
|
+ }
|
|
|
+
|
|
|
+ if(callback){
|
|
|
+ callback(info);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ xhr.open('POST', url, true);
|
|
|
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
|
|
+ xhr.send(formData);
|
|
|
+ }
|
|
|
+
|
|
|
+ gantt.importFromExcel = function(config){
|
|
|
+ var formData = config.data;
|
|
|
+
|
|
|
+ if(formData instanceof FormData){
|
|
|
+
|
|
|
+ }else if(formData instanceof File){
|
|
|
+ var data = new FormData();
|
|
|
+ data.append("file", formData);
|
|
|
+ config.data = data;
|
|
|
+ }
|
|
|
+ sendImportAjax(config);
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt._msp_config = function(config){
|
|
|
+
|
|
|
+ if (config.project)
|
|
|
+ for (var i in config.project){
|
|
|
+ if (!config._custom_data)
|
|
|
+ config._custom_data = {};
|
|
|
+ config._custom_data[i] = config.project[i](this.config);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (config.tasks)
|
|
|
+ for (var j = 0; j < config.data.length; j++){
|
|
|
+ var el = this.getTask(config.data[j].id);
|
|
|
+ if (!el._custom_data)
|
|
|
+ el._custom_data = {};
|
|
|
+ for (var i in config.tasks)
|
|
|
+ el._custom_data[i] = config.tasks[i](el, this.config);
|
|
|
+ }
|
|
|
+
|
|
|
+ delete config.project;
|
|
|
+ delete config.tasks;
|
|
|
+
|
|
|
+ config.time = gantt._getWorktimeSettings();
|
|
|
+
|
|
|
+ var p_dates = this.getSubtaskDates();
|
|
|
+ var format = this.date.date_to_str("%d-%m-%Y %H:%i:%s");
|
|
|
+ config.start_end = {
|
|
|
+ start_date: format(p_dates.start_date),
|
|
|
+ end_date: format(p_dates.end_date)
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt._msp_data = function(){
|
|
|
+ var old_xml_format = this.templates.xml_format;
|
|
|
+ var old_format_date = this.templates.format_date;
|
|
|
+ this.templates.xml_format = this.date.date_to_str("%d-%m-%Y %H:%i:%s");
|
|
|
+ this.templates.format_date = this.date.date_to_str("%d-%m-%Y %H:%i:%s");
|
|
|
+
|
|
|
+ var data = this._serialize_all();
|
|
|
+
|
|
|
+ this.templates.xml_format = old_xml_format;
|
|
|
+ this.templates.format_date = old_format_date;
|
|
|
+ return data;
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt._ajax_to_export = function(data, type, callback){
|
|
|
+ delete data.callback;
|
|
|
+
|
|
|
+ var url = data.server || apiUrl;
|
|
|
+ var pack = "type="+type+"&store=1&data="+encodeURIComponent(JSON.stringify(data));
|
|
|
+
|
|
|
+ var cb = function(loader){
|
|
|
+ var xdoc = loader.xmlDoc || loader;
|
|
|
+ var fail = xdoc.status > 400;
|
|
|
+ var info = null;
|
|
|
+
|
|
|
+ if (!fail){
|
|
|
+ try{
|
|
|
+ info = JSON.parse(xdoc.responseText);
|
|
|
+ }catch(e){}
|
|
|
+ }
|
|
|
+ callback(info);
|
|
|
+ };
|
|
|
+
|
|
|
+ xdr(url, pack, cb);
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt._send_to_export = function(data, type){
|
|
|
+ var convert = this.date.date_to_str(this.config.date_format || this.config.xml_date);
|
|
|
+ if (data.config){
|
|
|
+ data.config = this.copy(data.config);
|
|
|
+ mark_columns(data, type);
|
|
|
+
|
|
|
+ if(data.config.start_date && data.config.end_date){
|
|
|
+ if(data.config.start_date instanceof Date){
|
|
|
+ data.config.start_date = convert(data.config.start_date)
|
|
|
+ }
|
|
|
+ if(data.config.end_date instanceof Date){
|
|
|
+ data.config.end_date = convert(data.config.end_date)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (data.callback)
|
|
|
+ return gantt._ajax_to_export(data, type, data.callback);
|
|
|
+
|
|
|
+ var form = this._create_hidden_form();
|
|
|
+ form.firstChild.action = data.server || apiUrl;
|
|
|
+ form.firstChild.childNodes[0].value = JSON.stringify(data);
|
|
|
+ form.firstChild.childNodes[1].value = type;
|
|
|
+ form.firstChild.submit();
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt._create_hidden_form = function(){
|
|
|
+ if (!this._hidden_export_form){
|
|
|
+ var t = this._hidden_export_form = document.createElement("div");
|
|
|
+ t.style.display = "none";
|
|
|
+ t.innerHTML = "<form method='POST' target='_blank'><textarea name='data' style='width:0px; height:0px;' readonly='true'></textarea><input type='hidden' name='type' value=''></form>";
|
|
|
+ document.body.appendChild(t);
|
|
|
+ }
|
|
|
+ return this._hidden_export_form;
|
|
|
+ };
|
|
|
+
|
|
|
+ //patch broken json serialization in gantt 2.1
|
|
|
+ var original = gantt.json._copyObject;
|
|
|
+ function copy_object_base(obj){
|
|
|
+ var copy = {};
|
|
|
+ for (var key in obj){
|
|
|
+ if (key.charAt(0) == "$")
|
|
|
+ continue;
|
|
|
+ copy[key] = obj[key];
|
|
|
+ }
|
|
|
+
|
|
|
+ var formatDate = gantt.templates.xml_format || gantt.templates.format_date;
|
|
|
+
|
|
|
+ copy.start_date = formatDate(copy.start_date);
|
|
|
+ if (copy.end_date)
|
|
|
+ copy.end_date = formatDate(copy.end_date);
|
|
|
+
|
|
|
+ return copy;
|
|
|
+ }
|
|
|
+
|
|
|
+ function copy_object_plain(obj){
|
|
|
+ var text = gantt.templates.task_text(obj.start_date, obj.end_date, obj);
|
|
|
+
|
|
|
+ var copy = copy_object_base(obj);
|
|
|
+ copy.text = text || copy.text;
|
|
|
+
|
|
|
+ return copy;
|
|
|
+ }
|
|
|
+
|
|
|
+ function get_color(node, style){
|
|
|
+ var value = node.currentStyle ? node.currentStyle[style] : getComputedStyle(node, null)[style];
|
|
|
+ var rgb = value.replace(/\s/g,'').match(/^rgba?\((\d+),(\d+),(\d+)/i);
|
|
|
+ return ((rgb && rgb.length === 4) ?
|
|
|
+ ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
|
|
|
+ ("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
|
|
|
+ ("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : value).replace("#","");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Excel interprets UTC time as local time in every timezone, send local time instead of actual UTC time.
|
|
|
+ // https://github.com/SheetJS/js-xlsx/issues/126#issuecomment-60531614
|
|
|
+ var toISOstring = gantt.date.date_to_str("%Y-%m-%dT%H:%i:%s.000Z");
|
|
|
+
|
|
|
+ // excel serialization
|
|
|
+ function copy_object_table(obj){
|
|
|
+ var copy = copy_object_columns(obj, copy_object_plain(obj));
|
|
|
+ if (copy.start_date)
|
|
|
+ copy.start_date = toISOstring(obj.start_date);
|
|
|
+ if (copy.end_date)
|
|
|
+ copy.end_date = toISOstring(obj.end_date);
|
|
|
+
|
|
|
+ // private gantt._day_index_by_date was replaced by public gantt.columnIndexByDate in gantt 5.0
|
|
|
+ var getDayIndex = gantt._day_index_by_date ? gantt._day_index_by_date : gantt.columnIndexByDate;
|
|
|
+
|
|
|
+ copy.$start = getDayIndex.call(gantt, obj.start_date);
|
|
|
+ copy.$end = getDayIndex.call(gantt, obj.end_date);
|
|
|
+ copy.$level = obj.$level;
|
|
|
+ copy.$type = obj.$rendered_type;
|
|
|
+
|
|
|
+ var tmps = gantt.templates;
|
|
|
+ copy.$text = tmps.task_text(obj.start, obj.end_date, obj);
|
|
|
+ copy.$left = tmps.leftside_text ? tmps.leftside_text(obj.start, obj.end_date, obj) : "";
|
|
|
+ copy.$right = tmps.rightside_text ? tmps.rightside_text(obj.start, obj.end_date, obj) : "";
|
|
|
+
|
|
|
+ return copy;
|
|
|
+ }
|
|
|
+
|
|
|
+ function copy_object_colors(obj){
|
|
|
+ var copy = copy_object_table(obj);
|
|
|
+
|
|
|
+ var node = gantt.getTaskNode(obj.id);
|
|
|
+ if (node && node.firstChild){
|
|
|
+ var color = get_color((gantt._no_progress_colors ? node : node.firstChild), "backgroundColor");
|
|
|
+ if (color == "363636")
|
|
|
+ color = get_color(node, "backgroundColor");
|
|
|
+
|
|
|
+ copy.$color = color;
|
|
|
+ } else if (obj.color)
|
|
|
+ copy.$color = obj.color;
|
|
|
+
|
|
|
+ return copy;
|
|
|
+ }
|
|
|
+
|
|
|
+ function copy_object_columns(obj, copy){
|
|
|
+ for(var i=0; i<gantt.config.columns.length; i++){
|
|
|
+ var ct = gantt.config.columns[i].template;
|
|
|
+ if (ct) {
|
|
|
+ var val = ct(obj);
|
|
|
+ if (val instanceof Date)
|
|
|
+ val = gantt.templates.date_grid(val, obj);
|
|
|
+ copy["_"+i] = val;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return copy;
|
|
|
+ }
|
|
|
+
|
|
|
+ function copy_object_all(obj){
|
|
|
+ var copy = copy_object_base(obj);
|
|
|
+
|
|
|
+ //serialize all text templates
|
|
|
+ for (var i = 0; i < templates.length; i++){
|
|
|
+ var template = gantt.templates[templates[i]];
|
|
|
+ if (template)
|
|
|
+ copy["$"+i] = template(obj.start_date, obj.end_date, obj);
|
|
|
+ }
|
|
|
+
|
|
|
+ copy_object_columns(obj, copy);
|
|
|
+ copy.open = obj.$open;
|
|
|
+ return copy;
|
|
|
+ }
|
|
|
+
|
|
|
+ function fix_columns(gantt, columns){
|
|
|
+ for (var i = 0; i < columns.length; i++) {
|
|
|
+ columns[i].label = columns[i].label || gantt.locale.labels["column_"+columns[i].name];
|
|
|
+ if (typeof columns[i].width == "string") columns[i].width = columns[i].width*1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ gantt._serialize_html = function(){
|
|
|
+ var smartScales = gantt.config.smart_scales;
|
|
|
+ var smartRendering = gantt.config.smart_rendering;
|
|
|
+ if(smartScales || smartRendering){
|
|
|
+ gantt.config.smart_rendering = false;
|
|
|
+ gantt.config.smart_scales = false;
|
|
|
+ gantt.render();
|
|
|
+ }
|
|
|
+
|
|
|
+ var html = this.$container.parentNode.innerHTML;
|
|
|
+
|
|
|
+ if(smartScales || smartRendering){
|
|
|
+ gantt.config.smart_scales = smartScales;
|
|
|
+ gantt.config.smart_rendering = smartRendering;
|
|
|
+ gantt.render();
|
|
|
+ }
|
|
|
+
|
|
|
+ return html;
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt._serialize_all = function(){
|
|
|
+ gantt.json._copyObject = copy_object_all;
|
|
|
+ var data = export_serialize();
|
|
|
+ gantt.json._copyObject = original;
|
|
|
+ return data;
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt._serialize_plain = function(){
|
|
|
+ var oldXmlFormat = gantt.templates.xml_format;
|
|
|
+ var oldFormatDate = gantt.templates.format_date;
|
|
|
+ gantt.templates.xml_format = gantt.date.date_to_str("%Y%m%dT%H%i%s", true);
|
|
|
+ gantt.templates.format_date = gantt.date.date_to_str("%Y%m%dT%H%i%s", true);
|
|
|
+ gantt.json._copyObject = copy_object_plain;
|
|
|
+
|
|
|
+ var data = export_serialize();
|
|
|
+
|
|
|
+ gantt.templates.xml_format = oldXmlFormat;
|
|
|
+ gantt.templates.format_date = oldFormatDate;
|
|
|
+ gantt.json._copyObject = original;
|
|
|
+
|
|
|
+ delete data.links;
|
|
|
+ return data;
|
|
|
+ };
|
|
|
+
|
|
|
+ function get_raw() {
|
|
|
+ // support Gantt < 5.0
|
|
|
+ if (gantt._scale_helpers) {
|
|
|
+ var scales = gantt._get_scales(),
|
|
|
+ min_width = gantt.config.min_column_width,
|
|
|
+ autosize_min_width = gantt._get_resize_options().x ? Math.max(gantt.config.autosize_min_width, 0) : config.$task.offsetWidth,
|
|
|
+ height = config.config.scale_height - 1;
|
|
|
+ return gantt._scale_helpers.prepareConfigs(scales, min_width, autosize_min_width, height);
|
|
|
+ } else { // Gantt >= 5.0
|
|
|
+ var timeline = gantt.$ui.getView("timeline");
|
|
|
+ if (timeline) {
|
|
|
+ var availWidth = timeline.$config.width;
|
|
|
+ if (gantt.config.autosize == "x" || gantt.config.autosize == "xy") {
|
|
|
+ availWidth = Math.max(gantt.config.autosize_min_width, 0);
|
|
|
+ }
|
|
|
+ var state = gantt.getState(),
|
|
|
+ scales = timeline._getScales(),
|
|
|
+ min_width = gantt.config.min_column_width,
|
|
|
+ height = gantt.config.scale_height-1,
|
|
|
+ rtl = gantt.config.rtl;
|
|
|
+ return timeline.$scaleHelper.prepareConfigs(scales, min_width, availWidth, height, state.min_date, state.max_date, rtl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ gantt._serialize_table = function(config){
|
|
|
+ gantt.json._copyObject = config.visual ? copy_object_colors : copy_object_table;
|
|
|
+ var data = export_serialize();
|
|
|
+ gantt.json._copyObject = original;
|
|
|
+
|
|
|
+ delete data.links;
|
|
|
+
|
|
|
+ if (config.cellColors){
|
|
|
+ var css = this.templates.timeline_cell_class || this.templates.task_cell_class;
|
|
|
+ if (css){
|
|
|
+ var raw = get_raw();
|
|
|
+ var steps = raw[0].trace_x;
|
|
|
+ for (var i=1; i<raw.length; i++)
|
|
|
+ if (raw[i].trace_x.length > steps.length)
|
|
|
+ steps = raw[i].trace_x;
|
|
|
+
|
|
|
+ for (var i=0; i<data.data.length; i++){
|
|
|
+ data.data[i].styles = [];
|
|
|
+ var task = this.getTask(data.data[i].id);
|
|
|
+ for (var j = 0; j < steps.length; j++) {
|
|
|
+ var date = steps[j];
|
|
|
+ var cell_css = css(task, date);
|
|
|
+ if (cell_css)
|
|
|
+ data.data[i].styles.push({ index: j, styles: get_styles(cell_css) });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt._serialize_scales = function(config){
|
|
|
+ var scales = [];
|
|
|
+ var raw = get_raw();
|
|
|
+
|
|
|
+ var min = Infinity;
|
|
|
+ var max = 0;
|
|
|
+ for (var i=0; i<raw.length; i++) min = Math.min(min, raw[i].col_width);
|
|
|
+
|
|
|
+ for (var i=0; i<raw.length; i++){
|
|
|
+ var start = 0;
|
|
|
+ var end = 0;
|
|
|
+ var row = [];
|
|
|
+
|
|
|
+ scales.push(row);
|
|
|
+ var step = raw[i];
|
|
|
+ max = Math.max(max, step.trace_x.length);
|
|
|
+ var template = step.format || step.template || (step.date ? gantt.date.date_to_str(step.date) : gantt.config.date_scale);
|
|
|
+
|
|
|
+ for (var j = 0; j < step.trace_x.length; j++) {
|
|
|
+ var date = step.trace_x[j];
|
|
|
+ end = start + Math.round(step.width[j]/min);
|
|
|
+
|
|
|
+ var scale_cell = { text: template(date), start: start, end: end };
|
|
|
+
|
|
|
+ if (config.cellColors){
|
|
|
+ var css = step.css || this.templates.scale_cell_class;
|
|
|
+ if (css){
|
|
|
+ var scale_css = css(date);
|
|
|
+ if (scale_css)
|
|
|
+ scale_cell.styles=get_styles(scale_css);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ row.push(scale_cell);
|
|
|
+ start = end;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return { width:max, height:scales.length, data:scales };
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt._serialize_columns = function(config){
|
|
|
+ gantt.exportMode = true;
|
|
|
+
|
|
|
+ var columns = [];
|
|
|
+ var cols = gantt.config.columns;
|
|
|
+
|
|
|
+ var ccount = 0;
|
|
|
+ for (var i = 0; i < cols.length; i++){
|
|
|
+ if (cols[i].name == "add" || cols[i].name == "buttons") continue;
|
|
|
+
|
|
|
+ columns[ccount] = {
|
|
|
+ id: ((cols[i].template) ? ("_"+i) : cols[i].name),
|
|
|
+ header: cols[i].label || gantt.locale.labels["column_"+cols[i].name],
|
|
|
+ width: (cols[i].width ? Math.floor(cols[i].width/4) : "")
|
|
|
+ };
|
|
|
+
|
|
|
+ if (cols[i].name == "duration")
|
|
|
+ columns[ccount].type = "number";
|
|
|
+ if (cols[i].name == "start_date" || cols[i].name == "end_date"){
|
|
|
+ columns[ccount].type = "date";
|
|
|
+ if (config && config.rawDates)
|
|
|
+ columns[ccount].id = cols[i].name;
|
|
|
+ }
|
|
|
+
|
|
|
+ ccount++;
|
|
|
+ }
|
|
|
+
|
|
|
+ gantt.exportMode = false;
|
|
|
+ return columns;
|
|
|
+ };
|
|
|
+
|
|
|
+ function export_serialize(){
|
|
|
+ gantt.exportMode = true;
|
|
|
+ var data = gantt.serialize();
|
|
|
+ gantt.exportMode = false;
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+add_export_methods(gantt);
|
|
|
+if (window.Gantt && Gantt.plugin)
|
|
|
+ Gantt.plugin(add_export_methods);
|
|
|
+
|
|
|
+})();
|
|
|
+
|
|
|
+(function () {
|
|
|
+ var apiUrl = "https://export.dhtmlx.com/gantt";
|
|
|
+
|
|
|
+ function set_level(data) {
|
|
|
+ for (var i = 0; i < data.length; i++) {
|
|
|
+ if (data[i].parent == 0) {
|
|
|
+ data[i]._lvl = 1;
|
|
|
+ }
|
|
|
+ for (var j = i + 1; j < data.length; j++) {
|
|
|
+ if (data[i].id == data[j].parent) {
|
|
|
+ data[j]._lvl = data[i]._lvl + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function clear_level(data) {
|
|
|
+ for (var i = 0; i < data.length; i++) {
|
|
|
+ delete data[i]._lvl
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function clear_rec_links(data) {
|
|
|
+ set_level(data.data);
|
|
|
+ var tasks = {};
|
|
|
+ for (var i = 0; i < data.data.length; i++) {
|
|
|
+ tasks[data.data[i].id] = data.data[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ var links = {};
|
|
|
+ for (i = 0; i < data.links.length; i++) {
|
|
|
+ var link = data.links[i];
|
|
|
+ if(gantt.isTaskExists(link.source) && gantt.isTaskExists(link.target)){
|
|
|
+ links[link.id] = link;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i in links) {
|
|
|
+ make_links_same_level(links[i], tasks);
|
|
|
+ }
|
|
|
+
|
|
|
+ var skippedLinks = {};
|
|
|
+ for (i in tasks) {
|
|
|
+ clear_circ_dependencies(tasks[i], links, tasks, {}, skippedLinks, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i in links) {
|
|
|
+ clear_links_same_level(links, tasks);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < data.links.length; i++) {
|
|
|
+ if (!links[data.links[i].id]) {
|
|
|
+ data.links.splice(i, 1);
|
|
|
+ i--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ clear_level(data.data);
|
|
|
+ }
|
|
|
+
|
|
|
+ function clear_circ_dependencies(task, links, tasks, usedTasks, skippedLinks, prevLink) {
|
|
|
+ var sources = task.$_source;
|
|
|
+ if (!sources) return;
|
|
|
+
|
|
|
+ if (usedTasks[task.id]) {
|
|
|
+ on_circ_dependency_find(prevLink, links, usedTasks, skippedLinks);
|
|
|
+ }
|
|
|
+
|
|
|
+ usedTasks[task.id] = true;
|
|
|
+
|
|
|
+ var targets = {};
|
|
|
+
|
|
|
+ for (var i = 0; i < sources.length; i++) {
|
|
|
+ if (skippedLinks[sources[i]]) continue;
|
|
|
+ var curLink = links[sources[i]];
|
|
|
+ var targetTask = tasks[curLink._target];
|
|
|
+ if (targets[targetTask.id]) { // two link from one task to another
|
|
|
+ on_circ_dependency_find(curLink, links, usedTasks, skippedLinks);
|
|
|
+ }
|
|
|
+ targets[targetTask.id] = true;
|
|
|
+ clear_circ_dependencies(targetTask, links, tasks, usedTasks, skippedLinks, curLink);
|
|
|
+ }
|
|
|
+ usedTasks[task.id] = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ function on_circ_dependency_find(link, links, usedTasks, skippedLinks) {
|
|
|
+ if (link) {
|
|
|
+ if (gantt.callEvent("onExportCircularDependency", [link.id, link])) {
|
|
|
+ delete links[link.id];
|
|
|
+ }
|
|
|
+
|
|
|
+ delete usedTasks[link._source];
|
|
|
+ delete usedTasks[link._target];
|
|
|
+ skippedLinks[link.id] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function make_links_same_level(link, tasks) {
|
|
|
+ var task,
|
|
|
+ targetLvl,
|
|
|
+ linkT = {
|
|
|
+ target: tasks[link.target],
|
|
|
+ source: tasks[link.source]
|
|
|
+ };
|
|
|
+
|
|
|
+ if (linkT.target._lvl != linkT.source._lvl) {
|
|
|
+ if (linkT.target._lvl < linkT.source._lvl) {
|
|
|
+ task = "source";
|
|
|
+ targetLvl = linkT.target._lvl
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ task = "target";
|
|
|
+ targetLvl = linkT.source._lvl;
|
|
|
+ }
|
|
|
+
|
|
|
+ do {
|
|
|
+ var parent = tasks[linkT[task].parent];
|
|
|
+ if (!parent) break;
|
|
|
+ linkT[task] = parent;
|
|
|
+ } while (linkT[task]._lvl < targetLvl);
|
|
|
+
|
|
|
+ var sourceParent = tasks[linkT.source.parent],
|
|
|
+ targetParent = tasks[linkT.target.parent];
|
|
|
+
|
|
|
+ while (sourceParent && targetParent && sourceParent.id != targetParent.id) {
|
|
|
+ linkT.source = sourceParent;
|
|
|
+ linkT.target = targetParent;
|
|
|
+ sourceParent = tasks[linkT.source.parent];
|
|
|
+ targetParent = tasks[linkT.target.parent];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ link._target = linkT.target.id;
|
|
|
+ link._source = linkT.source.id;
|
|
|
+
|
|
|
+ if (!linkT.target.$_target)
|
|
|
+ linkT.target.$_target = [];
|
|
|
+ linkT.target.$_target.push(link.id);
|
|
|
+
|
|
|
+ if (!linkT.source.$_source)
|
|
|
+ linkT.source.$_source = [];
|
|
|
+ linkT.source.$_source.push(link.id);
|
|
|
+ }
|
|
|
+
|
|
|
+ function clear_links_same_level(links, tasks) {
|
|
|
+ for (var link in links) {
|
|
|
+ delete links[link]._target;
|
|
|
+ delete links[link]._source;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (var task in tasks) {
|
|
|
+ delete tasks[task].$_source;
|
|
|
+ delete tasks[task].$_target;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ function customProjectProperties(data, config){
|
|
|
+ if (config && config.project) {
|
|
|
+ for (var i in config.project) {
|
|
|
+ if (!gantt.config.$custom_data)
|
|
|
+ gantt.config.$custom_data = {};
|
|
|
+ gantt.config.$custom_data[i] = typeof config.project[i] == "function" ? config.project[i](gantt.config) : config.project[i];
|
|
|
+ }
|
|
|
+ delete config.project;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function customTaskProperties(data, config){
|
|
|
+ if (config && config.tasks) {
|
|
|
+ data.data.forEach(function (el) {
|
|
|
+ for (var i in config.tasks) {
|
|
|
+ if (!el.$custom_data)
|
|
|
+ el.$custom_data = {};
|
|
|
+ el.$custom_data[i] = typeof config.tasks[i] == "function" ? config.tasks[i](el, gantt.config) : config.tasks[i];
|
|
|
+ }
|
|
|
+ });
|
|
|
+ delete config.tasks;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function exportConfig(data, config){
|
|
|
+ var p_name = config.name || 'gantt.xml';
|
|
|
+ delete config.name;
|
|
|
+
|
|
|
+ gantt.config.custom = config;
|
|
|
+
|
|
|
+ var time = gantt._getWorktimeSettings();
|
|
|
+
|
|
|
+ var p_dates = gantt.getSubtaskDates();
|
|
|
+ if (p_dates.start_date && p_dates.end_date) {
|
|
|
+ var formatDate = gantt.templates.xml_format || gantt.templates.format_date;
|
|
|
+ gantt.config.start_end = {
|
|
|
+ start_date: formatDate(p_dates.start_date),
|
|
|
+ end_date: formatDate(p_dates.end_date)
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ var manual = config.auto_scheduling === undefined ? false : !!config.auto_scheduling;
|
|
|
+
|
|
|
+ var res = {
|
|
|
+ callback: config.callback || null,
|
|
|
+ config: gantt.config,
|
|
|
+ data: data,
|
|
|
+ manual: manual,
|
|
|
+ name: p_name,
|
|
|
+ worktime: time
|
|
|
+ };
|
|
|
+ for(var i in config) res[i] = config[i];
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ function add_export_methods(gantt) {
|
|
|
+ gantt._ms_export = {};
|
|
|
+
|
|
|
+ gantt.exportToMSProject = function (config) {
|
|
|
+ config = config || {};
|
|
|
+ config.skip_circular_links = config.skip_circular_links === undefined ? true : !!config.skip_circular_links;
|
|
|
+
|
|
|
+ var old_xml_format = this.templates.xml_format;
|
|
|
+ var old_format_date = this.templates.format_date;
|
|
|
+ this.templates.xml_format = this.date.date_to_str("%d-%m-%Y %H:%i:%s");
|
|
|
+ this.templates.format_date = this.date.date_to_str("%d-%m-%Y %H:%i:%s");
|
|
|
+ var data = this._serialize_all();
|
|
|
+
|
|
|
+ customProjectProperties(data, config);
|
|
|
+
|
|
|
+ customTaskProperties(data, config);
|
|
|
+
|
|
|
+ if (config.skip_circular_links) {
|
|
|
+ clear_rec_links(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ config = exportConfig(data, config);
|
|
|
+
|
|
|
+ this._send_to_export(config, config.type || "msproject");
|
|
|
+ this.templates.xml_format = old_xml_format;
|
|
|
+ this.templates.format_date = old_format_date;
|
|
|
+ this.config.$custom_data = null;
|
|
|
+ this.config.custom = null;
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt.exportToPrimaveraP6 = function(config){
|
|
|
+ config.type = "primaveraP6";
|
|
|
+ return gantt.exportToMSProject(config);
|
|
|
+ };
|
|
|
+
|
|
|
+ function sendImportAjax(config){
|
|
|
+ var url = config.server || apiUrl;
|
|
|
+ var store = config.store || 0;
|
|
|
+ var formData = config.data;
|
|
|
+ var callback = config.callback;
|
|
|
+
|
|
|
+ var settings = {};
|
|
|
+ if(config.durationUnit) settings.durationUnit = config.durationUnit
|
|
|
+ if(config.projectProperties) settings.projectProperties = config.projectProperties;
|
|
|
+ if(config.taskProperties) settings.taskProperties = config.taskProperties;
|
|
|
+
|
|
|
+ formData.append("type", config.type || "msproject-parse");
|
|
|
+ formData.append("data", JSON.stringify(settings));
|
|
|
+
|
|
|
+ if(store)
|
|
|
+ formData.append("store", store);
|
|
|
+
|
|
|
+ var xhr = new XMLHttpRequest();
|
|
|
+ xhr.onreadystatechange = function (e) {
|
|
|
+ if(xhr.readyState == 4 && xhr.status == 0){// network error
|
|
|
+ if(callback){
|
|
|
+ callback(null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ xhr.onload = function() {
|
|
|
+
|
|
|
+ var fail = xhr.status > 400;
|
|
|
+ var info = null;
|
|
|
+
|
|
|
+ if (!fail){
|
|
|
+ try{
|
|
|
+ info = JSON.parse(xhr.responseText);
|
|
|
+ }catch(e){}
|
|
|
+ }
|
|
|
+
|
|
|
+ if(callback){
|
|
|
+ callback(info);
|
|
|
+ }
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ xhr.open('POST', url, true);
|
|
|
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
|
|
+ xhr.send(formData);
|
|
|
+ }
|
|
|
+
|
|
|
+ gantt.importFromMSProject = function(config){
|
|
|
+ var formData = config.data;
|
|
|
+
|
|
|
+ if(formData instanceof FormData){
|
|
|
+
|
|
|
+ }else if(formData instanceof File){
|
|
|
+ var data = new FormData();
|
|
|
+ data.append("file", formData);
|
|
|
+ config.data = data;
|
|
|
+ }
|
|
|
+ sendImportAjax(config);
|
|
|
+ };
|
|
|
+
|
|
|
+ gantt.importFromPrimaveraP6 = function(config){
|
|
|
+ config.type = "primaveraP6-parse";
|
|
|
+ return gantt.importFromMSProject(config);
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ add_export_methods(gantt);
|
|
|
+ if (window.Gantt && Gantt.plugin)
|
|
|
+ Gantt.plugin(add_export_methods);
|
|
|
+
|
|
|
+})();
|