Javascript 圆图上的曲线标签(D3.js)
所以,我基本上是在尝试用D3.js(v4)和JSON数据创建一个多级循环分区(也称为sunburst图) 我放置了一些标签,这些标签必须根据其在分区上的级别(圆)具有不同的角度:Javascript 圆图上的曲线标签(D3.js),javascript,d3.js,svg,Javascript,D3.js,Svg,所以,我基本上是在尝试用D3.js(v4)和JSON数据创建一个多级循环分区(也称为sunburst图) 我放置了一些标签,这些标签必须根据其在分区上的级别(圆)具有不同的角度: -标高0&&parseInt(d.data.level)90){ 角度=角度-180; } 结果=“平移(“+质心+”)旋转(“+角度+”); }否则{ 角度=(180/Math.PI*(arc.startAngle()(d)+arc.endAngle()(d))/2); 结果=“平移(“+质心+”)旋转(“+角度+”
-标高<3必须是弯曲的,并且“遵循”圆弧半径。
-标高==3必须笔直且垂直于弧半径 我没有使用textPath标记,因为我对SVG没有真正的经验,而且它看起来过于复杂,我也不知道如何使用它 以下是我的代码(没有JSON,但这是一个非常经典的代码,如果需要,我可以添加一部分):
var宽度=800;
var高度=800;
var半径=400;
var formatNumber=d3.format(“,d”);
var x=d3.scaleLinear().range([0,2*Math.PI]);
变量y=d3.scaleSqrt().range([0,radius]);
var arc=d3.arc()
.startAngle(函数(d){返回Math.max(0,Math.min(2*Math.PI,x(d.x0));})
.endAngle(函数(d){返回Math.max(0,Math.min(2*Math.PI,x(d.x1));})
.innerRadius(函数(d){返回setRadius(“inner”,d.data.level);})
.outerRadius(函数(d){return setRadius(“outer”,d.data.level);});
var svg=d3。选择(“图表”)
.append(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度)
.附加(“g”)
.attr(“变换”、“平移”(+width/2+)、“+(height/2)+”);
var hierarchy=d3.hierarchy(数据集)
.sum(函数(d){返回d.size;});
var partition=d3.partition();
svg.selectAll(“路径”)
.data(分区(层次结构).子体())
.enter().append(“路径”)
.attr(“id”,函数(d,i){return“path”+i;})
.attr(“d”,弧)
.attr(“笔划”、“白色”)
.attr(“笔划宽度”,“1px”)
.style(“fill”,函数(d){return(d.data.color)→d.data.color:'black';});
svg.selectAll(“文本”)
.data(分区(层次结构).子体())
.enter().append(“文本”)
.attr(“转换”,函数(d){return setLabelPosition(d);})
.attr(“文本锚定”、“中间”)
.attr(“路线基线”、“中间”)
.attr(“字体大小”,“18px”)
.attr(“fill”,函数(d){return d.data.textcolor;})
.text(函数(d){if(parseInt(d.data.level)>0&&parseInt(d.data.level)<4){return(d.data.name).toUpperCase();});
d3.select(self.frameElement)
.样式(“高度”,高度+px”);
功能设置半径(侧面、水平){
var结果=0;
var innerValues=[0、120、180、240、365];
var-outerValues=[0,180,240,365,400];
如果(!侧){
投掷误差;
}
如果(侧面=“内部”){
结果=内部值[级别];
}
如果(侧面=“外部”){
结果=外部值[级别];
}
返回结果;
};
功能设置位置(d){
var结果=“”;
var角=0;
var形心=弧形心(d);
if(parseInt(d.data.level)==3){
角度=(180/Math.PI*(arc.startAngle()(d)+arc.endAngle()(d))/2-90);
如果(角度>90){
角度=角度-180;
}
结果=“平移(“+质心+”)旋转(“+角度+”);
}否则{
角度=(180/Math.PI*(arc.startAngle()(d)+arc.endAngle()(d))/2);
结果=“平移(“+质心+”)旋转(“+角度+”);
}
返回结果;
};
结果是:我的问题是,如何弯曲这些1级和2级标签(如有红色边框的标签),但保持我的3级标签目前的状态 这真是让人头疼,我做了很多搜索(在谷歌等网站上),但没有找到任何令人满意的答案。
如果可能的话,一个不使用文本路径的解决方案将非常棒,但是任何建议都是欢迎的 非常感谢你们,为我的英语感到抱歉(你们可能会看到这不是我的母语)
PS:这是D3.js v4。我想答案在这里给出:我想答案在这里给出:
var width = 800;
var height = 800;
var radius = 400;
var formatNumber = d3.format(",d");
var x = d3.scaleLinear().range([0, 2 * Math.PI]);
var y = d3.scaleSqrt().range([0, radius]);
var arc = d3.arc()
.startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x0))); })
.endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x1))); })
.innerRadius(function(d) { return setRadius("inner", d.data.level); })
.outerRadius(function(d) { return setRadius("outer", d.data.level); });
var svg = d3.select("#chart")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/2 + "," + (height/2) + ")");
var hierarchy = d3.hierarchy(dataset)
.sum(function(d) { return d.size; });
var partition = d3.partition();
svg.selectAll("path")
.data(partition(hierarchy).descendants())
.enter().append("path")
.attr("id", function(d, i){ return "path" + i; })
.attr("d", arc)
.attr("stroke", "white")
.attr("stroke-width", "1px")
.style("fill", function(d) { return (d.data.color) ? d.data.color : 'black'; });
svg.selectAll("text")
.data(partition(hierarchy).descendants())
.enter().append("text")
.attr("transform", function(d){ return setLabelPosition(d); })
.attr("text-anchor", "middle")
.attr("alignment-baseline", "middle")
.attr("font-size", "18px")
.attr("fill", function(d){ return d.data.textcolor; })
.text(function(d){ if(parseInt(d.data.level) > 0 && parseInt(d.data.level) < 4){ return (d.data.name).toUpperCase(); }});
d3.select(self.frameElement)
.style("height", height + "px");
function setRadius(side, level){
var result = 0;
var innerValues = [0, 120, 180, 240, 365];
var outerValues = [0, 180, 240, 365, 400];
if(!side){
throw error;
}
if(side === "inner"){
result = innerValues[level];
}
if(side === "outer"){
result = outerValues[level];
}
return result;
};
function setLabelPosition(d){
var result = '';
var angle = 0;
var centroid = arc.centroid(d);
if(parseInt(d.data.level) === 3){
angle = (180/Math.PI * (arc.startAngle()(d) + arc.endAngle()(d))/2 - 90);
if(angle > 90){
angle = angle - 180;
}
result = "translate(" + centroid + ")rotate(" + angle + ")";
} else {
angle = (180/Math.PI * (arc.startAngle()(d) + arc.endAngle()(d))/2);
result = "translate(" + centroid + ")rotate(" + angle + ")";
}
return result;
};