首页 > 解决方案 > D3js v3 到 v5 升级:无法将字符串转换为整数

问题描述

我有一个 D3js 代码,它可以生成条形图,并且可以在 3.x 版本中正常工作。为了更新,我想将代码升级到版本 5。这样做后,我能够更正一些语法更新,例如scaleLinear,scaleBand等。数据是通过 tsv 导入的。该代码能够在页面上显示具有正确 x 轴宽度的条形图。但是,y 轴条超出范围,并且 y 轴上的刻度非常短。比如数据显示数据的最大值是30000,但是y轴只有0-90。经过进一步调查,生成 y 数据的 d.RFU 值似乎没有从字符串转换为整数。在 v3 代码中,我最后有一个函数,它使用一元运算符将 d.RFU 的类型转换为整数 d.RFU = +d.RFU

但是,它似乎不适用于 v5。这可能是由于替换异步代码的承诺实现吗?有关如何在版本 5 中解决此问题的任何解决方案?

如果您需要更多信息,请告诉我,如果我错过了任何东西,因为我是编程和这个网站的新手,请原谅我。任何帮助表示赞赏。

这是我现在拥有的部分代码:

  //set dimensions of SVG and margins
  var margin = { top: 30,  right: 100,  bottom: 50,   left: 100,  },
    width = divWidth - margin.left - margin.right,
    height = 250 - margin.top - margin.bottom,
    x = d3.scaleBand()
            .range([0, width - 20], 0.1),
    y = d3.scaleLinear()
        .range([height,0]); 
  //setup the axis
  var xAxis = d3.axisBottom(x);
  var yAxis = d3.axisLeft(y);  
  var svg = d3.select("#bargraphID")
    .append("svg")
    .attr("width", width + margin.left + margin.right - 100)
    .attr("height", height + margin.top + margin.bottom - 10)
    .append("g")
    .attr("transform", "translate (" + margin.left + "," + margin.top + ")");


d3.tsv(filename).then(function(data) {
    // get x values from the document id
    x.domain(data.map(function(d) {
      return d.ID;
    }));
    yMax = d3.max(data, function(d) {
      return d.RFU;
    });
    // get the y values from the document RFU tab
    y.domain([0, yMax]);

 //create the x-axis
    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate (0, " + height + ")")
      .call(xAxis)
      .selectAll("text")
      .style("text-anchor", "middle")
      .attr("dx", "0em")
      .attr("dy", "-0.55em")
      .attr("y", 30)
      .attr("class", "x-axisticks");


  //create the y-axis
    svg.append("g")
      .attr("class", "y axis")
      .call(yAxis);          

    //add the data as bars
    var bar = svg.selectAll("bar")
      .data(data)
      .enter()
      .append("rect")
      .style("fill", barColor)
      .attr("fill-opacity", "0.3")
      .attr("x", function(d) {
        return x(d.ID);
      })
      .attr("width", x.bandwidth())
      //set initial coords for bars for animation.
      .attr("y", height)
      .attr("height", 0)
      //animate bars to final heights
      .transition()
      .duration(700)
      .attr("y", function(d) {
        return y(d.RFU);
      })
      .attr("height", function(d) {
        return height - y(d.RFU);
        })
      .attr("fill-opacity", "1.0")
      .attr("class", "y-data");

 });

  //convert RFU to integers
  function type(d) {
    d.RFU = +d.RFU;
    return d;
  }

标签: javascriptd3.js

解决方案


就像旧的 v3 和 v4 版本一样,您必须将行转换功能传递给d3.tsvD3 v5:

d3.tsv(filename, type)

然后,将承诺与then. 请记住,d3.tsv始终返回字符串(无论是 D3 v3、v4 还是 v5),因为

如果未指定行转换函数,则字段值是字符串。

这是带有假数据的演示:

var tsv = URL.createObjectURL(new Blob([
  `name	RFU
  foo	12
  bar	42
  baz	17`
]));

d3.tsv(tsv, type).then(function(data) {
  console.log(data)
})

function type(d) {
  d.RFU = +d.RFU;
  return d;
}
<script src="https://d3js.org/d3.v5.min.js"></script>

PS:由于 SO 代码段可能在某些浏览器中加载该 blob 时出现问题,因此 JSFiddle 中的代码相同,请检查控制台:https ://jsfiddle.net/kv0ea0x2/


推荐阅读