Подтвердить что ты не робот

Не удалось интегрировать D3.js(сбрасываемое дерево) в приложение Angular

Я работаю над приложением angular. Я хочу добавить в следующий d3 chart, однако, когда я просто подключаю Javascript к моему контроллеру, стили в мою таблицу стилей, ничего не появляется. Что-то подсказывает мне, что angular и D3 не играют хорошо.

Я подключил мою установку angular без добавления в объект 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", "size": 283},
              {"name": "mod", "size": 591},
              {"name": "mul", "size": 603},
              {"name": "neq", "size": 599},
              {"name": "not", "size": 386},
              {"name": "or", "size": 323},
              {"name": "orderby", "size": 307},
              {"name": "range", "size": 772},
              {"name": "select", "size": 296},
              {"name": "stddev", "size": 363},
              {"name": "sub", "size": 600},
              {"name": "sum", "size": 280},
              {"name": "update", "size": 307},
              {"name": "variance", "size": 335},
              {"name": "where", "size": 299},
              {"name": "xor", "size": 354},
              {"name": "_", "size": 264}
             ]
            },
            {"name": "Minimum", "size": 843},
            {"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", "size": 335},
            {"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", "size": 3165},
                {"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
4b9b3361

Ответ 1

Очень просто сделать приложение angular и использовать d3 в вашем приложении. Прежде всего вам нужно узнать что-то о структуре angular. Как вы знаете, вам нужно ng-app использовать библиотеку angular, вы можете определить ее в теге html или body. Если вы хотите делиться данными между вашими директивами или работать с angular services, вам нужен контроллер angular. В этом случае $scope делится между контроллером и директивами. Последняя функция, которую вы должны использовать, является директивой. Таким образом, согласно этому отрывку, нормализуйте свой код. Прежде всего, вы не должны определять директиву для параметра css. Просто добавьте все из них в файл и введите его на главную страницу или вставьте в тег <style>. Поскольку я упоминаю директиву, просто используйте функции JavaScript. Итак, пусть реализует angular приложение:

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

Это две функции: контроллер ng-app и angular, и это директива.

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 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 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 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 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], search, 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], leaves, 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, [], 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"
 });

При этом:

d3.json("flare.json", function(error,values){
        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"
        });
    });

Вот весь код:

Часть Js:

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

        }]);
        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;
                    //values is the flare.json 
                    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 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 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 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 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], search, 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], leaves, index)[0];
                            }
                        }
                        else {
                            leaves.push({ id: ++index, text: node.name });
                        }
                        return [index, 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

Я создал рабочую демонстрационную версию , надеюсь эта помощь.

Ответ 2

Так что это трудно понять наверняка, не видя ваш фактический код D3, но я считаю, что проблема заключается в том, где вы загружаете свой D3 script.

В принципе, вы запускаете свой D3 script в своем контроллере, что слишком поздно. К моменту создания экземпляра контроллера DOM уже отображается Angular. Это справедливо даже по директиве. Чтобы манипулировать DOM (например, добавлять визуализацию D3), вам нужно переместить D3 script в директиву link. Функция link в директиве запускается один раз для каждого экземпляра директивы, чтобы скомпилировать представление директивы против правильной области действия и создать DOM.

function link (scope, element, attributes) {
  // D3 code here
}

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

return directive;

Вот хороший пример создания директивы D3

И здесь хороший обзор директив Angular, который детализирует фазу ссылки