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>