我是编程D3的新手,我们在更新旭日形图时遇到问题而不会导致其破坏过渡。更改数据后,图表的某些部分将停止调整缩放功能,并且看起来相互重叠。另外,显然,我得到的错误来自图中每个“弧”的标志的插值(即错误:属性d:期望的弧标志('0'或'1'),“...... 125862517296 0 0.987032831999999 ...”。 )。我们正在使用特定于此问题的补间,因此无法理解可能导致它的原因。 由于我对这种语言缺乏经验,所以我花了几天时间来解决这个问题只是为了让它回来。如果你们中的任何人能够提供帮助,我将非常感激。
这是我创建的一个工作小提琴来说明我们的问题: - https://jsfiddle.net/v9ab0vms/1/
通过等待5秒并单击“商业”然后单击“通信”弧可以看到问题。导致转换错误并打破一些弧。在数据发生变化时缩放图形会导致它以其他方式中断,对此的任何帮助也将非常受欢迎。我只是想一步一步地修复它。
代码也必须发布,所以我只是为sunburst插入两个主要功能:
function genSunburst2() {
var width = d3.select("#container_sunburst").style("width").split("px")[0],
height = d3.select("#container_sunburst").style("height").split("px")[0],
radius = Math.min(width, height) / 2;
var x = d3.scale.linear()
.range([0, 2 * Math.PI]);
var y = d3.scale.sqrt()
.range([0, radius]);
var color = d3.scale.category20c();
var svg = d3.select("#sunburst")
.attr("id", "sunburst")
.attr("width", width)
.attr("height", height)
.select("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
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));
});
function computeTextRotation(d) {
var angle = x(d.x + d.dx / 2) - Math.PI / 2;
return angle / Math.PI * 180;
}
function arcTween(d) {
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) {
x.domain(xd(t));
y.domain(yd(t)).range(yr(t));
return arc(d);
};
};
}
function arcTweenUpdate(a) {
console.log(path);
var _self = this;
var i = d3.interpolate({
x: this.x0,
dx: this.dx0
}, a);
return function(t) {
var b = i(t);
console.log(window);
_self.x0 = b.x;
_self.dx0 = b.dx;
return arc(b);
};
}
updateSunburst3 = function() {
if (sunburstClick) {
sunburstClick = false;
return;
}
var root = createJsonDataset();
// DATA JOIN - Join new data with old elements, if any.
var gs = svg.selectAll("g").data(partition.nodes(root));
// ENTER
var g = gs.enter().append("g").on("click", click);
// UPDATE
var path = g.append("path");
gs.select('path')
.style("fill", function(d) {
return color(d.name);
})
.on("click", click)
.each(function(d) {
this.x0 = d.x;
this.dx0 = d.dx;
})
.transition().duration(500)
.attr("d", arc);
var text = g.append("text");
gs.select('text')
.attr("x", function(d) {
return y(d.y);
})
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.attr("transform", function(d) {
return "rotate(" + computeTextRotation(d) + ")";
})
.text(function(d) {
return d.name;
})
.style("fill", "white");
function click(d) {
sunburstClick = true;
console.log(d);
// fade out all text elements
/*if (d.size !== undefined) {
d.size += 100;
};*/
text.transition().attr("opacity", 0);
console.log(path);
for (var i = 0; i < path[0].length; ++i) {
if (path[0][i] === undefined || path[0][i] === null) {
path[0].splice(i, 1);
--i;
}
}
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);
});
}
});
userSelection = undefined;
purposeSelection = undefined;
// TODO: alterar para ele ter em conta a hierarquia da selecao corrente
// para so sair de uma hierarquia
if (typeof d.name != "undefined" && d.name != "") {
if (typeof d.size === "undefined") {
userSelection = d.name;
purposeSelection = undefined;
} else {
userSelection = d.parent.name;
purposeSelection = d.name;
}
} else {
// if only the user was selected, back out to no selection
if (purposeSelection === undefined && userSelection != undefined) {
userSelection = undefined;
// if both the user and the purpose were selected, back out to just user selection
} else if (purposeSelection != undefined && userSelection != undefined) {
purposeSelection = undefined;
}
}
applySelection();
}
// EXIT - Remove old elements as needed.
gs.exit().transition().duration(500).style("fill-opacity", 1e-6).remove();
}
}
提前谢谢
编辑:澄清: