怎么把D3js V2转换成V4?

时间:2018-11-23 05:42:51

标签: d3.js visualization

我尝试将D3js V2迁移到以下示例的V4:

https://jasonneylon.wordpress.com/2013/09/05/two-sided-horizontal-barchart-using-d3-js/

但是在迁移时出错: 错误:属性y:预期长度为“ NaN”。

第201行: .attr(“ y”,function(d,z){return y(z)+ y.bandwidth()/ 2;}) 和 第223行: .attr(“ y”,function(d){返回y(d)+ y.bandwidth()/ 2;}

请咨询。

<!DOCTYPE html>
<html>
<head>
<title>Bar Chart</title>
<script src="http://d3js.org/d3.v4.js"></script>
<style type="text/css">
.chart {
  background: #00ccff;
  margin: 10px;
  padding-top: 10px; 
}
.chart .right {
  stroke: white;
  fill: indianred; 
}
.chart .left {
  stroke: white;
  fill: steelblue; 
}
.chart rect:hover {
  fill: #64707d; 
}
.chart text {
  fill: white; 
}
.chart text.name {
  fill: black; 
}
</style>
</head>
<body>
<h1>Two sided horiztontal bar chart</h1>
<script type="text/javascript">
  var randomNumbers = function() { 
    var numbers = [];
    for (var i = 0; i < 20; i++) {
      numbers.push(parseInt(Math.random() * 19) + 1);
    }
    return numbers;
  };

  var randomNames = function() { 
    var names = [];
    for (var i = 0; i < 20; i++) {
      names.push(String.fromCharCode(65 + Math.random() * 25) + String.fromCharCode(65 + Math.random() * 25) + String.fromCharCode(65 + Math.random() * 25));
    }
    return names;
  };

  var names = randomNames();
  var leftData = randomNumbers();  
  var rightData = randomNumbers();

  for (var i= 0; i< names.length; i++) {
    console.log(names[i] + " from: " + leftData[i] + " to: " + rightData[i]);  
  }
  var labelArea = 160;
  var chart,
      width = 400,
      bar_height = 20,
      height = bar_height * (names.length);
  var rightOffset = width + labelArea;
  var chart = d3.select("body")
    .append('svg')
    .attr('class', 'chart')
    .attr('width', labelArea + width + width)
    .attr('height', height);

  var xFrom = d3.scaleLinear()
     .domain([0, d3.max(leftData)])
     .range([0, width]);

  var y = d3.scaleBand()
     .domain(names)
     .rangeRound([10, height]);
    console.log('Y Range: '+y.range());
    console.log('y.bandwidth(): '+y.bandwidth()); // 33

  var yPosByIndex = function(d, index){ return y(index); } 
  chart.selectAll("rect.left")
    .data(leftData)
    .enter().append("rect")
    .attr("x", function(pos) { return width - xFrom(pos); })
    .attr("y", yPosByIndex)
    .attr("class", "left")
    .attr("width", xFrom)
    .attr("height", y.bandwidth()); 

  chart.selectAll("text.leftscore")
    .data(leftData)
    .enter().append("text")
    .attr("x", function(d) { return width - xFrom(d); })
    .attr("y", function(d, z){ return y(z) + y.bandwidth()/2; } )
    .attr("dx", "20")
    .attr("dy", ".36em")
    .attr("text-anchor", "end")
    .attr('class', 'leftscore')
    .text(String);

  chart.selectAll("text.name")
    .data(names)
    .enter().append("text")
    .attr("x", (labelArea / 2) + width)
    .attr("y", function(d){ return y(d) + y.bandwidth()/2; } )
    .attr("dy", ".20em")
    .attr("text-anchor", "middle")
    .attr('class', 'name')
    .text(String);

  var xTo = d3.scaleLinear()
     .domain([0, d3.max(rightData)])
     .range([0, width]);

  chart.selectAll("rect.right")
    .data(rightData)
    .enter().append("rect")
    .attr("x", rightOffset)
    .attr("y", yPosByIndex)
    .attr("class", "right")
    .attr("width", xTo)
    .attr("height", y.bandwidth()); 

  chart.selectAll("text.score")
    .data(rightData)
    .enter().append("text")
    .attr("x", function(d) { return xTo(d) +  rightOffset; })
    .attr("y", function(d,z){ console.log(y(z)); return y(z) + y.bandwidth()/2; } )
    .attr("dx", -5)
    .attr("dy", ".36em")
    .attr("text-anchor", "end")
    .attr('class', 'score')
    .text(String);
</script>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

您致电console.log(y(z));,您将得到40 undefined。而且您不调查原因?

y的域是什么? 字符串

因此,如果您给它一个数字,很可能会给您一个错误的答案。

功能相同的原因

var yPosByIndex = function(d, index){ return y(index); }

错了。

出现所有这些问题的主要原因是,您有多个与索引相关的信息数组。用包含所有相关数据的对象创建1个数组。

var data = d3.range(20).map(i => { return {name: randomName(), left:randomNumber(), right:randomNumber()}; } );

现在调整您的程序以使用d.named.leftd.right

如果要计算数字的整数部分,请不要使用parseInt,这会很慢并且不清楚您想要什么,请使用Math.floor()

最好对左右栏使用相同的xScale。为什么其中一侧的值10的小条会变小?