Difference between revisions of "HTML Presentation Object: Gantt chart"

From Mea Wiki
Jump to navigation Jump to search
m
m
Line 49: Line 49:
 
}
 
}
 
   
 
   
function <#resizeFunction>(newWidth, newHeight) {debugger;
+
function <#resizeFunction>(newWidth, newHeight) {
 
   width<#uniqueId> = newWidth;
 
   width<#uniqueId> = newWidth;
 
   height<#uniqueId> = newHeight;
 
   height<#uniqueId> = newHeight;
Line 62: Line 62:
 
   Highcharts.chart("container<#uniqueId>", {
 
   Highcharts.chart("container<#uniqueId>", {
 
     chart: {
 
     chart: {
        type: 'columnrange',
+
      type: 'columnrange',
        inverted: true
+
      inverted: true,
 +
      zoomType: 'y'
 
     },
 
     },
 
     title: {
 
     title: {
 
     text: 'Gantt chart' },
 
     text: 'Gantt chart' },
     xAxis: { type: "category" },
+
     xAxis: {
 +
      type: "category",
 +
      labels: {
 +
        style: {
 +
          fontSize: '13px'
 +
        }
 +
      }
 +
    },
 
     credits: { enabled: false },
 
     credits: { enabled: false },
 
     yAxis: {
 
     yAxis: {
 
       type: 'datetime',
 
       type: 'datetime',
 
       opposite: true,
 
       opposite: true,
        dateTimeLabelFormats: {
+
      tickPixelInterval: 90,
          day: '%d/%m', week: '%d/%m', month: '%m/%Y', year: '%Y'
+
      dateTimeLabelFormats: {
        },
+
        day: '%d/%m', week: '%d/%m', month: '%m/%Y', year: '%Y'
        title: ""
+
      },
 +
      title: "",
 +
      labels: {
 +
        style: {
 +
          fontSize: '13px'
 +
        }
 +
      }
 
     },
 
     },
 
 
     tooltip: {
 
     tooltip: {
        useHTML: true,
+
      useHTML: true,
        formatter: function () {
+
      formatter: function () {
            return  "<span style='font-weight: bold;font-size:125%;'>" + this.point.name + "</span></br>Actual: <b>" + (new Date(this.point.low)).toLocaleDateString() + "</b> - <b>" + (new Date(this.point.high)).toLocaleDateString() + "</b></br>" +
+
        return  "<span style='font-weight: bold;font-size:125%;'>" + this.point.name + "</span></br>Actual: <b>" +
              "Planned: <b>" + (new Date(this.point.PlannedStartDate)).toLocaleDateString() + "</b> - <b>" + (new Date(this.point.PlannedEndDate)).toLocaleDateString() + "</b></br>" +  
+
          (new Date(this.point.StartDate)).toLocaleDateString() + "</b> - <b>" + (new Date(this.point.EndDate)).toLocaleDateString() + "</b></br>" +
              "Progress: <b>" + this.point.progress + "%</b>";
+
          "Planned: <b>" + (new Date(this.point.PlannedStartDate)).toLocaleDateString() + "</b> - <b>" +
        }
+
          (new Date(this.point.PlannedEndDate)).toLocaleDateString() + "</b></br>" +  
 +
          "Progress: <b>" + this.point.progress + " %</b>";
 +
      }
 
     },
 
     },
 
     legend: { enabled: false },
 
     legend: { enabled: false },
 
     series: [{
 
     series: [{
       color: "#296293",
+
       color: "#195283",
 
       stacking: "normal",
 
       stacking: "normal",
        data: formatDataset(poData<#uniqueId>, {"low": "StartDate", "high": "ProgressPoint", "progress": "Progress", "name": "TaskName"}),
+
      pointPadding: 0,
        dataLabels: {
+
      groupPadding: 0,
            enabled: true,
+
      borderRadius: 0,
            align: 'center',
+
      borderWidth: 0,
            inside: true,
+
      data: formatDataset(poData<#uniqueId>, {"low": "StartDate", "StartDate": "StartDate", "high": "ProgressPoint", "progress": "Progress", "name": "TaskName"}),
            format: '{point.progress} %',
+
      dataLabels: {
            style: {
+
        enabled: true,
                fontSize: '13px'
+
        align: 'center',
            }
+
        inside: true,
        }
+
        verticalAlign:"middle",
 +
        format: '{point.progress} %',
 +
        style: {
 +
          fontSize: '13px'
 +
        }
 +
      }
 
     },
 
     },
 
     {
 
     {
 
       color: "#3277b2",
 
       color: "#3277b2",
 
       stacking:"normal",
 
       stacking:"normal",
        data: formatDataset(poData<#uniqueId>, {"low": "ProgressPoint", "high": "EndDate", "progress": "Progress", "name": "TaskName"}),
+
      pointPadding: 0,
        dataLabels: {
+
      groupPadding: 0,
            enabled: true,
+
      borderRadius: 0,
            align: 'center',
+
      borderWidth: 0,
            inside: true,
+
      data: formatDataset(poData<#uniqueId>, {"low": "ProgressPoint", "high": "EndDate", "EndDate": "EndDate", "progress": "Progress", "name": "TaskName"}),
            format: '',
+
      dataLabels: {
            style: {
+
        enabled: true,
                fontSize: '13px'
+
        align: 'center',
            }
+
        inside: true,
 +
        format: '',
 +
        style: {
 +
          fontSize: '13px'
 
         }
 
         }
 +
      }
 +
    },
 +
    {
 +
      color: "#fba41c",
 +
      pointPadding: 0,
 +
      groupPadding: 0.4,
 +
      borderRadius: 0,
 +
      borderWidth: 0,
 +
      data: formatDataset(poData<#uniqueId>, {"low": "PlannedStartDate", "PlannedStartDate": "PlannedStartDate", "high": "PlannedEndDate", "PlannedEndDate": "PlannedEndDate", "progress": "Progress", "name": "TaskName"}),
 +
    dataLabels: {
 +
      enabled: true,
 +
      align: 'center',
 +
      inside: true,
 +
      format: '',
 +
      style: {
 +
        fontSize: '13px'
 +
      }
 +
    }
 
     }
 
     }
    ]
+
  ]
});
+
  });
 
}
 
}
  

Revision as of 18:59, 16 December 2017

The following query contains example data for the gantt chart. Add it to a HTML presentation object's dataset with name "exampleData". Note that this example needs QPR Reporting Expression datasource installed.

data0=CreateDataset(Array('TaskName', 'StartDate', 'EndDate', 'PlannedStartDate', 'PlannedEndDate', 'Progress'))
data1=AddDatasetRow([data0], 'Project Task 1', NewDatetime(2017,1,1), NewDatetime(2017,2,15), NewDatetime(2017,1,10), NewDatetime(2017,2,20), 35)
data2=AddDatasetRow([data1], 'Project Task 2', NewDatetime(2017,2,1), NewDatetime(2017,4,1), NewDatetime(2017,2,1), NewDatetime(2017,3,15), 90)
data3=AddDatasetRow([data2], 'Project Task 3', NewDatetime(2017,4,1), NewDatetime(2017,6,1), NewDatetime(2017,4,5), NewDatetime(2017,6,15), 15)
data4=AddDatasetRow([data3], 'Project Task 4', NewDatetime(2017,4,10), NewDatetime(2017,7,31), NewDatetime(2017,4,10), NewDatetime(2017,7,31), 10)
data5=AddDatasetRow([data4], 'Project Task 5', NewDatetime(2017,5,1), NewDatetime(2017,8,1), NewDatetime(2017,5,10), NewDatetime(2017,7,16), 100)
data6=AddDatasetRow([data5], 'Project Task 6', NewDatetime(2017,7,1), NewDatetime(2017,7,31), NewDatetime(2017,6,20), NewDatetime(2017,7,20), 0)
data7=AddDatasetRow([data6], 'Project Task 7', NewDatetime(2017,8,1), NewDatetime(2017,10,15), NewDatetime(2017,7,15), NewDatetime(2017,9,30), 50)
data8=AddDatasetRow([data7], 'Project Task 8', NewDatetime(2017,8,1), NewDatetime(2017,10,1), NewDatetime(2017,8,10), NewDatetime(2017,10,1), 30)
data9=AddDatasetRow([data8], 'Project Task 9', NewDatetime(2017,9,1), NewDatetime(2017,11,1), NewDatetime(2017,8,20), NewDatetime(2017,10,20), 5)

Use the following HTML code:

<div id="container<#uniqueId>"></div>

<script>
var poData<#uniqueId>;
var width<#uniqueId>;
var height<#uniqueId>;

function <#datasetChangeFunction>(datasetIdentifier, datasetChangeCallbackFunction) {
  if (datasetIdentifier == "exampleData") {
    datasetChangeCallbackFunction(myDatasetAvailable<#uniqueId>);
  }
}

function myDatasetAvailable<#uniqueId>(datasetData) {
  if (datasetData == null || datasetData.sheets == null || datasetData.sheets.length == 0 || datasetData.sheets[0] == null || datasetData.sheets[0].values == null || datasetData.sheets[0].values.length == 0) return;
  poData<#uniqueId> = [];
  for (var row = 1; row < datasetData.sheets[0].values[0].length; row++) {
    var rowObject = {};
    for (var column = 0; column < datasetData.sheets[0].values.length; column++) {
      rowObject[datasetData.sheets[0].values[column][0].attribute] = datasetData.sheets[0].values[column][row].value;
    }
    poData<#uniqueId>.push(rowObject);
  }
  for (var i = 0; i < poData<#uniqueId>.length; i++) { 
    poData<#uniqueId>[i]["StartDate"] = parseInt(poData<#uniqueId>[i]["StartDate"].replace("/Date(", "").replace(")/", ""));
    poData<#uniqueId>[i]["EndDate"] = parseInt(poData<#uniqueId>[i]["EndDate"].replace("/Date(", "").replace(")/", ""));
    poData<#uniqueId>[i]["PlannedStartDate"] = parseInt(poData<#uniqueId>[i]["PlannedStartDate"].replace("/Date(", "").replace(")/", ""));
    poData<#uniqueId>[i]["PlannedEndDate"] = parseInt(poData<#uniqueId>[i]["PlannedEndDate"].replace("/Date(", "").replace(")/", ""));
    poData<#uniqueId>[i]["ProgressPoint"] = (new Date(poData<#uniqueId>[i]["StartDate"] + (poData<#uniqueId>[i]["EndDate"] - poData<#uniqueId>[i]["StartDate"]) * poData<#uniqueId>[i]["Progress"] / 100)).getTime();
  }
  drawPO<#uniqueId>();
}
 
function <#resizeFunction>(newWidth, newHeight) {
  width<#uniqueId> = newWidth;
  height<#uniqueId> = newHeight;
  $("#container<#uniqueId>").width(newWidth);
  $("#container<#uniqueId>").height(newHeight);
  drawPO<#uniqueId>();
}

function drawPO<#uniqueId>() {
  if (poData<#uniqueId> == null || width<#uniqueId> == null) return;
  $("#container<#uniqueId>").empty();
  Highcharts.chart("container<#uniqueId>", {
    chart: {
      type: 'columnrange',
      inverted: true,
      zoomType: 'y'
    },
    title: {
    text: 'Gantt chart' },
    xAxis: {
      type: "category", 
      labels: {
        style: {
          fontSize: '13px'
        }
      }
    },
    credits: { enabled: false },
    yAxis: {
      type: 'datetime',
      opposite: true,
      tickPixelInterval: 90,
      dateTimeLabelFormats: {
        day: '%d/%m', week: '%d/%m', month: '%m/%Y', year: '%Y'
      },
      title: "",
      labels: {
        style: {
          fontSize: '13px'
        }
      }
    },
    tooltip: {
      useHTML: true,
      formatter: function () {
        return  "<span style='font-weight: bold;font-size:125%;'>" + this.point.name + "</span></br>Actual: <b>" +
          (new Date(this.point.StartDate)).toLocaleDateString() + "</b> - <b>" + (new Date(this.point.EndDate)).toLocaleDateString() + "</b></br>" +
          "Planned: <b>" + (new Date(this.point.PlannedStartDate)).toLocaleDateString() + "</b> - <b>" +
          (new Date(this.point.PlannedEndDate)).toLocaleDateString() + "</b></br>" + 
          "Progress: <b>" + this.point.progress + " %</b>";
      }
    },
    legend: { enabled: false },
    series: [{
      color: "#195283",
      stacking: "normal",
      pointPadding: 0,
      groupPadding: 0,
      borderRadius: 0,
      borderWidth: 0,
      data: formatDataset(poData<#uniqueId>, {"low": "StartDate", "StartDate": "StartDate", "high": "ProgressPoint", "progress": "Progress", "name": "TaskName"}),
       dataLabels: {
         enabled: true,
         align: 'center',
         inside: true,
         verticalAlign:"middle",
         format: '{point.progress} %',
         style: {
           fontSize: '13px'
         }
      }
    },
    {
      color: "#3277b2",
      stacking:"normal",
      pointPadding: 0,
      groupPadding: 0,
      borderRadius: 0,
      borderWidth: 0,
      data: formatDataset(poData<#uniqueId>, {"low": "ProgressPoint", "high": "EndDate", "EndDate": "EndDate", "progress": "Progress", "name": "TaskName"}),
      dataLabels: {
        enabled: true,
        align: 'center',
        inside: true,
        format: '',
        style: {
          fontSize: '13px'
        }
      }
    },
    {
      color: "#fba41c",
      pointPadding: 0,
      groupPadding: 0.4,
      borderRadius: 0,
      borderWidth: 0,
      data: formatDataset(poData<#uniqueId>, {"low": "PlannedStartDate", "PlannedStartDate": "PlannedStartDate", "high": "PlannedEndDate", "PlannedEndDate": "PlannedEndDate", "progress": "Progress", "name": "TaskName"}),
     dataLabels: {
       enabled: true,
       align: 'center',
       inside: true,
       format: '',
       style: {
         fontSize: '13px'
       }
     }
    }
  ]
  });
}

function formatDataset(inputData, mappings, groupColumn, groupAttribute, innerArrayAttribute) {
  var mappedData = [];
  var namesToMap = Object.getOwnPropertyNames(mappings);
  for (var i = 0; i < inputData.length; i++) {
    var row = {};
    var mappedColumns = [];
    for (var j = 0; j < namesToMap.length; j++) {
      row[namesToMap[j]] = inputData[i][mappings[namesToMap[j]]];
      mappedColumns.push(mappings[namesToMap[j]]);
    }
    var dataColumns = Object.getOwnPropertyNames(inputData[i]);
    for (j = 0; j < dataColumns.length; j++) {
      if (mappedColumns.indexOf(dataColumns[j]) == -1) {
        row[dataColumns[j]] = inputData[i][dataColumns[j]];
      }
    }
    mappedData.push(row);
  }

  if (groupColumn == null) {
    return mappedData;
  } else {
    var groups = {};
    for (var i = 0; i < mappedData.length; i++) {
      var groupName = mappedData[i][groupColumn];
      if (groups[groupName] == null) groups[groupName] = [];
      groups[groupName].push(mappedData[i]);
      delete mappedData[i][groupColumn];
    }
    var groupedData = [];
    var groupNames = Object.getOwnPropertyNames(groups);
    for (var i = 0; i < groupNames.length; i++) {
      var group = {};
      group[groupAttribute] = groupNames[i];
      group[innerArrayAttribute] = groups[groupNames[i]];
      groupedData.push(group);
    }
    return groupedData;
  }
}
</script>