d3文本函数在选择中给出undefined

时间:2016-01-03 05:28:37

标签: d3.js

我正在进行this练习,请注意下面第3行中的文字功能提示未定义。参数 i 正在按预期给出数字。但为什么 d 未定义? d 不代表特定的 td 元素吗?如果不是它(文本回调函数中的d参数)实际上代表什么?

var td = d3.selectAll("#tableTrial tbody tr").selectAll("td");
td.style("color", function (d, i) { return i ? null : "red"; });
td.text(function (d, i) { alert(d); return i;});
myFactory.drawd3Dia();

如果我将第3行更改为此

td.text(function (i) { alert(i); return i;});

即将出现未定义。

上述的全部HTML如下。刚刚在文本文件中浏览并在浏览器中查看。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>My Angular App</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.12/d3.min.js" charset="utf-8"></script>
    <script type="text/javascript">

        (function () {
            'use strict';

            function myController($scope, $controller) {
                var td = d3.selectAll("#tableTrial tbody tr").selectAll("td");
                td.style("color", function (d, i) { return i ? null : "red"; });
                td.text(function (d, i) { alert(d); return i;});
                // If the above line is replaced with the following it again does not work.
                // td.text(function (i) { alert(i); return i;});
            }

            angular.module('myApp', []);
            angular.module('myApp').controller('myController', myController);
            myController.$inject = ['$scope', '$controller'];

        }())
    </script>
</head>
<body>
    <div data-ng-app="myApp">
        <div data-ng-controller="myController">
            <h1>Happy New Year :)</h1>
            <div id='tableTrial'>
                <table>
                    <thead>
                        <tr><td>  A</td><td>  B</td><td>  C</td><td>  D</td></tr>
                    </thead>
                    <tbody>
                        <tr><td>  0</td><td>  1</td><td>  2</td><td>  3</td></tr>
                        <tr><td>  4</td><td>  5</td><td>  6</td><td>  7</td></tr>
                        <tr><td>  8</td><td>  9</td><td> 10</td><td> 11</td></tr>
                        <tr><td> 12</td><td> 13</td><td> 14</td><td> 15</td></tr>
                    </tbody>
                </table>

            </div>
        </div>
    </div>
</body>
</html>

2 个答案:

答案 0 :(得分:1)

您需要将数据绑定到您的选择,以便d在回调函数中可用。在你的情况下:

var matrix = [
  [ 0,  1,  2,  3],
  [ 4,  5,  6,  7],
  [ 8,  9, 10, 11],
  [12, 13, 14, 15],
];
var td = d3.selectAll("#tableTrial tbody tr").selectAll("td")
         .data(matrix)  //bind selection with data as mentioned in the blog post
         .enter() // use the enter selection
         .append("td") // to append element on the page
td.style("color", function (d, i) { return i ? null : "red"; }); 
td.text(function (d, i) { alert(d); return i;}); // now d is available since this selection is binded with data.

有关此选择的更多信息post

答案 1 :(得分:0)

以下是最终的工作。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>My Angular App</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.12/d3.min.js" charset="utf-8"></script>
    <script type="text/javascript">

        (function () {
            'use strict';

            function myFactory($http) {
                var service = {
                    treeCollapse: CollpaseFunction,
                    drawd3Dia: D3DiagramFunction,
                    callParams: {}
                };

                return service;

                function D3DiagramFunction() { }

                function CollpaseFunction(c) { }
            }

            function myController($scope, $controller, myFactory) {

                var matrix = [
                  [10, 11, 12, 13],
                  [14, 15, 16, 17],
                  [18, 19, 110, 111],
                  [112, 113, 114, 115],
                ];

                var td = d3.selectAll("#tableTrial tbody tr")
                    //.selectAll("td")
                    .data(matrix)  //bind selection with data as mentioned in the blog post
                    //.enter() // use the enter selection
                    //.append("td"); // to append element on the page
                    .selectAll("td")
                    .data(function (d, i) { return d; })
                    .style("color", function (d, i) { return i ? null : "red"; })
                    .text(function (d, i) { return d; }) // now d is available since this selection is binded with data.
                ;
            }

            angular.module('myApp', []);
            angular.module('myApp').factory('myFactory', myFactory);
            myFactory.$inject = ['$http'];
            angular.module('myApp').controller('myController', myController);
            myController.$inject = ['$scope', '$controller', 'myFactory'];

        }())
    </script>
</head>
<body>
    <div data-ng-app="myApp">
        <div data-ng-controller="myController">
            <h1>Here we go...</h1>
            <div id='tableTrial'>
                <table>
                    <thead>
                        <tr><td>  A</td><td>  B</td><td>  C</td><td>  D</td></tr>
                    </thead>
                    <tbody>
                        <tr><td>  0</td><td>  1</td><td>  2</td><td>  3</td></tr>
                        <tr><td>  4</td><td>  5</td><td>  6</td><td>  7</td></tr>
                        <tr><td>  8</td><td>  9</td><td> 10</td><td> 11</td></tr>
                        <tr><td> 12</td><td> 13</td><td> 14</td><td> 15</td></tr>
                    </tbody>
                </table>

            </div>
        </div>
    </div>
</body>
</html>