Skip to content

Instantly share code, notes, and snippets.

@SkyLeach
Forked from mattgiguere/README.md
Last active October 10, 2017 02:31
Show Gist options
  • Save SkyLeach/7c3eb99384cbfd10ee0d6c0e1b7991a2 to your computer and use it in GitHub Desktop.
Save SkyLeach/7c3eb99384cbfd10ee0d6c0e1b7991a2 to your computer and use it in GitHub Desktop.
d3v4 JSON Tree

Modification of the d3 radial implementation

  • Moved api/impl from d3v3 to d3v4
  • Changed data type from csv to JSON
  • Place svg inside scrollable div/canvas
  • Add IDs to all text elements in order to hotlink to any/rootnode
  • Added example root node link
  • Modified root node link to add active centering.
  • Modified to add window frame drag and drop.
  • Added jquery for setting window width/height if we're in an iframe (like bl.ocks.org)

Planned changes/upcoming

  • Add :hover CSS (will probably break IE but... who cares right?)
  • Add overlay comment box on hover
<!DOCTYPE html>
<meta charset="utf-8">
<!-- Page Style -->
<style>
.node circle {
fill: #999;
}
.node text {
font: 10px sans-serif;
}
.node--internal circle {
fill: #555;
}
.node--internal text {
text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}
.link {
fill: none;
stroke: #555;
stroke-opacity: 0.4;
stroke-width: 1.5px;
}
.svgcanvas {
border:1px dotted #ccc;
background-color: #ccc;
}
.canvasdiv {
height: 800px;
width: 800px;
border:2px solid #000;
overflow: scroll;
}
/* Add style for draggable area*/
.grabbable {
cursor: move; /* fallback if grab cursor is unsupported */
cursor: grab;
cursor: -moz-grab;
cursor: -webkit-grab;
}
/* (Optional) Apply a "closed-hand" cursor during drag operation. */
.grabbable:active {
cursor: grabbing;
cursor: -moz-grabbing;
cursor: -webkit-grabbing;
}
</style>
<!-- end Page Style -->
<span><a href='' id='rootlink'>Jump To Root Node</a></span>
<div class="canvasdiv grabbable" id="canvasdiv">
<svg class="svgcanvas" width="2000" height="2000"></svg>
</div>
<script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
g = svg.append("g").attr("transform", "translate(" + (width / 2 + 40) + "," + (height / 2 + 90) + ")");
/*var tree = d3.cluster()
.size([height, width - 160]);*/
var tree = d3.tree()
//.size([2 * Math.PI, 500])
.size([4 * Math.PI, height])
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
var root_id; //set below
d3.json("treeData.json", function(error, treeData) {
if (error) throw error;
//grab the root id and set the href of the jump-to-root link
root_id = treeData.id;
var rootlink = document.getElementById('rootlink');
rootlink.setAttribute("href", '#nodetext_' + root_id);
rootlink.onclick = jump_to_node;
var root = d3.hierarchy(treeData);
tree(root);
var link = g.selectAll(".link")
.data(root.links())
.enter().append("path")
.attr("class", "link")
.attr("d", d3.linkRadial()
.angle(function(d) { return d.x; })
.radius(function(d) { return d.y; }));
var node = g.selectAll(".node")
.data(root.descendants())
.enter().append("g")
.attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); })
.attr("transform", function(d) { return "translate(" + radialPoint(d.x, d.y) + ")"; });
node.append("circle")
.attr("r", 2.5);
node.append("text")
.attr("dy", "0.31em")
.attr("x", function(d) { return d.x < Math.PI === !d.children ? 6 : -6; })
.attr("text-anchor", function(d) { return d.x < Math.PI === !d.children ? "start" : "end"; })
.attr("transform", function(d) { return "rotate(" + (d.x < Math.PI ? d.x - Math.PI / 2 : d.x + Math.PI / 2) * 180 / Math.PI + ")"; })
.text(function(d) {
return d.data.user;
}).attr('id',function(d){return 'nodetext_'+d.data.id;}); //add an idea to each nodetext for reference selection
});
function radialPoint(x, y) {
return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
}
//see if we can move to a specific link by id now (autoscroll)
function jump_to_node(node) {
/*********************************************************************************************
* In the case where this is being viewed in bl.ocks.org change the canvasdiv width/height to
* match the containing span, which can only yield width/heigh reliably using jquery.
*/
// find out if we are in an iframe. If so, set the canvasdiv width/height to the iframe width/height.
if(self !== top) {
$('#canvasdiv').width($(window).width()).height($(window).height());
}
cdiv = $('div#canvasdiv');
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
console.log({'svgwidth' : width, 'svgheight' : height, 'divwidth' : cdiv.width(), 'divheight' : cdiv.height() });
cdiv.scrollLeft((width/2)-(cdiv.width()/2));
cdiv.scrollTop((height/2)-(cdiv.height()/2));
}
// Canvas Window dragging
document.getElementById('canvasdiv').onmousedown = function() {
this.dragging = true;
return true;
};
document.getElementById('canvasdiv').onmouseup = function() {
this.dragging = false;
return true;
};
document.getElementById('canvasdiv').onmousemove = function(event) {
if(this.dragging) {
this.scrollLeft += (this.ppageX-event.pageX)*0.02;
this.scrollTop += (this.ppageY-event.pageY)*0.02;
} else {
this.ppageX = event.pageX;
this.ppageY = event.pageY;
}
return true;
};
//make sure the document is ready before auto-scrolling.
document.addEventListener("DOMContentLoaded", function(event) {
jump_to_node(root_id);
});
</script>

