首页 > 解决方案 > 在水平条形图上的条形之后附加文本

问题描述

我正在处理水平条形图,我想在条形之后移动 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 )then 替换该行,它会将标签向右移动。但是,当我尝试通过条形的宽度使其保持动态时,文本将保持在 y 轴的起点。

标签: javascriptd3.jssvg

解决方案


<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>


推荐阅读