lineageController.js 9.37 KB
Newer Older
1 2 3 4 5 6
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
7
 * 'License'); you may not use this file except in compliance
8 9 10 11 12
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an 'AS IS' BASIS,
14 15 16 17 18
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

Vishal Kadam committed
19 20
'use strict';

21 22 23
angular.module('dgc.lineage').controller('LineageController', ['$element', '$scope', '$state', '$stateParams', 'lodash', 'LineageResource', 'd3', 'DetailsResource', '$q',
    function($element, $scope, $state, $stateParams, _, LineageResource, d3, DetailsResource, $q) {
        var guidsList = [];
Vishal Kadam committed
24

25 26 27 28 29
        function getLineageData(tableData, callRender) {
            LineageResource.get({
                tableName: tableData.tableName,
                type: tableData.type
            }, function lineageSuccess(response) {
30
                if (!_.isEmpty(response.results.values.vertices)) {
31 32
                    var allGuids = loadProcess(response.results.values.edges, response.results.values.vertices);
                    allGuids.then(function(res) {
33
                        guidsList = res;
34 35 36 37 38
                        $scope.lineageData = transformData(response.results);
                        if (callRender) {
                            render();
                        }
                    });
39
                }
40
                $scope.requested = false;
41 42
            });
        }
43

44 45 46 47 48 49 50 51 52 53 54 55 56 57
        function loadProcess(edges, vertices) {

            var urlCalls = [];
            var deferred = $q.defer();
            for (var guid in edges) {
                if (!vertices.hasOwnProperty(guid)) {
                    urlCalls.push(DetailsResource.get({
                        id: guid
                    }).$promise);
                }

            }
            $q.all(urlCalls)
                .then(function(results) {
58
                    deferred.resolve(results);
59 60 61 62
                });
            return deferred.promise;
        }

63
        $scope.type = $element.parent().attr('data-table-type');
64
        $scope.requested = false;
65

66 67 68 69 70 71 72 73
        function render() {
            renderGraph($scope.lineageData, {
                element: $element[0],
                height: $element[0].offsetHeight,
                width: $element[0].offsetWidth
            });
            $scope.rendered = true;
        }
74

75 76 77
        $scope.$on('render-lineage', function(event, lineageData) {
            if (lineageData.type === $scope.type) {
                if (!$scope.lineageData) {
78
                    if (!$scope.requested) {
79
                        getLineageData(lineageData, true);
80
                        $scope.requested = true;
81 82 83 84 85
                    }
                } else {
                    render();
                }
            }
86
        });
87 88

        function transformData(metaData) {
89 90 91 92 93
            var edges = metaData.values.edges,
                vertices = metaData.values.vertices,
                nodes = {};

            function getNode(guid) {
94 95 96 97 98 99 100 101 102 103 104 105 106 107
                var name, type;
                if (vertices.hasOwnProperty(guid)) {
                    name = vertices[guid].values.name;
                    type = vertices[guid].values.vertexId.values.typeName;
                } else {
                    var loadProcess = getLoadProcessTypes(guid);
                    if (typeof loadProcess !== "undefined") {
                        name = loadProcess.name;
                        type = loadProcess.typeName;
                    } else {
                        name = 'Load Process';
                        type = 'Load Process';
                    }
                }
108
                var vertex = {
109
                    guid: guid,
110 111
                    name: name,
                    type: type
112 113 114 115 116 117 118
                };
                if (!nodes.hasOwnProperty(guid)) {
                    nodes[guid] = vertex;
                }
                return nodes[guid];
            }

119 120 121 122 123 124 125 126 127 128 129
            function getLoadProcessTypes(guid) {
                var procesRes = [];
                angular.forEach(guidsList, function(value) {
                    if (value.id.id === guid) {
                        procesRes.name = value.values.name;
                        procesRes.typeName = value.typeName;
                    }
                });
                return procesRes;
            }

130 131 132 133 134 135
            function attachParent(edge, node) {
                edge.forEach(function eachPoint(childGuid) {
                    var childNode = getNode(childGuid);
                    node.children = node.children || [];
                    node.children.push(childNode);
                    childNode.parent = node.guid;
136
                });
137 138
            }

139 140 141 142 143 144 145
            /* Loop through all edges and attach them to correct parent */
            for (var guid in edges) {
                var edge = edges[guid],
                    node = getNode(guid);

                /* Attach parent to each endpoint of edge */
                attachParent(edge, node);
146
            }
147 148 149 150 151

            /* Return the first node w/o parent, this is root node*/
            return _.find(nodes, function(node) {
                return !node.hasOwnProperty('parent');
            });
152 153
        }

154
        function renderGraph(data, container) {
155 156 157 158 159 160
            // ************** Generate the tree diagram	 *****************
            var element = d3.select(container.element),
                width = Math.max(container.width, 960),
                height = Math.max(container.height, 350);

            var margin = {
DarshanKumar committed
161
                top: 100,
DarshanKumar committed
162
                right: 80,
DarshanKumar committed
163
                bottom: 30,
DarshanKumar committed
164
                left: 80
165 166 167 168 169
            };
            width = width - margin.right - margin.left;
            height = height - margin.top - margin.bottom;

            var i = 0;
170

171
            var tree = d3.layout.tree()
Vishal Kadam committed
172
                .size([height, width]);
173

174 175 176
            var diagonal = d3.svg.diagonal()
                .projection(function(d) {
                    return [d.y, d.x];
177
                });
Vishal Kadam committed
178

179 180 181 182
            var svg = element.select('svg')
                .attr('width', width + margin.right + margin.left)
                .attr('height', height + margin.top + margin.bottom)
                .select('g')
DarshanKumar committed
183 184 185 186 187

            .attr('transform',
                'translate(' + margin.left + ',' + margin.right + ')');
            //arrow
            svg.append("svg:defs").append("svg:marker").attr("id", "arrow").attr("viewBox", "0 0 10 10").attr("refX", 26).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidth", 6).attr("markerHeight", 9).attr("orient", "auto").append("svg:path").attr("d", "M 0 0 L 10 5 L 0 10 z");
188 189 190 191 192 193 194 195 196 197 198 199

            var root = data;

            function update(source) {

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

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

202 203 204 205 206
                // Declare the nodes…
                var node = svg.selectAll('g.node')
                    .data(nodes, function(d) {
                        return d.id || (d.id = ++i);
                    });
Vishal Kadam committed
207

208 209 210 211 212 213 214
                // Enter the nodes.
                var nodeEnter = node.enter().append('g')
                    .attr('class', 'node')
                    .attr('transform', function(d) {
                        return 'translate(' + d.y + ',' + d.x + ')';
                    });

DarshanKumar committed
215 216 217 218
                nodeEnter.append("image")
                    .attr("xlink:href", function(d) {
                        //return d.icon;
                        return d.type === 'Table' ? '../img/tableicon.png' : '../img/process.png';
219
                    })
220 221
                    .attr("x", "-18px")
                    .attr("y", "-18px")
222 223
                    .attr("width", "34px")
                    .attr("height", "34px");
224 225 226
                nodeEnter.append('text')
                    .attr('x', function(d) {
                        return d.children || d._children ?
DarshanKumar committed
227
                            (5) * -1 : +15;
228
                    })
229
                    .attr('dy', '-1.75em')
230
                    .attr('text-anchor', function(d) {
DarshanKumar committed
231
                        return d.children || d._children ? 'middle' : 'middle';
232 233 234 235
                    })
                    .text(function(d) {
                        return d.name;
                    })
DarshanKumar committed
236 237

                .style('fill-opacity', 1);
238 239 240 241 242 243 244 245 246 247

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

                link.enter().insert('path', 'g')
                    .attr('class', 'link')
                    //.style('stroke', function(d) { return d.target.level; })
DarshanKumar committed
248
                    .style('stroke', 'green')
249
                    .attr('d', diagonal);
250
                link.attr("marker-end", "url(#arrow)");
251 252 253 254

            }

            update(root);
255
        }
Vishal Kadam committed
256 257

    }
Vishal Kadam committed
258
]);