D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
Pragyagarg
Full window
Github gist
final
Built with
blockbuilder.org
<!DOCTYPE html> <meta charset="utf-8"> <style> svg { border: solid 1px black; } 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: #424242; } .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; } .link { fill: none; stroke: #000; stroke-opacity: .2; } .link:hover { stroke-opacity: .5; } </style> <input type="text" id="myId" placeholder="Add mouseId…"> <input name="button" type="submit" value="View Hierarchy" onclick="search()"> <div></div> <div id = "genNo"></div> <script src="https://d3js.org/d3.v4.min.js"></script> <script src="sankey.js"></script> <script> var svg1 = d3.select("div").append("svg") .attr("width", 450) .attr("height", 750); var svg2 = d3.select("div").append("svg") .attr('width',750) .attr('height',750), margin = 300, diameter = svg2.attr("width"), g2 = svg2.append("g").attr("transform", "translate(" + (diameter / 2)+ "," + ((diameter / 2) - 50) + ")"); var svg3 = d3.select("div").append("svg") .attr("width", 1200) .attr("height", 300); 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; svg1.selectAll("*").remove(); svg2.selectAll("*").remove(); svg3.selectAll("*").remove(); var margin = 300, diameter = svg2.attr("width"), g2 = svg2.append("g").attr("transform", "translate(" + (diameter / 2)+ "," + ((diameter / 2) - 50) + ")"); d3.json("colony_result2.json", function(error, root) { if(error) { console.log("in error"); // svg1.selectAll("*").remove(); // svg2.selectAll("*").remove(); // svg3.selectAll("*").remove(); throw error; } 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) { searchId2(d.data.name);} if (focus !== d) zoom(d), d3.event.stopPropagation(); }) .on("mouseover", function(d){ if(!d.children) { 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") : printGen(d.data.name);}) .on("mouseout", function(){ removeGen(); 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 printGen(val) { document.getElementById("genNo").innerHTML = val; } function removeGen(val) { document.getElementById("genNo").innerHTML = ""; } 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)); }; }); } 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() { id = document.getElementById("myId").value; searchId2(id) } function searchId2(id) { svg3.selectAll("*").remove(); var sankey = d3.sankey() .nodeWidth(36) .nodePadding(40) .size([500, 200]); var path = sankey.link(); console.log(path); d3.queue() .defer(d3.csv, "colony2_updated.csv") .defer(d3.json, "result2_parent_child.json") .await(function(error,data10,data){ var graph = f2(data, id); console.log("result: " + graph); console.log("num of nodes: " + graph.nodes1.length); console.log("num of links: " + graph.links1.length); var graph1 = { "nodes1":[ {"name":"1"}, {"name":"2"}, {"name":"10"}, {"name":"11"}, {"name":"101"}, {"name":"102"}, {"name":"204"} ], "links1":[ {"source":"1","target":"10","value":1}, {"source":"1","target":"11","value":1}, {"source":"2","target":"10","value":1}, {"source":"2","target":"11","value":1}, {"source":"10","target":"101","value":1}, {"source":"10","target":"102","value":1}, {"source":"11","target":"101","value":1}, {"source":"11","target":"102","value":1}, {"source":"101","target":"204","value":1}, {"source":"102","target":"204","value":1} ]}; color = d3.scaleOrdinal(d3.schemeCategory20); console.log("here1") var nodeMap = {}; graph.nodes1.forEach(function(x) { nodeMap[x.name] = x; }); graph.links1 = graph.links1.map(function(x) { return { source: nodeMap[x.source], target: nodeMap[x.target], value: x.value }; }); console.log("here2") sankey .nodes(graph.nodes1) .links(graph.links1) .layout(32); console.log(sankey.nodes) console.log("here3") // add in the links var link = svg3.append("g").selectAll(".link") .data(graph.links1) .enter().append("path") .attr("class", "link") .attr("d", path) .style("stroke-width", function(d) { console.log("dy: " + d.dy) return Math.max(1, d.dy); }) .sort(function(a, b) { return b.dy - a.dy; }); console.log("here4") // add the link titles link.append("title") .text(function(d) { return d.source.name + " → " + d.target.name; }); console.log("link: " + link) console.log("here6") // add in the nodes var node3 = svg3.append("g").selectAll(".node3") .data(graph.nodes1) .enter().append("g") .attr("class", "node3") .attr("transform", function(d) { console.log("name: " + d.name) if(graph.links1.length == 0) { return "translate(0,0)"; } return "translate(" + d.x + "," + d.y + ")"; }) .call(d3.drag() .subject(function(d) { return d; }) .on("start", function() { this.parentNode.appendChild(this); }) .on("drag", dragmove)) .on("click", function(d) { console.log("onclick on: ") });; console.log("node3: " + node3) console.log("here7") // add the rectangles for the nodes node3.append("rect") .attr("height", function(d) { if(graph.links1.length == 0) { return 130; } return d.dy; }) .attr("width", sankey.nodeWidth()) .style("fill", function(d) { return findGender(data10, d.name) == 'M' ? color1(1) : color1(2); }) .style("stroke", function(d) { return d3.rgb(d.color).darker(1); }) .on("click", function(d) { console.log("onclick on: ") searchId2(d.name);}); console.log("here8") // add in the title for the nodes node3.append("text") .attr("x", -6) .attr("y", function(d) { if(graph.links1.length == 0) { return 65; } return d.dy / 2; }) .attr("dy", ".35em") .attr("text-anchor", "end") .attr("transform", null) .text(function(d) { console.log("name: " + d.name) return d.name; }) .filter(function(d) { return d.x < 700 / 2; }) .attr("x", 6 + sankey.nodeWidth()) .attr("text-anchor", "start"); console.log("here9") // the function for moving the nodes function dragmove(d) { d3.select(this) .attr("transform", "translate(" + d.x + "," + (d.y = Math.max( 0, Math.min(300 - d.dy, d3.event.y)) ) + ")"); sankey.relayout(); link.attr("d", path); } console.log("here10") findFamily2(id,data10); }); } function gen(id,data) { console.log("in gen " + id); var val; d3.csv("colony2_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 findFamily2(id, data) { // d3.csv("colony2_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 = svg3.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); }) .attr("fill", "white") .attr("cx", 750) .attr("cy", function(d, i) {return(150 - (i*50));}) .on("click", function(d) { searchId2(d);}); mates.append("text") .attr("dx", 715) .attr("dy", function(d, i) {return(150 - (i*50))+5;}) .text(function(d) { return d }); var i = 0,j = 0, k = 0; matesId.forEach(function(mate){ var childrenId = findChildren(data,gender,id,mate); console.log("female childre are: " + childrenId.childrenFemale) console.log("male childre are: " + childrenId.childrenMale) var children = svg3.selectAll("children") .data(childrenId.childrenFemale) .enter().append("g") .attr("class", "children"); children.append("circle") .attr("r", 7) .style("fill", function(d) { return findGender(data, d) == 'M' ? color1(1) : color1(2); }) .attr("cx", function(d, i) {return 780 + (i*20);}) .attr("cy",150 - (j*50)) .on("click", function(d) { searchId2(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");}); var children = svg3.selectAll("children") .data(childrenId.childrenMale) .enter().append("g") .attr("class", "children"); children.append("circle") .attr("r", 7) .style("fill", function(d) { return findGender(data, d) == 'M' ? color1(1) : color1(2); }) .attr("cx", function(d, i) {return 780 + (i*20);}) .attr("cy",150 - (j*50) + 20) .on("click", function(d) { searchId2(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");}); j = j+1; }); // }); } function findFamily(data, id) { var mates = []; var gender = findGender(data, id); var matesId = []; if(gender == "M") { mates = data.filter(function(d, i) { return d.fatherId == id }); console.log("mates are: " + mates); if(mates.length > 0) { Object.keys(mates).forEach(function(key){ console.log("mates are: " + mates); if(matesId.indexOf(mates[key].motherId) < 0) { matesId.push(mates[key].motherId); } }); } } else { mates = data.filter(function(d, i) { return d.motherId == id }); console.log("mates are: " + mates); if(mates.length > 0) { Object.keys(mates).forEach(function(key){ console.log("mates are: " + mates); 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 childrenMale = []; var childrenFemale = []; 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){ if(children[key].gender == 'M') { childrenMale.push(children[key].mouseId); } else if(children[key].gender == 'F') { childrenFemale.push(children[key].mouseId); } }); console.log("Inside children function, male children: " + childrenMale); console.log("Inside children function, female children: " + childrenFemale); return { childrenMale: childrenMale, childrenFemale: childrenFemale, }; } 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]) console.log("adding data: " + data[key]["name"] + "and parent" + data[key]["parent"]) } }); list.shift(); } data1.push( {"name": id, "parent": null}) return data1; } function f2(data, id) { console.log("1, id: " + id); var data1 = {}; var list = []; var uniqueIds = []; var uniqueLinks = []; var nodeList = []; var linkList = []; list.push(id); uniqueIds.push(id); while(list.length > 0) { Object.keys(data).forEach(function(key){ if(data[key]["parent"] == list[0]) { list.push(data[key]["name"]) var dataNode = {}; var dataLink = {}; if(!uniqueIds.includes(data[key]["name"])) { uniqueIds.push(data[key]["name"]) dataNode["name"] = data[key]["name"]; nodeList.push(dataNode); } var s = data[key]["name"] <= data[key]["parent"] ? data[key]["name"].concat(data[key]["parent"]) : data[key]["parent"].concat(data[key]["name"]); if(!uniqueLinks.includes(s)) { dataLink["source"] = data[key]["name"]; dataLink["target"] = data[key]["parent"]; dataLink["value"] = "1"; uniqueLinks.push(s); linkList.push(dataLink); // map.set(data[key]["name"],data[key]["parent"]) } console.log("datanode: " + dataNode["name"]); console.log("datalink: " + dataLink["source"] + ", " + dataLink["target"] + ", " + dataLink["value"]); } }); list.shift(); } nodeList.push( {"name": id}) data1 = Object.assign( { nodes1: nodeList }, { links1: linkList } ); console.log("nodeList: " + JSON.stringify(nodeList)); console.log("linkList: " + JSON.stringify(linkList)); console.log("data1: " + JSON.stringify(data1)); return data1; } </script>
https://d3js.org/d3.v4.min.js