xxxxxxxxxx
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<title>Sketchy HILT Tweets Burshable by Centrality</title>
<meta charset="utf-8" />
<link type="text/css" rel="stylesheet" href="gexfd3.css" />
<link href='https://fonts.googleapis.com/css?family=Indie+Flower' rel='stylesheet' type='text/css'>
</head>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/colorbrewer.v1.min.js"></script>
<script src="d3.sketchy.js"></script>
<script src="parser.js" type="text/javascript">
</script>
<script src="gexfd3.js" type="text/javascript">
</script>
<body onload="loadGraph('tweets.gexf')">
<div id="vizcontainer" style="width:100%;height:100%">
<canvas style="background: white;1000px;width:1000px;position:absolute;z-index:-1;" height=1000 width=1000></canvas>
<svg id="graphSVG" style="border:1px lightgray solid;">
<g id="graphG" />
<div id="modal"><div id="content"></div><button id="modalClose" onclick="nodeFocus=false;nodeOut();d3.select('#modal').style('display','none');">X</button></div>
</div>
<div id="controls">
</div>
<div id="brushDiv" style="background: rgba(255,255,255,0.85);opacity: .95;">
<div id="brushTitle" style="color:black;font-weight: 900;position: absolute;left:150px;top:24px;font-size: 26px;opacity: .75;z-index: 0;">More Central</div>
<div id="brushTitle" style="color:black;font-weight: 900;position: absolute;right:100px;top:24px;font-size: 26px;opacity: .75;z-index: 0;">Less Central</div>
<div style="position:absolute;width:100%;"><svg style="width:100%;height:80px;"><g id="brushG" class="brush" transform="translate(50,20)"></g></svg></div></div>
<footer>
<script>
nodeFocus = false;
currentBrush =[0,0];
docHash = {};
allLinks = [];
currentScale = 0;
function loadGraph(sourceGEXF) {
newGEXF = GexfParser.fetch(sourceGEXF);
gD3 = gexfD3().graph(newGEXF).size([1000,1000]).dynamicAttribute("centrality");
force = d3.layout.force()
.charge(-200)
.linkDistance(50)
.size([1000, 1000])
.gravity(.1)
.on("tick", redrawGraph)
d3.select("#brushG").call(gD3.dynamicBrush);
// d3.select("#brushG").selectAll("g.resize").append("circle").attr("r", 15).style("stroke", d3.sketchy.randomColor("black", .2)).style("fill", d3.sketchy.randomColor("white", .2)).attr("cy", 17)
d3.select("#brushG").select("rect.extent").style("fill-opacity", .5)
var randomWidth = d3.scale.linear().domain([0,1]).range([10,30]);
var e = randomWidth(Math.random());
console.log(e);
var sketchyCircle = d3.sketchy.circle();
sketchyCircle
.radius(20)
.cx(0)
.cy(17)
.fill(d3.sketchy.randomColor("white",.05))
.stroke("black")
.strokeWidth(e);
d3.select("#brushG").select("g.e").call(sketchyCircle);
var e = randomWidth(Math.random());
console.log(e);
var sketchyCircle2 = d3.sketchy.circle();
sketchyCircle2
.radius(20)
.cx(0)
.cy(17)
.fill(d3.sketchy.randomColor("white",.05))
.stroke("black")
.strokeWidth(e);
d3.select("#brushG").select("g.w").call(sketchyCircle2);
gD3.dynamicBrush().on("brush", brushMove);
zoom = d3.behavior.zoom()
.scaleExtent([.1, 10])
.on("zoom", zoomed);
allLinks = gD3.links();
for (x in allLinks) {
allLinks[x]["highlighted"] = false;
}
brushMove();
d3.select("svg").call(zoom);
createControls();
zoomed();
}
function highlightNeighbors(d,i) {
var nodeNeighbors = findNeighbors(d,i);
d3.selectAll("g.node").each(function(p) {
var isNeighbor = nodeNeighbors.nodes.indexOf(p);
d3.select(this).select("circle")
.style("opacity", isNeighbor > -1 ? 1 : .25)
.style("stroke-width", isNeighbor > -1 ? 3 : 1)
.style("stroke", isNeighbor > -1 ? d3.sketchy.randomColor("blue", .1) : d3.sketchy.randomColor("white", .1))
})
nodeNeighbors.links.forEach(function (link){
link.highlighted = true;
})
redrawGraph();
}
function findNeighbors(d,i) {
neighborArray = [d];
var linkArray = [];
filteredLinks.filter(function(p) {return p.source == d || p.target == d}).forEach(function(p) {
neighborArray.indexOf(p.source) == -1 ? neighborArray.push(p.source) : null;
neighborArray.indexOf(p.target) == -1 ? neighborArray.push(p.target) : null;
linkArray.push(p);
})
return {nodes: neighborArray, links: linkArray};
}
function zoomed() {
force.stop();
var canvWidth = parseInt(d3.select("#vizcontainer").style("width"));
var canvHeight = parseInt(d3.select("#vizcontainer").style("height"));
var canvasTranslate = zoom.translate();
currentScale = zoom.scale();
var halfCanvas = canvHeight / 2;
var zoomLevel = halfCanvas * currentScale;
gD3.xScale().range([(halfCanvas - zoomLevel) + canvasTranslate[0], (halfCanvas + zoomLevel) + canvasTranslate[0]]);
gD3.yScale().range([(halfCanvas + zoomLevel) + canvasTranslate[1], (halfCanvas - zoomLevel) + canvasTranslate[1]]);
redrawGraph();
}
function createControls() {
d3.select("#controls").append("button").attr("class", "origButton topology").html("Force On").on("click", function() {
force.start();})
d3.select("#controls").append("button").attr("class", "origButton topology").html("Force Off").on("click", function() {
force.stop();})
d3.select("#controls").append("button").attr("class", "origButton topology").html("Reset Layout").on("click", function() {
force.stop();
gD3.nodes().forEach(function (el) {el.x = el.originalX;el.px = el.originalX;el.y = el.originalY;el.py = el.originalY;});
currentBrush = [0,0];
brushMove();
redrawGraph();
})
d3.select("#controls").append("button").attr("class", "origButton node-appearance").html("Reset Colors").on("click", function() {
var sizeScale = gD3.nodeScale();
d3.selectAll("circle")
.attr("r", function (d) {return sizeScale(d.size)})
.style("fill", function(d) {return d3.sketchy.randomColor(d.rgbColor,.05)})
.style("opacity", 1);
})
d3.select("#controls").selectAll("button.nodeButtons").data(gD3.nodeAttributes())
.enter()
.append("button")
.attr("class", "nodeButtons node-appearance")
.on("click", nodeButtonClick)
.html(function(d) {return d});
d3.select("#controls").selectAll("button.linkButtons").data(gD3.linkAttributes())
.enter()
.append("button")
.attr("class", "linkButtons node-appearance")
.on("click", linkButtonClick)
.html(function(d) {return d});
}
function nodeButtonClick(d,i) {
var nodeAttExtent = d3.extent(filteredNodes, function(p) {return parseFloat(p.properties[d])});
var colorScale = d3.scale.quantize().domain(nodeAttExtent).range(colorbrewer.YlGnBu[6]);
d3.selectAll("circle").style("fill", function(d) {return d3.sketchy.randomColor(colorScale(p.properties[d]),.05)}).style("opacity", 1)
}
function linkButtonClick(d,i) {
var linkAttExtent = d3.extent(filteredLinks, function(p) {return parseFloat(p.properties[d])});
var colorScale = d3.scale.quantize().domain(linkAttExtent).range(colorbrewer.YlGnBu[6]);
d3.selectAll("line").style("stroke", function(d) {return d3.sketchy.randomColor(colorScale(p.properties[d]),.05)}).style("opacity", 1)
}
function redrawGraph() {
var xScale = gD3.xScale();
var yScale = gD3.yScale();
var context = d3.select("canvas").node
var canvas = d3.select("canvas").node();
var context = canvas.getContext("2d");
context.clearRect (0,0,canvas.width,canvas.height);
context.lineWidth = 1;
context.strokeStyle = "rgba(0, 0, 0, 0.5)";
filteredLinks.forEach(function (link) {
context.beginPath();
context.moveTo(xScale(link.source.x),yScale(link.source.y))
context.lineTo(xScale(link.target.x),yScale(link.target.y))
context.stroke();
})
context.lineWidth = 2;
context.strokeStyle = "rgba(0, 255, 122, 0.75)";
filteredLinks.filter(function (d) {return d.highlighted}).forEach(function (link) {
context.beginPath();
context.moveTo(xScale(link.source.x),yScale(link.source.y))
context.lineTo(xScale(link.target.x),yScale(link.target.y))
context.stroke();
})
d3.selectAll("g.node")
.attr("transform", function(d) {return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")"});
}
function collapseNetwork(collapseVector) {
currentBrush = [0,0];
dAtt = gD3.dynamicAttribute();
if (collapseVector == "base") {
gD3.links(allLinks);
brushMove();
return;
}
newLinks = [];
for (x in allLinks) {
if (allLinks[x].source.properties.type == collapseVector) {
for (y in allLinks) {
if (allLinks[y].source.properties.type == collapseVector) {
if (allLinks[y].target == allLinks[x].target && (allLinks[y].properties[dAtt] || allLinks[y].source.properties[dAtt]) == (allLinks[x].properties[dAtt] || allLinks[x].source.properties[dAtt])) {
var newLink = {id: collapseVector + newLinks.length, source: allLinks[x].source, target: allLinks[y].source, properties: {}};
if (gD3.linkAttributes().indexOf(dAtt) > -1) {
newLink.properties[dAtt] = allLinks[x].properties[dAtt];
}
else if (gD3.nodeAttributes().indexOf(dAtt) > -1) {
newLink.properties[dAtt] = allLinks[y].target.properties[dAtt];
}
newLinks.push(newLink);
}
}
}
}
else if (allLinks[x].target.properties.type == collapseVector) {
for (y in allLinks) {
if (allLinks[y].target.properties.type == collapseVector) {
if (allLinks[y].source == allLinks[x].source && (allLinks[y].properties[dAtt] || allLinks[y].target.properties[dAtt]) == (allLinks[x].properties[dAtt] || allLinks[x].target.properties[dAtt])) {
var newLink = {id: collapseVector + newLinks.length, source: allLinks[x].target, target: allLinks[y].target, properties: {}};
if (gD3.linkAttributes().indexOf(dAtt) > -1) {
newLink.properties[dAtt] = allLinks[x].properties[dAtt];
}
else if (gD3.nodeAttributes().indexOf(dAtt) > -1) {
newLink.properties[dAtt] = allLinks[y].source.properties[dAtt];
}
newLinks.push(newLink);
}
}
}
}
}
console.log(newLinks)
gD3.links(newLinks);
brushMove();
redrawGraph();
}
function brushMove() {
var s = gD3.dynamicBrush().extent();
var dAtt = gD3.dynamicAttribute();
var xScale = gD3.xScale();
var yScale = gD3.yScale();
var sizeScale = gD3.nodeScale();
if (Math.ceil(s[0]) == currentBrush[0] && Math.floor(s[1]) == currentBrush[1]) {
return;
}
else {
currentBrush[0] = Math.floor(s[0]);
currentBrush[1] = Math.ceil(s[1]);
}
var forceRunning = false;
if (force.alpha() > 0) {
force.stop();
forceRunning = true;
}
if (typeof gD3.links()[0].properties["startyr"] != "undefined") {
filteredLinks = gD3.links().filter(function (d) {return d.properties[dAtt] == 0 || (d.properties[dAtt] >= currentBrush[0] && d.properties[dAtt] <= currentBrush[1])});
sourceNodes = filteredLinks.map(function (el) {return el.source});
targetNodes = filteredLinks.map(function (el) {return el.target});
filteredNodes = gD3.nodes().filter(function (d) {return sourceNodes.indexOf(d) > -1 || targetNodes.indexOf(d) > -1});
}
else {
filteredLinks = gD3.links();
filteredNodes = gD3.nodes();
}
if (gD3.nodeAttributes().indexOf(dAtt) > -1) {
filteredNodes = filteredNodes.filter(function (d) {return d.properties[dAtt] == 0 || (d.properties[dAtt] >= currentBrush[0] && d.properties[dAtt] <= currentBrush[1])});
nodeIDs = filteredNodes.map(function (el) {return el.id})
filteredLinks = filteredLinks.filter(function (d) {return nodeIDs.indexOf(d.source.id) > -1 && nodeIDs.indexOf(d.target.id) > -1})
}
d3.select("#graphG").selectAll("g.node").data(filteredNodes, function (d) {return d.id})
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) {return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")"})
.on("mouseover", nodeOver)
.on("mouseout", nodeOut)
.on("click", nodeClick)
.each(function(d) {
var randomWidth = d3.scale.linear().domain([0,1]).range([2,3]);
var e = randomWidth(Math.random());
var sketchyCircle = d3.sketchy.circle();
sketchyCircle
.radius(5)
.cx(0)
.cy(0)
.fill(d3.sketchy.randomColor(d.rgbColor,.05))
.stroke("black")
.strokeWidth(e);
d3.select(this).call(sketchyCircle)
})
d3.selectAll("g.node").data(filteredNodes, function (d) {return d.id})
.exit()
.remove();
force
.nodes(filteredNodes)
.links(filteredLinks);
force.start();
var maxWeight = d3.max(filteredNodes, function(d) {return d.weight || 0});
if (maxWeight > 0) {
var nodeScale = d3.scale.linear().domain([1,maxWeight]).range([2,10]).clamp(true);
d3.selectAll("g.node").each(function(d) {
d3.select(this).selectAll(".sketchy").remove();
var randomWidth = d3.scale.linear().domain([0,.25,1]).range([2,3,6]);
var e = randomWidth(Math.random());
var sketchyCircle = d3.sketchy.circle();
sketchyCircle
.radius(nodeScale(d.weight) || 0)
.cx(0)
.cy(0)
.fill(d3.sketchy.randomColor(d.rgbColor,.05))
.stroke("black")
.strokeWidth(e);
d3.select(this).call(sketchyCircle)
})
}
if (!forceRunning) {
force.stop();
}
function nodeOver(d,i,e) {
var el = this;
if (!d3.event.fromElement) {
el = e;
}
if (nodeFocus) {
return;
}
//Only do the element stuff if this came from mouseover
el.parentNode.appendChild(el);
d3.select(el).append("text").attr("class", "hoverLabel").attr("stroke", d3.sketchy.randomColor("white", .1)).attr("stroke-width", "5px")
.style("opacity", .9)
.style("pointer-events", "none")
.text(d.label);
d3.select(el).append("text").attr("class", "hoverLabel")
.style("pointer-events", "none")
.text(d.label);
highlightNeighbors(d,i);
}
function nodeClick(d,i) {
nodeFocus = false;
nodeOut();
nodeOver(d,i,this);
nodeFocus = true;
var newContent = "<p>" + d.label + "</p>";
newContent += "<p>Attributes: </p><p><ul>";
for (x in gD3.nodeAttributes()) {
newContent += "<li>" + gD3.nodeAttributes()[x] + ": " + d.properties[gD3.nodeAttributes()[x]]+ "</li>";
}
newContent += "</ul></p><p>Connections:</p><ul>";
var neighbors = findNeighbors(d,i);
for (x in neighbors.nodes) {
if (neighbors.nodes[x] != d) {
newContent += "<li>" + neighbors.nodes[x].label + "</li>";
}
}
newContent += "</ul></p>";
d3.select("#modal").style("display", "block").select("#content").html(newContent);
}
redrawGraph();
gnarlifyBar();
}
function createAnonymousEdgeTable() {
var htmlTable = "source,target,year<br>";
for (x in gD3.links()) {
htmlTable+=gD3.links()[x].source.properties.type + "-" + gD3.nodes().indexOf(gD3.links()[x].source) + "," + gD3.links()[x].target.properties.type + "-" + gD3.nodes().indexOf(gD3.links()[x].target) + "," + gD3.links()[x].properties.year;
htmlTable+="<br>";
}
d3.select("#content").html(htmlTable)
}
function nodeOut() {
if (nodeFocus) {
return;
}
d3.selectAll(".hoverLabel").remove();
d3.selectAll("circle").style("opacity", 1).style("stroke", d3.sketchy.randomColor("black", .1)).style("stroke-width", "1px");
filteredLinks.forEach(function (link) {link.highlighted = false});
redrawGraph();
}
function gnarlifyBar() {
d3.select("g.sketchy").remove();
var x = parseInt(d3.selectAll("#brushG").select("rect.extent").attr("x"));
var y = 0;
var rw = parseInt(d3.selectAll("#brushG").select("rect.extent").attr("width"));
var rh = parseInt(d3.selectAll("#brushG").select("rect.extent").attr("height"));
var sketchyBrush = d3.sketchy.rect();
sketchyBrush
.height(rh)
.width(rw)
.x(x)
.y(y)
.stroke("black")
.strokeWidth(10)
.jostle(5)
d3.select("#brushG > #fgBrush").insert("g", ".resize").attr("class", "sketchy").call(sketchyBrush);
d3.select("#brushG").select("rect.sketchy").remove();
d3.select("#brushG").select("path.sketchy").style("pointer-events","none");
d3.select("#brushG").select("rect.extent").style("fill", d3.sketchy.randomColor("pink",.075))
}
</script>
</footer>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/colorbrewer.v1.min.js to a secure url
https://d3js.org/d3.v3.min.js
https://d3js.org/colorbrewer.v1.min.js