我正在制作水平条形图,我想在条形图后移动y标签。
d3.csv("mydata.csv", function(data) {
// Add X axis
var x = d3.scaleLinear()
.domain([0, 100])
.range([ 0, width])
svg.append("g")
.attr("transform", "translate(0,0)")
.call(d3.axisTop(x).ticks(10).tickFormat(function(d){return d+ "%"}))
.selectAll("text")
.attr("transform", "translate(10,-12)rotate(-45)")
.style("text-anchor", "end");
// Y axis
var y = d3.scaleBand()
.range([ 0, height ])
.domain(data.map(function(d) { return d.type; }))
.padding(.5);
svg.append("g")
.call(d3.axisRight(y))
.selectAll('text')
.attr("x", function(d) { return d.number; } )
//Bars
svg.selectAll("myRect")
.data(data)
.enter()
.append("rect")
.attr("x", x(0.5) )
.attr("y", function(d) { return y(d.type); })
.attr("width", function(d) { return x(d.number); })
.attr("height", y.bandwidth() )
.attr("fill", "#69b3a2")
})
CSV文件有两列
在这部分代码上
svg.append("g")
.call(d3.axisRight(y))
.selectAll('text')
.attr("x", function(d) { return d.number; } )
如果我将.attr("x", function(d) { return d.number; } )
行替换为
.attr("x", 100 )
然后将标签向右移动。但是,当我尝试通过条形图的宽度使它保持动态时,文本保持在y轴的开始。
答案 0 :(得分:2)
在您的代码中,您试图移动轴的刻度,而不是使用标签作为<text>
元素来创建新的选择!这是一种非常不常见的方法,但是肯定是可行的。
主要问题只是数据:在这一行...
.attr("x", function(d) { return d.number; })
...原点(d
)与矩形所具有的原点不同,该原点来自您的数据。此处的数据只是轴刻度中的字符串。
因此,我们必须获取实际数据,因此我们可以获取number
值。像这样:
.attr("x", function(d) {
const datum = data.find(function(e){return e.type === d})
return x(datum.number);
})
这是您所做的更改(和一些伪造数据)的代码:
var width = 500,
height = 300,
padding = 20;
var data = [{
type: "foo",
number: 42
},
{
type: "bar",
number: 12
},
{
type: "baz",
number: 79
},
{
type: "foobar",
number: 17
},
{
type: "foobaz",
number: 36
}
];
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var x = d3.scaleLinear()
.domain([0, 100])
.range([padding, width - padding])
svg.append("g")
.attr("transform", "translate(0,20)")
.call(d3.axisTop(x).ticks(10).tickFormat(function(d) {
return d + "%"
}))
.selectAll("text")
.attr("transform", "translate(10,-12)rotate(-45)")
.style("text-anchor", "end");
// Y axis
var y = d3.scaleBand()
.range([padding, height - padding])
.domain(data.map(function(d) {
return d.type;
}))
.padding(0.5);
svg.append("g")
.attr("transform", "translate(20,0)")
.call(d3.axisRight(y))
.selectAll('text')
.attr("x", function(d) {
const datum = data.find(function(e) {
return e.type === d
})
return x(datum.number) + 6;
})
//Bars
svg.selectAll("myRect")
.data(data)
.enter()
.append("rect")
.attr("x", x(0.5))
.attr("y", function(d) {
return y(d.type);
})
.attr("width", function(d) {
return x(d.number);
})
.attr("height", y.bandwidth())
.attr("fill", "#69b3a2")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>