Difference between revisions of "HTML Presentation Object: Gantt chart"
Jump to navigation
Jump to search
m |
m |
||
| Line 49: | Line 49: | ||
} | } | ||
| − | function <#resizeFunction>(newWidth, newHeight) { | + | 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', | |
| − | + | 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, | ||
| − | + | tickPixelInterval: 90, | |
| − | + | dateTimeLabelFormats: { | |
| − | + | day: '%d/%m', week: '%d/%m', month: '%m/%Y', year: '%Y' | |
| − | + | }, | |
| + | title: "", | ||
| + | labels: { | ||
| + | style: { | ||
| + | fontSize: '13px' | ||
| + | } | ||
| + | } | ||
}, | }, | ||
| − | |||
tooltip: { | 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 }, | legend: { enabled: false }, | ||
series: [{ | series: [{ | ||
| − | color: "# | + | color: "#195283", |
stacking: "normal", | 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", | color: "#3277b2", | ||
stacking:"normal", | 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' | ||
| + | } | ||
| + | } | ||
} | } | ||
| − | + | ] | |
| − | }); | + | }); |
} | } | ||
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>