【问题标题】:Why do bars appear with "inverted values"? d3.js为什么条形图出现“反转值”? d3.js
【发布时间】:2023-04-10 23:54:02
【问题描述】:

我正在尝试学习如何在 react 中使用 d3.js,但我的代码有问题。

我正在做一个条形图,但条形的值是“反转”的,例如,条形的值为 30%,但在图表中,条形显示为 70%(如 100% - 30 % = 70%)。 我该如何解决?

这是我的代码:codeSandBox.

我的其他问题是:如何更改条形的高度?我想添加一些 margin-top 以显示 y 轴的所有内容,但如果我这样做,条形仍然具有相同的高度并且与 yAxis 值不匹配

【问题讨论】:

    标签: javascript reactjs d3.js


    【解决方案1】:

    这里的问题是你正在交换 yheight 逻辑,它应该是:

    .attr("y", d => yScale(d.percent))
    .attr("height", d => height - margin.bottom - margin.top - yScale(d.percent)) 
    

    或者,如果您将工作高度设置为...

    height = totalHeight - margin.bottom - margin.top
    

    ...它可以只是:

    .attr("y", d => yScale(d.percent))
    .attr("height", d => height - yScale(d.percent)) 
    

    最重要的是(这解决了您的第二个问题),您使用 Bostock 的 margin convention 错误。您应该根据边距翻译g 组,然后将所有条形附加到该翻译组,而无需再次翻译它们。此外,将坐标区组附加到该 g 组。

    话虽如此,以下是进行这些更改的代码:

    const data = [{
        year: 2012,
        percent: 50
      },
      {
        year: 2013,
        percent: 30
      },
      {
        year: 2014,
        percent: 90
      },
      {
        year: 2015,
        percent: 60
      },
      {
        year: 2016,
        percent: 75
      },
      {
        year: 2017,
        percent: 20
      }
    ];
    
    const height = 300;
    const width = 370;
    const margin = {
      top: 20,
      right: 10,
      bottom: 20,
      left: 25
    };
    
    const xScale = d3.scaleBand()
      .domain(data.map(d => d.year))
      .padding(0.2)
      .range([0, width - margin.right - margin.left]);
    
    const yScale = d3
      .scaleLinear()
      .domain([0, 100])
      .range([height - margin.bottom - margin.top, 0]);
    
    const svg = d3
      .select("body")
      .append("svg")
      .attr("width", width)
      .attr("height", height)
      .style("margin-left", 10);
    
    const g = svg
      .append("g")
      .attr("transform", `translate(${margin.left}, ${margin.top})`);
    
    g
      .selectAll("rect")
      .data(data)
      .enter()
      .append("rect")
      .attr("x", d => xScale(d.year))
      .attr("y", d => yScale(d.percent))
      .attr("width", xScale.bandwidth())
      .attr("height", d => height - margin.bottom - margin.top - yScale(d.percent))
      .attr("fill", "steelblue")
    
    
    g.append("g")
      .call(d3.axisLeft(yScale));
    
    g.append("g")
      .call(d3.axisBottom(xScale))
      .attr(
        "transform",
        `translate(0, ${height - margin.bottom - margin.top})`
      );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

    【讨论】:

    • 宽度可以改成100%吗?
    【解决方案2】:
    svg
          .selectAll("rect")
          .data(data)
          .enter()
          .append("rect")
          .attr("x", d => xScale(d.year))
          .attr("y", d => height - yScale(100-d.percent))
          .attr("width", xScale.bandwidth())
          .attr("height", d => yScale(100-d.percent))
          .attr("fill", "steelblue")
          .attr("transform", `translate(${margin.left}, -${margin.bottom})`);
    

    你需要从 100 中减去百分比

    工作:https://codesandbox.io/s/crimson-microservice-8kjqd

    【讨论】:

    • 谢谢你,你能帮忙解决2个问题吗?
    • 是的,告诉我,上面的解决方案对你有用,请接受答案。
    • 第二个是关于问题的
    • 您的意思是 100 在顶部切割,您要修复它吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    相关资源
    最近更新 更多