diff --git a/datalets/datasetexplorer-datalet/datasetexplorer-datalet.html b/datalets/datasetexplorer-datalet/datasetexplorer-datalet.html new file mode 100644 index 0000000..2fd120a --- /dev/null +++ b/datalets/datasetexplorer-datalet/datasetexplorer-datalet.html @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/datalets/datasetexplorer-datalet/datasetexplorer-datalet.png b/datalets/datasetexplorer-datalet/datasetexplorer-datalet.png new file mode 100644 index 0000000..a9fd8c6 --- /dev/null +++ b/datalets/datasetexplorer-datalet/datasetexplorer-datalet.png diff --git a/datalets/datasetexplorer-datalet/demo/index.html b/datalets/datasetexplorer-datalet/demo/index.html new file mode 100644 index 0000000..4345369 --- /dev/null +++ b/datalets/datasetexplorer-datalet/demo/index.html @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/datalets/datasetexplorer-datalet/docs.html b/datalets/datasetexplorer-datalet/docs.html new file mode 100644 index 0000000..4b99f6f --- /dev/null +++ b/datalets/datasetexplorer-datalet/docs.html @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/datalets/datasetexplorer-datalet/js/buildtreemap.js b/datalets/datasetexplorer-datalet/js/buildtreemap.js new file mode 100644 index 0000000..1d96e46 --- /dev/null +++ b/datalets/datasetexplorer-datalet/js/buildtreemap.js @@ -0,0 +1,220 @@ +/** + * Created by Utente on 17/07/2015. + */ + +function build(root, place_holder) { + + var plwidth = $("#" + place_holder).width(), + plheight = $("#" + place_holder).height(); + + var margin = {top: 20, right: 0, bottom: 0, left: 0}, + //width = 960, + //height = 500 - margin.top - margin.bottom, + width = plwidth, + height = plheight - margin.top - margin.bottom, + formatNumber = d3.format(",d"), + transitioning; + + var x = d3.scale.linear() + .domain([0, width]) + .range([0, width]); + + var y = d3.scale.linear() + .domain([0, height]) + .range([0, height]); + + var treemap = d3.layout.treemap() + .children(function(d, depth) { return depth ? null : d._children; }) + .sort(function(a, b) { return a.value - b.value; }) + .ratio(height / width * 0.5 * (1 + Math.sqrt(5))) + .round(false); + + var svg = d3.select("#" + place_holder).append("svg") + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.bottom + margin.top) + .style("margin-left", -margin.left + "px") + .style("margin.right", -margin.right + "px") + .append("g") + .attr("transform", "translate(" + margin.left + "," + margin.top + ")") + .style("shape-rendering", "crispEdges"); + + var grandparent = svg.append("g") + .attr("class", "grandparent"); + + var dataletContainer = null; + + grandparent.append("rect") + .attr("y", -margin.top) + .attr("width", width) + .attr("height", margin.top); + + grandparent.append("text") + .attr("x", 6) + .attr("y", 6 - margin.top) + .attr("dy", ".75em"); + + //d3.json + initialize(root); + accumulate(root); + layout(root); + display(root); + + function initialize(root) { + root.x = root.y = 0; + root.dx = width; + root.dy = height; + root.depth = 0; + } + + // Aggregate the values for internal nodes. This is normally done by the + // treemap layout, but not here because of our custom implementation. + // We also take a snapshot of the original children (_children) to avoid + // the children being overwritten when when layout is computed. + function accumulate(d) { + return (d._children = d.children) + ? d.value = d.children.reduce(function(p, v) { return p + accumulate(v); }, 5) + : d.value; + } + + // Compute the treemap layout recursively such that each group of siblings + // uses the same size (1×1) rather than the dimensions of the parent cell. + // This optimizes the layout for the current zoom state. Note that a wrapper + // object is created for the parent node for each group of siblings so that + // the parent’s dimensions are not discarded as we recurse. Since each group + // of sibling was laid out in 1×1, we must rescale to fit using absolute + // coordinates. This lets us use a viewport to zoom. + function layout(d) { + if (d._children) { + treemap.nodes({_children: d._children}); + var i = 0; + d._children.forEach(function(c) { + c.x = d.x + c.x * d.dx; + c.y = d.y + c.y * d.dy; + c.dx *= d.dx; + c.dy *= d.dy; + c.parent = d; + c.depth = d.depth + 1; + c.color = c.depth < 2 + ? d3.scale.ordinal().domain(d3.range(d._children.length)).range(["#8dd3c7","#ffffb3","#bebada","#fb8072","#80b1d3","#fdb462","#b3de69","#fccde5","#d9d9d9","#bc80bd","#ccebc5","#ffed6f"])(i++) + //? interpolate(0, d._children.length, i++) + : d.color; //d3.rgb(d.color).brighter(.5); + layout(c); + }); + } + } + + function display(d) {0 + grandparent + .datum(d.parent) + .on("click", transition) + .select("text") + .text(name(d)); + + var g1 = svg.insert("g", ".grandparent") + .datum(d) + .attr("class", "depth"); + + var g = g1.selectAll("g") + .data(d._children) + .enter().append("g"); + + g.filter(function(d) { return d._children; }) + .classed("children", true) + .on("click", transition); + + g.selectAll(".child") + .data(function(d) { return d._children || [d]; }) + .enter().append("rect") + .attr("class", "child") + .call(rect); + + g.append("rect") + .attr("class", "parent") + .call(rect) + .append("title") + .text(function(d) { return d.name; /*formatNumber(d.value);*/ }); + + g.append("text") + .attr("dy", ".75em") + .text(function(d) { return (d._children) ? d.name : ''; }) + //.style("font-size", function(d) { return Math.min(16, (d.dx - 8) / this.getComputedTextLength() * 16) + "px"; }) + .call(text) + ; + + function transition(d) { + if (transitioning || !d) return; + transitioning = true; + + if (dataletContainer) { + //svg.select("foreignObject") + //svg.remove(dataletContainer); + dataletContainer.remove(); + dataletContainer = null; + } + + var g2 = display(d), + t1 = g1.transition().duration(750), + t2 = g2.transition().duration(750); + + // Update the domain only after entering new elements. + x.domain([d.x, d.x + d.dx]); + y.domain([d.y, d.y + d.dy]); + + // Enable anti-aliasing during the transition. + svg.style("shape-rendering", null); + + // Draw child nodes on top of parent nodes. + svg.selectAll(".depth").sort(function(a, b) { return a.depth - b.depth; }); + + // Fade-in entering text. + g2.selectAll("text").style("fill-opacity", 0); + + // Transition to the new view. + t1.selectAll("text").call(text).style("fill-opacity", 0); + t2.selectAll("text").call(text).style("fill-opacity", 1); + t1.selectAll("rect").call(rect); + t2.selectAll("rect").call(rect); + + // Remove the old node when the transition is finished. + t1.remove().each("end", function() { + svg.style("shape-rendering", "crispEdges"); + transitioning = false; + }); + } + + if (!d._children[0]._children) { + var dataurl = d._children[0].name; + var pageurl = dataurl.replace(/\/download\/.*/, ''); + dataletContainer = svg + .append("foreignObject") + .attr("width", 480) + .attr("height", 500) + .append("xhtml:body") + .html(''); + + } + + return g; + } + + function text(text) { + text.attr("x", function(d) { return x(d.x) + 6; }) + .attr("y", function(d) { return y(d.y) + 6; }) + ; + } + + function rect(rect) { + rect.attr("x", function(d) { return x(d.x); }) + .attr("y", function(d) { return y(d.y); }) + .attr("width", function(d) { return x(d.x + d.dx) - x(d.x); }) + .attr("height", function(d) { return y(d.y + d.dy) - y(d.y); }) + .style("fill", function(d, i) { return d.color; }) + ; + } + + function name(d) { + return d.parent + ? name(d.parent) + "." + d.name + : d.name; + } +}; \ No newline at end of file