refactored javascript codes in project_map.php

This commit is contained in:
hyung-hwan 2016-12-16 16:01:59 +00:00
parent 35d92f2950
commit 615925180d
5 changed files with 264 additions and 199 deletions

View File

@ -198,7 +198,7 @@ class Graph extends Controller
print codepot_json_encode ($rg); print codepot_json_encode ($rg);
} }
function enjson_project_user_relation_graph ($filter = '') function enjson_project_members ($filter = '')
{ {
$this->load->model ('ProjectModel', 'projects'); $this->load->model ('ProjectModel', 'projects');
@ -210,7 +210,7 @@ class Graph extends Controller
} }
$filter = $this->converter->HexToAscii ($filter); $filter = $this->converter->HexToAscii ($filter);
$rel = $this->projects->getProjectUserRelationGraph($filter); $rel = $this->projects->getProjectMembers($filter);
print codepot_json_encode($rel); print codepot_json_encode($rel);
} }
} }

View File

@ -592,26 +592,15 @@ class ProjectModel extends Model
return TRUE; return TRUE;
} }
private function _add_rg_node (&$nodeids, &$nodes, $name, $type) function getProjectMembers ($userid_filter)
{
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 getProjectUserRelationGraph ($filter)
{ {
$this->db->trans_begin (); $this->db->trans_begin ();
$this->db->select ('project.id,project_membership.userid'); $this->db->select ('project.id,project_membership.userid');
if ($filter != '') $this->db->where ('userid', $filter); if (is_array($userid_filter) && count($userid_filter) > 0)
$this->db->where_in ('userid', $userid_filter);
else if ($userid_filter != '')
$this->db->where ('userid', $userid_filter);
$this->db->join ('project_membership', 'project_membership.projectid = project.id'); $this->db->join ('project_membership', 'project_membership.projectid = project.id');
$query = $this->db->get ('project'); $query = $this->db->get ('project');
@ -622,25 +611,26 @@ class ProjectModel extends Model
} }
$result = $query->result (); $result = $query->result ();
$data = array();
$nodes = array();
$nodeids = array();
$edges = array();
if (count($result) > 0) if (count($result) > 0)
{ {
foreach ($result as $r) foreach ($result as $r)
{ {
$id1 = $this->_add_rg_node ($nodeids, $nodes, $r->id, 'project'); if (array_key_exists ($r->id, $data))
$id2 = $this->_add_rg_node ($nodeids, $nodes, $r->userid, 'user'); array_push ($data[$r->id], $r->userid);
$this->_add_rg_edge ($edges, $id1, $id2, ""); else
$data[$r->id] = array ($r->userid);
} }
if ($filter != '') if ((is_array($userid_filter) && count($userid_filter) > 0) || $userid_filter != '')
{ {
$this->db->select ('project.id,project_membership.userid'); $this->db->select ('project.id,project_membership.userid');
$this->db->where_in ('id', array_keys($nodeids)); $this->db->where_in ('id', array_keys($data));
$this->db->where ('userid <>', $filter); if (is_array($userid_filter) && count($userid_filter) > 0)
$this->db->where_not_in ('userid <>', $userid_filter);
else
$this->db->where ('userid <>', $userid_filter);
$this->db->join ('project_membership', 'project_membership.projectid = project.id'); $this->db->join ('project_membership', 'project_membership.projectid = project.id');
$query = $this->db->get ('project'); $query = $this->db->get ('project');
if ($this->db->trans_status() === FALSE) if ($this->db->trans_status() === FALSE)
@ -652,15 +642,16 @@ class ProjectModel extends Model
$result = $query->result (); $result = $query->result ();
foreach ($result as $r) foreach ($result as $r)
{ {
$id1 = $this->_add_rg_node ($nodeids, $nodes, $r->id, 'project'); if (array_key_exists ($r->id, $data))
$id2 = $this->_add_rg_node ($nodeids, $nodes, $r->userid, 'user'); array_push ($data[$r->id], $r->userid);
$this->_add_rg_edge ($edges, $id1, $id2, ""); else
$data[$r->id] = array ($r->userid);
} }
} }
} }
$this->db->trans_commit (); $this->db->trans_commit ();
return array ('nodes' => $nodes, 'edges' => $edges); return $data;
} }
} }

