jsfiddle.net/spacehaz/jpzaj92o/31
我想创建一个sunburst并给它一个带回调的事件监听器,它将扩展它,而不是缩放!所以我的想法是将所有更深层次扩展到100%(并隐藏从根开始的所有其他分支)!我找到了做缩放的解决方案,但这不是解决方案,我需要扩展它,而不是缩放!这是我现在的代码:
var app = {}
function stash (d) {
d.x0 = d.x
d.dx0 = d.dx
}
function getSvg (width, height, margin) {
return d3.select('#sunburst').append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')')
}
function prepareArcForSunburst (component) {
var arc = d3
.svg
.arc()
.startAngle(function (d) {
return Math.max(0, Math.min(2 * Math.PI, component.x(d.x)))
})
.endAngle(function (d) {
return Math.max(0, Math.min(2 * Math.PI, component.x(d.x + d.dx)))
})
.innerRadius(function (d) {
return Math.max(0, component.y(d.y))
})
.outerRadius(function (d) {
return Math.max(0, component.y(d.y + d.dy))
})
return arc
}
function preparePartitionOptionsForSunburst () {
var partition = d3
.layout
.partition()
.sort(null)
.value(function (d) {
return 1
})
return partition
}
function compileDataForSunburst (component, partition, data) {
var dataCompiled = component
.svg
.datum(data)
.selectAll('path')
.data(partition.nodes)
return dataCompiled
}
function drawChart (data) {
var color = d3.scale.category20c();
this.initiallyDrawed = true
var margin = { left: 20 }
var component = app
component.width = 300
component.height = component.width
component.data = data
component.radius = Math.min(component.width, component.height) / 2
component.x = d3.scale.linear()
.range([0, 2 * Math.PI])
component.y = d3.scale.sqrt()
.range([0, component.radius])
component.svg = getSvg(component.width, component.height, margin)
component.partition = preparePartitionOptionsForSunburst()
// данные по углам и радиусам каждой ячейки
component.arc = prepareArcForSunburst(component)
var dataCompiled = compileDataForSunburst(component, component.partition, data)
var arcTweenZoom = function (d) {
var component = app
var xd = d3.interpolate(component.x.domain(), [d.x, d.x + d.dx])
var yd = d3.interpolate(component.y.domain(), [d.y, 1])
var yr = d3.interpolate(component.y.range(), [d.y ? 20 : 0, component.radius])
return function (d, i) {
return i ? function (t) {
return component.arc(d)
} : function (t) {
component.x.domain(xd(t))
component.y.domain(yd(t)).range(yr(t))
return component.arc(d)
}
}
}
var magnify = function (d) {
var component = app
component.path
.transition()
.duration(1000)
.attrTween('d', arcTweenZoom(d))
}
component.path = dataCompiled
.enter()
.append('path')
.attr('d', component.arc)
.style('stroke', '#fff')
.on('click', magnify)
.style('fill', function (d) {
return color((d.children ? d : d.parent).name);
})
.style('fill-rule', 'evenodd')
.each(stash)
d3.select(self.frameElement).style('height', component.height + 'px')
}