added a project-user relation graph

This commit is contained in:
hyung-hwan 2016-12-15 07:10:01 +00:00
parent 1983cb8c45
commit 680bc1a2f6
7 changed files with 322 additions and 5 deletions

View File

@ -197,4 +197,19 @@ class Graph extends Controller
$rg = $this->subversion->revisionGraph ($projectid, $path, $rev); $rg = $this->subversion->revisionGraph ($projectid, $path, $rev);
print codepot_json_encode ($rg); print codepot_json_encode ($rg);
} }
function enjson_project_user_relation_graph ()
{
$this->load->model ('ProjectModel', 'projects');
$login = $this->login->getUser ();
if (CODEPOT_SIGNIN_COMPULSORY && $login['id'] == '')
{
header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
return;
}
$rel = $this->projects->getAllProjectUserRelationGraph();
print codepot_json_encode($rel);
}
} }

View File

@ -8,6 +8,7 @@ class Project extends Controller
var $VIEW_DELETE = 'project_delete'; var $VIEW_DELETE = 'project_delete';
var $VIEW_CATALOG = 'project_catalog'; var $VIEW_CATALOG = 'project_catalog';
var $VIEW_LOG = 'log'; var $VIEW_LOG = 'log';
var $VIEW_MAP = 'project_map';
function Project () function Project ()
{ {
@ -117,6 +118,18 @@ class Project extends Controller
} }
} }
function map ()
{
$this->load->model ('ProjectModel', 'projects');
$login = $this->login->getUser ();
if (CODEPOT_SIGNIN_COMPULSORY && $login['id'] == '')
redirect (CODEPOT_SIGNIN_REDIR_PATH . $this->converter->AsciiTohex(current_url()));
$data['login'] = $login;
$this->load->view ($this->VIEW_MAP, $data);
}
function home ($projectid = "") function home ($projectid = "")
{ {
$this->load->model ('ProjectModel', 'projects'); $this->load->model ('ProjectModel', 'projects');
@ -126,7 +139,6 @@ class Project extends Controller
$login = $this->login->getUser (); $login = $this->login->getUser ();
if (CODEPOT_SIGNIN_COMPULSORY && $login['id'] == '') if (CODEPOT_SIGNIN_COMPULSORY && $login['id'] == '')
redirect (CODEPOT_SIGNIN_REDIR_PATH . $this->converter->AsciiTohex(current_url())); redirect (CODEPOT_SIGNIN_REDIR_PATH . $this->converter->AsciiTohex(current_url()));
$data['login'] = $login; $data['login'] = $login;
$project = $this->projects->get ($projectid); $project = $this->projects->get ($projectid);

View File

@ -438,7 +438,7 @@ class ProjectModel extends Model
$this->db->trans_start (); $this->db->trans_start ();
$this->db->limit ($limit); $this->db->limit ($limit);
$this->db->order_by ('createdon', 'desc'); $this->db->order_by ('createdon', 'desc');
$query = $this->db->get ('project'); $query = $this->db->get ('project');
$this->db->trans_complete (); $this->db->trans_complete ();
@ -446,6 +446,8 @@ class ProjectModel extends Model
return $query->result (); return $query->result ();
} }
function _scandir ($dir) function _scandir ($dir)
{ {
$files = array (); $files = array ();
@ -589,6 +591,47 @@ class ProjectModel extends Model
mail ($recipients, $subject, base64_encode($message), $additional_headers); mail ($recipients, $subject, base64_encode($message), $additional_headers);
return TRUE; return TRUE;
} }
private function _add_rg_node (&$nodeids, &$nodes, $name, $type)
{
if (array_key_exists($name, $nodeids)) return $nodeids[$name];
$nid = count($nodeids);
array_push ($nodes, array ('id' => $nid, 'label' => $name, '_type' => $type));
$nodeids[$name] = $nid;
return $nid;
}
private function _add_rg_edge (&$edges, $from, $to, $label)
{
array_push ($edges, array ('from' => $from, 'to' => $to, 'label' => $label));
}
function getAllProjectUserRelationGraph ()
{
$this->db->trans_start ();
$this->db->select ('project.id,project_membership.userid');
$this->db->join ('project_membership', 'project_membership.projectid = project.id');
$query = $this->db->get ('project');
$this->db->trans_complete ();
if ($this->db->trans_status() === FALSE) return FALSE;
$result = $query->result ();
$nodes = array();
$nodeids = array();
$edges = array();
foreach ($result as $r)
{
$id1 = $this->_add_rg_node ($nodeids, $nodes, $r->id, 'project');
$id2 = $this->_add_rg_node ($nodeids, $nodes, $r->userid, 'user');
$this->_add_rg_edge ($edges, $id1, $id2, "");
}
return array ('nodes' => $nodes, 'edges' => $edges);
}
} }
?> ?>

View File

@ -1634,7 +1634,7 @@ class SubversionModel extends Model
return $cloc; return $cloc;
} }
function _add_rg_node (&$nodeids, &$nodes, $name) private function _add_rg_node (&$nodeids, &$nodes, $name)
{ {
if (array_key_exists($name, $nodeids)) return $nodeids[$name]; if (array_key_exists($name, $nodeids)) return $nodeids[$name];
$nid = count($nodeids); $nid = count($nodeids);
@ -1643,7 +1643,7 @@ class SubversionModel extends Model
return $nid; return $nid;
} }
function _add_rg_edge (&$edges, $from, $to, $label) private function _add_rg_edge (&$edges, $from, $to, $label)
{ {
array_push ($edges, array ('from' => $from, 'to' => $to, 'label' => $label)); array_push ($edges, array ('from' => $from, 'to' => $to, 'label' => $label));
} }

View File

@ -21,6 +21,7 @@ www_DATA = \
project_catalog.php \ project_catalog.php \
project_delete.php \ project_delete.php \
project_edit.php \ project_edit.php \
project_map.php \
project_home.php \ project_home.php \
projectbar.php \ projectbar.php \
site_catalog.php \ site_catalog.php \

View File

@ -189,7 +189,8 @@ $this->load->view (
), ),
'ctxmenuitems' => array ( 'ctxmenuitems' => array (
array ("project/create", '<i class="fa fa-plus"></i> ' . $this->lang->line('New'), 'project_catalog_new') array ("project/create", '<i class="fa fa-plus"></i> ' . $this->lang->line('New'), 'project_catalog_new'),
array ("project/map", $this->lang->line('Graph'), 'project_catalog_map')
) )
) )
); );

View File

