d3.js 中有一个关于treemap树墙的功能,效果很强大,最近项目需求想用此实现一个业务分类的扫描效果,调研查找方法研究了很久,终于找到解决方案,将代码贴出供学习。
首先,d3呈现的最终网页元素是svg格式,不同于dom元素,我们看一下加载完的基本属性
function InitMap() { // console.log("shuaxin"); $.ajax({ type: "get", url: "../../TreeMap/getBusinessWallJson", data: {}, async: true, success: function (data, status) { //加载 var jsondata = data; node = root = jsondata; var nodes = treemap.nodes(root) .filter(function (d) { return !d.children; }); var cell = svg.selectAll("g") .data(nodes) .enter().append("svg:g") .attr("class", "cell") .attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; }) .on("click", function (d) { return zoom(node == d.parent ? root : d.parent); }); cell.append("svg:rect") //标记:此处可设置缝隙的大小,减号后面的值越大,间隙越大 .attr("width", function (d) { return d.dx - 2; }) .attr("height", function (d) { return d.dy - 2; }) .attr("id", function (d) { return d.id })//此处设置元素的唯一标识 .style("fill", function (d) { //默认使用数据库中配置的颜色 if (d.color != null && d.color != '') { return d.color; } else {//分配颜色 //一个业务大类使用一种颜色 if (d.parent.name != paName) { paName = d.parent.name; if (i == color.length - 1) i = 0; else i++; }; return color[i]; } }) .attr("colororign", function (d) { return d3.select(this).style("fill"); }) .attr("widthorign", function (d) { return d3.select(this).attr("width"); }); cell.append("svg:text") .attr("x", function (d) { return d.dx / 2; }) .attr("y", function (d) { return d.dy / 2; }) .attr("dy", ".35em") .attr("text-anchor", "middle") .text(function (d) { return d.name; }) .style('fill', function (node) { return "#FFFFFF"; }) .style("opacity", function (d) { for (var i = 5; i > 0; i--) { d.w = this.getComputedTextLength(); if (d.dx <= d.w) { d3.select(this).text(function (d) { var namela = d.name.substring(0, i); if (namela.charAt(namela.length - 1) == "-") { return namela.substring(0, namela.length - 1); } else return namela; }); } } return 1; }) .attr("textstr", function (d) { return d3.select(this).text(); }); }, error: function (e) { alert("获取业务墙数据失败!"); }, complete: function () { } }); // console.log("shuaxin1"); }
treemap加载完成后,通过d3.js自身的动画函数修改rect宽度来实现扫描效果,上代码
function colorchange(key) { var co = d3.select("rect[id='" + key + "']").attr('colororign'); var wi = d3.select("rect[id='" + key + "']").attr('width'); var wiorign = d3.select("rect[id='" + key + "']").attr('widthorign'); //if (wi < wiorign) // wi = wiorign; d3.select("rect[id='" + key + "']").attr('width', 0); d3.select("rect[id='" + key + "']").transition() .duration(3000) .attrTween("fill", function () { var ci = d3.interpolate("green", co); var that = this; return function (t) { that.style.fill = ci(t); } }) .ease("linear") //.attr("width", wi); .attr("width", wiorign); }