rewrote revision graph functions

This commit is contained in:
hyung-hwan 2017-01-03 14:43:08 +00:00
parent cb3dbc0d7a
commit e47ecf2afd
9 changed files with 586 additions and 82 deletions

View File

@ -169,7 +169,6 @@ class Graph extends Controller
print codepot_json_encode ($cloc); print codepot_json_encode ($cloc);
} }
function enjson_revision_graph ($projectid = '', $path = '', $rev = SVN_REVISION_HEAD) function enjson_revision_graph ($projectid = '', $path = '', $rev = SVN_REVISION_HEAD)
{ {
$this->load->model ('ProjectModel', 'projects'); $this->load->model ('ProjectModel', 'projects');

View File

@ -14,7 +14,6 @@ $lang['Change'] = 'Change';
$lang['Change log'] = 'Change log'; $lang['Change log'] = 'Change log';
$lang['Close'] = 'Close'; $lang['Close'] = 'Close';
$lang['Code'] = 'Code'; $lang['Code'] = 'Code';
$lang['Code changes'] = 'Code changes';
$lang['Column'] = 'Column'; $lang['Column'] = 'Column';
$lang['Columns'] = 'Columns'; $lang['Columns'] = 'Columns';
$lang['Comment'] = 'Comment'; $lang['Comment'] = 'Comment';

View File

@ -14,7 +14,6 @@ $lang['Changes'] = 'Perubahan';
$lang['Change log'] = 'Change log'; $lang['Change log'] = 'Change log';
$lang['Close'] = 'Close'; $lang['Close'] = 'Close';
$lang['Code'] = 'Kode'; $lang['Code'] = 'Kode';
$lang['Code changes'] = 'Kode changes'
$lang['Column'] = 'Column'; $lang['Column'] = 'Column';
$lang['Columns'] = 'Columns'; $lang['Columns'] = 'Columns';
$lang['Comment'] = 'Comment'; $lang['Comment'] = 'Comment';

View File

@ -10,11 +10,10 @@ $lang['Blame'] = '책임전가';
$lang['Blank'] = '공백'; $lang['Blank'] = '공백';
$lang['Cancel'] = '취소'; $lang['Cancel'] = '취소';
$lang['Change'] = '변경'; $lang['Change'] = '변경';
$lang['Changes'] = '변경'; $lang['Changes'] = '변경내역';
$lang['Change log'] = '변경기록'; $lang['Change log'] = '변경기록';
$lang['Close'] = '닫기'; $lang['Close'] = '닫기';
$lang['Code'] = '코드'; $lang['Code'] = '코드';
$lang['Code changes'] = '코드변경';
$lang['Column'] = '칼럼'; $lang['Column'] = '칼럼';
$lang['Columns'] = '칼럼'; $lang['Columns'] = '칼럼';
$lang['Comment'] = '소견'; $lang['Comment'] = '소견';

View File

@ -1648,7 +1648,7 @@ class SubversionModel extends Model
array_push ($edges, array ('from' => $from, 'to' => $to, 'label' => $label)); array_push ($edges, array ('from' => $from, 'to' => $to, 'label' => $label));
} }
function revisionGraph ($projectid, $path, $rev) function __revisionGraph ($projectid, $path, $rev)
{ {
// this function is almost blind translation of svn-graph.pl // this function is almost blind translation of svn-graph.pl
@ -1794,6 +1794,340 @@ class SubversionModel extends Model
return array ('nodes' => $nodes, 'edges' => $edges); return array ('nodes' => $nodes, 'edges' => $edges);
} }
private function _normalize_revision_changes (&$log)
{
$deleted = array();
$movedfrom = array();
$movedto = array();
$copiedfrom = array();
$copiedto = array();
$added = array();
$modified = array();
$copyinfo = array();
$currev = $log['rev'];
foreach ($log['paths'] as $p)
{
if (!array_key_exists('action', $p) || !array_key_exists('path', $p)) continue;
$action = $p['action'];
$path = $p['path'];
if ($action == 'A')
{
if (array_key_exists('copyfrom', $p))
{
// $path:$p['rev'] has been copied to $copyinfo:$currev
$copyinfo[$p['copyfrom']] = array($path, $p['rev'], $currev);
}
else
{
$added[$path] = 1;
}
}
else if ($action == 'D')
{
$deleted[$path] = 1;
}
else if ($action == 'M')
{
$modified[$path] = 1;
}
}
foreach ($copyinfo as $op => $ci)
{
if (array_key_exists($op, $deleted))
{
/* moved */
$movedfrom[$ci[0]] = array($op, $ci[1], $ci[2]); // $ci[0] has been moved from $op:$ci[1]
$movedto[$op] = $ci; // $op:$ci[1] has been moved to $ci[0]:$ci[2]
unset ($deleted[$op]);
}
else
{
/* copied */
$copiedfrom[$ci[0]] = array($op, $ci[1], $ci[2]);
$copiedto[$op] = $ci;
}
}
$result = new stdClass();
$result->modified = $modified;
$result->deleted = $deleted;
$result->copiedfrom = $copiedfrom;
$result->copiedto = $copiedto;
$result->movedfrom = $movedfrom;
$result->movedto = $movedto;
$result->added = $added;
return $result;
}
private function _add_revision_transition (&$trans, $from, $to)
{
if (array_key_exists($from, $trans)) array_push ($trans[$from], $to);
else $trans[$from] = array ($to);
}
private function _add_revision_trackset (&$trackset, $trapath, $rev, $act)
{
if (array_key_exists($trapath, $trackset))
{
// keep array elements sorted by the revision number
$arr = &$trackset[$trapath];
$cnt = count($arr);
while ($cnt > 0)
{
$x = $arr[--$cnt];
if ($x[0] <= $rev)
{
array_splice ($trackset[$trapath], $cnt + 1, 0, array(array($rev, $act)));
return;
}
}
array_splice ($trackset[$trapath], 0, 0, array(array($rev, $act)));
}
else $trackset[$trapath] = array(array($rev, $act));
}
private function _backtrack_revision (&$trackset, $trapath, $rev)
{
if (array_key_exists($trapath, $trackset))
{
$arr = $trackset[$trapath];
$cnt = count($arr);
while ($cnt > 0)
{
$br = $arr[--$cnt];
if ($br[0] < $rev)
{
if ($br[1] == 'D') return -1;
return $br[0];
}
}
}
return -1;
}
function revisionGraph ($projectid, $path, $rev)
{
$orgurl = 'file://'.$this->_canonical_path(CODEPOT_SVNREPO_DIR."/{$projectid}");
$startpath = $path;
$nodeids = array ();
$nodes = array ();
$edges = array ();
$log = @svn_log ($orgurl, 1, $rev, 0, SVN_DISCOVER_CHANGED_PATHS);
if ($log === FALSE || count($log) <= 0) return FALSE;
//print_r ($log);
$trackset = array ();
$delset = array();
$trans = array();
$this->_add_revision_trackset ($trackset, $path, -1, '');
foreach ($log as $l)
{
$currev = $l['rev'];
$changes = $this->_normalize_revision_changes ($l);
/*
print "==== {$l['rev']} ====\n";
foreach ($changes->deleted as $op => $one) print "DELETED ===> $op\n";
foreach ($changes->added as $op => $one) print "ADDED ===> $op\n";
foreach ($changes->modified as $op => $one) print "MODIFIED ===> $op\n";
foreach ($changes->movedfrom as $np => $op) print "MOVED ===> {$op[0]},{$op[1]} -> $np\n";
foreach ($changes->copiedfrom as $np => $op) print "COPIED ===> {$op[0]},{$op[1]} -> $np\n";
//foreach ($changes->movedto as $op=> $np) print "MOVED ===> $op -> $np\n";
//foreach ($changes->copiedto as $op => $np) print "COPIED ===> $op -> $np\n";
*/
//print_r ($changes);
//print "---------------------------------\n";
foreach ($trackset as $trapath => $dummy)
{
if (array_key_exists($trapath, $changes->copiedto))
{
/* $trapath has been copied to a new file */
$newpath = $changes->copiedto[$trapath][0];
$oldrev = $changes->copiedto[$trapath][1];
$this->_add_revision_trackset ($trackset, $trapath, $oldrev, '');
$this->_add_revision_trackset ($trackset, $newpath, $currev, '');
$this->_add_revision_transition ($trans, "{$oldrev},{$trapath}", "CP,{$currev},{$newpath}");
}
else if (array_key_exists($trapath, $changes->copiedfrom))
{
/* something else has been copied to become $trapath */
$oldpath = $changes->copiedfrom[$trapath][0];
$oldrev = $changes->copiedfrom[$trapath][1];
$this->_add_revision_trackset ($trackset, $oldpath, $oldrev, '');
$this->_add_revision_trackset ($trackset, $trapath, $currev, '');
$this->_add_revision_transition ($trans, "{$oldrev},{$oldpath}", "CP,{$currev},{$trapath}");
}
else if (array_key_exists($trapath, $changes->movedto))
{
$newpath = $changes->movedto[$trapath][0];
$oldrev = $changes->movedto[$trapath][1];
$this->_add_revision_trackset ($trackset, $trapath, $oldrev, 'D');
$this->_add_revision_trackset ($trackset, $newpath, $currev, '');
$this->_add_revision_transition ($trans, "{$oldrev},{$trapath}", "MV,{$currev},{$newpath}");
}
else if (array_key_exists($trapath, $changes->movedfrom))
{
/* something else has been moved to become $trapath */
$oldpath = $changes->movedfrom[$trapath][0];
$oldrev = $changes->movedfrom[$trapath][1];
$this->_add_revision_trackset ($trackset, $oldpath, $oldrev, 'D');
$this->_add_revision_trackset ($trackset, $trapath, $currev, '');
$this->_add_revision_transition ($trans, "{$oldrev},{$oldpath}", "MV,{$currev},{$trapath}");
}
else if (array_key_exists($trapath, $changes->deleted))
{
$this->_add_revision_transition ($trans, "${currev},{$trapath}", "RM,-1,<<deleted>>");
$delset[$trapath] = 1;
$this->_add_revision_trackset ($trackset, $trapath, $currev, 'D');
}
else if (array_key_exists($trapath, $changes->added))
{
$this->_add_revision_trackset ($trackset, $trapath, $currev, '');
if (array_key_exists($trapath, $delset))
{
$this->_add_revision_transition ($trans, "-1,<<deleted>>", "AD,{$currev},{$trapath}");
unset ($delset[$trapath]);
}
else
{
$this->_add_revision_transition ($trans, "-1,<<start>>", "AD,{$currev},{$trapath}");
}
}
else if (array_key_exists($trapath, $changes->modified))
{
$this->_add_revision_trackset ($trackset, $trapath, $currev, '');
$oldrev = $this->_backtrack_revision ($trackset, $trapath, $currev);
$this->_add_revision_transition ($trans, "{$oldrev},{$trapath}", "MF,{$currev},{$trapath}");
}
}
}
//print_r ($trackset);
//print_r ($trans);
//print_r ($trackset);
$mf_cand = array();
foreach ($trans as $transfrom => $transtos)
{
$x = explode (',', $transfrom, 2);
$frompath = $x[1];
$fromrev = $x[0];
$numtranstos = count($transtos);
for ($i = 0; $i < $numtranstos; $i++)
{
$transto = $transtos[$i];
$x = explode (',', $transto, 3);
$act = $x[0];
$topath = $x[2];
$torev = $x[1];
switch ($act)
{
case 'CP':
$br = $this->_backtrack_revision ($trackset, $frompath, $fromrev);
if ($br >= 0)
{
$id1 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$br}");
$id2 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$fromrev}");
$this->_add_rg_edge ($edges, $id1, $id2, '');
}
$id1 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$fromrev}");
$id2 = $this->_add_rg_node ($nodeids, $nodes, "{$topath}:{$torev}");
$this->_add_rg_edge ($edges, $id1, $id2, 'copied');
break;
case 'MV':
$br = $this->_backtrack_revision ($trackset, $frompath, $fromrev);
if ($br >= 0)
{
$id1 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$br}");
$id2 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$fromrev}");
$this->_add_rg_edge ($edges, $id1, $id2, '');
}
$id1 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$fromrev}");
$id2 = $this->_add_rg_node ($nodeids, $nodes, "{$topath}:{$torev}");
$this->_add_rg_edge ($edges, $id1, $id2, 'moved');
break;
case 'RM':
$br = $this->_backtrack_revision ($trackset, $frompath, $fromrev);
if ($br >= 0)
{
$id1 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$br}");
$id2 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$fromrev}");
$this->_add_rg_edge ($edges, $id1, $id2, '');
}
$id1 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$fromrev}");
$id2 = $this->_add_rg_node ($nodeids, $nodes, $topath);
$this->_add_rg_edge ($edges, $id1, $id2, 'deleted');
break;
case 'AD':
$id1 = $this->_add_rg_node ($nodeids, $nodes, $frompath);
$id2 = $this->_add_rg_node ($nodeids, $nodes, "{$topath}:{$torev}");
$this->_add_rg_edge ($edges, $id1, $id2, '');
break;
case 'MF':
/*
$id1 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$fromrev}");
$id2 = $this->_add_rg_node ($nodeids, $nodes, "{$topath}:{$torev}");
$this->_add_rg_edge ($edges, $id1, $id2, '');
*/
if (array_key_exists($frompath, $mf_cand))
{
$z = &$mf_cand[$frompath];
$z[1] = $topath;
$z[2] = $torev;
$z[3]++;
}
else
{
$mf_cand[$frompath] = array ($fromrev, $topath, $torev, 1);
}
break;
}
}
}
foreach ($mf_cand as $frompath => $ti)
{
$fromrev = $ti[0];
$topath = $ti[1];
$torev = $ti[2];
$num_changes = $ti[3];
$id1 = $this->_add_rg_node ($nodeids, $nodes, "{$frompath}:{$fromrev}");
$id2 = $this->_add_rg_node ($nodeids, $nodes, "{$topath}:{$torev}");
$this->_add_rg_edge ($edges, $id1, $id2, "{$num_changes} change(s)");
}
return array ('nodes' => $nodes, 'edges' => $edges);
}
function zipSubdir ($projectid, $path, $rev, $topdir) function zipSubdir ($projectid, $path, $rev, $topdir)
{ {
// codepot_zip_dir() uses ZipArchive. Check if the class // codepot_zip_dir() uses ZipArchive. Check if the class

View File

@ -233,28 +233,185 @@ function showRawCode()
} }
<?php endif; ?> <?php endif; ?>
var revision_network = null; var GraphApp = (function ()
function show_revision_graph (response)
{ {
// -------------------------------------------------------------------
// CONSTRUCTOR
// -------------------------------------------------------------------
function App (top_container, graph_container, graph_msgdiv, graph_canvas, graph_button, graph_spin, graph_url, graph_title)
{
//if (this.constructor != App)
//{
// return new App (top_container, graph_container, graph_canvas, graph_button, graph_spin, graph_title);
//}
this.top_container = top_container;
this.graph_container = graph_container;
this.graph_msgdiv = graph_msgdiv;
this.graph_canvas = graph_canvas;
this.graph_button = graph_button;
this.graph_spin = graph_spin;
this.graph_ajax = null;
this.graph_url = graph_url;
this.graph_title = graph_title;
this.graph_msgdiv.hide();
this.graph_msgdiv.css ({'background-color': 'red', 'color': 'white', 'padding': '1em', 'float': 'left'});
return this;
}
// -------------------------------------------------------------------
// PRIVATE FUNCTIONS
// -------------------------------------------------------------------
function on_graph_success (response, textStatus, jqXHR)
{
var data; var data;
try { data = $.parseJSON(response); } try { data = $.parseJSON(response); }
catch (e) { data = null; } catch (e) { data = null; }
if (data == null) if (data == null)
{ {
show_alert ('Invalid data received', "<?php print $this->lang->line('Error')?>"); this.showMessage ('Invalid data received');
}
else if (data.nodes.length <= 0)
{
show_alert ('No data to show', "<?php print $this->lang->line('Error')?>");
} }
else else
{ {
this.renderGraph (data);
this.graph_container.dialog("option", "height", (this.top_container.height() * 90 / 100));
this.graph_container.dialog("option", "width", (this.top_container.width() * 90 / 100));
this.graph_container.dialog ({
position: {
my: "center center",
at: "center center",
of: this.top_container
}
});
this.resizeGraph ();
}
this.graph_button.button("enable");
this.graph_spin.removeClass ("fa-cog fa-spin");
this.graph_ajax = null;
}
function on_graph_error (jqXHR, textStatus, errorThrown)
{
this.showMessage (jqXHR.status + ' ' + errorThrown);
this.graph_button.button("enable");
this.graph_spin.removeClass ("fa-cog fa-spin");
this.graph_ajax = null;
}
function open_graph()
{
this.graph_button.button ("disable");
this.graph_spin.addClass ("fa-cog fa-spin");
this.graph_container.dialog ("open");
if (this.graph_ajax != null) this.graph_ajax.abort();
this.graph_ajax = $.ajax ({
url: this.graph_url,
context: this,
success: on_graph_success,
error: on_graph_error
});
}
// -------------------------------------------------------------------
// PUBLIC FUNCTIONS
// -------------------------------------------------------------------
App.prototype.initWidgets = function ()
{
var self = this;
this.graph_container.dialog ({
title: this.graph_title,
resizable: true,
autoOpen: false,
width: 'auto',
height: 'auto',
modal: true,
buttons: {
'<?php print $this->lang->line('Close')?>': function () {
if (self.graph_ajax != null) return;
self.graph_container.dialog('close');
}
},
beforeClose: function() {
return self.graph_ajax == null;
},
});
this.graph_container.on ("dialogresize", function (evt, ui) {
self.resizeGraph ();
});
this.graph_button.button().click (function ()
{
open_graph.call (self);
return false;
});
};
App.prototype.showMessage = function (msg)
{
this.graph_msgdiv.show();
this.graph_msgdiv.text (msg);
this.graph_msgdiv.position ({
my: "center",
at: "center",
of: this.graph_container
});
}
App.prototype.clearMessage = function()
{
this.graph_msgdiv.hide();
}
// -------------------------------------------------------------------
// VIRTUAL FUNCTIONS
// -------------------------------------------------------------------
App.prototype.renderGraph = function (json)
{
/* SHOULD BE IMPLEMENTED BY INHERITER */
}
App.prototype.resizeGraph = function ()
{
/* SHOULD BE IMPLEMENTED BY INHERITER */
}
return App;
})();
var RevGraphApp = (function ()
{
function App (top_container, graph_container, graph_msgdiv, graph_canvas, graph_button, graph_spin, graph_url, graph_title)
{
GraphApp.call (this, top_container, graph_container, graph_msgdiv, graph_canvas, graph_button, graph_spin, graph_url, graph_title);
this.revision_network = null;
return this;
}
App.prototype = Object.create (GraphApp.prototype);
App.prototype.constructor = App;
App.prototype.renderGraph = function (data)
{
if (data.nodes.length <= 0)
{
this.showMessage ('No data to show');
return;
}
this.clearMessage ();
var options = { var options = {
autoResize: false, autoResize: false,
height: '500px', height: '400px',
width: '100%', width: '90%',
clickToUse: false, clickToUse: false,
layout: { layout: {
hierarchical: { hierarchical: {
@ -295,25 +452,29 @@ function show_revision_graph (response)
data.edges[i].font = { color: 'red' }; data.edges[i].font = { color: 'red' };
} }
if (revision_network === null) if (this.revision_network === null)
{ {
revision_network = new vis.Network(document.getElementById('code_file_result_revision_graph'), data, options); this.revision_network = new vis.Network(this.graph_canvas[0], data, options);
$('#code_file_result_revision_graph').resizable({
resize: function (event, ui) {
revision_network.setSize (ui.size.width - 10, ui.size.height - 10);
revision_network.redraw();
}
});
} }
else else
{ {
revision_network.setData (data); this.revision_network.setData (data);
} }
} }
$("#code_file_revision_graph_button").button("enable"); App.prototype.resizeGraph = function ()
$("#code_file_revision_graph_spin" ).removeClass ("fa-cog fa-spin"); {
} if (this.revision_network != null)
{
this.revision_network.setSize (this.graph_container.width(), this.graph_container.height());
this.revision_network.redraw();
this.revision_network.fit();
}
}
return App;
})();
$(function () { $(function () {
@ -341,24 +502,18 @@ $(function () {
$("#code_file_edit_button").button(); $("#code_file_edit_button").button();
<?php endif; ?> <?php endif; ?>
$("#code_file_revision_graph_button").button().click (function () {
$("#code_file_revision_graph_button").button("disable");
$("#code_file_revision_graph_spin").addClass ("fa-cog fa-spin");
var ajax_req = $.ajax ({
url: codepot_merge_path (
"<?php print site_url(); ?>",
"/graph/enjson_revision_graph/<?php print $project->id; ?>/<?php print $hex_headpath;?><?php print $revreq?>"),
context: document.body,
success: show_revision_graph,
error: function (xhr, ajaxOptions, thrownError) {
show_alert (xhr.status + ' ' + thrownError, "<?php print $this->lang->line('Error')?>");
$("#code_file_revision_graph_button").button("enable");
$("#code_file_revision_graph_spin" ).removeClass ("fa-cog fa-spin");
}
});
return false; var rev_graph_app = new RevGraphApp (
}); $(window),
$("#code_file_revision_graph_container"),
$("#code_file_revision_graph_error"),
$("#code_file_revision_graph"),
$("#code_file_revision_graph_button"),
$("#code_file_revision_graph_spin"),
codepot_merge_path ("<?php print site_url(); ?>", "/graph/enjson_revision_graph/<?php print $project->id; ?>/<?php print $hex_headpath;?><?php print $revreq?>"),
"<?php print $this->lang->line('Revision')?>"
);
rev_graph_app.initWidgets ();
<?php if ($file['created_rev'] != $file['head_rev']): ?> <?php if ($file['created_rev'] != $file['head_rev']): ?>
$("#code_file_headrev_button").button().click (function() { $("#code_file_headrev_button").button().click (function() {
@ -658,8 +813,11 @@ $this->load->view (
</div> </div>
</div> </div>
<div id="code_folder_graph" class="graph"> <div id="code_file_graph" class="graph">
<div id="code_file_result_revision_graph"></div> <div id="code_file_revision_graph_container">
<div id="code_file_revision_graph"></div>
<div id="code_file_revision_graph_error"></div>
</div>
</div> </div>
<div style="display:none"> <div style="display:none">

View File

@ -94,7 +94,7 @@ var GraphApp = (function ()
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// CONSTRUCTOR // CONSTRUCTOR
// ------------------------------------------------------------------- // -------------------------------------------------------------------
function App (top_container, graph_container, graph_canvas, graph_button, graph_spin, graph_url, graph_title) function App (top_container, graph_container, graph_msgdiv, graph_canvas, graph_button, graph_spin, graph_url, graph_title)
{ {
//if (this.constructor != App) //if (this.constructor != App)
//{ //{
@ -103,6 +103,7 @@ var GraphApp = (function ()
this.top_container = top_container; this.top_container = top_container;
this.graph_container = graph_container; this.graph_container = graph_container;
this.graph_msgdiv = graph_msgdiv;
this.graph_canvas = graph_canvas; this.graph_canvas = graph_canvas;
this.graph_button = graph_button; this.graph_button = graph_button;
this.graph_spin = graph_spin; this.graph_spin = graph_spin;
@ -110,6 +111,8 @@ var GraphApp = (function ()
this.graph_url = graph_url; this.graph_url = graph_url;
this.graph_title = graph_title; this.graph_title = graph_title;
this.graph_msgdiv.hide();
this.graph_msgdiv.css ({'background-color': 'red', 'color': 'white', 'padding': '1em', 'float': 'left'});
return this; return this;
} }
@ -124,12 +127,8 @@ var GraphApp = (function ()
if (data == null) if (data == null)
{ {
show_alert ('Invalid data received', "<?php print $this->lang->line('Error')?>"); this.showMessage ('Invalid data received');
} }
/* else if (data.nodes.length <= 0)
{
show_alert ('No data to show', "<?php print $this->lang->line('Error')?>");
} */
else else
{ {
this.renderGraph (data); this.renderGraph (data);
@ -154,7 +153,7 @@ var GraphApp = (function ()
function on_graph_error (jqXHR, textStatus, errorThrown) function on_graph_error (jqXHR, textStatus, errorThrown)
{ {
show_alert (xhr.status + ' ' + thrownError, "<?php print $this->lang->line('Error')?>"); this.showMessage (jqXHR.status + ' ' + errorThrown);
this.graph_button.button("enable"); this.graph_button.button("enable");
this.graph_spin.removeClass ("fa-cog fa-spin"); this.graph_spin.removeClass ("fa-cog fa-spin");
this.graph_ajax = null; this.graph_ajax = null;
@ -212,6 +211,23 @@ var GraphApp = (function ()
}); });
}; };
App.prototype.showMessage = function (msg)
{
this.graph_msgdiv.show();
this.graph_msgdiv.text (msg);
this.graph_msgdiv.position ({
my: "center",
at: "center",
of: this.graph_container
});
}
App.prototype.clearMessage = function()
{
this.graph_msgdiv.hide();
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// VIRTUAL FUNCTIONS // VIRTUAL FUNCTIONS
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -230,9 +246,9 @@ var GraphApp = (function ()
var RevGraphApp = (function () var RevGraphApp = (function ()
{ {
function App (top_container, graph_container, graph_canvas, graph_button, graph_spin, graph_url, graph_title) function App (top_container, graph_container, graph_msgdiv, graph_canvas, graph_button, graph_spin, graph_url, graph_title)
{ {
GraphApp.call (this, top_container, graph_container, graph_canvas, graph_button, graph_spin, graph_url, graph_title); GraphApp.call (this, top_container, graph_container, graph_msgdiv, graph_canvas, graph_button, graph_spin, graph_url, graph_title);
this.revision_network = null; this.revision_network = null;
return this; return this;
} }
@ -241,6 +257,13 @@ var RevGraphApp = (function ()
App.prototype.renderGraph = function (data) App.prototype.renderGraph = function (data)
{ {
if (data.nodes.length <= 0)
{
this.showMessage ('No data to show');
return;
}
this.clearMessage ();
var options = { var options = {
autoResize: false, autoResize: false,
height: '400px', height: '400px',
@ -311,9 +334,9 @@ var RevGraphApp = (function ()
var LocLangApp = (function () var LocLangApp = (function ()
{ {
function App (top_container, graph_container, graph_canvas, graph_button, graph_spin, graph_url, graph_title) function App (top_container, graph_container, graph_msgdiv, graph_canvas, graph_button, graph_spin, graph_url, graph_title)
{ {
GraphApp.call (this, top_container, graph_container, graph_canvas, graph_button, graph_spin, graph_url, graph_title); GraphApp.call (this, top_container, graph_container, graph_msgdiv, graph_canvas, graph_button, graph_spin, graph_url, graph_title);
this.tooltip = null; this.tooltip = null;
this.plot_last_point = null; this.plot_last_point = null;
this.plot_dataset = null; this.plot_dataset = null;
@ -370,6 +393,8 @@ var LocLangApp = (function ()
{ {
var self = this; var self = this;
this.clearMessage ();
var blank = []; var blank = [];
for (var key in loc) blank.push ([ key, loc[key][1]] ); for (var key in loc) blank.push ([ key, loc[key][1]] );
@ -439,9 +464,9 @@ var LocLangApp = (function ()
var LocFileApp = (function () var LocFileApp = (function ()
{ {
function App (top_container, graph_container, graph_canvas, graph_button, graph_spin, graph_url, graph_title) function App (top_container, graph_container, graph_msgdiv, graph_canvas, graph_button, graph_spin, graph_url, graph_title)
{ {
GraphApp.call (this, top_container, graph_container, graph_canvas, graph_button, graph_spin, graph_url, graph_title); GraphApp.call (this, top_container, graph_container, graph_msgdiv, graph_canvas, graph_button, graph_spin, graph_url, graph_title);
this.cf = null; this.cf = null;
this.loc_data = null; this.loc_data = null;
@ -461,6 +486,7 @@ var LocFileApp = (function ()
App.prototype.renderGraph = function (loc) App.prototype.renderGraph = function (loc)
{ {
this.clearMessage ();
this.loc_data = loc; this.loc_data = loc;
} }
@ -934,6 +960,7 @@ $(function () {
var rev_graph_app = new RevGraphApp ( var rev_graph_app = new RevGraphApp (
$(window), $(window),
$("#code_folder_revision_graph_container"), $("#code_folder_revision_graph_container"),
$("#code_folder_revision_graph_error"),
$("#code_folder_revision_graph"), $("#code_folder_revision_graph"),
$("#code_folder_revision_graph_button"), $("#code_folder_revision_graph_button"),
$("#code_folder_revision_graph_spin"), $("#code_folder_revision_graph_spin"),
@ -945,6 +972,7 @@ $(function () {
var loc_by_lang_app = new LocLangApp ( var loc_by_lang_app = new LocLangApp (
$(window), $(window),
$("#code_folder_loc_by_lang_container"), $("#code_folder_loc_by_lang_container"),
$("#code_folder_loc_by_lang_error"),
$("#code_folder_loc_by_lang"), $("#code_folder_loc_by_lang"),
$("#code_folder_loc_by_lang_button"), $("#code_folder_loc_by_lang_button"),
$("#code_folder_loc_by_lang_spin"), $("#code_folder_loc_by_lang_spin"),
@ -956,6 +984,7 @@ $(function () {
var loc_by_file_app = new LocFileApp ( var loc_by_file_app = new LocFileApp (
$(window), $(window),
$("#code_folder_loc_by_file_container"), $("#code_folder_loc_by_file_container"),
$("#code_folder_loc_by_file_error"),
$("#code_folder_loc_by_file"), $("#code_folder_loc_by_file"),
$("#code_folder_loc_by_file_button"), $("#code_folder_loc_by_file_button"),
$("#code_folder_loc_by_file_spin"), $("#code_folder_loc_by_file_spin"),
@ -1208,14 +1237,17 @@ $this->load->view (
<div id="code_folder_graph" class="graph"> <div id="code_folder_graph" class="graph">
<div id="code_folder_loc_by_lang_container"> <div id="code_folder_loc_by_lang_container">
<div id="code_folder_loc_by_lang"></div> <div id="code_folder_loc_by_lang"></div>
<div id="code_folder_loc_by_lang_error"></div>
</div> </div>
<div id="code_folder_loc_by_file_container"> <div id="code_folder_loc_by_file_container">
<div id="code_folder_loc_by_file"></div> <div id="code_folder_loc_by_file"></div>
<div id="code_folder_loc_by_file_error"></div>
</div> </div>
<div id="code_folder_revision_graph_container"> <div id="code_folder_revision_graph_container">
<div id="code_folder_revision_graph"></div> <div id="code_folder_revision_graph"></div>
<div id="code_folder_revision_graph_error"></div>
</div> </div>
</div> </div>

View File

@ -92,22 +92,6 @@ $this->load->view (
<div style="clear: both;"></div> <div style="clear: both;"></div>
</div> </div>
<!-- <div class="graph" id="code_history_graph">
<?php
/*
$xfullpath = $this->converter->AsciiToHex (($fullpath == '')? '.': $fullpath);
$graph_url = codepot_merge_path (site_url(), "/code/graph/commits-by-users/{$project->id}/{$xfullpath}{$revreq}");
print "<img src='{$graph_url}' />";
$graph_url = codepot_merge_path (site_url(), "/code/graph/commit-share-by-users/{$project->id}/{$xfullpath}{$revreq}");
print "<img src='{$graph_url}' />";
*/
?>
</div> -->
<div id="code_history_result" class="codepot-relative-container-view"> <div id="code_history_result" class="codepot-relative-container-view">
<table id="code_history_result_table" class="codepot-full-width-table codepot-spacious-table"> <table id="code_history_result_table" class="codepot-full-width-table codepot-spacious-table">
<?php <?php

View File

@ -227,9 +227,9 @@ var GraphApp = (function()
this.ajax_req = null; this.ajax_req = null;
} }
function handle_error (xhr, textStatus, thrownError) function handle_error (jqXHR, textStatus, errorThrown)
{ {
show_alert.call (this, xhr.status + ' ' + thrownError, "<?php print $this->lang->line('Error')?>"); show_alert.call (this, jqXHR.status + ' ' + errorThrown, "<?php print $this->lang->line('Error')?>");
this.refresh_button.button("enable"); this.refresh_button.button("enable");
this.refresh_spin.removeClass ("fa-cog fa-spin"); this.refresh_spin.removeClass ("fa-cog fa-spin");
this.ajax_req = null; this.ajax_req = null;