Skip to content

Instantly share code, notes, and snippets.

@erszcz
Last active December 16, 2015 01:48
Show Gist options
  • Select an option

  • Save erszcz/5357308 to your computer and use it in GitHub Desktop.

Select an option

Save erszcz/5357308 to your computer and use it in GitHub Desktop.
Historic SNA
/*jslint vars:true*/
/*global d3, $*/
var arachne = (function () {
"use strict";
var arachne = {
version: "0.0.1",
d3version: d3.version
};
var ArachneView = function (json, size) {
this.width = size[0];
this.height = size[1];
this.json = json;
return this;
};
ArachneView.prototype.show = function (where) {
var color = d3.scale.category20(),
svg = d3.select(where).append("svg")
.attr("width", this.width)
.attr("height", this.height),
force = d3.layout.force()
.charge(-500)
.linkDistance(140)
.theta(0.9)
.alpha(0.9)
.size([this.width, this.height]);
this.svg = svg;
this.force = force;
d3.json(this.json, function (error, graph) {
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter()
.append("line")
.attr("class", "link")
.style("stroke-width", function (d) { return d.value / 5; });
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter()
.append("g")
.attr("class", "node")
.on("mouseover", function (d) {
d3.select(this).select("circle")
.style("fill", color(d.group));
})
.on("mouseout", function (d) {
d3.select(this).select("circle")
.style("fill", "#fff");
});
node.append("circle")
.attr("r", function (d) { return 4 + d.importance * 4; })
.style("stroke", function (d) { return color(d.group); })
.style("fill", "#fff")
.call(force.drag);
node.append("text")
.attr("text-anchor", "start")
.text(function (d) { return d.name; });
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.select("circle")
.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; });
node.select("text")
.attr("x", function (d) { return d.x + 5 + 3.5 * d.importance; })
.attr("y", function (d) { return d.y + 3.5 + 2 * d.importance; });
});
svg.selectAll(".node")
.transition()
.delay(0)
.duration(0)
.each("end", function (d) {
$(this).powerTip({
placement: "nw"
});
var desc = d.name + "<br/>" + d.born + " - " + d.died;
$(this).data('powertip', desc);
$('#cnt').text($('#cnt').text() + 1);
});
});
};
arachne.view = function (json, size) {
return new ArachneView(json, size);
};
return arachne;
}());
<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg {
background-color: #fafafa;
border: 1px solid #ddd;
}
.node circle {
stroke-width: 1.5px;
}
.node {
font: 10px sans-serif;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
.content {
width: 960px;
margin-left: auto;
margin-right: auto;
text-align: center;
}
</style>
<link href="jquery.powertip.css" rel="stylesheet" type="text/css" />
<body>
<div class="content">
<h1>Sieć społeczna postaci historycznych</h1>
<div id="main_view">
</div>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="jquery.powertip.min.js"></script>
<script src="arachne.js"></script>
<script type="text/javascript" charset="utf-8">
$(".tooltip").powerTip({placement: "ne"});
</script>
<script type="text/javascript" charset="utf-8">
var view = arachne.view("simple.json", [430, 400]);
view.show("#main_view");
</script>
</body>
/* PowerTip Plugin */
#powerTip {
cursor: default;
background-color: #333;
background-color: rgba(0, 0, 0, 0.8);
border-radius: 6px;
color: #fff;
display: none;
padding: 10px;
position: absolute;
white-space: nowrap;
z-index: 2147483647;
}
#powerTip:before {
content: "";
position: absolute;
}
#powerTip.n:before, #powerTip.s:before {
border-right: 5px solid transparent;
border-left: 5px solid transparent;
left: 50%;
margin-left: -5px;
}
#powerTip.e:before, #powerTip.w:before {
border-bottom: 5px solid transparent;
border-top: 5px solid transparent;
margin-top: -5px;
top: 50%;
}
#powerTip.n:before {
border-top: 10px solid #333;
border-top: 10px solid rgba(0, 0, 0, 0.8);
bottom: -10px;
}
#powerTip.e:before {
border-right: 10px solid #333;
border-right: 10px solid rgba(0, 0, 0, 0.8);
left: -10px;
}
#powerTip.s:before {
border-bottom: 10px solid #333;
border-bottom: 10px solid rgba(0, 0, 0, 0.8);
top: -10px;
}
#powerTip.w:before {
border-left: 10px solid #333;
border-left: 10px solid rgba(0, 0, 0, 0.8);
right: -10px;
}
#powerTip.ne:before, #powerTip.se:before {
border-right: 10px solid transparent;
border-left: 0;
left: 10px;
}
#powerTip.nw:before, #powerTip.sw:before {
border-left: 10px solid transparent;
border-right: 0;
right: 10px;
}
#powerTip.ne:before, #powerTip.nw:before {
border-top: 10px solid #333;
border-top: 10px solid rgba(0, 0, 0, 0.8);
bottom: -10px;
}
#powerTip.se:before, #powerTip.sw:before {
border-bottom: 10px solid #333;
border-bottom: 10px solid rgba(0, 0, 0, 0.8);
top: -10px;
}
#powerTip.nw-alt:before, #powerTip.ne-alt:before,
#powerTip.sw-alt:before, #powerTip.se-alt:before {
border-top: 10px solid #333;
border-top: 10px solid rgba(0, 0, 0, 0.8);
bottom: -10px;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
left: 10px;
}
#powerTip.ne-alt:before {
left: auto;
right: 10px;
}
#powerTip.sw-alt:before, #powerTip.se-alt:before {
border-top: none;
border-bottom: 10px solid #333;
border-bottom: 10px solid rgba(0, 0, 0, 0.8);
bottom: auto;
top: -10px;
}
#powerTip.se-alt:before {
left: auto;
right: 10px;
}
/*!
PowerTip - v1.2.0 - 2013-04-03
http://stevenbenner.github.com/jquery-powertip/
Copyright (c) 2013 Steven Benner (http://stevenbenner.com/).
Released under MIT license.
https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt
*/
(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){function t(){var t=this;t.top="auto",t.left="auto",t.right="auto",t.bottom="auto",t.set=function(o,n){e.isNumeric(n)&&(t[o]=Math.round(n))}}function o(e,t,o){function n(n,i){r(),e.data(v)||(n?(i&&e.data(m,!0),o.showTip(e)):(P.tipOpenImminent=!0,l=setTimeout(function(){l=null,s()},t.intentPollInterval)))}function i(n){r(),P.tipOpenImminent=!1,e.data(v)&&(e.data(m,!1),n?o.hideTip(e):(P.delayInProgress=!0,l=setTimeout(function(){l=null,o.hideTip(e),P.delayInProgress=!1},t.closeDelay)))}function s(){var i=Math.abs(P.previousX-P.currentX),s=Math.abs(P.previousY-P.currentY),r=i+s;t.intentSensitivity>r?o.showTip(e):(P.previousX=P.currentX,P.previousY=P.currentY,n())}function r(){l=clearTimeout(l),P.delayInProgress=!1}function a(){o.resetPosition(e)}var l=null;this.show=n,this.hide=i,this.cancel=r,this.resetPosition=a}function n(){function e(e,i,r,a,l){var p,c=i.split("-")[0],u=new t;switch(p=s(e)?n(e,c):o(e,c),i){case"n":u.set("left",p.left-r/2),u.set("bottom",P.windowHeight-p.top+l);break;case"e":u.set("left",p.left+l),u.set("top",p.top-a/2);break;case"s":u.set("left",p.left-r/2),u.set("top",p.top+l);break;case"w":u.set("top",p.top-a/2),u.set("right",P.windowWidth-p.left+l);break;case"nw":u.set("bottom",P.windowHeight-p.top+l),u.set("right",P.windowWidth-p.left-20);break;case"nw-alt":u.set("left",p.left),u.set("bottom",P.windowHeight-p.top+l);break;case"ne":u.set("left",p.left-20),u.set("bottom",P.windowHeight-p.top+l);break;case"ne-alt":u.set("bottom",P.windowHeight-p.top+l),u.set("right",P.windowWidth-p.left);break;case"sw":u.set("top",p.top+l),u.set("right",P.windowWidth-p.left-20);break;case"sw-alt":u.set("left",p.left),u.set("top",p.top+l);break;case"se":u.set("left",p.left-20),u.set("top",p.top+l);break;case"se-alt":u.set("top",p.top+l),u.set("right",P.windowWidth-p.left)}return u}function o(e,t){var o,n,i=e.offset(),s=e.outerWidth(),r=e.outerHeight();switch(t){case"n":o=i.left+s/2,n=i.top;break;case"e":o=i.left+s,n=i.top+r/2;break;case"s":o=i.left+s/2,n=i.top+r;break;case"w":o=i.left,n=i.top+r/2;break;case"nw":o=i.left,n=i.top;break;case"ne":o=i.left+s,n=i.top;break;case"sw":o=i.left,n=i.top+r;break;case"se":o=i.left+s,n=i.top+r}return{top:n,left:o}}function n(e,t){function o(){d.push(p.matrixTransform(u))}var n,i,s,r,a=e.closest("svg")[0],l=e[0],p=a.createSVGPoint(),c=l.getBBox(),u=l.getScreenCTM(),f=c.width/2,w=c.height/2,d=[],h=["nw","n","ne","e","se","s","sw","w"];if(p.x=c.x,p.y=c.y,o(),p.x+=f,o(),p.x+=f,o(),p.y+=w,o(),p.y+=w,o(),p.x-=f,o(),p.x-=f,o(),p.y-=w,o(),d[0].y!==d[1].y||d[0].x!==d[7].x)for(i=Math.atan2(u.b,u.a)*O,s=Math.ceil((i%360-22.5)/45),1>s&&(s+=8);s--;)h.push(h.shift());for(r=0;d.length>r;r++)if(h[r]===t){n=d[r];break}return{top:n.y+P.scrollTop,left:n.x+P.scrollLeft}}this.compute=e}function i(o){function i(e){e.data(v,!0),O.queue(function(t){s(e),t()})}function s(e){var t;if(e.data(v)){if(P.isTipOpen)return P.isClosing||r(P.activeHover),O.delay(100).queue(function(t){s(e),t()}),void 0;e.trigger("powerTipPreRender"),t=p(e),t&&(O.empty().append(t),e.trigger("powerTipRender"),P.activeHover=e,P.isTipOpen=!0,O.data(g,o.mouseOnToPopup),o.followMouse?a():(b(e),P.isFixedTipOpen=!0),O.fadeIn(o.fadeInTime,function(){P.desyncTimeout||(P.desyncTimeout=setInterval(H,500)),e.trigger("powerTipOpen")}))}}function r(e){P.isClosing=!0,P.activeHover=null,P.isTipOpen=!1,P.desyncTimeout=clearInterval(P.desyncTimeout),e.data(v,!1),e.data(m,!1),O.fadeOut(o.fadeOutTime,function(){var n=new t;P.isClosing=!1,P.isFixedTipOpen=!1,O.removeClass(),n.set("top",P.currentY+o.offset),n.set("left",P.currentX+o.offset),O.css(n),e.trigger("powerTipClose")})}function a(){if(!P.isFixedTipOpen&&(P.isTipOpen||P.tipOpenImminent&&O.data(T))){var e,n,i=O.outerWidth(),s=O.outerHeight(),r=new t;r.set("top",P.currentY+o.offset),r.set("left",P.currentX+o.offset),e=c(r,i,s),e!==I.none&&(n=u(e),1===n?e===I.right?r.set("left",P.windowWidth-i):e===I.bottom&&r.set("top",P.scrollTop+P.windowHeight-s):(r.set("left",P.currentX-i-o.offset),r.set("top",P.currentY-s-o.offset))),O.css(r)}}function b(t){var n,i;o.smartPlacement?(n=e.fn.powerTip.smartPlacementLists[o.placement],e.each(n,function(e,o){var n=c(y(t,o),O.outerWidth(),O.outerHeight());return i=o,n===I.none?!1:void 0})):(y(t,o.placement),i=o.placement),O.addClass(i)}function y(e,n){var i,s,r=0,a=new t;a.set("top",0),a.set("left",0),O.css(a);do i=O.outerWidth(),s=O.outerHeight(),a=k.compute(e,n,i,s,o.offset),O.css(a);while(5>=++r&&(i!==O.outerWidth()||s!==O.outerHeight()));return a}function H(){var e=!1;!P.isTipOpen||P.isClosing||P.delayInProgress||(P.activeHover.data(v)===!1||P.activeHover.is(":disabled")?e=!0:l(P.activeHover)||P.activeHover.is(":focus")||P.activeHover.data(m)||(O.data(g)?l(O)||(e=!0):e=!0),e&&r(P.activeHover))}var k=new n,O=e("#"+o.popupId);0===O.length&&(O=e("<div/>",{id:o.popupId}),0===d.length&&(d=e("body")),d.append(O)),o.followMouse&&(O.data(T)||(f.on("mousemove",a),w.on("scroll",a),O.data(T,!0))),o.mouseOnToPopup&&O.on({mouseenter:function(){O.data(g)&&P.activeHover&&P.activeHover.data(h).cancel()},mouseleave:function(){P.activeHover&&P.activeHover.data(h).hide()}}),this.showTip=i,this.hideTip=r,this.resetPosition=b}function s(e){return window.SVGElement&&e[0]instanceof SVGElement}function r(){P.mouseTrackingActive||(P.mouseTrackingActive=!0,e(function(){P.scrollLeft=w.scrollLeft(),P.scrollTop=w.scrollTop(),P.windowWidth=w.width(),P.windowHeight=w.height()}),f.on("mousemove",a),w.on({resize:function(){P.windowWidth=w.width(),P.windowHeight=w.height()},scroll:function(){var e=w.scrollLeft(),t=w.scrollTop();e!==P.scrollLeft&&(P.currentX+=e-P.scrollLeft,P.scrollLeft=e),t!==P.scrollTop&&(P.currentY+=t-P.scrollTop,P.scrollTop=t)}}))}function a(e){P.currentX=e.pageX,P.currentY=e.pageY}function l(e){var t=e.offset(),o=e[0].getBoundingClientRect(),n=o.right-o.left,i=o.bottom-o.top;return P.currentX>=t.left&&P.currentX<=t.left+n&&P.currentY>=t.top&&P.currentY<=t.top+i}function p(t){var o,n,i=t.data(y),s=t.data(H),r=t.data(k);return i?(e.isFunction(i)&&(i=i.call(t[0])),n=i):s?(e.isFunction(s)&&(s=s.call(t[0])),s.length>0&&(n=s.clone(!0,!0))):r&&(o=e("#"+r),o.length>0&&(n=o.html())),n}function c(e,t,o){var n=P.scrollTop,i=P.scrollLeft,s=n+P.windowHeight,r=i+P.windowWidth,a=I.none;return(n>e.top||n>Math.abs(e.bottom-P.windowHeight)-o)&&(a|=I.top),(e.top+o>s||Math.abs(e.bottom-P.windowHeight)>s)&&(a|=I.bottom),(i>e.left||e.right+t>r)&&(a|=I.left),(e.left+t>r||i>e.right)&&(a|=I.right),a}function u(e){for(var t=0;e;)e&=e-1,t++;return t}var f=e(document),w=e(window),d=e("body"),h="displayController",v="hasActiveHover",m="forcedOpen",T="hasMouseMove",g="mouseOnToPopup",b="originalTitle",y="powertip",H="powertipjq",k="powertiptarget",O=180/Math.PI,P={isTipOpen:!1,isFixedTipOpen:!1,isClosing:!1,tipOpenImminent:!1,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,mouseTrackingActive:!1,delayInProgress:!1,windowWidth:0,windowHeight:0,scrollTop:0,scrollLeft:0},I={none:0,top:1,bottom:2,left:4,right:8};e.fn.powerTip=function(t,n){if(!this.length)return this;if("string"===e.type(t)&&e.powerTip[t])return e.powerTip[t].call(this,this,n);var s=e.extend({},e.fn.powerTip.defaults,t),a=new i(s);return r(),this.each(function(){var t,n=e(this),i=n.data(y),r=n.data(H),l=n.data(k);n.data(h)&&e.powerTip.destroy(n),t=n.attr("title"),i||l||r||!t||(n.data(y,t),n.data(b,t),n.removeAttr("title")),n.data(h,new o(n,s,a))}),s.manual||this.on({"mouseenter.powertip":function(t){e.powerTip.show(this,t)},"mouseleave.powertip":function(){e.powerTip.hide(this)},"focus.powertip":function(){e.powerTip.show(this)},"blur.powertip":function(){e.powerTip.hide(this,!0)},"keydown.powertip":function(t){27===t.keyCode&&e.powerTip.hide(this,!0)}}),this},e.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:!1,popupId:"powerTip",intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:!1,offset:10,mouseOnToPopup:!1,manual:!1},e.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]},e.powerTip={show:function(t,o){return o?(a(o),P.previousX=o.pageX,P.previousY=o.pageY,e(t).data(h).show()):e(t).first().data(h).show(!0,!0),t},reposition:function(t){return e(t).first().data(h).resetPosition(),t},hide:function(t,o){return t?e(t).first().data(h).hide(o):P.activeHover&&P.activeHover.data(h).hide(!0),t},destroy:function(t){return e(t).off(".powertip").each(function(){var t=e(this),o=[b,h,v,m];t.data(b)&&(t.attr("title",t.data(b)),o.push(y)),t.removeData(o)}),t}},e.powerTip.showTip=e.powerTip.show,e.powerTip.closeTip=e.powerTip.hide});
{
"nodes": [
{"name": "Aleksander Macedoński",
"group": 1,
"importance": 0.7,
"born": "356 p.n.e.",
"died": "323 p.n.e."},
{"name": "Dariusz III Kodoman",
"group": 2,
"importance": 0.5,
"born": "ok. 380 p.n.e.",
"died": "ok. 330 p.n.e."},
{"name": "Bucefał",
"group": 1,
"importance": 0.1,
"born": "brak danych",
"died": "326 p.n.e"},
{"name": "Pauzaniasz z Orestis",
"group": 3,
"importance": 0.4,
"born": "brak danych",
"died": "336 p.n.e"}
],
"links": [
{"source":1, "target":0, "value": 7},
{"source":2, "target":0, "value": 7},
{"source":3, "target":1, "value": 4},
{"source":3, "target":0, "value": 4}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment