angularjs – 将D3.js(可折叠树)集成到Angular应用程序中有困难

前端之家收集整理的这篇文章主要介绍了angularjs – 将D3.js(可折叠树)集成到Angular应用程序中有困难前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在一个角度的应用程序.我想添加以下 d3 chart,但是当我简单地将JavaScript插入到我的控制器中时,样式到我的样式表中,没有任何显示.有人向我推荐,Angular和D3不是很好玩.

我附加了我的角度设置,而不添加在d3对象中.我想将它添加到workHistory Controller / Directive / View中.关于什么是正确的方式来设定这个问题的建议是什么?谢谢!

的index.html

<!doctype html>
    <html lang="en" ng-app="webApp">
    <head>
        <Meta charset="utf-8">

        <title>My Portfolio</title>

        <!--Stylesheets -->
        <link rel="stylesheet" href="styles/main.css"/>
        <link rel="stylesheet" href="styles/d3.tree.css"/>
        <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css"/>
        <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/select2/3.5.0/select2.min.css"/>
        <!--Libraries -->
        <script src="bower_components/angular/angular.min.js"></script>
        <script src="bower_components/jquery/dist/jquery.min.js"></script>
        <script src="bower_components/angular-route/angular-route.min.js"></script>
        <script src="bower_components/angular-loader/angular-loader.min.js"></script>
        <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/select2/3.5.0/select2.min.js"></script>
        <!--Module -->
        <script src="scripts/modules/module.js"></script>
        <script src="scripts/modules/d3.module.js"></script>
        <!--Controllers -->
        <script src="scripts/controllers/mainHeroController.js"></script>
        <script src="scripts/controllers/workHistoryController.js"></script>
        <!--Directives-->
        <script src="scripts/directives/mainHero.directive.js"></script>
        <script src="scripts/directives/mainNavbar.directive.js"></script>
        <script src="scripts/directives/workHistory.directive.js"></script>
    </head>

     <!--Main Landing Page-->    
    <body>
        <main-navbar></main-navbar>
        <main-hero></main-hero>
        <div id="container1" ng-controller="WorkHistoryController"> 
            <h3 id="tree-title">Work History</h3>
                <work-history chart-data="$scope.values"></work-history>
            </div>
        <div id="container2">
            Container 2
        </div>
    </body>
    </html>

workHistory.directive.js

(function()
    {
    'use strict';

    angular
        .module('webApp')
        .directive('workHistory',workHistory);

    function workHistory()
    {
        var directive = 
            {
                restrict: 'E',controller: 'WorkHistoryController',controllerAs: 'workhistory',scope: {},templateUrl: './views/workHistory.html'
            };

        return directive;

    }
    })();

workHistoryController.js

(function() 
  {

'use strict'

angular
    .module('webApp')
    .controller('WorkHistoryController',WorkHistoryController);

WorkHistoryController.$inject = ['$scope'];

function WorkHistoryController($scope) 
    {            
     console.log($scope);
      $scope.values = $scope.values || {};    
      $scope.values = {
         "name": "Work History","children": [
          {
           "name": "analytics","children": [
            {
             "name": "cluster","children": [
              {"name": "AgglomerativeCluster","size": 3938},{"name": "CommunityStructure","size": 3812},{"name": "HierarchicalCluster","size": 6714},{"name": "MergeEdge","size": 743}
             ]
            },{
             "name": "graph","children": [
              {"name": "BetweennessCentrality","size": 3534},{"name": "LinkDistance","size": 5731},{"name": "MaxFlowMinCut","size": 7840},{"name": "ShortestPaths","size": 5914},{"name": "SpanningTree","size": 3416}
             ]
            },{
             "name": "optimization","children": [
              {"name": "AspectRatioBanker","size": 7074}
             ]
            }
           ]
          },{
           "name": "animate","children": [
            {"name": "Easing","size": 17010},{"name": "FunctionSequence","size": 5842},{
             "name": "interpolate","children": [
              {"name": "ArrayInterpolator","size": 1983},{"name": "ColorInterpolator","size": 2047},{"name": "DateInterpolator","size": 1375},{"name": "Interpolator","size": 8746},{"name": "MatrixInterpolator","size": 2202},{"name": "NumberInterpolator","size": 1382},{"name": "ObjectInterpolator","size": 1629},{"name": "PointInterpolator","size": 1675},{"name": "RectangleInterpolator","size": 2042}
             ]
            },{"name": "ISchedulable","size": 1041},{"name": "Parallel","size": 5176},{"name": "Pause","size": 449},{"name": "Scheduler","size": 5593},{"name": "Sequence","size": 5534},{"name": "Transition","size": 9201},{"name": "Transitioner","size": 19975},{"name": "TransitionEvent","size": 1116},{"name": "Tween","size": 6006}
           ]
          },{
           "name": "data","children": [
            {
             "name": "converters","children": [
              {"name": "Converters","size": 721},{"name": "DelimitedTextConverter","size": 4294},{"name": "GraphMLConverter","size": 9800},{"name": "IDataConverter","size": 1314},{"name": "JSONConverter","size": 2220}
             ]
            },{"name": "DataField","size": 1759},{"name": "DataSchema","size": 2165},{"name": "DataSet","size": 586},{"name": "DataSource","size": 3331},{"name": "DataTable","size": 772},{"name": "DataUtil","size": 3322}
           ]
          },{
           "name": "display","children": [
            {"name": "DirtySprite","size": 8833},{"name": "LineSprite","size": 1732},{"name": "RectSprite","size": 3623},{"name": "TextSprite","size": 10066}
           ]
          },{
           "name": "flex","children": [
            {"name": "FlareVis","size": 4116}
           ]
          },{
           "name": "physics","children": [
            {"name": "DragForce","size": 1082},{"name": "GravityForce","size": 1336},{"name": "IForce","size": 319},{"name": "NBodyForce","size": 10498},{"name": "Particle","size": 2822},{"name": "Simulation","size": 9983},{"name": "Spring","size": 2213},{"name": "SpringForce","size": 1681}
           ]
          },{
           "name": "query","children": [
            {"name": "AggregateExpression","size": 1616},{"name": "And","size": 1027},{"name": "Arithmetic","size": 3891},{"name": "Average","size": 891},{"name": "BinaryExpression","size": 2893},{"name": "Comparison","size": 5103},{"name": "CompositeExpression","size": 3677},{"name": "Count","size": 781},{"name": "DateUtil","size": 4141},{"name": "Distinct","size": 933},{"name": "Expression","size": 5130},{"name": "ExpressionIterator","size": 3617},{"name": "Fn","size": 3240},{"name": "If","size": 2732},{"name": "IsA","size": 2039},{"name": "Literal","size": 1214},{"name": "Match","size": 3748},{"name": "Maximum","size": 843},{
             "name": "methods","children": [
              {"name": "add","size": 593},{"name": "and","size": 330},{"name": "average","size": 287},{"name": "count","size": 277},{"name": "distinct","size": 292},{"name": "div","size": 595},{"name": "eq","size": 594},{"name": "fn","size": 460},{"name": "gt","size": 603},{"name": "gte","size": 625},{"name": "iff","size": 748},{"name": "isa","size": 461},{"name": "lt","size": 597},{"name": "lte","size": 619},{"name": "max","size": 283},{"name": "min",{"name": "mod","size": 591},{"name": "mul",{"name": "neq","size": 599},{"name": "not","size": 386},{"name": "or","size": 323},{"name": "orderby","size": 307},{"name": "range",{"name": "select","size": 296},{"name": "stddev","size": 363},{"name": "sub","size": 600},{"name": "sum","size": 280},{"name": "update",{"name": "variance","size": 335},{"name": "where","size": 299},{"name": "xor","size": 354},{"name": "_","size": 264}
             ]
            },{"name": "Minimum",{"name": "Not","size": 1554},{"name": "Or","size": 970},{"name": "Query","size": 13896},{"name": "Range","size": 1594},{"name": "StringUtil","size": 4130},{"name": "Sum","size": 791},{"name": "Variable","size": 1124},{"name": "Variance","size": 1876},{"name": "Xor","size": 1101}
           ]
          },{
           "name": "scale","children": [
            {"name": "IScaleMap","size": 2105},{"name": "LinearScale","size": 1316},{"name": "LogScale","size": 3151},{"name": "OrdinalScale","size": 3770},{"name": "QuantileScale","size": 2435},{"name": "QuantitativeScale","size": 4839},{"name": "RootScale","size": 1756},{"name": "Scale","size": 4268},{"name": "ScaleType","size": 1821},{"name": "TimeScale","size": 5833}
           ]
          },{
           "name": "util","children": [
            {"name": "Arrays","size": 8258},{"name": "Colors","size": 10001},{"name": "Dates","size": 8217},{"name": "Displays","size": 12555},{"name": "Filter","size": 2324},{"name": "Geometry","size": 10993},{
             "name": "heap","children": [
              {"name": "FibonacciHeap","size": 9354},{"name": "HeapNode","size": 1233}
             ]
            },{"name": "IEvaluable",{"name": "IPredicate","size": 383},{"name": "IValueProxy","size": 874},{
             "name": "math","children": [
              {"name": "DenseMatrix","size": 3165},{"name": "IMatrix","size": 2815},{"name": "SparseMatrix","size": 3366}
             ]
            },{"name": "Maths","size": 17705},{"name": "Orientation","size": 1486},{
             "name": "palette","children": [
              {"name": "ColorPalette","size": 6367},{"name": "Palette","size": 1229},{"name": "ShapePalette","size": 2059},{"name": "SizePalette","size": 2291}
             ]
            },{"name": "Property","size": 5559},{"name": "Shapes","size": 19118},{"name": "Sort","size": 6887},{"name": "Stats","size": 6557},{"name": "Strings","size": 22026}
           ]
          },{
           "name": "vis","children": [
            {
             "name": "axis","children": [
              {"name": "Axes","size": 1302},{"name": "Axis","size": 24593},{"name": "AxisGridLine","size": 652},{"name": "AxisLabel","size": 636},{"name": "CartesianAxes","size": 6703}
             ]
            },{
             "name": "controls","children": [
              {"name": "AnchorControl","size": 2138},{"name": "ClickControl","size": 3824},{"name": "Control","size": 1353},{"name": "ControlList","size": 4665},{"name": "DragControl","size": 2649},{"name": "ExpandControl","size": 2832},{"name": "HoverControl","size": 4896},{"name": "IControl","size": 763},{"name": "PanZoomControl","size": 5222},{"name": "SelectionControl","size": 7862},{"name": "TooltipControl","size": 8435}
             ]
            },{
             "name": "data","children": [
              {"name": "Data","size": 20544},{"name": "DataList","size": 19788},{"name": "DataSprite","size": 10349},{"name": "EdgeSprite","size": 3301},{"name": "NodeSprite","size": 19382},{
               "name": "render","children": [
                {"name": "ArrowType","size": 698},{"name": "EdgeRenderer","size": 5569},{"name": "IRenderer","size": 353},{"name": "ShapeRenderer","size": 2247}
               ]
              },{"name": "ScaleBinding","size": 11275},{"name": "Tree","size": 7147},{"name": "TreeBuilder","size": 9930}
             ]
            },{
             "name": "events","children": [
              {"name": "DataEvent","size": 2313},{"name": "SelectionEvent","size": 1880},{"name": "TooltipEvent","size": 1701},{"name": "VisualizationEvent","size": 1117}
             ]
            },{
             "name": "legend","children": [
              {"name": "Legend","size": 20859},{"name": "LegendItem","size": 4614},{"name": "LegendRange","size": 10530}
             ]
            },{
             "name": "operator","children": [
              {
               "name": "distortion","children": [
                {"name": "BifocalDistortion","size": 4461},{"name": "Distortion","size": 6314},{"name": "FisheyeDistortion","size": 3444}
               ]
              },{
               "name": "encoder","children": [
                {"name": "ColorEncoder","size": 3179},{"name": "Encoder","size": 4060},{"name": "PropertyEncoder","size": 4138},{"name": "ShapeEncoder","size": 1690},{"name": "SizeEncoder","size": 1830}
               ]
              },{
               "name": "filter","children": [
                {"name": "FisheyeTreeFilter","size": 5219},{"name": "GraphDistanceFilter",{"name": "VisibilityFilter","size": 3509}
               ]
              },{"name": "IOperator","size": 1286},{
               "name": "label","children": [
                {"name": "Labeler","size": 9956},{"name": "RadialLabeler","size": 3899},{"name": "StackedAreaLabeler","size": 3202}
               ]
              },{
               "name": "layout","children": [
                {"name": "AxisLayout","size": 6725},{"name": "BundledEdgeRouter","size": 3727},{"name": "CircleLayout","size": 9317},{"name": "CirclePackingLayout","size": 12003},{"name": "DendrogramLayout","size": 4853},{"name": "ForceDirectedLayout","size": 8411},{"name": "IcicleTreeLayout","size": 4864},{"name": "IndentedTreeLayout","size": 3174},{"name": "Layout","size": 7881},{"name": "NodeLinkTreeLayout","size": 12870},{"name": "PieLayout","size": 2728},{"name": "RadialTreeLayout","size": 12348},{"name": "RandomLayout","size": 870},{"name": "StackedAreaLayout","size": 9121},{"name": "TreeMapLayout","size": 9191}
               ]
              },{"name": "Operator","size": 2490},{"name": "OperatorList","size": 5248},{"name": "OperatorSequence","size": 4190},{"name": "OperatorSwitch","size": 2581},{"name": "SortOperator","size": 2023}
             ]
            },{"name": "Visualization","size": 16540}
           ]
          }
         ]
        };
    }
})();

workHistory.html

//insert d3 view here

的main.css

//insert d3 styles here
在应用程序中进行角度应用和使用d3非常简单.首先,您需要了解有关角度结构的内容.如你所知,您需要使用ng-app来使用角度库,您可以使用html或body标签来定义.如果要在您的指令之间共享数据或使用角度服务,您需要角度控制器.在这种情况下,$scope在控制器和指令之间共享.你必须使用的最后一个功能是指令.
所以根据这个段落,我们来规范你的代码.首先,您不应该为css参数定义一个指令,只需将它们全部添加到一个文件中,并将其注入主页面或将其插入到< style>标签.
正如我提到的只是使用JavaScript函数的指令.
所以我们来实现角度应用:
var app = angular.module('App');
var ctrl = app.controller("treeCrtl",["$scope",function ($scope) { 
}]);

这两个功能是ng-app和角度控制器,这是指令.

ctrl.directive("workHistory",function () {
         return {
                restrict: 'E',link: function link(scope,el,attr) {

                    var div = d3.select("body")
                        .append("div") // declare the tooltip div
                        .attr("class","tooltip")
                        .style("opacity",0);

                    var margin = { top: 20,right: 120,bottom: 20,left: 120 },width = 960 - margin.right - margin.left,height = 800 - margin.top - margin.bottom;
                    var i = 0,duration = 750,root,select2_data;
                    var diameter = 960;
                    var tree = d3.layout.tree()
                        .size([height,width]);

                    var diagonal = d3.svg.diagonal()
                        .projection(function (d) { return [d.y,d.x]; });

                    var svg = d3.select(el[0]).append("svg")
                        .attr("width",width + margin.right + margin.left)
                        .attr("height",height + margin.top + margin.bottom)
                        .append("g")
                        .attr("transform","translate(" + margin.left + "," + margin.top + ")");

                    //recursively collapse children
                    function collapse(d) {
                        if (d.children) {
                            d._children = d.children;
                            d._children.forEach(collapse);
                            d.children = null;
                        }
                    }

                    // Toggle children on click.
                    function click(d) {
                        if (d.children) {
                            d._children = d.children;
                            d.children = null;
                        }
                        else {
                            d.children = d._children;
                            d._children = null;
                        }
                        update(d);
                    }

                    function openPaths(paths) {
                        for (var i = 0; i < paths.length; i++) {
                            if (paths[i].id !== "1") {//i.e. not root
                                paths[i].class = 'found';
                                if (paths[i]._children) { //if children are hidden: open them,otherwise: don't do anything
                                    paths[i].children = paths[i]._children;
                                    paths[i]._children = null;
                                }
                                update(paths[i]);
                            }
                        }
                    }


                        root = values;
                        select2_data = extract_select2_data(values,[],0)[1];//I know,not the prettiest...
                        root.x0 = height / 2;
                        root.y0 = 0;
                        root.children.forEach(collapse);
                        update(root);
                        //init search Box
                        $("#search").select2({
                            data: select2_data,containerCssClass: "search"
                        });


                    //attach search Box listener
                    $("#search").on("select2-selecting",function(e) {
                        var paths = searchTree(root,e.object.text,[]);
                        if (typeof (paths) !== "undefined") {
                            openPaths(paths);
                        } else {
                            alert(e.object.text + " not found!");
                        }
                    });

                    d3.select(self.frameElement).style("height","800px");

                    function update(source) {
                        // Compute the new tree layout.
                        var nodes = tree.nodes(root).reverse(),links = tree.links(nodes);

                        // Normalize for fixed-depth.
                        nodes.forEach(function (d) { d.y = d.depth * 180; });

                        // Update the nodes…
                        var node = svg.selectAll("g.node")
                            .data(nodes,function (d) { return d.id || (d.id = ++i); });

                        // Enter any new nodes at the parent's prevIoUs position.
                        var nodeEnter = node.enter().append("g")
                            .attr("class","node")
                        .attr("transform",function (d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
                        .on("click",click);

                        nodeEnter.append("circle")
                        .attr("r",1e-6)
                        .style("fill",function (d) { return d._children ? "lightsteelblue" : "#fff"; });

                        nodeEnter.append("text")
                            .attr("x",function (d) { return d.children || d._children ? -10 : 10; })
                            .attr("dy",".35em")
                            .attr("text-anchor",function (d) { return d.children || d._children ? "end" : "start"; })
                            .text(function (d) { return d.name; })
                            .style("fill-opacity",1e-6);

                        // Transition nodes to their new position.
                        var nodeUpdate = node.transition()
                            .duration(duration)
                            .attr("transform",function (d) { return "translate(" + d.y + "," + d.x + ")"; });

                        nodeUpdate.select("circle")
                            .attr("r",4.5)
                            .style("fill",function (d) {
                                if (d.class === "found") {
                                    return "#ff4136"; //red
                                }
                                else if (d._children) {
                                    return "lightsteelblue";
                                }
                                else {
                                    return "#fff";
                                }
                            })
                            .style("stroke",function (d) {
                                if (d.class === "found") {
                                    return "#ff4136"; //red
                                }
                            });

                        nodeUpdate.select("text")
                            .style("fill-opacity",1);

                        // Transition exiting nodes to the parent's new position.
                        var nodeExit = node.exit().transition()
                            .duration(duration)
                            .attr("transform",function (d) { return "translate(" + source.y + "," + source.x + ")"; })
                            .remove();

                        nodeExit.select("circle")
                            .attr("r",1e-6);

                        nodeExit.select("text")
                            .style("fill-opacity",1e-6);

                        // Update the links…
                        var link = svg.selectAll("path.link")
                            .data(links,function (d) { return d.target.id; });

                        // Enter any new links at the parent's prevIoUs position.
                        link.enter().insert("path","g")
                            .attr("class","link")
                            .attr("d",function (d) {
                                var o = { x: source.x0,y: source.y0 };
                                return diagonal({ source: o,target: o });
                            });

                        // Transition links to their new position.
                        link.transition()
                            .duration(duration)
                            .attr("d",diagonal)
                            .style("stroke",function (d) {
                                if (d.target.class === "found") {
                                    return "#ff4136";
                                }
                            });

                        // Transition exiting nodes to the parent's new position.
                        link.exit().transition()
                            .duration(duration)
                            .attr("d",function (d) {
                                var o = { x: source.x,y: source.y };
                                return diagonal({ source: o,target: o });
                            })
                            .remove();

                        // Stash the old positions for transition.
                        nodes.forEach(function (d) {
                            d.x0 = d.x;
                            d.y0 = d.y;
                        });
                    }

                    function searchTree(obj,search,path) {
                        if (obj.name === search) { //if search is found return,add the object to the path and return it
                            path.push(obj);
                            return path;
                        }
                        else if (obj.children || obj._children) { //if children are collapsed d3 object will have them instantiated as _children
                            var children = (obj.children) ? obj.children : obj._children;
                            for (var i = 0; i < children.length; i++) {
                                path.push(obj);// we assume this path is the right one
                                var found = searchTree(children[i],path);
                                if (found) {// we were right,this should return the bubbled-up path from the first if statement
                                    return found;
                                }
                                else {//we were wrong,remove this parent from the path and continue iterating
                                    path.pop();
                                }
                            }
                        }
                        else {//not the right object,return false so it will continue to iterate in the loop
                            return false;
                        }
                    }

                    function extract_select2_data(node,leaves,index) {
                        if (node.children) {
                            for (var i = 0; i < node.children.length; i++) {
                                index = extract_select2_data(node.children[i],index)[0];
                            }
                        }
                        else {
                            leaves.push({ id: ++index,text: node.name });
                        }
                        return [index,leaves];
                    }

                }
            }
        });

有一点我不得不提:

1-如果您必须实现不同的指令,只需使用与不同名称相同的格式.

2-要将代码链接到指令标签,您必须使用这种类型的编码:
d3.select(el [0]),注意el是链接函数参数.

3-如果你使用不同的目录为flare.json替换这部分:

root = values;
select2_data = extract_select2_data(values,not the prettiest...
root.x0 = height / 2;
root.y0 = 0;
root.children.forEach(collapse);
 update(root);
 //init search Box
 $("#search").select2({
   data: select2_data,containerCssClass: "search"
 });

有了这个:

d3.json("flare.json",function(error,values){
        root = values;
        select2_data = extract_select2_data(values,not the prettiest...
        root.x0 = height / 2;
        root.y0 = 0;
        root.children.forEach(collapse);
        update(root);
        //init search Box
        $("#search").select2({
            data: select2_data,containerCssClass: "search"
        });
    });

这是整个代码

Js部分:

var app = angular.module('App');
        var ctrl = app.controller("treeCrtl",function ($scope) {

        }]);
        ctrl.directive("workHistory",otherwise: don't do anything
                                    paths[i].children = paths[i]._children;
                                    paths[i]._children = null;
                                }
                                update(paths[i]);
                            }
                        }
                    }

                    root = values;
                    //values is the flare.json 
                    select2_data = extract_select2_data(values,not the prettiest...
                    root.x0 = height / 2;
                    root.y0 = 0;
                    root.children.forEach(collapse);
                    update(root);
                    //init search Box
                   $("#search").select2({
                     data: select2_data,containerCssClass: "search"
                    });

                    //attach search Box listener
                    $("#search").on("select2-selecting",leaves];
                    }

                }
            }
        });

Html部分:

<html>
<head>
    <title>flare</title>
    <Meta charset="utf-8" />
    <style>
        .node {
            cursor: pointer;
        }

        .node circle {
            fill: #fff;
            stroke: steelblue;
            stroke-width: 1.5px;
        }

        .found {
            fill: #ff4136;
            stroke: #ff4136;
        }
        .node text {
            font: 10px sans-serif;
        }

        .link {
            fill: none;
            stroke: #ccc;
            stroke-width: 1.5px;
        }
        /*Just to ensure the select2 Box is "glued" to the top*/
        .search {
            width: 100%;
        }
    </style>
    <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/select2/3.5.0/select2.min.css">
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/select2/3.5.0/select2.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
</head>
<body ng-app="App" ng-controller="treeCrtl">
    <div id="search"></div>
    <work-history></work-history>
</body>
</html>

更新1

我做了一个working demo,我希望这个帮助.

猜你在找的Angularjs相关文章