@ -0,0 +1,245 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="<?php print base_url_make('/js/codepot.js')?>"></script>
<script type="text/javascript" src="<?php print base_url_make('/js/codepot.js')?>"></script>
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/common.css')?>" />
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/project.css')?>" />
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/font-awesome.min.css')?>" />
<script type="text/javascript" src="<?php print base_url_make('/js/jquery.min.js')?>"></script>
<script type="text/javascript" src="<?php print base_url_make('/js/jquery-ui.min.js')?>"></script>
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/jquery-ui.css')?>" />
<script type="text/javascript" src="<?php print base_url_make('/js/vis.min.js')?>"></script>
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/vis.min.css')?>" />
<script type="text/javascript">
function show_alert (outputMsg, titleMsg)
{
$('#project_map_alert').html(outputMsg).dialog({
title: titleMsg,
resizable: true,
modal: true,
width: 'auto',
height: 'auto',
buttons: {
"<?php print $this->lang->line('OK')?>": function () {
$(this).dialog("close");
}
}
});
}
var revision_network = null;
var revision_network_data = null;
function resize_window()
{
var footer = $("#codepot_footer");
var mainarea = $("#project_map_mainarea");
var code = $("#project_user_relation_graph");
if (revision_network !== null)
{
// make it low so that the footer gets places at the right place.
revision_network.setSize (300, 300);
//revision_network.redraw();
}
var ioff = mainarea.offset();
var foff = footer.offset();
if (revision_network !== null)
{
revision_network.setSize (footer.innerWidth() - 10, foff.top - ioff.top - 10);
revision_network.redraw();
revision_network.fit();
}
}
function show_project_user_relation_graph (response)
{
var data = $.parseJSON(response);
if (data == null)
{
show_alert ('Invalid data received', "<?php print $this->lang->line('Error')?>");
}
else if (data.nodes.length <= 0)
{
show_alert ('No data to show', "<?php print $this->lang->line('Info')?>");
}
else
{
var options = {
autoResize: false,
height: '300px',
width: '300px',
clickToUse: false,
layout: {
hierarchical: {
enabled: true,
//levelSeparation: 150,
//nodeSpacing: 200,
//treeSpacing: 300,
//direction: 'LR', //'LR' 'UD', 'DU', 'RL'
sortMethod: 'hubsize' // 'directed'
}
},
edges: {
smooth: {
type: 'cubicBezier',
forceDirection: 'horizontal', // 'vertical',
roundness: 0.4
}
},
physics: {
enabled: true
}
};
var i, j;
j = data.nodes.length;
for (i = 0; i < j; i++)
{
if (data.nodes[i]._type == 'project')
{
data.nodes[i].shape = 'box';
//data.nodes[i].label = '<a href="xxx">' + codepot_htmlspecialchars(data.nodes[i].label) + '</a>';
}
else
{
data.nodes[i].shape = 'ellipse';
data.nodes[i].color = { border: '#FF7777', background: '#DACACA' };
}
}
j = data.edges.length;
for (i = 0; i < j; i++)
{
data.edges[i].length = 60;
data.edges[i].width = 1;
data.edges[i].arrows = 'to';
data.edges[i].font = { color: 'red' };
}
if (revision_network === null)
{
revision_network = new vis.Network(document.getElementById('project_user_relation_graph'), data, options);
revision_network_data = data;
revision_network.on ('click', function (props) {
if (props.nodes.length > 0)
{
var i, j;
for (i = 0, j = revision_network_data.nodes.length; i < j; i++)
{
if (revision_network_data.nodes[i].id == props.nodes[0])
{
if (revision_network_data.nodes[i]._type == 'project')
{
$(location).attr ('href', codepot_merge_path('<?php print site_url(); ?>', '/project/home/' + revision_network_data.nodes[i].label));
}
else
{
$(location).attr ('href', codepot_merge_path('<?php print site_url(); ?>', '/user/home/' + codepot_string_to_hex(revision_network_data.nodes[i].label)));
}
}
}
}
});
}
else
{
revision_network.setData (data);
}
}
$(window).resize(resize_window);
resize_window ();
}
$(function () {
var ajax_req = $.ajax ({
url: codepot_merge_path (
"<?php print site_url(); ?>",
"/graph/enjson_project_user_relation_graph"),
context: document.body,
success: show_project_user_relation_graph,
error: function (xhr, ajaxOptions, thrownError) {
show_alert (xhr.status + ' ' + thrownError, "<?php print $this->lang->line('Error')?>");
//$("#code_folder_revision_graph_button").button("enable");
//$("#code_folder_revision_graph_spin" ).removeClass ("fa-cog fa-spin");
}
});
});
</script>
<title><?php print $this->lang->line('Projects')?></title>
</head>
<body>
<div class="content" id="project_map_content">
<!---------------------------------------------------------------------------->
<?php $this->load->view ('taskbar'); ?>
<!---------------------------------------------------------------------------->
<?php
$this->load->view (
'projectbar',
array (
'banner' => $this->lang->line('Projects'),
'page' => array (
'type' => '',
'id' => ''
),
'ctxmenuitems' => array (
array ("project/create", '<i class="fa fa-plus"></i> ' . $this->lang->line('New'), 'project_map_new'),
array ("project/catalog", $this->lang->line('Directory'), 'project_map_catalog')
)
)
);
?>
<!---------------------------------------------------------------------------->
<div class="mainarea" id="project_map_mainarea">
<div class="result" id="project_map_result">
<div id="project_user_relation_graph">
</div>
</div> <!-- project_map_result -->
<div id='code_folder_alert'></div>
</div> <!-- project_map_mainarea -->
<div class='codepot-footer-pusher'></div> <!-- for sticky footer -->
</div> <!-- project_map_content -->
<!---------------------------------------------------------------------------->
<?php $this->load->view ('footer'); ?>
<!---------------------------------------------------------------------------->
</body>
</html>