/** Function: renderTreemap * Variables : * * dataTreeMap: contains data to be plotted as treeMap, data is grouped in the suitable format using the d3.nest function called in the controller * sample can be found in the 'cashflowrollupCtrl' controller, in which the data is requested using the http request as a JSON object and grouped * accordingly. * * dom_element_to_append_to : class name of the div element to which the treemap has to be appended. * * keyPassed: string element passed as a param, shown at the top og graph as the title of graph. * * isColorCategorySplitable: set it true if two parent elements are there and both have different color schemes , an false when colorscheme is same throughout * the graph,example can be found in the positive and negative cashflow graphs together with different coloschemes, if 'true ' then set the colorSchemes * namely 'positiveColorScheme' and 'negativeColorScheme' manually provided as varibles in the rootscope at the variable declaraions. * * isForwarUnit: set it 'true' if passed unit is to be placed at the forward of the vaule else false if to be placed at the backwards , else if no value passed then it can be set either true or false * * * unitName: name of the unit to be placed in the graph, set it "" if no unit is required */ function renderTreemap (dataTreeMap,dom_element_to_append_to, titlePassed, keyPassed,isColorCategorySplitable,isForwardUnit, unitName, defaultColorScheme, positiveColorScheme, negativeColorScheme) { var treemap_card_width = 800; var defaults = { margin: {top: 24, right: 0, bottom: 0, left: 0}, rootname: "TOP", format: ",d", title: "", width: (treemap_card_width ? treemap_card_width : 500), //height: $(window).height() - 120 height: treemap_card_width * 3/5 }; function main(o, data) { var root, opts = $.extend(true, {}, defaults, o), formatNumber = d3.format(opts.format), rname = opts.rootname, margin = opts.margin, theight = 36 + 16; $(dom_element_to_append_to).width(opts.width).height(opts.height); var width = opts.width - margin.left - margin.right, height = opts.height - margin.top - margin.bottom - theight, transitioning; if(!isColorCategorySplitable) var color = d3.scale.ordinal().range(defaultColorScheme); else { var positiveColor = d3.scale.ordinal().range(positiveColorScheme); var negativeColor = d3.scale.ordinal().range(negativeColorScheme); } 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(dom_element_to_append_to).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"); 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", ".85em"); var tip = d3.tip() .attr('class', 'd3-tip') .offset([0, 0]) .html(function(d) { if(isForwardUnit) return "
Category: " + d.key + "
" + "
Value: " + unitName +"" + d3.format(",")(d.value) + "
"; else return "
Category: " + d.key + "
" + "
Value: " + d3.format(",")(d.value) +"" + unitName + "
"; }); svg.call(tip); if (data instanceof Array) { root = { key: rname, values: data }; } else { root = data; } initialize(root); accumulate(root); layout(root); display(root); if (window.parent !== window) { var myheight = document.documentElement.scrollHeight || document.body.scrollHeight; window.parent.postMessage({height: myheight}, '*'); } function initialize(root) { root.x = root.y = 0; root.dx = width; root.dy = height; root.depth = 0; } function accumulate(d) { return (d._children = d.values) ? d.value = d.values.reduce(function(p, v) { return p + accumulate(v); }, 0) : d.value; } function layout(d) { if (d._children) { treemap.nodes({_children: d._children}); 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; layout(c); }); } } function display(d) { 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); var children = g.selectAll(".child") .data(function(d) { return d._children || [d]; }) .enter().append("g"); children.append("rect") .attr("class", "child") .call(rect) .append("title") .text(function(d) { return d.key + " (" + formatNumber(d.value) + ")"; }); children.append("text") .attr("class", "ctext") .text(function(d) { return d.key; }) .call(text2); g.append("rect") .attr("class", "parent") .call(rect) .append("title"); var t = g.append("text") .attr("class", "ptext") .attr("dy", "0.90em") .style("font-size", width * 0.010) t.append("tspan") .text(function(d) { return d.key; }); if(isForwardUnit) { t.append("tspan") .attr("dy", "1.0em") .text(function(d) { return unitName + "" +formatNumber(d.value); }); t.call(text); } else { t.append("tspan") .attr("dy", "1.0em") .text(function(d) { return formatNumber(d.value) + "" + unitName; }); t.call(text); } g.selectAll("rect") .on('mouseover', tip.show) .on('mouseout', tip.hide) .style("fill", function(d) { if(isColorCategorySplitable) { if(d.parent.key=="Positive Cashflow") return positiveColor(d.key); else if(d.parent.key=="Negative Cashflow") return negativeColor(d.key); } else return color(d.key); }); function transition(d) { if (transitioning || !d) return; transitioning = true; var g2 = display(d), t1 = g1.transition().duration(750), t2 = g2.transition().duration(750); x.domain([d.x, d.x + d.dx]); y.domain([d.y, d.y + d.dy]); svg.style("shape-rendering", null); svg.selectAll(".depth").sort(function(a, b) { return a.depth - b.depth; }); g2.selectAll("text").style("fill-opacity", 0); t1.selectAll(".ptext").call(text).style("fill-opacity", 0); t1.selectAll(".ctext").call(text2).style("fill-opacity", 0); t2.selectAll(".ptext").call(text).style("fill-opacity", 1); t2.selectAll(".ctext").call(text2).style("fill-opacity", 1); t1.selectAll("rect").call(rect); t2.selectAll("rect").call(rect); t1.remove().each("end", function() { svg.style("shape-rendering", "crispEdges"); transitioning = false; }); } return g; } function text(text) { text.selectAll("tspan") .attr("x", function(d) { return x(d.x) + 6; }) text.attr("x", function(d) { return x(d.x) + 6; }) .attr("y", function(d) { return y(d.y) + 6; }) .style("opacity", function(d) { return this.getComputedTextLength() < x(d.x + d.dx) - x(d.x) ? 1 : 0; }); } function text2(text) { text.attr("x", function(d) { return x(d.x + d.dx) - this.getComputedTextLength() - 6; }) .attr("y", function(d) { return y(d.y + d.dy) - 6; }) .style("opacity", function(d) { return this.getComputedTextLength() < x(d.x + d.dx) - x(d.x) ? 1 : 0; }); } 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); }); } function name(d) { return d.parent ? name(d.parent) + " / " + d.key + " (" + formatNumber(d.value) + ")" : d.key + " (" + formatNumber(d.value) + ")"; } } main({title: titlePassed}, {key: keyPassed, values: dataTreeMap}); };