HTML 页面无法使用 SVG 数组
SVG array not available to HTML page
我正在从我的 .html 文件中引用一个 .js 文件,并尝试将我的 SVG 图表附加到特定的 div 中。但是,当我打开 html 文件时,我在控制台中收到以下消息:
TypeError: svg[0] is undefined
当我在我的 html 中包含 script 标签以及我的 script.js 代码时,我可以找到 "svg" 数组(和预期的饼图)来自控制台。 [我使用该数据在下面的 stack.js 末尾构建了 forEach 循环。] 我知道 stack.js 代码有效,因为它与我几天前发布的 中的代码相同以前。
我很好奇为什么我无法将我的 .html 文件从我的 .js 文件获取到 "see" 数组。有没有办法做到这一点,或者我错过了我应该使用的 d3 的最佳实践?它与 有某种关系吗?
stack.html:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="stack.js"></script>
</head>
<body>
<div id="pie1"></div>
<div id="pie2"></div>
</body>
</html>
stack.js
var data = {
"data":[
{"pie_one": {
"id": "pie1",
"results": [
{"ratio": 0.04, "total": 7, "failures": 1},
{"ratio": 0.04, "total": 8, "failures": 0},
{"ratio": 0.04, "total": 9001, "failures": 0}
]}
},
{"pie_two": {
"id": "pie2",
"results": [
{"ratio": 0.04, "total": 10, "failures": 0},
{"ratio": 0.04, "total": 11, "failures": 1},
{"ratio": 0.04, "total": 12, "failures": 1}
]}
}
]
};
var width = 300,
height = 300,
radius = Math.min(width, height) / 2;
var arc = d3.svg.arc()
.outerRadius(radius)
.innerRadius(radius - (radius / 2));
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.ratio; });
var svg = d3.select("body").selectAll("svg")
.data(data.data)
.enter()
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
svg[0].forEach(function(pie) {
var div = document.getElementById(pie.__data__.id);
div.innerHTML = pie;
});
var g = svg.selectAll(".arc")
.data(function(d,i) { return pie(d["pie"+(i+1)].results) })
.enter().append("g")
.attr("class", "arc")
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return (d.data.failures > 0) ? "#d63535" : "#22c12d"; });
window.onload = function() {
svg[0].forEach(function(pie) {
var div = document.getElementById(pie.__data__.id);
div.innerHTML = pie;
});
};
你不能引用你的 svg[0] 的原因是——正如我在评论中提到的——因为你试图在加载 DOM 之前做一些事情。将您的代码移至 window.onload 将修复该特定错误,但您尝试做事的方式会遇到其他问题。
下面是一个工作示例,更符合您的要求。您应该使用 d3 的功能将图表嵌入到您想要的位置。而不是将它们粘在体内然后尝试移动它们。
stack.js
var data = {
"data":[
{
"id": "pie1",
"results": [
{"ratio": 0.04, "total": 7, "failures": 1},
{"ratio": 0.04, "total": 8, "failures": 0},
{"ratio": 0.04, "total": 9001, "failures": 0}
]
},
{
"id": "pie2",
"results": [
{"ratio": 0.04, "total": 10, "failures": 0},
{"ratio": 0.04, "total": 11, "failures": 1},
{"ratio": 0.04, "total": 12, "failures": 1}
]
}
]
};
window.onload = function() {
var width = 300,
height = 300,
radius = Math.min(width, height) / 2;
var arc = d3.svg.arc()
.outerRadius(radius)
.innerRadius(radius - (radius / 2));
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.ratio; });
var svg = d3.select("body")
.selectAll("div")
.data(data.data, function(d) { return d ? d.id : this.id })
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var g = svg.selectAll(".arc")
.data(function(d) { return pie(d.results) })
.enter().append("g")
.attr("class", "arc")
.append("path")
.attr("d", arc)
.style("fill", function(d) { return (d.data.failures > 0) ? "#d63535" : "#22c12d"; });
};
在数据绑定调用的第二个参数中获取所需图表的关键。
.selectAll("div")
.data(data.data, function(d) { return d ? d.id : this.id })
以上为元素和数据行生成一个键值——当这些键匹配时,d3 将该特定数据行绑定到数据元素。
我还稍微更改了您的数据结构,因为您使用唯一键来识别对象的方式使得使用 d3 的数据理念变得困难。如果由于某种原因你不能改变你的数据结构,那么我会建议一个中间函数来将你的数据重塑成更容易使用的东西。您上一个问题中的另一位发帖人也对您的数据结构发表了评论。
你的stack.html没有变化。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="stack.js"></script>
</head>
<body>
<div id="pie1"></div>
<div id="pie2"></div>
</body>
</html>
我正在从我的 .html 文件中引用一个 .js 文件,并尝试将我的 SVG 图表附加到特定的 div 中。但是,当我打开 html 文件时,我在控制台中收到以下消息:
TypeError: svg[0] is undefined
当我在我的 html 中包含 script 标签以及我的 script.js 代码时,我可以找到 "svg" 数组(和预期的饼图)来自控制台。 [我使用该数据在下面的 stack.js 末尾构建了 forEach 循环。] 我知道 stack.js 代码有效,因为它与我几天前发布的
我很好奇为什么我无法将我的 .html 文件从我的 .js 文件获取到 "see" 数组。有没有办法做到这一点,或者我错过了我应该使用的 d3 的最佳实践?它与
stack.html:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="stack.js"></script>
</head>
<body>
<div id="pie1"></div>
<div id="pie2"></div>
</body>
</html>
stack.js
var data = {
"data":[
{"pie_one": {
"id": "pie1",
"results": [
{"ratio": 0.04, "total": 7, "failures": 1},
{"ratio": 0.04, "total": 8, "failures": 0},
{"ratio": 0.04, "total": 9001, "failures": 0}
]}
},
{"pie_two": {
"id": "pie2",
"results": [
{"ratio": 0.04, "total": 10, "failures": 0},
{"ratio": 0.04, "total": 11, "failures": 1},
{"ratio": 0.04, "total": 12, "failures": 1}
]}
}
]
};
var width = 300,
height = 300,
radius = Math.min(width, height) / 2;
var arc = d3.svg.arc()
.outerRadius(radius)
.innerRadius(radius - (radius / 2));
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.ratio; });
var svg = d3.select("body").selectAll("svg")
.data(data.data)
.enter()
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
svg[0].forEach(function(pie) {
var div = document.getElementById(pie.__data__.id);
div.innerHTML = pie;
});
var g = svg.selectAll(".arc")
.data(function(d,i) { return pie(d["pie"+(i+1)].results) })
.enter().append("g")
.attr("class", "arc")
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return (d.data.failures > 0) ? "#d63535" : "#22c12d"; });
window.onload = function() {
svg[0].forEach(function(pie) {
var div = document.getElementById(pie.__data__.id);
div.innerHTML = pie;
});
};
你不能引用你的 svg[0] 的原因是——正如我在评论中提到的——因为你试图在加载 DOM 之前做一些事情。将您的代码移至 window.onload 将修复该特定错误,但您尝试做事的方式会遇到其他问题。
下面是一个工作示例,更符合您的要求。您应该使用 d3 的功能将图表嵌入到您想要的位置。而不是将它们粘在体内然后尝试移动它们。
stack.js
var data = {
"data":[
{
"id": "pie1",
"results": [
{"ratio": 0.04, "total": 7, "failures": 1},
{"ratio": 0.04, "total": 8, "failures": 0},
{"ratio": 0.04, "total": 9001, "failures": 0}
]
},
{
"id": "pie2",
"results": [
{"ratio": 0.04, "total": 10, "failures": 0},
{"ratio": 0.04, "total": 11, "failures": 1},
{"ratio": 0.04, "total": 12, "failures": 1}
]
}
]
};
window.onload = function() {
var width = 300,
height = 300,
radius = Math.min(width, height) / 2;
var arc = d3.svg.arc()
.outerRadius(radius)
.innerRadius(radius - (radius / 2));
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.ratio; });
var svg = d3.select("body")
.selectAll("div")
.data(data.data, function(d) { return d ? d.id : this.id })
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var g = svg.selectAll(".arc")
.data(function(d) { return pie(d.results) })
.enter().append("g")
.attr("class", "arc")
.append("path")
.attr("d", arc)
.style("fill", function(d) { return (d.data.failures > 0) ? "#d63535" : "#22c12d"; });
};
在数据绑定调用的第二个参数中获取所需图表的关键。
.selectAll("div")
.data(data.data, function(d) { return d ? d.id : this.id })
以上为元素和数据行生成一个键值——当这些键匹配时,d3 将该特定数据行绑定到数据元素。
我还稍微更改了您的数据结构,因为您使用唯一键来识别对象的方式使得使用 d3 的数据理念变得困难。如果由于某种原因你不能改变你的数据结构,那么我会建议一个中间函数来将你的数据重塑成更容易使用的东西。您上一个问题中的另一位发帖人也对您的数据结构发表了评论。
你的stack.html没有变化。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="stack.js"></script>
</head>
<body>
<div id="pie1"></div>
<div id="pie2"></div>
</body>
</html>