我正在尝试使用 D3 从 csv 文件绘制散点图。 csv 看起来像这样:
location smokeSomeDays allFamPovPct
AL 5% 15%
AK 5% 8%
AZ 4% 13%
AR 6% 14%
CA 4% 12%
CO 4% 8%
CT 4% 8%
DE 4% 9%
DC 5% 14%
...
...
...
我希望 Y 轴为“smokeSomeDays”,X 轴为“allFamPovPct”
这是我的 js,它引发了“无法读取 null 的属性“getAttribute””错误,即使代码中的任何地方都没有提到“getAttribute”:
var svgW = 960;
var svgH = 500;
var margin = { top: 20, right: 40, bottom: 60, left: 50 };
var chartWidth = svgW - margin.left - margin.right;
var chartHeight = svgH - margin.top - margin.bottom;
var svg = d3.select("body")
.append("svg")
.attr("width", svgW)
.attr("height", svgH)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv('data.csv', function(data) {
data.forEach(function () {
// Scales
var xScale = d3.scaleLinear()
.domain([
d3.min([0,d3.min(data,function (d) { return d.allFamPovPct })]),
d3.max([0,d3.max(data,function (d) { return d.allFamPovPct })])
])
.range([0,chartWidth])
var yScale = d3.scaleLinear()
.domain([
d3.min([0,d3.min(data,function (d) { return d.smokeSomeDays })]),
d3.max([0,d3.max(data,function (d) { return d.smokeSomeDays })])
])
.range([chartHeight,0])
// X-axis
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(5)
// Y-axis
var yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5)
// Circles
var circles = svg.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cx',function (d) { return xScale(d.allFamPovPct) })
.attr('cy',function (d) { return yScale(d.smokeSomeDays) })
.attr('r','10')
.attr('stroke','black')
.attr('stroke-width',1)
.attr('fill')
svg.append('g')
.attr('class','axis')
.attr('transform', 'translate(0,' + chartHeight + ')')
.call(xAxis)
.append('text') // X-axis Label
.attr('class','label')
.attr('y',-10)
.attr('x',chartWidth)
svg.append('g')
.attr('class', 'axis')
.call(yAxis)
.append('text') // y-axis Label
.attr('class','label')
.attr('transform','rotate(-90)')
.attr('x',0)
.attr('y',5)
});
});
完整的错误消息如下所示:
Uncaught TypeError: Cannot read property 'getAttribute' of null d3.min.js:4
at dt.ul [as attr] (d3.min.js:4)
at app.js:49
at Array.forEach (<anonymous>)
at app.js:17
at d3.min.js:3
at Object.<anonymous> (d3.min.js:7)
at v.call (d3.min.js:4)
at XMLHttpRequest.e (d3.min.js:7)
但是错误中提到的所有行对我来说看起来都很好,也许我遗漏了一些东西。
该代码也没有生成我想要的散点图。它给了我这样的东西:
|
|
|
|
|
|
|
|
|
O ---------------------------------------
这是我的 html,如果有帮助的话:
<!DOCTYPE html>
<html>
<head>
<title>Data Journalism</title>
<style>
.chart {
}
.main text {
font: 10px sans-serif;
}
.axis circle, .axis path {
shape-rendering: crispEdges;
stroke: black;
fill: none;
}
circle {
fill: steelblue;
}
</style>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.7.3/d3.min.js">
</script>
</head>
<body>
<div class='content'></div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
提前感谢您的帮助!
最佳答案
您现在遇到的错误是由于...
.attr("fill")
...是一个getter,而不是setter。请记住,此错误是由 D3 库引发的,但您的控制台显示的您的代码行才是真正的罪魁祸首。
但是,这是您遇到的最小问题。
第一个大问题是回调中的 forEach
。这在 D3 代码中是完全没有必要的。摆脱它。
第二个问题是 smokeSomeDays
和 allFamPovPct
是字符串,而不是数字。您必须将它们转换为数字才能使用您的秤。在本例中,我使用行函数:
function(d){
d.smokeSomeDays = +d.smokeSomeDays.split("%")[0];
d.allFamPovPct = +d.allFamPovPct.split("%")[0];
return d;
}
以下是包含这些更改的代码(以及 CSV 的几行):
var csv = `location,smokeSomeDays,allFamPovPct
AL,5%,15%
AK,5%,8%
AZ,4%,13%
AR,6%,14%`;
var svgW = 400;
var svgH = 300;
var margin = {
top: 20,
right: 40,
bottom: 60,
left: 50
};
var chartWidth = svgW - margin.left - margin.right;
var chartHeight = svgH - margin.top - margin.bottom;
var svg = d3.select("body")
.append("svg")
.attr("width", svgW)
.attr("height", svgH)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var data = d3.csvParse(csv, function(d) {
d.smokeSomeDays = +d.smokeSomeDays.split("%")[0];
d.allFamPovPct = +d.allFamPovPct.split("%")[0];
return d;
})
var xScale = d3.scaleLinear()
.domain([
d3.min([0, d3.min(data, function(d) {
return d.allFamPovPct
})]),
d3.max([0, d3.max(data, function(d) {
return d.allFamPovPct
})])
])
.range([0, chartWidth])
var yScale = d3.scaleLinear()
.domain([
d3.min([0, d3.min(data, function(d) {
return d.smokeSomeDays
})]),
d3.max([0, d3.max(data, function(d) {
return d.smokeSomeDays
})])
])
.range([chartHeight, 0])
// X-axis
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(5)
// Y-axis
var yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5)
// Circles
var circles = svg.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cx', function(d) {
return xScale(d.allFamPovPct)
})
.attr('cy', function(d) {
return yScale(d.smokeSomeDays)
})
.attr('r', '10')
.attr('stroke', 'black')
.attr('stroke-width', 1)
.attr("fill", "teal");
svg.append('g')
.attr('class', 'axis')
.attr('transform', 'translate(0,' + chartHeight + ')')
.call(xAxis)
.append('text') // X-axis Label
.attr('class', 'label')
.attr('y', -10)
.attr('x', chartWidth)
svg.append('g')
.attr('class', 'axis')
.call(yAxis)
.append('text') // y-axis Label
.attr('class', 'label')
.attr('transform', 'rotate(-90)')
.attr('x', 0)
.attr('y', 5)
<script src="https://d3js.org/d3.v4.min.js"></script>
关于javascript - 得到 "Cannot read property ' getAttribute' of null“错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47231814/