D3可变焦森伯斯特无法变焦(来自R的数据) [英] D3 zoomable sunburst not zooming (with data from R)
问题描述
我正在尝试修改一些代码,以便可以将旭日形图(使用D3)中的数据与来自R的数据作为数据帧一起绘制.
I'm trying to adapt some code so I can plot data in a sunburst (using D3) chart with data coming from R as a dataframe.
除缩放部分外,我大部分都可以正常工作,当我单击(几乎)时,什么也没发生.
I've got most of it working ok except the zooming part, when i click (almost) nothing happens.
在mouseOver上,我得到的一部分圆的半径大于朝阳半径,以帮助强调我所徘徊的数据.这解释了arcHighlight
变量.也可以注意到它不是使用我的标尺a
和b
构造的.我修改了原始代码以使用磅秤,并且现在保持了arcHighlight
的状态.
On mouseOver I've got a portion of circle with a greater radius than the one for the sunburst to help emphasizing the data I'm hovering. This explains the arcHighlight
variable. Also one can notice it is not constructed using my scales a
and b
. I modifed the original code to use the scales, and I left the arcHighlight
as is for now.
经过一番挖掘,这个问题似乎表明我需要删除partition.size
,因为我的体重秤a
和b
会照顾到它.我确实尝试过,但是如果我这样注释尺寸部分,则不会显示任何内容:
After a bit of digging around, this question seems to indicate that I need to delete the partition.size
since it will be taken care of by my scales a
and b
. I did try that but it does not plot anything if I comment the size part like this :
var partition = d3.layout.partition()
//.size([2 * Math.PI, (radius - outerRadius) * (radius - outerRadius)])
.value(function(d) { return d[x.options.valueField || "size"]; });
在单击功能结束时,我使突出显示的圆圈不可见.可以正常工作,但不进行缩放.一旦将鼠标移到其他位置,我的突出显示圆圈就会重新出现(正常,鼠标悬停功能中使用颜色编码).因此,这一切都可以正常工作,而不会崩溃或冻结,而只是缩放部分.我一定想念一些简单的事情,但不知道是什么.
At the end of the click function, I'm making my highlight circle invisible. That works correctly, but do not do the zooming. As soon as I move my mouse elsewhere, my highlight circle reappear (normal, color coded in the mouseover function). So it all works correctly without crashing or freezing, but just the zooming part. I must be missing something easy but can't figure out what.
感谢所有可能提供帮助的人.还请注意,我是JS的新手,所以这可能只是一个非常简单的错误,如果可以的话,我深表歉意.
Thanks for all of you guys who might be able to help out. Please also note that I'm pretty new to JS so it might just be a very simple mistake, my apologies if so.
我的代码(我认为是相关的...):
My code (what I think is relevant... ) :
// Dimensions of sunburst
var width = el.getBoundingClientRect().width - (x.options.legend.w ? x.options.legend.w : 75);
var height = el.getBoundingClientRect().height - 70;
var radius = Math.min(width, height) / 2;
var outerRadius = radius/3.5; // reserved pixels all around the vis
// Create scales
var a = d3.scale.linear()
.range([0, 2 * Math.PI]);
var b = d3.scale.linear()
.range([0, (radius - outerRadius)]);
var vis = d3.select(el).select(".sunburst-chart").select("svg")
.append("g")
.attr("id", el.id + "-container")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var partition = d3.layout.partition()
.size([2 * Math.PI, (radius - outerRadius) * (radius - outerRadius)])
.value(function(d) { return d[x.options.valueField || "size"]; });
var arc = d3.svg.arc()
.startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, a(d.x/(2 * Math.PI)))); })
.endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, a((d.x+d.dx)/(2 * Math.PI)))); })
.innerRadius(function(d) { return (d.dy == d.y) ? Math.max(0, b((Math.sqrt(d.y))/(radius - outerRadius))/3) : Math.max(0, b((Math.sqrt(d.y))/(radius - outerRadius))); })
.outerRadius(function(d) { return Math.max(0, b((Math.sqrt(d.y + d.dy))/(radius - outerRadius))); });
var arcHighlight = d3.svg.arc()
.startAngle(function(d) { return d.x; })
.endAngle(function(d) { return d.x + d.dx; })
.innerRadius(function(d) { return 0; })
.outerRadius(function(d) { return radius; });
var highlight = vis.append("path")
.attr("d", null)
//.style("opacity", 0);
.style("fill", "#eee");
var path = vis.data([json]).selectAll("dataArc")
.data(nodes)
.enter().append("path")
.attr("display", function(d) { return d.depth ? null : "none"; })
.attr("d", arc)
.attr("fill-rule", "evenodd")
.style("fill", function(d) { return colors.call(this, d.name); })
.style("opacity", 1)
.on("mouseover", mouseover)
//.on("mouseleave", mouseleave) // do not work
.on("click", click);
// Add the mouseleave handler to the bounding circle.
d3.select(el).select("#"+ el.id + "-container").on("mouseleave", mouseleave);
点击功能:
function click(d) {
vis.selectAll("path")
.transition('arc_tween')
.duration(1750)
.attrTween("d", arcTween(d));
highlight
.transition()
.duration(250)
.attr("d", null);
}
和arcTween函数:
and the arcTween function :
function arcTween(d) {
var xd = d3.interpolate(a.domain(), [ (d.x/(2 * Math.PI)) , ((d.x+d.dx)/(2 * Math.PI)) ]);
var yd = d3.interpolate(b.domain(), [ ((Math.sqrt(d.y))/(radius - outerRadius)) , (radius - outerRadius) ]);
var yr = d3.interpolate(b.range(), [0, (radius - outerRadius)] );
// For each node, return an interpolator function that D3 can use to transition.
// The scales only need to be modified once per transition step, so only do this
// when i = 0. In all cases the interpolator just re-applies the arc function,
// which uses our newly updated scales to produce new curves.
return function(d, i) {
(i == 0) ?
function(t) {
a.domain(xd(t));
b.domain(yd(t));
return arc(d);
}
: function(t) {
return arc(d);
};
}
}
我要适应的原始arcTween函数如下所示:
The original arcTween function I'm trying to adapt looks like this :
function arcTween(root) {
var xd = d3.interpolate(x.domain(), [root.x, root.x + root.dx]);
var yd = d3.interpolate(y.domain(), [root.y, 1]);
var yr = d3.interpolate(y.range(), [root.y ? 20 : 0, r - outerRadius]);
// For each node, return an interpolator function that D3 can use to transition.
// The scales only need to be modified once per transition step, so only do this
// when i = 0. In all cases the interpolator just re-applies the arc function,
// which uses our newly updated scales to produce new curves.
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); };
};
}
此函数位于无法与R一起使用的.js文件中.出于某些原因,return i
指令冻结了我的图表,但没有同时缩放,因此我选择了(i==0)?...
.
This function is in a .js file that does not work with R. For some reason the return i
instruction is freezing my chart while not zooming either, hence my go with (i==0)?...
.
R如何喂养这张朝阳图 我为此使用的数据框只有两列,第一列仅包含层次结构作为字符串(连字符(连字符)),第二列包含此类层次结构的出现次数.看起来可能像这样:
Edit 1 : how R is feeding this sunburst chart The dataframe I use for this has only two columns, the first one containing only the hierarchy as a string (hyphen seperated) and the second column the number of occurences of such a hierarchy. It could look like this :
search-search-search-product-product-product, 7311
search-search-search-product-product-search, 2807
search-search-search-product-search-account, 145
search-search-search-product-search-end, 501
search-search-search-product-search-home, 57
search-search-search-product-search-other, 16
search-search-search-product-search-product, 4559
search-search-search-product-search-search, 2030
search-search-search-search-account-account, 300
search-search-search-search-account-end, 49
.JS文件中有一个buildhierarchy
函数,该函数具有2列df并将其转换为适合分区的分层结构.这是代码:
In the .JS file, there is a buildhierarchy
function that takes a 2 column df and transform it into a hierarchical structure suitable for partitioning. Here is the code :
function buildHierarchy(csv) {
var root = {"name": "root", "children": []};
for (var i = 0; i < csv.length; i++) {
var sequence = csv[i][0];
var size = +csv[i][1];
if (isNaN(size)) { // e.g. if this is a header row
continue;
}
var parts = sequence.split("-");
var currentNode = root;
for (var j = 0; j < parts.length; j++) {
var children = currentNode["children"];
var nodeName = parts[j];
var childNode;
if (j + 1 < parts.length) {
// Not yet at the end of the sequence; move down the tree.
var foundChild = false;
for (var k = 0; k < children.length; k++) {
if (children[k]["name"] == nodeName) {
childNode = children[k];
foundChild = true;
break;
}
}
// If we don't already have a child node for this branch, create it.
if (!foundChild) {
childNode = {"name": nodeName, "children": []};
children.push(childNode);
}
currentNode = childNode;
} else {
// Reached the end of the sequence; create a leaf node.
childNode = {"name": nodeName, "size": size};
children.push(childNode);
}
}
}
return root;
};
推荐答案
似乎您没有返回以t为参数的函数.您会看到原始补间的收益比更改后的补间多.
It looks like you are not returning the function that takes t as an argument. You can see the original tween has one more return than your changed version has.
return function(d, i) {
return (i == 0) ?
function(t) {
a.domain(xd(t));
b.domain(yd(t));
return arc(d);
}
: function(t) {
return arc(d);
};
}
这篇关于D3可变焦森伯斯特无法变焦(来自R的数据)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!