gpt4 book ai didi

javascript - d3 径向条形图中的标签放置

转载 作者:行者123 更新时间:2023-11-29 17:51:53 24 4
gpt4 key购买 nike

在我的 d3 径向图表中,我试图让标签文本恰好位于线段圆弧上方,而不是保持在外圆之外。

Fiddle

    var width = 360,
height = 300,
barHeight = height / 2 - 40;

var formatNumber = d3.format("s");

var color = d3.scale.ordinal()
.range(["#F15D5D","#FAD64B"]);

var svg = d3.select('#chart').append("svg")
.attr("width", width)
.attr("height", height)
.attr('class','radial')
.append("g")
.attr("transform", "translate(" + width/2 + "," + height/2 + ")");

var data = [{
"name": "ABC",
"value":4
},
{
"name": "XYZ",
"value":5
},{
"name": "DEF",
"value":2
},
{
"name": "GHI",
"value":3
},{
"name": "JKL",
"value":1
}];

data.sort(function(a,b) { return b.value - a.value; });

var extent = [0, d3.max(data, d=>d.value)];
var barScale = d3.scale.linear()
.domain(extent)
.range([0, barHeight]);

var keys = data.map(function(d,i) { return d.name; });
var numBars = keys.length;


// X scale
var x = d3.scale.linear()
.domain(extent)
.range([0, -barHeight]);

// X axis
var xAxis = d3.svg.axis()
.scale(x).orient("left")
.ticks(3)
.tickFormat(formatNumber);

// Inner circles
var circles = svg.selectAll("circle")
.data(x.ticks(5))
.enter().append("circle")
.attr("r", function(d) {return barScale(d);})
.style("fill", "none")
//.style("stroke", "black")
//.style("stroke-dasharray", "2,2")
.style("stroke-width",".5px");

// Create arcs
var arc = d3.svg.arc()
.startAngle(function(d,i) {
var a = (i * 2 * Math.PI) / numBars;
var b = ((i + 1) * 2 * Math.PI) / numBars;
var d = (b-a) / 4;
var x = a+d;
var y = b-d;

return x;//(i * 2 * Math.PI) / numBars;
})
.endAngle(function(d,i) {
var a = (i * 2 * Math.PI) / numBars;
var b = ((i + 1) * 2 * Math.PI) / numBars;
var d = (b-a) / 4;
var x = a+d;
var y = b-d;
return y;//((i + 1) * 2 * Math.PI) / numBars;
})
.innerRadius(0);

// Render colored arcs
var segments = svg.selectAll("path")
.data(data)
.enter().append("path")
.each(function(d) { d.outerRadius = 0; })
.style("fill", function (d) { return color(d.name); })
.attr("d", arc);

// Animate segments
segments.transition().ease("elastic").duration(1000).delay(function(d,i) {return (25-i)*50;})
.attrTween("d", function(d,index) {
var i = d3.interpolate(d.outerRadius, barScale(+d.value));
return function(t) { d.outerRadius = i(t); return arc(d,index); };
});

// Outer circle
svg.append("circle")
.attr("r", barHeight)
.classed("outer", true)
.style("fill", "none")
//.style("stroke", "black")
.style("stroke-width",".5px");

// Apply x axis
svg.append("g")
.attr("class", "x axis")
.call(xAxis);

// Labels
var labelRadius = barHeight * 1.025;

var labels = svg.append("g")
.classed("labels", true);

labels.append("def")
.append("path")
.attr("id", "label-path")
.attr("d", "m0 " + -labelRadius + " a" + labelRadius + " " + labelRadius + " 0 1,1 -0.01 0");

labels.selectAll("text")
.data(keys)
.enter().append("text")
.style("text-anchor", "middle")
.style("font-weight","bold")
.style("fill", function(d, i) {return "#555";})
.append("textPath")
.attr("xlink:href", "#label-path")
.attr("startOffset", function(d, i) {return i * 100 / numBars + 50 / numBars + '%';})
.text(function(d) {return d.toUpperCase(); });

最佳答案

我们可以设置<defs>的位置的路径使用您用来创建圆弧的相同数据。

首先,让我们创建一个输入选择:

var labels = svg.selectAll("foo")
.data(data)
.enter()
.append("g")
.classed("labels", true);

然后,我们使用 barScale 附加路径对于每个值(此处为 4px 的硬编码填充):

labels.append("def")
.append("path")
.attr("id", (d, i) => "label-path" + i)
.attr("d", d => "m0 " + -(barScale(d.value) + 4) +
" a" + (barScale(d.value) + 4) + " " +
(barScale(d.value) + 4) + " 0 1,1 -0.01 0");

请注意,我们必须使用唯一 ID。然后,我们更改文本路径中的 ID:

.attr("xlink:href", (d, i) => "#label-path" + i)

这是您更新的 fiddle :https://jsfiddle.net/qt3e0rex/

Stack 片段中的相同代码:

var width = 360,
height = 300,
barHeight = height / 2 - 40;

var formatNumber = d3.format("s");

var color = d3.scale.ordinal()
.range(["#F15D5D", "#FAD64B"]);

var svg = d3.select('body').append("svg")
.attr("width", width)
.attr("height", height)
.attr('class', 'radial')
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var data = [{
"name": "ABC",
"value": 4
}, {
"name": "XYZ",
"value": 5
}, {
"name": "DEF",
"value": 2
}, {
"name": "GHI",
"value": 3
}, {
"name": "JKL",
"value": 1
}];

data.sort(function(a, b) {
return b.value - a.value;
});

var extent = [0, d3.max(data, d => d.value)];
var barScale = d3.scale.linear()
.domain(extent)
.range([0, barHeight]);

var keys = data.map(function(d, i) {
return d.name;
});
var numBars = keys.length;

// X scale
var x = d3.scale.linear()
.domain(extent)
.range([0, -barHeight]);

// X axis
var xAxis = d3.svg.axis()
.scale(x).orient("left")
.ticks(3)
.tickFormat(formatNumber);

// Inner circles
var circles = svg.selectAll("circle")
.data(x.ticks(5))
.enter().append("circle")
.attr("r", function(d) {
return barScale(d);
})
.style("fill", "none")
//.style("stroke", "black")
//.style("stroke-dasharray", "2,2")
.style("stroke-width", ".5px");

// Create arcs
var arc = d3.svg.arc()
.startAngle(function(d, i) {
var a = (i * 2 * Math.PI) / numBars;
var b = ((i + 1) * 2 * Math.PI) / numBars;
var d = (b - a) / 4;
var x = a + d;
var y = b - d;

return x; //(i * 2 * Math.PI) / numBars;
})
.endAngle(function(d, i) {
var a = (i * 2 * Math.PI) / numBars;
var b = ((i + 1) * 2 * Math.PI) / numBars;
var d = (b - a) / 4;
var x = a + d;
var y = b - d;
return y; //((i + 1) * 2 * Math.PI) / numBars;
})
.innerRadius(0);

// Render colored arcs
var segments = svg.selectAll("path")
.data(data)
.enter().append("path")
.each(function(d) {
d.outerRadius = 0;
})
.style("fill", function(d) {
return color(d.name);
})
.attr("d", arc);

// Animate segments
segments.transition().ease("elastic").duration(1000).delay(function(d, i) {
return (25 - i) * 50;
})
.attrTween("d", function(d, index) {
var i = d3.interpolate(d.outerRadius, barScale(+d.value));
return function(t) {
d.outerRadius = i(t);
return arc(d, index);
};
});

// Outer circle
svg.append("circle")
.attr("r", barHeight)
.classed("outer", true)
.style("fill", "none")
//.style("stroke", "black")
.style("stroke-width", ".5px");

// Apply x axis
svg.append("g")
.attr("class", "x axis")
.call(xAxis);

// Labels
var labelRadius = barHeight * 1.025;

var labels = svg.selectAll("foo")
.data(data)
.enter()
.append("g")
.classed("labels", true);

labels.append("def")
.append("path")
.attr("id", (d, i) => "label-path" + i)
.attr("d", d => "m0 " + -(barScale(d.value) + 4) + " a" + (barScale(d.value) + 4) + " " + (barScale(d.value) + 4) + " 0 1,1 -0.01 0");

labels.append("text")
.style("text-anchor", "middle")
.style("font-weight", "bold")
.style("fill", function(d, i) {
return "#555";
})
.append("textPath")
.attr("xlink:href", (d, i) => "#label-path" + i)
.attr("startOffset", function(d, i) {
return i * 100 / numBars + 50 / numBars + '%';
})
.text(function(d) {
return d.name.toUpperCase();
});
body {
background-color:#fff;
}
.axis path, .axis line {
fill: none;
shape-rendering: crispEdges;
}

.x.axis path {
display: none;
}

.tick text, line {
display:none;
}

circle {
stroke:#ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

关于javascript - d3 径向条形图中的标签放置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42777234/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com