2016-10-24 51 views
0

我想改变sunburst图表上的传统缩放功能。传统上,当您单击某个分区时,该分区会增长以覆盖基本层的100%,同一层上的所有其他分区会消失。所选分区的子项都会增长以填充新创建的空间。如何更改d3旭日形图表上的缩放功能?

我目前的代码正好如上所述。我想改变我的代码,以允许选定的分区只占75%的基础层。儿童元素将增长到覆盖这个新的空间,但其余的25%仍将包含所有其他未选择的分区。

我试着改变从d3.interpolate()返回的't'值,但我有不可预知的结果。

我希望我的描述很清楚。

有没有人对此有任何想法?

<script> 

var width = 960, 
height = 700, 
radius = Math.min(width, height)/2; 

var x = d3.scale.linear() 
.range([0, 2 * Math.PI]); 

var y = d3.scale.linear() 
.range([0, radius]); 

var color = d3.scale.category20c(); 

function percent(d) { 
    var percentage = (d.value/956129) * 100; 
    return percentage.toFixed(2); 
} 

var tip = d3.tip() 
    .attr('class', 'd3-tip') 
    .offset([-10, 0]) 
    .html(function(d) { 
return "<strong>" + d.name + "</strong> <span style='color:red'>" + percent(d) + "%</span>"; 
    }) 

var svg = d3.select("body").append("svg") 
.attr("width", width) 
.attr("height", height) 
    .append("g") 
.attr("transform", "translate(" + width/2 + "," + (height/2 + 10) + ")"); 

svg.call(tip); 

var partition = d3.layout.partition() 
.value(function(d) { return d.size; }); 

var arc = d3.svg.arc() 
.startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); }) 
.endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); }) 
.innerRadius(function(d) { return Math.max(0, y(d.y)) }) 
.outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)) }); 

d3.json("flare.json", function(error, root) { 
    var g = svg.selectAll("g") 
    .data(partition.nodes(root)) 
.enter().append("g"); 

    var path = g.append("path") 
.attr("d", arc) 
// .attr("stroke", 'black') 
// .style("fill", function(d) { return color((d.children ? d : d.parent).name); }) 
.style("fill", function(d, i) { 
    return color(i); 
}) 
.on("click", click) 
.on('mouseover', tip.show) 
.on('mouseout', tip.hide); 

    var text = g.append("text") 
.attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; }) 
.attr("x", function(d) { return y(d.y); }) 
.attr("dx", "6") // margin 
.attr("dy", ".35em") // vertical-align 
.text(function(d) { 
    if (percent(d) > 1.35) { 
     return d.name; 
    } 

}) 
.attr('font-size', function(d) { 
    if (d.value < 100000) { 
     return '10px' 
    } else { 
     return '20px'; 
    } 
}) 
.on("click", click) 
.on('mouseover', tip.show) 
.on('mouseout', tip.hide); 

    function click(d) { 
console.log(d) 
// fade out all text elements 
text.transition().attr("opacity", 0); 

path 
    .transition() 
    .duration(750) 
    .attrTween("d", arcTween(d)) 
    .each("end", function(e, i) { 
     // check if the animated element's data e lies within the visible angle span given in d 
     if (e.x >= d.x && e.x < (d.x + d.dx)) { 
     // get a selection of the associated text element 
     var arcText = d3.select(this.parentNode).select("text"); 
     // fade in the text element and recalculate positions 
     arcText.transition().duration(750) 
      .attr("opacity", 1) 
      .attr("transform", function() { return "rotate(" + computeTextRotation(e) + ")" }) 
      .attr("x", function(d) { return y(d.y); }); 
     } 
    }); 
    } 
}); 

d3.select(self.frameElement).style("height", height + "px"); 

// Interpolate the scales! 
function arcTween(d) { 
console.log(d.name, x.domain()) 
console.log(d.name, y.domain()) 
console.log(d.name, y.range()) 
    var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]), 
    yd = d3.interpolate(y.domain(), [d.y, 1]), 
    yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]); 
    return function(d, i) { 
return i 
    ? function(t) { return arc(d); } 
    : function(t) { 
     console.log(t) 
     x.domain(xd(t)); 
     y.domain(yd(t)).range(yr(t)); 
     return arc(d); 

    }; 
    }; 
} 

function computeTextRotation(d) { 
    return (x(d.x + d.dx/2) - Math.PI/2)/Math.PI * 180; 
} 

+0

真的离题了,但您使用的是较早的d3 API,您应该查看最新的库版本。例如,'d3.scale.linear()'现在是'd3.scaleLinear()'。这不仅仅是关于函数名称的变化。新版本还包括错误修复和性能改进。 – Dummy

+0

我同意,我确实需要更新到新版本。因为bl.ocks.org上的大多数示例都使用了较早的d3 API,所以我认为我有点厌恶它。话虽如此,我同意我应该跳槽。 – Kerrin631

回答