D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
Pragyagarg
Full window
Github gist
colony5
Built with
blockbuilder.org
<!DOCTYPE html> <meta charset="utf-8"> <style> svg { border: solid 1px blue; } div { width: 1305px; } .node { cursor: pointer; } .node:hover { stroke: #3f3f3f; stroke-width: 4.5px; } .node--leaf { fill: #ffffff; } .label { font: 15px "Helvetica Neue", Helvetica, Arial, sans-serif; text-anchor: middle; text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff; } .label, .node--root, { pointer-events: none; } #graphic { background-color: #c9c9c9; } .node text { font: 12px sans-serif; } .node--internal text { text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff; } .link1 { fill: none; stroke: #ccc; stroke-width: 2px; } </style> <input type="text" id="myId" placeholder="Add mouseId…"> <input name="button" type="submit" value="View Hierarchy" onclick="search()"> <div></div> <script src="https://d3js.org/d3.v4.min.js"></script> <script> var svg1 = d3.select("div").append("svg") .attr("width", 300) .attr("height", 500); var svg2 = d3.select("div").append("svg") .attr('width',660) .attr('height',500), margin = 300, diameter = svg2.attr("width"), g2 = svg2.append("g").attr("transform", "translate(" + diameter / 2 + "," + ((diameter / 2) - 50) + ")"); var color = d3.scaleLinear() .domain([-1, 5]) .range(["hsl(204,81%,96%)", "hsl(228,30%,40%)"]) .interpolate(d3.interpolateHcl); var color1 = d3.scaleLinear() .domain([1, 2]) .range(["hsl(213,92%,63%)", "hsl(2,80%,74%)"]) .interpolate(d3.interpolateHcl); var tooltip = d3.select("body") .append("div") .style("position", "absolute") .style("visibility", "hidden") .style("color", "black") var focus,nodes,node,circle; d3.json("colony_result5.json", function(error, root) { if (error) throw error; // var tooltip = d3.select("body") // .append("div") // .style("position", "absolute") // .style("visibility", "hidden") // .style("color", "black") root = d3.hierarchy(root) .sum(function(d) { return d.size; }) .sort(function(a, b) { return b.value - a.value; }); var pack = d3.pack() .size([diameter, diameter]) .padding(10) focus = root, nodes = pack(root).descendants(); circle = g2.selectAll(".circle") .data(nodes) .enter().append("circle") .attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; }) .attr("id", function(d) { return "node-" + d.data.name}) .style("fill", function(d) { return d.children ? color(d.depth) : d.data.gender == 'M' ? color1(1) : color1(2); }) .on("click", function(d) { console.log("heya! d: " + d.data.name); var str = d.data.name.toString(); if(str.startsWith("Gen") == false) { searchId(d.data.name);} if (focus !== d) zoom(d), d3.event.stopPropagation(); }) .on("mouseover", function(d){return tooltip.text(d.data.name).style("visibility", "visible");}) .on("mousemove", function(d){return !d.children ? tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px") : tooltip.style("top", "100px").style("left","350px");}) .on("mouseout", function(){return tooltip.style("visibility", "hidden");}); node = g2.selectAll("circle"); svg2 .style("background", color(-1)) .on("click", function() { zoom(root); }); zoomTo([root.x, root.y, root.r * 2 + margin]); }); function zoom(d) { var focus0 = focus; focus = d; var transition = d3.transition() .duration(d3.event.altKey ? 7500 : 750) .tween("zoom", function(d) { var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]); return function(t) { zoomTo(i(t)); }; }); // transition.selectAll("text") // .filter(function(d) { return d.parent === focus || this.style.display === "inline"; }) // .style("fill-opacity", function(d) { return d.parent === focus ? 1 : 0; }) // .on("start", function(d) { if (d.parent === focus) this.style.display = "inline"; }) // .on("end", function(d) { if (d.parent !== focus) this.style.display = "none"; }); } function zoomTo(v) { var k = diameter / v[2]; view = v; node.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; }); circle.attr("r", function(d) { return d.r * k; }); } function search() { val = gen(1) console.log("in search(), gender is: " + val); id = document.getElementById("myId").value; console.log("id: " + id) searchId(id) } function gen(id) { console.log("in gen " + id); var val; d3.csv("colony5_updated.csv", function(data) { console.log("here"); val = data.filter(function(d) { return d.mouseId == id })[0].gender; console.log("val: " + val); }) console.log("data in gen: " + val); return val; } function searchId(id) { // if (focus.data.id !== "node-"+id) { // console.log("came in zoom,focus: " + focus.data.id) // var d = g2.selectAll("circle").filter(function(d) {return d.data.id == "node-"+id}) // console.log("d: " + d.data) // zoom(d), d3.event.stopPropagation(); // } svg1.selectAll("*").remove(); var g1 = svg1.append("g") .attr("transform", "translate(" + 20 + "," + 120 + ")"); d3.json("result5_parent_child.json", function(data) { var result = f1(data, id); var flatData = [ {"name": "13", "parent": null}, {"name": "1", "parent": "13" }, {"name": "2", "parent": "13" }, {"name": "3", "parent": "1" }, {"name": "4", "parent": "1" }, ]; // convert the flat data into a hierarchy var treeData = d3.stratify() .id(function(d) { return d.name; }) .parentId(function(d) { return d.parent; }) (result); // assign the name to each node treeData.each(function(d) { d.name = d.id; console.log("id: " + d.name); }); // set the dimensions and margins of the diagram var width = 150, height = 230; // declares a tree layout and assigns the size var treemap = d3.tree() .size([height, width]); // assigns the data to a hierarchy using parent-child relationships var nodes1 = d3.hierarchy(treeData, function(d) { return d.children; }); // maps the node data to the tree layout nodes1 = treemap(nodes1); // adds the links between the nodes var link1 = g1.selectAll(".link1") .data( nodes1.descendants().slice(1)) .enter().append("path") .attr("class", "link1") .attr("d", function(d) { return "M" + d.x + "," + (100-d.y) + "C" + d.x + "," + (100-(d.y + d.parent.y) / 2) + " " + d.parent.x + "," + (100-(d.y + d.parent.y) / 2) + " " + d.parent.x + "," + (100-d.parent.y); }); // adds each node as a group var node1 = g1.selectAll(".node1") .data(nodes1.descendants()) .enter().append("g") .attr("class", function(d) { return "node1" + (d.children ? " node--internal" : " node--leaf"); }) .attr("transform", function(d) { return "translate(" + d.x + "," + (100 - d.y) + ")"; }); // adds the circle to the node node1.append("circle") .attr("r", 10) .attr("stroke-width", 2) .style("stroke", "steelblue") .attr("fill", "white"); // adds the text to the node node1.append("text") .attr("dy", ".35em") .attr("x", function(d) { return d.children ? -13 : 13; }) .style("text-anchor", function(d) { return d.children ? "end" : "start"; }) .text(function(d) { return d.data.name; }) .style('fill', 'black'); }); findFamily1(id); } function findFamily1(id) { d3.csv("colony5_updated.csv", function(data) { var gender = findGender(data, id); console.log("gender of node: " + gender) var matesId = findFamily(data, id); console.log("mates are: " + matesId); var mates = svg1.selectAll("mates") .data(matesId) .enter().append("g") .attr("class", "mates"); mates.append("circle") .attr("r", 10) .attr("stroke-width", 2) .style("stroke", function(d) { return findGender(data,d) == 'M' ? color1(1) : color1(2); }) // .style("stroke", "steelblue") .attr("fill", "white") .attr("cx", 50) .attr("cy", function(d, i) {return(350 - (i*50));}) .on("click", function(d) { searchId(d);}); mates.append("text") .attr("dx", 25) .attr("dy", function(d, i) {return(350 - (i*50))+5;}) .text(function(d) { return d }); var i = 0,j = 0; matesId.forEach(function(mate){ var childrenId = findChildren(data,gender,id,mate); var children = svg1.selectAll("children") .data(childrenId) .enter().append("g") .attr("class", "children"); children.append("circle") .attr("r", 7) // .attr("stroke-width", 2) .style("fill", function(d) { return findGender(data, d) == 'M' ? color1(1) : color1(2); }) // .style("fill", "steelblue") .attr("cx", function(d, i) {return 80 + (i*20);}) .attr("cy",350 - (j*50)) .on("click", function(d) { searchId(d);}) .on("mouseover", function(d){return tooltip.text(d).style("visibility", "visible");}) .on("mousemove", function(d){return tooltip.style("top", (event.pageY-20)+"px").style("left",(event.pageX)+"px");;}) .on("mouseout", function(){return tooltip.style("visibility", "hidden");}); console.log("children of " + id + " and " + mate + " are: " + childrenId); j = j+1; }); }); } function findFamily(data, id) { // console.log("id: " + id); var mates = []; // console.log(data[0].motherId); var gender = findGender(data, id); var matesId = []; if(gender == "M") { mates = data.filter(function(d, i) { return d.fatherId == id }); Object.keys(mates).forEach(function(key){ if(matesId.indexOf(mates[key].motherId) < 0) { matesId.push(mates[key].motherId); } }); } else { mates = data.filter(function(d, i) { return d.motherId == id }); Object.keys(mates).forEach(function(key){ if(matesId.indexOf(mates[key].fatherId) < 0) { matesId.push(mates[key].fatherId); } }); } return matesId; } function findGender(data, id) { return data.filter(function(d) { return d.mouseId == id })[0].gender; } function findChildren(data, gender, id, mate) { var childrenId = []; var children = []; if(gender == "M") { // console.log("male") children = data.filter(function(d, i) { return d.fatherId == id && d.motherId == mate}); } else { children = data.filter(function(d, i) { return d.motherId == id && d.fatherId == mate}) } Object.keys(children).forEach(function(key){ childrenId.push(children[key].mouseId); }); return childrenId; } function f1(data, id) { var data1 = []; var list = []; list.push(id); while(list.length > 0) { Object.keys(data).forEach(function(key){ if(data[key]["parent"] == list[0]) { list.push(data[key]["name"]) data1.push(data[key]) } }); list.shift(); } data1.push( {"name": id, "parent": null}) console.log("data: " + data1) return data1; } </script>
https://d3js.org/d3.v4.min.js