d3.demo.flowbox = function() { "use strict"; var x = 0, y = 0, layout = d3.demo.layout.flow(), shape = null, base = null, uuid = d3.demo.util.uuid(), children = []; var dispatch = d3.dispatch( "flowboxMouseOver", "flowboxMouseOut", "flowboxMouseUp"); function flowbox(selection) { base = selection; layout.nodeWidth(75).nodeHeight(24); selection.each(function(d, i) { var parent = d3.select(this); var container = parent.append("g") .classed("flowbox", "true") .attr("transform", "translate(" + x + "," + y + ")") .attr("clip-path", "url(#clippath" + uuid + ")"); container.append("rect") .classed("background", true); flowbox.node = container.node(); var clipPath = d3.select("svg defs") .append("clipPath") .attr("class", "clippath") .attr("id", "clippath" + uuid); clipPath.append("rect") .attr("class", "background") .attr("width", shape.width() - (flowbox.x() * 2)) .attr("height", shape.height() - (flowbox.y() + flowbox.x())); flowbox.render = function() { container .select(".background") .attr("width", shape.width() - (flowbox.x() * 2)) .attr("height", shape.height() - (flowbox.y() + flowbox.x())); clipPath .attr("width", shape.width() - (flowbox.x() * 2)) .attr("height", shape.height() - (flowbox.y() + flowbox.x())) .select(".background") .attr("width", shape.width() - (flowbox.x() * 2)) .attr("height", shape.height() - (flowbox.y() + flowbox.x())); layout.width(shape.width()); var nodes = layout(children); var node = container.selectAll("g.node") .data(nodes[0], function(d) { return d.id || (d.id = ++i); }); var nodeEnter = node.enter().append("svg:g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) .style("opacity", 1e-6); nodeEnter.append("svg:rect") .attr("class", "background") .attr("rx", "4") .attr("ry", "4") .attr("height", function(d) { return d.height; }) .attr("width", function(d) { return d.width; }); nodeEnter.append("svg:text") .attr("class", "label nodelabel") .attr("transform", "translate(5, 15)") .text(function(d) { return d.name; }); // Transition nodes to their new position. nodeEnter.transition() .duration(300) .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) .style("opacity", 1); var nodeUpdate = node.transition() .duration(300); nodeUpdate.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) .style("opacity", 1) .select("rect"); nodeUpdate.select(".background") .attr("height", function(d) { return d.height; }) .attr("width", function(d) { return d.width; }); // Transition exiting nodes to the parent's new position. node.exit().transition() .duration(300) .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) .style("opacity", 1e-6) .remove(); }; flowbox.render(); shape.on("shapeUpdated.container", flowbox.render); // render when shape changes size/shape, etc }); } flowbox.children = function(value) { if (!arguments.length) { return children; } children = value; flowbox.render(); return this; }; flowbox.shape = function(value) { if (!arguments.length) { return r; } shape = value; return this; }; flowbox.x = function(value) { if (!arguments.length) { return x; } x = parseInt(value, 10); return this; }; flowbox.y = function(value) { if (!arguments.length) { return y; } y = parseInt(value, 10); return this; }; d3.rebind(flowbox, dispatch, "on"); return flowbox; };