Last active
August 8, 2017 18:55
-
-
Save fallenartist/f3438a9d17e481199e04c8e7d431dbd1 to your computer and use it in GitHub Desktop.
D3 v4 Zoomable Treemap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| *, *:before, *:after { | |
| box-sizing: border-box; | |
| } | |
| html, body { | |
| width: 100%; | |
| height: 100%; | |
| margin: 0; | |
| } | |
| .feature { | |
| position: relative; | |
| width: calc(100% - 50px); | |
| height: calc(100% - 50px); | |
| margin: 25px; | |
| background: #aaa; | |
| border: 1px solid red; | |
| } | |
| .node { | |
| position: absolute; | |
| background: transparent url("") no-repeat 50%/cover; | |
| border: 1px white solid; | |
| overflow: hidden; | |
| opacity: 0.5; | |
| -webkit-transition: opacity .8s; | |
| transition: opacity .8s; | |
| } | |
| .node .label { | |
| display: inline; | |
| font-family: sans-serif; | |
| color: rgba(255, 255, 255, 0.8); | |
| white-space: nowrap; | |
| position: absolute; | |
| padding: 0; | |
| margin: 0; | |
| top: 50%; | |
| left: 50%; | |
| -webkit-transform: translateX(-50%) translateY(-50%); | |
| transform: translateX(-50%) translateY(-50%); | |
| -webkit-transition: -webkit-filter .8s; | |
| transition: -webkit-filter .8s; | |
| transition: filter .8s; | |
| transition: filter .8s, -webkit-filter .8s; | |
| } | |
| .node:hover { | |
| opacity: 0; | |
| } | |
| .node:hover .label { | |
| -webkit-filter: blur(10px); | |
| filter: blur(10px); | |
| } | |
| .node.level-0 { | |
| z-index: 4; | |
| font-size: 15vmin; | |
| display: none; | |
| } | |
| .node.level-1 { | |
| z-index: 3; | |
| font-size: 10vmin; | |
| } | |
| .node.level-2 { | |
| z-index: 2; | |
| font-size: 5vmin; | |
| } | |
| .node.level-3 { | |
| z-index: 1; | |
| font-size: 2.5vmin; | |
| } | |
| </style> | |
| <body> | |
| <div class="feature" id="chart"></div> | |
| <script src="//d3js.org/d3.v4.min.js"></script> | |
| <script> | |
| var width = 100, // % of the parent element | |
| height = 100, | |
| x = d3.scaleLinear().domain([0, width]).range([0, width]), | |
| y = d3.scaleLinear().domain([0, width]).range([0, height]), | |
| node, | |
| root, | |
| imgUrl = "", | |
| blue = d3.hsl(216, 0.92, 0.68), | |
| color = d3.scaleOrdinal() | |
| .range([ | |
| d3.rgb(blue).brighter([0.25]), | |
| d3.rgb(blue), | |
| d3.rgb(blue).darker([0.25]) | |
| ] | |
| .map(function(c) { | |
| c = d3.rgb(c); | |
| return c; | |
| })), | |
| treemap = d3.treemap() | |
| .size([width, height]) | |
| .paddingInner(0) | |
| .round(true); | |
| var processData = { | |
| "name": "Process", | |
| "children": [ | |
| { | |
| "name": "Design", | |
| "children": [ | |
| { | |
| "name": "CGI", | |
| "children": [ | |
| { "name": "Photo 1", "value": "cgi-1.jpg" }, | |
| { "name": "Photo 2", "value": "cgi-2.jpg" }, | |
| { "name": "Photo 3", "value": "cgi-3.jpg" } | |
| ] | |
| }, | |
| { | |
| "name": "Photography", | |
| "children": [ | |
| { "name": "Photo 1", "value": "photo-1.jpg" }, | |
| { "name": "Photo 2", "value": "photo-2.jpg" }, | |
| { "name": "Photo 3", "value": "photo-3.jpg" }, | |
| { "name": "Photo 4", "value": "photo-4.jpg" }, | |
| { "name": "Photo 5", "value": "photo-5.jpg" } | |
| ] | |
| }, | |
| { | |
| "name": "EPCs", | |
| "children": [ | |
| { "name": "Photo 1", "value": "epc-1.jpg" }, | |
| { "name": "Photo 2", "value": "epc-2.jpg" }, | |
| { "name": "Photo 3", "value": "epc-3.jpg" } | |
| ] | |
| }, | |
| { | |
| "name": "Floor Plans", | |
| "children": [ | |
| { "name": "Photo 1", "value": "floorplan-1.jpg" }, | |
| { "name": "Photo 3", "value": "floorplan-2.jpg" } | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "Print", | |
| "children": [ | |
| { | |
| "name": "Litho", | |
| "children": [ | |
| { "name": "Photo 1", "value": "litho-1.jpg" }, | |
| { "name": "Photo 2", "value": "litho-2.jpg" }, | |
| { "name": "Photo 3", "value": "litho-3.jpg" }, | |
| { "name": "Photo 4", "value": "litho-4.jpg" }, | |
| { "name": "Photo 5", "value": "litho-5.jpg" }, | |
| { "name": "Photo 6", "value": "litho-6.jpg" } | |
| ] | |
| }, | |
| { | |
| "name": "Digital", | |
| "children": [ | |
| { "name": "Photo 1", "value": "digital-1.jpg" }, | |
| { "name": "Photo 2", "value": "digital-2.jpg" }, | |
| { "name": "Photo 3", "value": "digital-3.jpg" }, | |
| { "name": "Photo 4", "value": "digital-4.jpg" } | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "name": "Finish", | |
| "children": [ | |
| { | |
| "name": "Folding", | |
| "children": [ | |
| { "name": "Photo 1", "value": "folding-1.jpg" }, | |
| { "name": "Photo 2", "value": "folding-2.jpg" }, | |
| { "name": "Photo 3", "value": "folding-3.jpg" } | |
| ] | |
| }, | |
| { | |
| "name": "Stitched", | |
| "children": [ | |
| { "name": "Photo 1", "value": "stitched-1.jpg" }, | |
| { "name": "Photo 2", "value": "stitched-2.jpg" }, | |
| { "name": "Photo 3", "value": "stitched-3.jpg" }, | |
| { "name": "Photo 4", "value": "stitched-4.jpg" }, | |
| { "name": "Photo 5", "value": "stitched-5.jpg" } | |
| ] | |
| }, | |
| { | |
| "name": "Sewn", | |
| "children": [ | |
| { "name": "Photo 1", "value": "sewn-1.jpg" }, | |
| { "name": "Photo 2", "value": "sewn-2.jpg" }, | |
| { "name": "Photo 3", "value": "sewn-3.jpg" } | |
| ] | |
| }, | |
| { | |
| "name": "Softback", | |
| "children": [ | |
| { "name": "Photo 1", "value": "softback-1.jpg" }, | |
| { "name": "Photo 3", "value": "softback-2.jpg" } | |
| ] | |
| }, | |
| { | |
| "name": "Hardback", | |
| "children": [ | |
| { "name": "Photo 1", "value": "hardback-1.jpg" }, | |
| { "name": "Photo 2", "value": "hardback-2.jpg" }, | |
| { "name": "Photo 3", "value": "hardback-3.jpg" }, | |
| { "name": "Photo 4", "value": "hardback-4.jpg" } | |
| ] | |
| } | |
| ] | |
| } | |
| ] | |
| }; | |
| node = root = processData; //? | |
| var nodes = d3.hierarchy(root) | |
| .sum(function(d) { return d.value ? 1 : 0; }); | |
| treemap(nodes); | |
| var chart = d3.select("#chart"); | |
| var cell = chart | |
| .selectAll(".node") | |
| .data(nodes.descendants()) | |
| .enter().append("div") | |
| .attr("class", function(d) { return "node level-" + d.depth; }) | |
| .attr("title", function(d) { return d.data.name ? d.data.name : "null"; }) | |
| .style("left", function(d) { return x(d.x0) + "%"; }) | |
| .style("top", function(d) { return y(d.y0) + "%"; }) | |
| .style("width", function(d) { return x(d.x1 - d.x0) + "%"; }) | |
| .style("height", function(d) { return y(d.y1 - d.y0) + "%"; }) | |
| //.style("background-image", function(d) { return d.value ? imgUrl + d.value : ""; }) | |
| .style("background-color", function(d) { while (d.depth > 1) d = d.parent; return color(d.data.name); }) | |
| .on("mousedown touchstart", function(d) { | |
| zoom(d); | |
| //zoom(node == d.parent ? root : d.parent); | |
| //zoom(d.children !== null ? d : root); | |
| }) | |
| .append("p") | |
| .attr("class", "label") | |
| .text(function(d) { return d.data.name ? d.data.name : "null"; }); | |
| function zoom(d) { // http://jsfiddle.net/ramnathv/amszcymq/ | |
| console.log('clicked: ' + d.data.name + ', depth: ' + d.depth); | |
| console.log('cell x0: ' + d.x0 + ', y0: ' + d.y0 + ', x1: ' + d.x1 + ', y1: ' + d.y1); | |
| x.domain([d.x0, d.x1]); | |
| y.domain([d.y0, d.y1]); | |
| var t = d3.transition() | |
| .duration(800) | |
| .ease(d3.easeCubicOut); | |
| chart | |
| .merge(cell) | |
| .transition(t) | |
| .style("left", function(d) { return x(d.x0) + "%"; }) | |
| .style("top", function(d) { return y(d.y0) + "%"; }) | |
| .style("width", function(d) { return x(d.x1 - d.x0) + "%"; }) | |
| .style("height", function(d) { return y(d.y1 - d.y0) + "%"; }); | |
| //node = d; | |
| //d3.event.stopPropagation(); | |
| } | |
| </script> | |
| </body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment