Here's an example of how the Gantt chart can be integrated into a mini-app, which in this case, is an example of project managment. The Gantt chart is dynamic - you can drag the events left and right and enlarge the event if you you click the event towards the right-hand side.
The data is loaded from and saved to the browsers localData variable (which is like a cookie but does not get sent back and forth to the server).
TODO:
If you want a skeleton/cut down version of this page, with no extraneous text and just the Gantt chart on it then you can find it here.
Name:
Start date:
(dd/mm)
Duration:
(days)
% Complete:
This goes in the documents header:
<script src="RGraph.common.core.js"></script> <script src="RGraph.common.dynamic.js"></script> <script src="RGraph.gantt.js"></script>Put this where you want the chart to show up:
<canvas id="cvs" width="950" height="450">[No canvas support]</canvas>
<p />
<button onclick="addPerson()">Add...</button>
<button onclick="deletePerson()">Delete</button>
<p id="eventForm">
<span class="formLabel">Name:</span>
<input type="text" id="name" />
<button onclick="updateName()">Update</button>
<br />
<span class="formLabel">Start date:</span>
<input type="text" id="startdate" readonly />
<i>(dd/mm)</i>
<br />
<span class="formLabel">Duration:</span>
<input type="text" id="duration" readonly />
<i>(days)</i>
<br />
<span class="formLabel">% Complete:</span>
<input type="text" id="complete" />
<button onclick="updateComplete()">Update</button>
<p>
<button id="reset" onclick="reset()" style="background-color: red; color: white">Reset data to defaults</button>
</p>
</p>
This is the code that generates the chart:
<script>
// This function converts day numbers to dates
function day2date (num)
{
var ret = '';
if (num < 31) {ret = (num + 1) + '/01/17';return ret;
} else if (num < 59) {ret = (num - 31 + 1) + '/02/17';return ret;
} else if (num < 90) {ret = (num - 59 + 1) + '/03/17';return ret;
} else if (num < 120) {ret = (num - 90 + 1) + '/04/17';return ret;
} else if (num < 151) {ret = (num - 120 + 1) + '/05/17';return ret;
} else if (num < 181) {ret = (num - 151 + 1) + '/06/17';return ret;
} else if (num < 212) {ret = (num - 181 + 1) + '/07/17';return ret;
} else if (num < 243) {ret = (num - 212 + 1) + '/08/17';return ret;
} else if (num < 273) {ret = (num - 243 + 1) + '/09/17';return ret;
} else if (num < 304) {ret = (num - 273 + 1) + '/10/17';return ret;
} else if (num < 334) {ret = (num - 304 + 1) + '/11/17';return ret;
} else if (num < 365) {ret = (num - 334 + 1) + '/12/17';return ret;}
}
defaults = {};
// This is the maximum value thats repesented on the chart.
// Here it is 365 - ie one year
defaults.max = 365;
// The labels for the chart
defaults.labels = ['Jan', 'Feb', 'Mar', 'Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
// Some colors
defaults.background = '#cfc';
defaults.foreground = '#0f0';
// These are the defaults for a new event
defaults.event = [0, 90, 0, 'No name',defaults.background, defaults.foreground]
// This is the default data that is represented on the chart.
// You could modify this to get this data from your database.
defaults.data = load();
state = {
selected: null
};
myGantt = new RGraph.Gantt({
id: 'cvs',
data: defaults.data,
options: {
xmax: defaults.max,
gutterLeft: 100,
gutterRight: 50,
labels: defaults.labels,
backgroundGridAutofitNumvlines: 12,
borders: false,
textSize: 18,
adjustable: true,
textAccessiblePointerevents: false
}
}).on('firstdraw', function (obj)
{
var gutterLeft = getLongestLabel(obj);
obj.set('gutterLeft', gutterLeft);
RGraph.cache = [];
setTimeout(function () {RGraph.redraw();}, 25)
}).draw().on('adjustend', function (obj)
{
var el = RGraph.Registry.get('chart.adjusting.gantt');
}).on('adjust', function ()
{
save(myGantt.data);
var el = RGraph.Registry.get('chart.adjusting.gantt');
document.getElementById('name').value = el.object.data[el.index][3];
document.getElementById('startdate').value = day2date(el.object.data[el.index][0]);
document.getElementById('duration').value = el.object.data[el.index][1];
document.getElementById('complete').value = el.object.data[el.index][2];
}).on('draw', function (obj)
{
if (typeof state.selected === 'number') {
var index = state.selected;
var coords = obj.coords[index];
RGraph.path2(
obj.context,
'b r % % % % s red',
coords[0],
coords[1],
coords[2],
coords[3]
);
}
}).exec(function (obj)
{
obj.canvas.onmousedown = function (e)
{
var shape = obj.getShape(e);
state.selected = (shape && typeof shape.index === 'number') ? shape.index : null;
RGraph.redraw();
}
});
//
// This function is where you would load the data from the server
// using, for example, AJAX. By default it uses localData which
// means that the data is persistent - but only to the one computer
// and only the one browser.
function load ()
{
if (localStorage['rgraph-gantt-chart-mini-app']) {
return JSON.parse(localStorage['rgraph-gantt-chart-mini-app']);
} else {
return [
[0, 59, 0, 'Richard',defaults.background, defaults.foreground],
[28, 43, 70, 'Rachel', defaults.background, defaults.foreground],
[43, 65, 0, 'Fred', defaults.background, defaults.foreground],
[26, 31, 0, 'Jane', defaults.background, defaults.foreground],
[143, 84, 0, 'John', defaults.background, defaults.foreground],
[108, 100, 0, 'Lucy', defaults.background, defaults.foreground],
[185, 68, 0, 'Carl', defaults.background, defaults.foreground],
[303, 60, 0, 'Steven', defaults.background, defaults.foreground]
]
}
}
//
// This function is where you would send the data to the server
// You could use the jQuery $.post() function to do this. Then you'd
// need to write server-side script (egPHP, ASP) to take this post
// data and save it into a database or file).
function save ()
{
localStorage['rgraph-gantt-chart-mini-app'] = JSON.stringify(myGantt.data);
}
function addPerson ()
{
var name = prompt('Enter the persons name:','')
if (name) {
var event = RGraph.arrayClone(defaults.event);
event[3] = name;
myGantt.data.push(event);
myGantt.set('gutterLeft', getLongestLabel(myGantt));
save();
reindex();
RGraph.redraw();
}
}
//
// This deletes a person from the Gantt chart. It confirms it
// but there is no backup!!
//
function deletePerson ()
{
if (confirm('Are you sure that you wish to delete this person?')) {
myGantt.data[state.selected] = null;
reindex();
RGraph.redraw();
}
}
// This functions goes through the gantt chart data and gets rid
// of null values
function reindex ()
{
var arr = [];
for (var i=0; i<myGantt.data.length; ++i) {
if (myGantt.data[i]) {
arr.push(RGraph.arrayClone(myGantt.data[i]));
}
}
myGantt.data = RGraph.arrayClone(arr);
state.selected = null;
save();
myGantt.set('gutterLeft', Number(getLongestLabel()));
RGraph.cache = [];
RGraph.redraw();
}
function getLongestLabel ()
{
var obj = arguments[0] ? arguments[0] : myGantt;
// Go through the data and get the size of the longest label
for (var i=0,length = 0; i<obj.data.length; i++) {
var length = Math.max(
length,
RGraph.MeasureText(obj.data[i][3], false, 'Arial', 18)[0]
);
}
return length;
}
function updateComplete ()
{
var complete = parseInt(document.getElementById('complete').value);
myGantt.data[state.selected][2] = Math.min(complete, 100);
document.getElementById('complete').value = myGantt.data[state.selected][2];
save();
RGraph.redraw();
}
function updateName ()
{
var name = document.getElementById('name').value;
myGantt.data[state.selected][3] = name;
document.getElementById('name').value = name;
save();
RGraph.redraw();
}
function reset ()
{
if (confirm('Are you sure that you\'d like to reset the data to defaults?')) {
localStorage['rgraph-gantt-chart-mini-app'] = '';
myGantt.data = load();
RGraph.redraw();
}
}
myGantt.canvas.parentNode.style.display = 'inline-block';
</script>