View File

@ -244,7 +244,7 @@ function show_revision_graph (response)
} }
else if (data.nodes.length <= 0) else if (data.nodes.length <= 0)
{ {
show_alert ('No data to show', "<?php print $this->lang->line('Info')?>"); show_alert ('No data to show', "<?php print $this->lang->line('Error')?>");
} }
else else
{ {

View File

@ -212,7 +212,7 @@ function show_revision_graph (response)
} }
else if (data.nodes.length <= 0) else if (data.nodes.length <= 0)
{ {
show_alert ('No data to show', "<?php print $this->lang->line('Info')?>"); show_alert ('No data to show', "<?php print $this->lang->line('Error')?>");
} }
else else
{ {

View File

@ -17,192 +17,266 @@
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/vis.min.css')?>" /> <link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/vis.min.css')?>" />
<script type="text/javascript"> <script type="text/javascript">
var GraphApp = (function()
{
// -------------------------------------------------------------------
// PRIVATE DATA
// -------------------------------------------------------------------
var graph_options =
{
autoResize: false,
height: '300px',
width: '300px',
clickToUse: false,
layout:
{
hierarchical:
{
enabled: false,
}
},
physics:
{
enabled: true
}
};
var edge_font = { color: 'red' };
var edge_color = { color:'#5577CC', highlight:'pink', hover: '#5577CC', opacity:1.0 };
// -------------------------------------------------------------------
// CONSTRUCTOR
// -------------------------------------------------------------------
function App (graph_container_id, refresh_button_id, refresh_spin_id, refresh_progress_id, filter_id, header_id, footer_id, alert_container_id)
{
if (this.constructor != App)
{
return new App(refresh_button_id, refresh_spin_id);
}
this.graph_container = $('#' + graph_container_id);
this.refresh_button_inited = false;
this.refresh_button = $('#' + refresh_button_id);
this.refresh_spin = $('#' + refresh_spin_id);
this.refresh_progress = $('#' + refresh_progress_id);
this.filter = $('#' + filter_id);
this.header = $('#' + header_id);
this.footer = $('#' + footer_id);
this.alert_container = $('#' + alert_container_id);
this.url_base = codepot_merge_path ("<?php print site_url(); ?>", "/graph/enjson_project_members");
this.ajax_req = null;
this.graph = null;
this.data = null;
return this;
}
// -------------------------------------------------------------------
// PRIVATE FUNCTIONS
// -------------------------------------------------------------------
function show_alert (outputMsg, titleMsg) function show_alert (outputMsg, titleMsg)
{ {
$('#project_map_alert').html(outputMsg).dialog({ this.alert_container.html(outputMsg).dialog({
title: titleMsg, title: titleMsg,
resizable: true, resizable: true,
modal: true, modal: true,
width: 'auto', width: 'auto',
height: 'auto', height: 'auto',
buttons: { buttons: {
"<?php print $this->lang->line('OK')?>": function () { "<?php print $this->lang->line('OK')?>": function ()
{
$(this).dialog("close"); $(this).dialog("close");
} }
} }
}); });
} }
function convert_data (data)
var revision_network = null;
var revision_network_data = null;
var revision_rendering_progress = null;
function resize_window()
{ {
var footer = $("#codepot_footer"); var ids = {};
var titleband = $("#project_map_title_band"); var gd = { nodes: [], edges: [] };
var code = $("#project_user_relation_graph"); var seq = 0;
if (revision_network !== null) for (var prid in data)
{ {
// make it low so that the footer gets places at the right place. gd.nodes.push ({ __type: "p", id: seq, label: prid, shape: "box" });
revision_network.setSize (300, 300); ids[prid] = seq;
//revision_network.redraw(); seq++;
for (var i = 0; i < data[prid].length; i++)
{
var uid = data[prid][i];
if (!(uid in ids))
{
var image_url = codepot_merge_path('<?php print site_url(); ?>', "/user/icon/" + codepot_string_to_hex(uid));
gd.nodes.push ({ __type: "u", id: seq, label: uid, shape: "image", image: image_url });
ids[uid] = seq;
seq++;
} }
var ioff = titleband.offset(); gd.edges.push ({ from: ids[prid], to: ids[uid], width: 1, font: edge_font, color: edge_color });
var foff = footer.offset();
ioff.top += titleband.outerHeight() + 5;
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) return gd;
}
function handle_double_click (nodeid)
{
for (var i = 0, j = this.data.nodes.length; i < j; i++)
{
if (this.data.nodes[i].id == nodeid)
{
if (this.data.nodes[i].__type == "p")
{
$(location).attr ("href", codepot_merge_path('<?php print site_url(); ?>', "/project/home/" + this.data.nodes[i].label));
}
else
{
$(location).attr ("href", codepot_merge_path('<?php print site_url(); ?>', "/user/home/" + codepot_string_to_hex(this.data.nodes[i].label)));
}
break;
}
}
}
function show_graph (response)
{ {
var data = $.parseJSON(response); var data = $.parseJSON(response);
if (data == null) if (data == null)
{ {
show_alert ('Invalid data received', "<?php print $this->lang->line('Error')?>"); show_alert.call (this, 'Invalid data received', "<?php print $this->lang->line('Error')?>");
} }
else if (data.nodes.length <= 0) else if (data.length <= 0)
{ {
show_alert ('No data to show', "<?php print $this->lang->line('Info')?>"); show_alert.call (this, 'No data to show', "<?php print $this->lang->line('Error')?>");
} }
else else
{ {
var options = { this.data = convert_data.call (this, data);
autoResize: false, if (this.graph === null)
height: '300px', {
width: '300px', var self = this;
clickToUse: false,
layout: {
hierarchical: {
enabled: false,
}
},
physics: {
enabled: true
}
};
for (var i = 0, j = data.nodes.length; i < j; i++) this.graph = new vis.Network(this.graph_container[0], this.data, graph_options);
this.graph.on ('doubleClick', function (props)
{ {
if (data.nodes[i]._type == 'project') if (props.nodes.length > 0) handle_double_click.call (self, props.nodes[0]);
{
data.nodes[i].shape = 'box';
}
else
{
//data.nodes[i].shape = 'ellipse';
//data.nodes[i].color = { border: '#777799', background: '#DACACA' };
data.nodes[i].shape = 'image';
data.nodes[i].image = codepot_merge_path('<?php print site_url(); ?>', '/user/icon/' + codepot_string_to_hex(data.nodes[i].label));
}
}
for (var i = 0, j = data.edges.length; i < j; i++)
{
//data.edges[i].length = 500;
data.edges[i].width = 1;
data.edges[i].font = { color: 'red' };
data.edges[i].color = {
color:'#5577CC',
highlight:'pink',
hover: '#5577CC',
opacity:1.0
};
}
if (revision_network === null)
{
revision_network_progress = $('#project_map_progress');
revision_network_data = data;
revision_network = new vis.Network(document.getElementById('project_user_relation_graph'), data, options);
revision_network.on ('doubleClick', function (props) {
if (props.nodes.length > 0)
{
for (var 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)));
}
}
}
}
}); });
revision_network.on ('startStabilizing', function (params) { this.graph.on ('startStabilizing', function ()
$("#project_map_refresh_button").button("disable"); {
self.refresh_button.button ("enable");
}); });
revision_network.on ('stabilizationProgress', function (params) { this.graph.on ('stabilizationProgress', function (params)
{
var prog = params.iterations / params.total; var prog = params.iterations / params.total;
revision_network_progress.text (Math.round(prog*100)+'%'); self.refresh_progress.text (Math.round(prog*100)+'%');
}); });
revision_network.on ('stabilizationIterationsDone', function (params) { this.graph.on ('stabilizationIterationsDone', function ()
revision_network_progress.text (''); {
$("#project_map_refresh_button").button("enable"); self.refresh_progress.text ("");
self.refresh_button.button ("enable");
}); });
revision_network.on ('stabilized', function (params) { this.graph.on ('stabilized', function (params)
revision_network_progress.text (''); {
$("#project_map_refresh_button").button("enable"); self.refresh_progress.text ("");
self.refresh_button.button ("enable");
}); });
} }
else else
{ {
revision_network.setData (data); this.graph.setData (this.data);
}
} }
$(window).resize(resize_window); this.resize ();
resize_window ();
$("#project_map_refresh_button").button("enable");
$("#project_map_refresh_spin").removeClass ("fa-cog fa-spin");
} }
$(function () {
$("#project_map_refresh_button").button().click (function () {
$("#project_map_refresh_button").button("disable");
$("#project_map_refresh_spin").addClass ("fa-cog fa-spin");
var filter = $("#project_map_filter").val(); this.refresh_button.button("enable");
filter = filter.trim(); this.refresh_spin.removeClass ("fa-cog fa-spin");
this.ajax_req = null;
var graph_url = graph_url = codepot_merge_path ("<?php print site_url(); ?>", "/graph/enjson_project_user_relation_graph");
if(filter.length > 0) graph_url += "/" + codepot_string_to_hex(filter);
var ajax_req = $.ajax ({
url: graph_url,
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')?>");
$("#project_map_refresh_button").button("enable");
$("#project_map_refresh_spin").removeClass ("fa-cog fa-spin");
} }
});
function handle_error (xhr, textStatus, thrownError)
{
show_alert.call (this, xhr.status + ' ' + thrownError, "<?php print $this->lang->line('Error')?>");
this.refresh_button.button("enable");
this.refresh_spin.removeClass ("fa-cog fa-spin");
this.ajax_req = null;
}
// -------------------------------------------------------------------
// PUBLIC FUNCTIONS
// -------------------------------------------------------------------
App.prototype.refresh = function (filter)
{
var url = this.url_base;
if(filter.length > 0) url += "/" + codepot_string_to_hex(filter);
this.refresh_button.button("disable");
this.refresh_spin.addClass ("fa-cog fa-spin");
if (this.ajax_req !== null) this.ajax_req.abort();
this.ajax_req = $.ajax ({url: url, context: this, success: show_graph, error: handle_error });
};
App.prototype.initRefresh = function ()
{
if (!this.refresh_button_inited)
{
this.refresh_button_inited = true;
var self = this;
this.refresh_button.button().click (function ()
{
self.refresh (self.filter.val().trim());
return false; return false;
}); });
}
$("#project_map_refresh_button").trigger ('click'); };
App.prototype.triggerRefresh = function ()
{
this.refresh_button.trigger ('click');
};
App.prototype.resize = function ()
{
if (this.graph !== null)
{
// make it low so that the footer gets places at the right place.
this.graph.setSize (300, 300);
var hoff = this.header.offset();
var foff = this.footer.offset();
hoff.top += this.header.outerHeight() + 5;
this.graph.setSize (this.footer.innerWidth() - 10, foff.top - hoff.top - 10);
this.graph.redraw();
this.graph.fit();
}
};
return App;
})();
/* ---------------------------------------------------------------------- */
$(function () {
var graph_app = new GraphApp (
'project_map_graph', 'project_map_refresh_button',
'project_map_refresh_spin', 'project_map_progress',
'project_map_filter', 'project_map_title_band',
'codepot_footer', 'project_map_alert');
$(window).resize(function () { graph_app.resize(); });
graph_app.initRefresh ();
graph_app.triggerRefresh ();
}); });
</script> </script>
@ -256,7 +330,7 @@ $this->load->view (
<div class="result" id="project_map_result"> <div class="result" id="project_map_result">
<div id="project_user_relation_graph"> <div id="project_map_graph">
</div> </div>
</div> <!-- project_map_result --> </div> <!-- project_map_result -->