我尝试将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>
答案 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.name
,d.left
,d.right
。
如果要计算数字的整数部分,请不要使用parseInt
,这会很慢并且不清楚您想要什么,请使用Math.floor()
最好对左右栏使用相同的xScale。为什么其中一侧的值10的小条会变小?