Totally Open Source and stuff..

You can copy and do whatever with this code. You don't even have to give me credit, although I wouldn't complain if you did. Keep the information free!

{
"children": [
{
"children": [
{
"children": [],
"id": "dnxkvuo",
"parent": "dnxcjdb",
"user": "u/Hornyandnervous"
},
{
"children": [
{
"children": [],
"id": "dnxk7eu",
"parent": "dnxgf9c",
"user": "u/Zergmilran"
}
],
"id": "dnxgf9c",
"parent": "dnxcjdb",
"user": "u/thehighground"
},
{
"children": [],
"id": "dnxd3tx",
"parent": "dnxcjdb",
"user": "u/Cell_Technician"
},
{
"children": [
{
"children": [
{
"children": [],
"id": "dnxfasy",
"parent": "dnxeut1",
"user": "u/mtdobb01"
}
],
"id": "dnxeut1",
"parent": "dnxdog7",
"user": "u/PM_ME_PSN__GIFTCARDS"
}
],
"id": "dnxdog7",
"parent": "dnxcjdb",
"user": "u/sandwich_breath"
}
],
"id": "dnxcjdb",
"parent": "74byia",
"user": "u/C477um04"
},
{
"children": [
{
"children": [
{
"children": [
{
"children": [],
"id": "dnxjaje",
"parent": "dnx5eey",
"user": "u/Secuter"
}
],
"id": "dnx5eey",
"parent": "dnx57p5",
"user": "u/HussellWilson"
},
{
"children": [],
"id": "dnx9vng",
"parent": "dnx57p5",
"user": "u/altaltaltpornaccount"
}
],
"id": "dnx57p5",
"parent": "dnx4w4t",
"user": "u/SlyOlAbe"
}
],
"id": "dnx4w4t",
"parent": "74byia",
"user": "u/HussellWilson"
},
{
"children": [],
"id": "dnxccjy",
"parent": "74byia",
"user": "u/ohnoablack2"
},
{
"children": [
{
"children": [
{
"children": [],
"id": "dnxl71k",
"parent": "dnxbke8",
"user": "u/gremlintot"
}
],
"id": "dnxbke8",
"parent": "dnx8vwp",
"user": "u/Bangersss"
},
{
"children": [],
"id": "dnxg3r7",
"parent": "dnx8vwp",
"user": "u/GubmentTeatSucker"
},
{
"children": [],
"id": "dnxbmlu",
"parent": "dnx8vwp",
"user": "u/OxfordWhiteS197"
},
{
"children": [
{
"children": [],
"id": "dnxl1qj",
"parent": "dnxap9r",
"user": "u/EggnogMarmoset"
}
],
"id": "dnxap9r",
"parent": "dnx8vwp",
"user": "u/Lars--Himself"
},
{
"children": [],
"id": "dnxbdw7",
"parent": "dnx8vwp",
"user": "u/Jaggle"
}
],
"id": "dnx8vwp",
"parent": "74byia",
"user": "u/MrKrabsNotEugene"
},
{
"children": [
{
"children": [
{
"children": [],
"id": "dnxavsm",
"parent": "dnx4sts",
"user": "u/ChefTeo"
},
{
"children": [
{
"children": [
{
"children": [],
"id": "dnx813r",
"parent": "dnx56g8",
"user": "u/Slovene"
},
{
"children": [],
"id": "dnx8obh",
"parent": "dnx56g8",
"user": "u/cicadaenthusiat"
},
{
"children": [],
"id": "dnxfcuh",
"parent": "dnx56g8",
"user": "u/delithug"
}
],
"id": "dnx56g8",
"parent": "dnx4vj8",
"user": "u/_Buff_Drinklots_"
}
],
"id": "dnx4vj8",
"parent": "dnx4sts",
"user": "u/internalhippy"
}
],
"id": "dnx4sts",
"parent": "dnx4qri",
"user": "u/FuzzyBlumpkinz"
},
{
"children": [],
"id": "dnxit9w",
"parent": "dnx4qri",
"user": "u/OldeHickory"
}
],
"id": "dnx4qri",
"parent": "74byia",
"user": "u/internalhippy"
},
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [],
"id": "dnxhkdq",
"parent": "dnxhjcb",
"user": "u/WeskerFare"
}
],
"id": "dnxhjcb",
"parent": "dnxh1zg",
"user": "u/DestructoRama"
}
],
"id": "dnxh1zg",
"parent": "dnxg9j1",
"user": "u/WeskerFare"
},
{
"children": [],
"id": "dnxi1kb",
"parent": "dnxg9j1",
"user": "u/QueefingGilf"
}
],
"id": "dnxg9j1",
"parent": "dnxd7pv",
"user": "u/DestructoRama"
},
{
"children": [],
"id": "dnxgv4l",
"parent": "dnxd7pv",
"user": "u/SlyOlAbe"
}
],
"id": "dnxd7pv",
"parent": "dnx3ur8",
"user": "u/QueefingGilf"
},
{
"children": [
{
"children": [
{
"children": [
{
"children": [],
"id": "dnxbqi3",
"parent": "dnx8956",
"user": "u/severed13"
},
{
"children": [],
"id": "dnx8rwk",
"parent": "dnx8956",
"user": "u/ollegnor"
},
{
"children": [],
"id": "dnxfwhq",
"parent": "dnx8956",
"user": "u/DestructoRama"
}
],
"id": "dnx8956",
"parent": "dnx5i9n",
"user": "u/somerandumguy"
},
{
"children": [],
"id": "dnx5lvg",
"parent": "dnx5i9n",
"user": "u/I_TOUCH_THE_BOOTY"
}
],
"id": "dnx5i9n",
"parent": "dnx4ilr",
"user": "u/ImaWatt"
},
{
"children": [],
"id": "dnxkn2n",
"parent": "dnx4ilr",
"user": "u/Parkerol888"
}
],
"id": "dnx4ilr",
"parent": "dnx3ur8",
"user": "u/Czar-Fox"
}
],
"id": "dnx3ur8",
"parent": "dnx3rii",
"user": "u/SlyOlAbe"
},
{
"children": [],
"id": "dnxk9xj",
"parent": "dnx3rii",
"user": "u/Zergmilran"
}
],
"id": "dnx3rii",
"parent": "dnx3kei",
"user": "u/beautifulcreature86"
},
{
"children": [],
"id": "dnxkgm4",
"parent": "dnx3kei",
"user": "u/pezman"
}
],
"id": "dnx3kei",
"parent": "dnx2yx3",
"user": "u/QueefingGilf"
}
],
"id": "dnx2yx3",
"parent": "dnx2xz6",
"user": "u/beautifulcreature86"
},
{
"children": [],
"id": "dnx5k6p",
"parent": "dnx2xz6",
"user": "u/briandoescode"
}
],
"id": "dnx2xz6",
"parent": "74byia",
"user": "u/Spambop"
},
{
"children": [],
"id": "dnx5sv0",
"parent": "74byia",
"user": "u/Webbythunder499"
},
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [],
"id": "dnxgm5t",
"parent": "dnxeqpd",
"user": "u/Fifouxxe"
}
],
"id": "dnxeqpd",
"parent": "dnx8hx1",
"user": "u/OliveBoobs"
},
{
"children": [
{
"children": [],
"id": "dnxdv5i",
"parent": "dnxdrkn",
"user": "u/Fifouxxe"
}
],
"id": "dnxdrkn",
"parent": "dnx8hx1",
"user": "u/Wheatspin"
}
],
"id": "dnx8hx1",
"parent": "dnx8a11",
"user": "u/Fifouxxe"
}
],
"id": "dnx8a11",
"parent": "dnx59zc",
"user": "u/HamburgerMachineGun"
}
],
"id": "dnx59zc",
"parent": "dnx327m",
"user": "u/Fifouxxe"
},
{
"children": [],
"id": "dnx7ozg",
"parent": "dnx327m",
"user": "u/BluNautilus"
},
{
"children": [
{
"children": [],
"id": "dnx4yct",
"parent": "dnx4vj5",
"user": "u/EBDBBNBBLT"
}
],
"id": "dnx4vj5",
"parent": "dnx327m",
"user": "u/EBDBBNBBLT"
}
],
"id": "dnx327m",
"parent": "74byia",
"user": "u/dhlock"
},
{
"children": [],
"id": "dnxhe54",
"parent": "74byia",
"user": "u/curiousguyhere985"
},
{
"children": [
{
"children": [
{
"children": [],
"id": "dnxivrh",
"parent": "dnxh7i5",
"user": "u/bossfoundmyacct"
}
],
"id": "dnxh7i5",
"parent": "dnx910h",
"user": "u/ckowkay"
},
{
"children": [],
"id": "dnxaj6x",
"parent": "dnx910h",
"user": "u/bored-nerd"
},
{
"children": [],
"id": "dnxcu5j",
"parent": "dnx910h",
"user": "u/PAM111"
},
{
"children": [
{
"children": [],
"id": "dnxg1r6",
"parent": "dnxapdq",
"user": "u/S3b45714N"
},
{
"children": [],
"id": "dnxkgrz",
"parent": "dnxapdq",
"user": "u/regnald"
}
],
"id": "dnxapdq",
"parent": "dnx910h",
"user": "u/Ol_willy"
},
{
"children": [],
"id": "dnxk11h",
"parent": "dnx910h",
"user": "u/Kryptosis"
},
{
"children": [],
"id": "dnxk7nw",
"parent": "dnx910h",
"user": "u/Elgelsker"
}
],
"id": "dnx910h",
"parent": "74byia",
"user": "u/Buy_Us_Fuck_You"
},
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [],
"id": "dnxhspu",
"parent": "dnx9rbc",
"user": "u/omen316"
}
],
"id": "dnx9rbc",
"parent": "dnx6a7t",
"user": "u/DeltaBravo831"
}
],
"id": "dnx6a7t",
"parent": "dnx5tm8",
"user": "u/ilkikuinthadik"
}
],
"id": "dnx5tm8",
"parent": "dnx5hk1",
"user": "u/dogfck"
},
{
"children": [],
"id": "dnx5wcq",
"parent": "dnx5hk1",
"user": "u/imabirdlawyer"
}
],
"id": "dnx5hk1",
"parent": "dnx472q",
"user": "u/kirkplunkett"
}
],
"id": "dnx472q",
"parent": "74byia",
"user": "u/mMounirM"
},
{
"children": [],
"id": "dnx56bp",
"parent": "74byia",
"user": "u/somerandumguy"
},
{
"children": [],
"id": "dnx4sos",
"parent": "74byia",
"user": "u/sleepslate"
},
{
"children": [
{
"children": [],
"id": "dnx7mzl",
"parent": "dnx57dh",
"user": "u/SourCreamWater"
}
],
"id": "dnx57dh",
"parent": "74byia",
"user": "u/5meterhammer"
},
{
"children": [],
"id": "dnx6tlg",
"parent": "74byia",
"user": "u/Xyeeyx"
},
{
"children": [],
"id": "dnx8bxi",
"parent": "74byia",
"user": "u/pottymouthgrl"
},
{
"children": [],
"id": "dnxbrlj",
"parent": "74byia",
"user": "u/severed13"
},
{
"children": [],
"id": "dnxc3i3",
"parent": "74byia",
"user": "u/a38c16c5293d690d686b"
},
{
"children": [
{
"children": [
{
"children": [
{
"children": [],
"id": "dnxhmxb",
"parent": "dnxhmw0",
"user": "u/GoodBot_BadBot"
}
],
"id": "dnxhmw0",
"parent": "dnxha8q",
"user": "u/finalellipsis"
}
],
"id": "dnxha8q",
"parent": "dnxh8wo",
"user": "u/stabbot"
}
],
"id": "dnxh8wo",
"parent": "74byia",
"user": "u/SumThinChewy"
},
{
"children": [],
"id": "dnxhv0y",
"parent": "74byia",
"user": "u/u-n-i-t-y"
},
{
"children": [],
"id": "dnxi8nu",
"parent": "74byia",
"user": "u/WilsonHeaviside"
},
{
"children": [],
"id": "dnxis2e",
"parent": "74byia",
"user": "u/TexasTwins"
},
{
"children": [],
"id": "dnxj0i2",
"parent": "74byia",
"user": "u/MAGAParty"
}
],
"id": "74byia",
"user": "u/beautifulcreature86"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment