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 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:
keyup
event.
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)
Percent 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 that's 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.color = '#0f0';
// These are the defaults for a new event
defaults.event = {
start: 0,
duration: 90,
complete: 0,
label: 'No name',
background: defaults.background,
color: 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: {
xaxisScaleMax: defaults.max,
marginLeft: 100,
marginRight: 50,
labels: defaults.labels,
backgroundGridVlinesCount: 12,
borders: false,
textSize: 18,
adjustable: true,
textAccessiblePointerevents: false
}
}).on('firstdraw', function (obj)
{
var marginLeft = getLongestLabel(obj);
obj.set('marginLeft', marginLeft);
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].label;
document.getElementById('startdate').value = day2date(el.object.data[el.index].start);
document.getElementById('duration').value = el.object.data[el.index].duration;
document.getElementById('complete').value = el.object.data[el.index].complete;
}).on('draw', function (obj)
{
if (typeof state.selected === 'number') {
var index = state.selected,
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 [
{start: 0, duration: 59, complete: 0, label: 'Richard', background: defaults.background, color: defaults.color},
{start: 28, duration: 43, complete: 70, label: 'Rachel', background: defaults.background, color: defaults.color},
{start: 43, duration: 65, complete: 45, label: 'Fred', background: defaults.background, color: defaults.color},
{start: 26, duration: 31, complete: 23, label: 'Jane', background: defaults.background, color: defaults.color},
{start: 143, duration: 84, complete: 96, label: 'John', background: defaults.background, color: defaults.color},
{start: 108, duration: 100, complete: 42, label: 'Lucy', background: defaults.background, color: defaults.color},
{start: 185, duration: 68, complete: 19, label: 'Carl', background: defaults.background, color: defaults.color},
{start: 303, duration: 60, complete: 76, label: 'Steven', background: defaults.background, color: defaults.color}
]
}
}
//
// 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 (eg PHP, 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.label = name;
myGantt.data.push(event);
myGantt.set('marginLeft', 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();
location.href = location.href;
}
}
// This function 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('marginLeft', 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].label,
false,
'Arial',
18
)[0]
);
}
return length;
}
function updateComplete ()
{
var complete = parseInt(document.getElementById('complete').value);
myGantt.data[state.selected].complete = Math.min(complete, 100);
document.getElementById('complete').value = myGantt.data[state.selected].complete;
save();
RGraph.redraw();
}
function updateName ()
{
var name = document.getElementById('name').value;
myGantt.data[state.selected].label = 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>