如何定位文本标签在一个Sunburst图表与d3.js
How to position text labels on a Sunburst chart with d3.js
我正面临一个问题,试图在一个基于d3.js的Sunburst图表的楔形内定位文本。即使缩放,text
元素似乎也没有按预期定位…
var slices = svg.selectAll(".form")
.data(function(d) { return data_slices; })
.enter()
.append("g");
slices.append("path")
.attr("d", arc)
.attr("id",function(d,i){return d[2]+""+i;})
.style("fill", function(d) { return color(d[2]);})
.on("click",animate)
.attr("class","form")
.append("svg:title")
.text(function(d) { return Math.round(d[0]*100)/100 +" , "+ Math.round(d[1]*100)/100; });
//Something needs to change below....
slices.append("text")
.style("font-size", "10px")
.attr("x", function(d) { return y(d[1]); })
.attr("transform", function(d) { return "rotate(" + this.parentNode.getBBox().width + ")"; })
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.text(function(d){return d[2]})
.attr("pointer-events","none");
这是图表的提琴
提琴可能有什么问题?谁能告诉我或指导我如何定位svg <path>
内的<text>
.看起来解决方案是一个小的调整,但我不能得到它,即使尝试了很长一段时间后…
任何帮助/评论在一个解决方案的方向将非常感激…
我认为这接近你的目标:http://jsfiddle.net/4PS53/3/
需要做的修改如下:
function getAngle(d) {
// Offset the angle by 90 deg since the '0' degree axis for arc is Y axis, while
// for text it is the X axis.
var thetaDeg = (180 / Math.PI * (arc.startAngle()(d) + arc.endAngle()(d)) / 2 - 90);
// If we are rotating the text by more than 90 deg, then "flip" it.
// This is why "text-anchor", "middle" is important, otherwise, this "flip" would
// a little harder.
return (thetaDeg > 90) ? thetaDeg - 180 : thetaDeg;
}
slices.append("text")
.style("font-size", "10px")
.attr("x", function(d) { return d[1]; })
// Rotate around the center of the text, not the bottom left corner
.attr("text-anchor", "middle")
// First translate to the desired point and set the rotation
// Not sure what the intent of using this.parentNode.getBBox().width was here (?)
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")" + "rotate(" + getAngle(d) + ")"; })
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.text(function(d){return d[2]})
.attr("pointer-events","none");
现在,为了使它与缩放工作,参考点发生变化,我们需要更多的基础设施。
- 使
g.form-container
而不仅仅是path.form
可见/不可见。这意味着我们不必担心使标签单独消失。(我已经添加了form-container
类) 计算新点并计算其
centroid
和rotation
。这有点棘手,但并不太难:function change_ref(data_point, reference_point) { return [ get_start_angle(data_point, reference_point), get_stop_angle (data_point, reference_point), data_point[2], get_level (data_point, reference_point) ]; } // And while doing transitioning the `text.label`: svg.selectAll('.label') .filter( function (b) { return b[0] >= new_ref[0] && b[1] <= new_ref[1] && b[3] >= new_ref[3]; } ).transition().duration(1000) .attr("transform", function(b) { var b_prime = change_ref(b, d); return "translate(" + arc.centroid(b_prime) + ")" + "rotate(" + getAngle(b_prime) + ")"; })
我已将
label
类添加到text
中。
更新演示: http://jsfiddle.net/4PS53/6/
然而,我认为可能有更好的方式来呈现这些数据,特别是如果你允许缩放和平移:D3在饼图中放置弧形标签,如果有足够的空间
我对musically_ut代码做了一些改进。
现在你可以从一个数据切换到另一个。
$('#change').click(function () {
if (animating) {
return;
}
if (currentSet == 0) {
currentSet = 1;
svg.selectAll(".form").filter(
function (d) {
return d[0] >= ref[0] && d[1] <= ref[1] && d[level_index] >= ref[level_index];
}
)
.transition().duration(1000)
.attrTween("d", changeDatarebaseTween(0, 1, 2, 3));
svg.selectAll('.label').filter(
function (d) {
return d[0] >= ref[0] && d[1] <= ref[1] && d[level_index] >= ref[level_index];
}
)
.transition().duration(1000)
.attr("transform", function (b) {
var b_prime = change_ref_CD(b);
return "translate(" + arc.centroid(b_prime) + ")" +
"rotate(" + getAngle(b_prime) + ")";
})
}
else {
currentSet = 0;
svg.selectAll(".form").filter(
function (d) {
return d[2] >= ref[2] && d[3] <= ref[3] && d[level_index] >= ref[level_index];
}
)
.transition().duration(1000).attrTween("d", changeDatarebaseTween(2, 3, 0, 1));
svg.selectAll('.label').filter(
function (d) {
return d[2] >= ref[2] && d[3] <= ref[3] && d[level_index] >= ref[level_index];
}
)
.transition().duration(1000)
.attr("transform", function (b) {
var b_prime = change_ref_CD(b);
return "translate(" + arc.centroid(b_prime) + ")" +
"rotate(" + getAngle(b_prime) + ")";
})
}
setTimeout(function () {
animating = false;
}, 1000);
});
编辑:http://jsfiddle.net/k1031ogo/3/
(代码可以更简洁,太多的复制/粘贴)
相关文章:
- 可以't让我的if语句处理js中的html表单输入
- 使用agility.js进行页面布局和合成
- 使用Clipboard.js复制span文本
- 使用JS如何动态更改显示的html文件中的文本背景颜色
- 强制模板刷新ember.js
- 如何编写HTML输入的JS内联
- Angular JS IE9 Hashbang url rewriting
- 使用JS将数组转换为json对象
- Node.js v6.2.0类扩展不是函数错误
- 当js函数's已执行
- 要求未定义JS回调参数
- 在自定义mean.io包中使用angular-chart.js作为依赖项
- 无法在数据endVal中设置值=“”;{{ucount}}”;使用Angular JS的CountUp
- 如何从Java/scala调用js美化程序
- 如何更改<svg>标记为<img>用js标记
- 如何使用 node.js 比较两个 json 数组
- 将d3序列sunburst示例应用于新数据得到js错误
- d3.js,点击操作到另一个用sunburst的变量数组编码的URL
- 如何定位文本标签在一个Sunburst图表与d3.js
- js错误"d.parent.数据未定义"在mbostock/raw/910126/ sunburst