简体   繁体   English

SVG数组不适用于HTML页面

[英]SVG array not available to HTML page

I'm referencing a .js file from my .html file and trying to append my SVG charts into specific div's. 我正在从.html文件引用.js文件,并尝试将SVG图表附加到特定的div中。 However, I get the following message in the console when I open the html file: 但是,当我打开html文件时,会在控制台中收到以下消息:

TypeError: svg[0] is undefined

When I include the script tag in my html along with my script.js code, I can find the "svg" array (and expected pie chart's) from the console. 当我在HTML中包含script标签以及script.js代码时,我可以从控制台中找到“ svg”数组(以及期望的饼图)。 [I used that data to build the forEach loop at the end of stack.js below.] I know that the stack.js code works because it's the same code from this question which I posted a few days ago. [我使用这些数据在下面stack.js的末尾构建了forEach循环。]我知道stack.js代码是有效的,因为它与几天前发布的该问题的代码相同。

I'm curious as to why I cannot get my .html file to "see" the array from my .js file. 我很好奇为什么我无法从我的.html文件中获取.html文件来“查看”数组。 Is there a way to do this, or am I missing a best-practice with d3 which I should be using? 有没有办法做到这一点,还是我错过了应该使用的d3最佳实践? Is it somehow related to d3 being asynchronous ? 它与d3异步有关吗?

stack.html: 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 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;
    });
};

The reason that you can't reference your svg[0] is-- as I mentioned in my comment-- because you are trying to do things before the DOM is loaded. 您不能引用svg [0]的原因是-正如我在评论中提到的-因为您正在尝试在加载DOM之前执行操作。 Moving your code into the window.onload would fix that particular error but you have additional problems with the way you're trying to do things. 将您的代码移到window.onload中可以修复该特定错误,但是您尝试执行操作的方式还有其他问题。

Below is a working example and is more what you want to do. 以下是一个有效的示例,是您想要做的更多事情。 You should be using d3's functionality to embed your charts where you want them. 您应该使用d3的功能将图表嵌入所需的位置。 Rather than sticking them in the body and then trying to move them around. 与其将它们粘在体内然后设法使它们四处移动,不如将它们粘在体内。

stack.js 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"; });

};

The key to getting the charts where you want them is in the second parameter of the data binding call. 将图表获得所需位置的关键是在数据绑定调用的第二个参数中。

   .selectAll("div")
   .data(data.data, function(d) { return d ? d.id : this.id })

The above generates a key value for both the elements and your data rows-- where those keys match, d3 binds that particular data row to the data element. 上面的代码为元素和您的数据行生成一个键值-在这些键匹配的情况下,d3将该特定数据行绑定到数据元素。

I also changed up your data structure a tiny bit because the way you're doing things with unique keys to identify your objects makes it difficult to work with d3's idea of data. 我还稍微更改了数据结构,因为您使用唯一键来标识对象的操作方式使d3的数据概念难以使用。 If you can't change up your data structure for some reason, then I'd suggest an intermediate function to reshape your data into something easier to work with. 如果您由于某种原因无法更改数据结构,那么我建议您使用一个中间函数将数据重塑为更易于使用的格式。 The other poster in your previous question commented on your data structure as well. 您上一个问题中的另一个张贴者也评论了您的数据结构。

Your stack.html is unchanged. 您的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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM