Skip to content

Instantly share code, notes, and snippets.

@shyampurk
Last active June 27, 2016 08:24
Show Gist options
  • Save shyampurk/e71b2aeb82c331a32574c29a42c23b1b to your computer and use it in GitHub Desktop.
Save shyampurk/e71b2aeb82c331a32574c29a42c23b1b to your computer and use it in GitHub Desktop.
handleComment = function(obj,commentObj){
var comment = commentObj.commentsAndMeta.comment[0];
var foundComment = false;
var i = 0;
while(i < obj.links.length){
if((obj.links[i].type == 1) && (obj.links[i].target.data.comment_id == comment.comment_id) ){
foundComment = true;
break;
}
i++;
}
if(foundComment){
obj.links[i].target.data = comment;
} else {
var j = 0;
var foundPost = false;
while(j < obj.nodes.length){
if((obj.nodes[j].type == "post") && (obj.nodes[j].data.pid == comment.comment_post_id) ){
foundPost = true;
break;
}
j++;
}
if(foundPost){
obj.nodes.push({"type" : "comment" , "data" : comment })
obj.links.push({"source" : j , "target" : obj.nodes.length - 1 , "type" : 1 , "ref_post_id" : comment.comment_post_id, "key" : obj.nodes[j].data.pid + '-' + comment.comment_id});
}
}
}
{
"result": "Yes",
"records": [{
"Type": "Comments",
"commentsAndMeta": {
"comment": [{
"comment_post_id": "52",
"comment_content": "here is my comment",
"comment_author": "root",
"comment_author_email": "getto@siteviz.com",
"comment_date": "2016-06-05 17:13:23",
"comment_date_gmt": "2016-06-05 17:13:23",
"comment_approved": "1",
"neg": "",
"neutral": "",
"pos": "",
"label": ""
}]
}
}]
}
var pubnub = PUBNUB({
subscribe_key: '<?php echo $pubnub_subs_key; ?>', // always required
publish_key: '<?php echo $pubnub_pub_key; ?>' // only required if publishing
});
// Subscribe to a channel
pubnub.subscribe({
channel: '<?php echo $pubnub_chanel_name; ?>',
message: function(m){
if(viz){
viz.refresh(m);
} else {
loadAllPostData();
}
},
error: function (error) {
// Handle error here
alert('Error'+JSON.stringify(error));
}
});
/*
* VizElement Object for Managing the SiteViz SceneGraph. Based on D3js Force Layout
* @param parent_elem - ID of container element
* @param inputJson - JSON dump of the existing site strucure for initialization
* @param resourcePath - Internal path of the image resources within wordpress
*/
var VizElement = function(parent_elem,inputJson,resourcePath) {
// load in arguments from config object
var that = this;
this.data = inputJson;
this.pelement = parent_elem;
this.resPath = resourcePath + '/images/';
this.nodes = new Array();
this.links = new Array();
this.categoryCheck = new Array();
this.postSVG = null;
this.commentSVG = null;
d3.xml(this.resPath + "post.svg", "image/svg+xml", function(error, xml) {
if (error) throw error;
that.postSVG = document.importNode(xml.documentElement, true);
d3.xml(that.resPath + "comment.svg", "image/svg+xml", function(error, xml) {
if (error) throw error;
that.commentSVG = document.importNode(xml.documentElement, true);
// create the chart
that.derive();
that.draw();
});
});
}
if(refreshObj.action == "New"){
//New Post added to the wordpress site
addCategory(this,refreshObj.records[0]);
addPost(this,refreshObj.records[0]);
} else if(refreshObj.action == "Modify") {
//existing post modified in the wordpress site
modifyPost(this,refreshObj.records[0]);
} else if (refreshObj.action == "Delete") {
//Existing post deleted in wordpress site
deletePost(this,refreshObj.records);
}
{
"result": "Yes",
"action": "New",
"records": [{
"id": 20,
"pid": 70,
"post_status": "publish",
"post_author": 1,
"post_author_name": "root",
"user_login": "root",
"post_date": "2016 - 06 - 09 04: 18: 49 ",
"post_count": 0,
"post_title": "root dummy post",
"post_name": "root - dummy - post",
"tags": " ",
"categories": "demo - cat "
}]
}
/*
* Handles realtime updates on the visualization based on site activity
* @param msgObj - Message object containing the activity details.
* The Activity can be
* 1. Adding a new post
* 2. Modifying a post
* 3. Deleting a post
* 4. Adding a comment
* 5. Updating comment
*
* NOTE :- Delete comment is not supported.
*/
VizElement.prototype.refresh = function(msgObj){
var that = this;
var refreshObj = JSON.parse(msgObj);
if('action' in refreshObj)
{
//Checking for an existing post in draft state.
//In draft state it will be always reported as New , even if there is a modificaition to an existing post
//Hence an existing draft post with action "New" should be marked as "Modify"
if((refreshObj.action == "New") && this.doesPostExist(refreshObj.records[0])){
refreshObj.action = "Modify";
}
//Post Handling
if(refreshObj.action == "New"){
//New Post added to the wordpress site
addCategory(this,refreshObj.records[0]);
addPost(this,refreshObj.records[0]);
} else if(refreshObj.action == "Modify") {
//existing post modified in the wordpress site
modifyPost(this,refreshObj.records[0]);
} else if (refreshObj.action == "Delete") {
//Existing post deleted in wordpress site
deletePost(this,refreshObj.records);
}
} else {
//Comment update Handling
handleComment(this,refreshObj.records[0]);
}
update(this);
console.log(this.links);
}
VizElement.prototype.draw = function(){
var that = this;
//Setup Dimensions
this.width = this.pelement.offsetWidth - 100;
this.height = 600;
this.linearScale = d3.scale.linear().domain([0,10000]).range([15,50]);
//Initialize SVG
this.pelement.innerHTML = '';
this.svg = d3.select(this.pelement).append('svg');
this.svg.attr('width', this.width);
this.svg.attr('height', this.height);
this.linkg = this.svg.append('g').attr('class','link-group');
this.nodeg = this.svg.append('g').attr('class','node-group');
calculateCategorySpacing(this);
//Set up tooltip
this.tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function (d) {
var author = d.type == "post" ? d.data.post_author_name : d.data.comment_author;
var date = d.type == "post" ? d.data.post_date : d.data.comment_date;
var content = d.type == "post" ? d.data.post_title : d.data.comment_content;
if(d.type == "post"){
var htmlString ='<div style="padding:5px;">';
htmlString += "<div>" + "Post Author : " + author + '</div>';
htmlString += "<div>" + "Post Date: " + date + '</div>';
htmlString += '<div>' + "Post Title : " + content + '</div>';
htmlString += "</div>";
return htmlString;
}
if(d.type == "comment"){
var htmlString = '<div style="padding:5px;">';
htmlString += "<div>" + "Comment Author : " + author + '</div>';
htmlString += "<div>" + "Comment Date: " + date + '</div>';
htmlString += '<div class="comment-wrap">' + "Comment : " + content + '</div>';
htmlString += "</div>";
return htmlString;
}
if(d.type == "category"){
return '<div style="padding:5px;">' + "Category Name : " + d.data + '</div>';
}
})
this.svg.call(this.tip);
//Initialize Force Layout
this.force = d3.layout.force()
.nodes(this.nodes)
.links(this.links)
.gravity(0.5)
.charge(-240)
.linkDistance(function(d){
return d.type == 0 ? 50 : 5;
})
.size([this.width, this.height]);
this.fnode = this.force.nodes();
this.flink = this.force.links();
//Start force layout display
update(this);
}
function update(obj) {
//Setup Links
var link = obj.linkg.selectAll(".link")
.data(obj.links,function(d){
return d.key ;
});
link.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) {
return d.type == 0 ? "0.5" : "0.25" ;
})
.style("stroke", function(d) {
return d.type == 0 ? "blue" : "orange" ;
});
link.exit().remove();
//Setup Nodes
var node = obj.nodeg.selectAll(".node")
.data(obj.nodes,function(d){
if(d.type == "post"){
return "post-"+d.data.pid;
} else if (d.type == "comment"){
return "comment-"+d.data.comment_id;
} else if (d.type == "category"){
return "category-"+d.data;
}
});
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.each(function(d,i){
// Clone and append xml node to each data binded element.
if(d.type == "post"){
this.appendChild(obj.postSVG.cloneNode(true));
d3.select(this).select('svg').attr("x", -10)
.attr("y", -300)
.attr("width", function(d){
return obj.linearScale(d.data.post_count + 1);
})
} else if(d.type == "comment"){
this.appendChild(obj.commentSVG.cloneNode(true));
d3.select(this).select('svg').attr("x", -5)
.attr("y", -300)
.attr("width", function(d){
return 10;
})
}
})
.call(obj.force.drag)
.on('mouseover', obj.tip.show)
.on('mouseout', obj.tip.hide);
node.exit().remove();
colorize(node,-1);
//Setup the tick function
obj.force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});
//Start Force Layout simulation
obj.force.start();
}
//PHP PubNub Object Initialization
$pubnub = new Pubnub($pubnub_pub_key, $pubnub_subs_key);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment