You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by sh...@apache.org on 2016/01/13 15:37:41 UTC

incubator-atlas git commit: ATLAS-406 Resizing lineage window – should be an anchor on a corner – like ppt for graphic (sanjayp via shwethags)

Repository: incubator-atlas
Updated Branches:
  refs/heads/master 0e81ceb4a -> c4eebe0ed


ATLAS-406 Resizing lineage window – should be an anchor on a corner – like ppt for graphic (sanjayp via shwethags)


Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/c4eebe0e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/c4eebe0e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/c4eebe0e

Branch: refs/heads/master
Commit: c4eebe0ed4a8489d92a9f75edef4819dc3fcde32
Parents: 0e81ceb
Author: Shwetha GS <ss...@hortonworks.com>
Authored: Wed Jan 13 20:07:34 2016 +0530
Committer: Shwetha GS <ss...@hortonworks.com>
Committed: Wed Jan 13 20:07:34 2016 +0530

----------------------------------------------------------------------
 dashboard/bower.json                            |  47 +-
 dashboard/gruntfile.js                          |   4 +-
 dashboard/public/css/common.css                 |  25 +-
 dashboard/public/css/lineage.css                |   6 +-
 dashboard/public/index.html                     |   2 +
 .../public/modules/lineage/lineageController.js | 656 -------------------
 .../modules/lineage/lineage_ioController.js     |  59 +-
 .../modules/lineage/views/lineage_io.html       |   2 +
 release-log.txt                                 |   1 +
 9 files changed, 104 insertions(+), 698 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c4eebe0e/dashboard/bower.json
----------------------------------------------------------------------
diff --git a/dashboard/bower.json b/dashboard/bower.json
index 2ffdc90..18ce5da 100644
--- a/dashboard/bower.json
+++ b/dashboard/bower.json
@@ -1,25 +1,26 @@
 {
-    "name": "atlas-metadata",
-    "description": "Apache Atlas",
-    "version": "1.0.0-SNAPSHOT",
-    "devDependencies": {
-        "angular": "~1.2.15",
-        "angular-resource": "~1.2.15",
-        "angular-cookies": "~1.2.15",
-        "angular-route": "~1.2.15",
-        "angular-sanitize": "~1.2.15",
-        "bootstrap": "~3.1.1",
-        "angular-bootstrap": "~0.12.0",
-        "angular-ui-router": "~0.2.13",
-        "d3": "~3.5.3",
-        "d3-tip": "~0.6.6",
-        "lodash": "~3.0.0",
-        "angular-ui-utils": "~0.1.1",
-        "font-awesome": "~4.2.0",
-        "closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
-        "ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.3/assets/ng-closure-runner.zip"
-    },
-    "resolutions": {
-        "d3": "~3.5.3"
-    }
+  "name": "atlas-metadata",
+  "description": "Apache Atlas",
+  "version": "1.0.0-SNAPSHOT",
+  "devDependencies": {
+    "angular": "~1.2.15",
+    "angular-resource": "~1.2.15",
+    "angular-cookies": "~1.2.15",
+    "angular-route": "~1.2.15",
+    "angular-sanitize": "~1.2.15",
+    "bootstrap": "~3.1.1",
+    "angular-bootstrap": "~0.12.0",
+    "angular-ui-router": "~0.2.13",
+    "d3": "~3.5.3",
+    "d3-tip": "~0.6.6",
+    "lodash": "~3.0.0",
+    "angular-ui-utils": "~0.1.1",
+    "font-awesome": "~4.2.0",
+    "closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
+    "ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.3/assets/ng-closure-runner.zip",
+    "jquery-ui": "1.10.4"
+  },
+  "resolutions": {
+    "d3": "~3.5.3"
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c4eebe0e/dashboard/gruntfile.js
----------------------------------------------------------------------
diff --git a/dashboard/gruntfile.js b/dashboard/gruntfile.js
index 52ae412..ef91408 100644
--- a/dashboard/gruntfile.js
+++ b/dashboard/gruntfile.js
@@ -154,9 +154,7 @@ module.exports = function(grunt) {
                     'hosts': [{
                         'hostnames': ['*'],
                         'routes': {
-                            '/': distPath,
-                            //'/api': 'http://162.249.6.39:21000/api'
-                             '/api': 'http://ec2-52-25-142-7.us-west-2.compute.amazonaws.com:21000/api'
+                            '/': distPath
                         }
                     }]
                 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c4eebe0e/dashboard/public/css/common.css
----------------------------------------------------------------------
diff --git a/dashboard/public/css/common.css b/dashboard/public/css/common.css
index e8d9345..853c664 100644
--- a/dashboard/public/css/common.css
+++ b/dashboard/public/css/common.css
@@ -114,14 +114,14 @@ header ul.menuBar li a{
 header ul.menuBar li a>i {
     margin-right: 3px;
     font-size: 12px;
-} 
+}
 header ul.menuBar li a:hover{
     color: #fff;
     background: transparent;
-} 
+}
 header ul.menuBar li a:focus{
     background: transparent;
-} 
+}
 header ul.menuBar li.active a{
     color: #333333;
     background-color: #ffffff;
@@ -319,11 +319,11 @@ Tags on Home Page design
     -o-text-overflow: ellipsis;
     white-space: nowrap;
     text-transform: capitalize;
-    float: left; 
-    
+    float: left;
+
     background: lightblue !important;
     color: black !important;
-    margin: 4px !important; 
+    margin: 4px !important;
     padding-left: 7px !important;
     padding-right: 7px !important;
 }
@@ -335,7 +335,7 @@ Tags on Home Page design
     text-overflow: ellipsis;
     -o-text-overflow: ellipsis;
     white-space: nowrap;
-    text-transform: capitalize; 
+    text-transform: capitalize;
 }
 .searchResultCount {
     max-width: 500px;
@@ -343,7 +343,7 @@ Tags on Home Page design
     overflow: hidden;
     text-overflow: ellipsis;
     -o-text-overflow: ellipsis;
-    text-transform: capitalize; 
+    text-transform: capitalize;
 }
 
 .maxwidth125px {
@@ -361,11 +361,18 @@ Tags on Home Page design
 
 .tagAlign{
     text-align: center;
-} 
+}
 
 .h160 {
     height: 160px !important;
 }
 .tag-attr{
     font-weight:bold;
+}
+.zoom-buttons{
+   width:63px !important;
+}
+.graph{
+  overflow: hidden!important;
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c4eebe0e/dashboard/public/css/lineage.css
----------------------------------------------------------------------
diff --git a/dashboard/public/css/lineage.css b/dashboard/public/css/lineage.css
index 180bebf..36f2423 100644
--- a/dashboard/public/css/lineage.css
+++ b/dashboard/public/css/lineage.css
@@ -69,7 +69,7 @@ div.lineage {
 
 .lineage-viz {
     margin: 0 auto;
-    overflow: auto;
+    overflow: hidden;
     /*border: 1px solid #ddd;
     border-top: none;*/
 
@@ -78,6 +78,10 @@ div.lineage {
     margin: 5px;
     border-radius: 2px
 }
+
+.title-font{
+    font-size:12px!important;
+}
 /*.images {*/
     /*background-image: url("../img/process.png");*/
 /*}​*/

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c4eebe0e/dashboard/public/index.html
----------------------------------------------------------------------
diff --git a/dashboard/public/index.html b/dashboard/public/index.html
index 2d0993f..cfd4e6d 100644
--- a/dashboard/public/index.html
+++ b/dashboard/public/index.html
@@ -36,6 +36,7 @@
   <link rel="stylesheet" href="/css/lineage.css">
   <link rel="stylesheet" href="/css/tags.css">
   <link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.css">
+    <link rel="stylesheet" href="/lib/jquery-ui/themes/ui-lightness/jquery-ui.css">
  </head>
 
 
@@ -68,6 +69,7 @@
 <script src="/lib/lodash/lodash.js"></script>
 <script src="/lib/d3/d3.js"></script>
 <script src="/lib/d3-tip/index.js"></script>
+<script src="/lib/jquery-ui/ui/jquery-ui.js"></script>
 
 <script src="/js/app.min.js"></script>
 </body>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c4eebe0e/dashboard/public/modules/lineage/lineageController.js
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/lineage/lineageController.js b/dashboard/public/modules/lineage/lineageController.js
deleted file mode 100644
index 2d88147..0000000
--- a/dashboard/public/modules/lineage/lineageController.js
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * 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
- * 'License'); you may not use this file except in compliance
- * 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
- * distributed under the License is distributed on an 'AS IS' BASIS,
- * 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.
- */
-
-'use strict';
-
-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 = [];
-
-        function getLineageData(tableData, callRender) {
-            LineageResource.get({
-                tableName: tableData.tableName,
-                type: tableData.type
-            }, function lineageSuccess(response) {
-                if (!_.isEmpty(response.results.values.vertices)) {
-                    var allGuids = loadProcess(response.results.values.edges, response.results.values.vertices);
-                    allGuids.then(function(res) {
-                        guidsList = res;
-                        $scope.lineageData = transformData(response.results);
-                        if (callRender) {
-                            render();
-                        }
-                    })
-                    .on("dblclick", function(d) {
-                        $state.go("details", {
-                            id: d.guid
-                        });
-                    });
-                }else{ 
-                    $scope.requested = false;
-                }
-            });
-        }
-
-        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) {
-                    deferred.resolve(results);
-                });
-            return deferred.promise;
-        }
-
-        $scope.type = $element.parent().attr('data-table-type');
-        $scope.requested = false;
-        $scope.height = $element[0].offsetHeight;
-        $scope.width = $element[0].offsetWidth;
-
-        function render() {
-            renderGraph($scope.lineageData, {
-                eleObj : $element,
-                element: $element[0],
-                height: $scope.height,
-                width: $scope.width
-            });
-            $scope.rendered = true;
-        }
-
-        $scope.onReset = function(){
-            renderGraph($scope.lineageData, {
-                eleObj : $element,
-                element: $element[0],
-                height: $scope.height,
-                width: $scope.width
-            }); 
-        };
-
-        $scope.$on('render-lineage', function(event, lineageData) {
-            if (lineageData.type === $scope.type) {
-                if (!$scope.lineageData) {
-                    if (!$scope.requested) {
-                        getLineageData(lineageData, true);
-                        $scope.requested = true;
-                    }
-                } else {
-                    render();
-                }
-            }
-        });
-
-        function transformData(metaData) {
-            var edges = metaData.values.edges,
-                vertices = metaData.values.vertices,
-                nodes = {};
-
-            function getNode(guid) {
-                var name, type, tip;
-                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;
-                        tip = loadProcess.tip;
-                    } else {
-                        name = 'Load Process';
-                        type = 'Load Process';
-                    }
-                }
-                var vertex = {
-                    guid: guid,
-                    name: name,
-                    type: type,
-                    tip: tip
-                };
-                if (!nodes.hasOwnProperty(guid)) {
-                    nodes[guid] = vertex;
-                }
-                return nodes[guid];
-            }
-
-            function getLoadProcessTypes(guid) {
-                var procesRes = [];
-                angular.forEach(guidsList, function(value) {
-                    if (value.id.id === guid) {
-                        procesRes.name = value.values.name;
-                        procesRes.typeName = value.typeName;
-                        procesRes.tip = value.values.queryText;
-                    }
-                });
-                return procesRes;
-            }
-
-            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;
-                });
-            }
-
-            /* 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);
-            }
-
-            /* Return the first node w/o parent, this is root node*/
-            return _.find(nodes, function(node) {
-                return !node.hasOwnProperty('parent');
-            });
-        }
-
-        function renderGraph(data, container) {
-            // ************** Generate the tree diagram  *****************
-            var element = d3.select(container.element),  
-                widthg = Math.max(container.width, 960),
-                heightg = Math.max(container.height, 500),
-
-                totalNodes = 0,
-                maxLabelLength = 0,
-                selectedNode = null,
-                draggingNode = null,
-                dragListener = null,
-                dragStarted = true,
-                domNode = null,
-                multiParents = null,
-                nodes = null,
-                tooltip = null,
-                node = null,  
-                i = 0,
-                duration = 750,
-                root,
-                depthwidth = 10;
-                
-
-            var viewerWidth = widthg - 15,
-                viewerHeight = heightg;
- 
-             var tree = d3.layout.tree().nodeSize([100, 200]);
-                /*.size([viewerHeight, viewerWidth]);*/
-
-    container.eleObj.find(".graph").html('');    
-    container.eleObj.find("svg").remove();
-
-    // define a d3 diagonal projection for use by the node paths later on.
-    var diagonal = d3.svg.diagonal()
-        .projection(function(d) {
-            return [d.y, d.x];
-        });
-
-    // A recursive helper function for performing some setup by walking through all nodes
-
-    function visit(parent, visitFn, childrenFn) {
-        if (!parent) return;
-
-        visitFn(parent);
-
-        var children = childrenFn(parent);
-        if (children) {
-            var count = children.length;
-            for (var i = 0; i < count; i++) {
-                visit(children[i], visitFn, childrenFn);
-            }
-        }
-    }
-
-    // Call visit function to establish maxLabelLength
-    visit(data, function(d) {
-        totalNodes++;
-        maxLabelLength = Math.max(d.name.length, maxLabelLength);
-
-    }, function(d) {
-        return d.children && d.children.length > 0 ? d.children : null;
-    });
-
-
-    // sort the tree according to the node names
-
-    function sortTree() {
-        tree.sort(function(a, b) {
-            return b.name.toLowerCase() < a.name.toLowerCase() ? 1 : -1;
-        });
-    }
-    // Sort the tree initially incase the JSON isn't in a sorted order.
-    sortTree(); 
-     
-    // Define the zoom function for the zoomable tree
-
-    function zoom() {
-        svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
-    }
-
-
-    // define the zoomListener which calls the zoom function on the "zoom" event constrained within the scaleExtents
-    var zoomListener = d3.behavior.zoom().scaleExtent([0.1, 3]).on("zoom", zoom);
-     /* Initialize tooltip */
-    tooltip = d3.tip()
-        .attr('class', 'd3-tip')
-        .html(function(d) {
-            return '<pre class="alert alert-success">' + d.name + '</pre>';
-        });
-
-    // define the baseSvg, attaching a class for styling and the zoomListener
-    var baseSvg = element.append('svg')        
-        .attr("width", viewerWidth)
-        .attr("height", viewerHeight)
-        .attr("class", "overlay")
-        .call(zoomListener)
-        .call(tooltip);
-
-
-    // Define the drag listeners for drag/drop behaviour of nodes.
-    dragListener = d3.behavior.drag()
-        .on("dragstart", function(d) {
-            if (d ===root) {
-                return;
-            }
-            dragStarted = true;
-            nodes = tree.nodes(d);
-            d3.event.sourceEvent.stopPropagation();
-            // it's important that we suppress the mouseover event on the node being dragged. Otherwise it will absorb the mouseover event and the underlying node will not detect it d3.select(this).attr('pointer-events', 'none');
-        }) 
-        .on("dragend", function(d) {
-            if (d ===root) {
-                return;
-            }
-            domNode = this;
-            if (selectedNode) {
-                // now remove the element from the parent, and insert it into the new elements children
-                var index = draggingNode.parent.children.indexOf(draggingNode);
-                if (index > -1) {
-                    draggingNode.parent.children.splice(index, 1);
-                }
-                if (typeof selectedNode.children !== 'undefined' || typeof selectedNode._children !== 'undefined') {
-                    if (typeof selectedNode.children !== 'undefined') {
-                        selectedNode.children.push(draggingNode);
-                    } else {
-                        selectedNode._children.push(draggingNode);
-                    }
-                } else {
-                    selectedNode.children = [];
-                    selectedNode.children.push(draggingNode);
-                }
-                // Make sure that the node being added to is expanded so user can see added node is correctly moved
-                expand(selectedNode);
-                sortTree();
-                endDrag();
-            } else {
-                endDrag();
-            }
-        });
-
-    function endDrag() {
-        selectedNode = null;
-        d3.selectAll('.ghostCircle').attr('class', 'ghostCircle');
-        d3.select(domNode).attr('class', 'node');
-        // now restore the mouseover event or we won't be able to drag a 2nd time
-        d3.select(domNode).select('.ghostCircle').attr('pointer-events', '');
-        updateTempConnector();
-        if (draggingNode !== null) {
-            update(root);
-            centerNode(draggingNode);
-            draggingNode = null;
-        }
-    }
-
-
-    function expand(d) {
-        if (d._children) {
-            d.children = d._children;
-            d.children.forEach(expand);
-            d._children = null;
-        }
-    } 
-
-    // Function to update the temporary connector indicating dragging affiliation
-    var updateTempConnector = function() {
-        var data = [];
-        if (draggingNode !== null && selectedNode !== null) {
-            // have to flip the source coordinates since we did this for the existing connectors on the original tree
-            data = [{
-                source: {
-                    x: selectedNode.y0,
-                    y: selectedNode.x0
-                },
-                target: {
-                    x: draggingNode.y0,
-                    y: draggingNode.x0
-                }
-            }];
-        }
-        var link = svgGroup.selectAll(".templink").data(data);
-
-        link.enter().append("path")
-            .attr("class", "templink")
-            .attr("d", d3.svg.diagonal())
-            .attr('pointer-events', 'none');
-
-        link.attr("d", d3.svg.diagonal());
-
-        link.exit().remove();
-    };
-
-    // Function to center node when clicked/dropped so node doesn't get lost when collapsing/moving with large amount of children.
-
-    function centerNode(source) {
-        var scale =  (depthwidth === 10) ? zoomListener.scale() : 0.4;
-        var x = -source.y0;
-        var y = -source.x0;
-        x = x * scale + 150;
-        y = y * scale + viewerHeight / 2;
-        d3.select('g').transition()
-            .duration(duration)
-            .attr("transform", "translate(" + x + "," + y + ")scale(" + scale + ")");
-        zoomListener.scale(scale);
-        zoomListener.translate([x, y]);
-    }
-
-    // Toggle children function
-
-    function toggleChildren(d) {
-        if (d.children) {
-            d._children = d.children;
-            d.children = null;
-        } else if (d._children) {
-            d.children = d._children;
-            d._children = null;
-        }
-        return d;
-    }
-
-    // Toggle children on click.
-
-    function click(d) {
-        if (d3.event.defaultPrevented) return; // click suppressed
-        d = toggleChildren(d);
-        update(d);
-        //centerNode(d);
-    }
-
-    //arrow
-            baseSvg.append("svg:defs")
-                .append("svg:marker")
-                .attr("id", "arrow")
-                .attr("viewBox", "0 0 10 10")
-                .attr("refX", 22)
-                .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");
-
-            //marker for input type graph
-            baseSvg.append("svg:defs")
-                .append("svg:marker")
-                .attr("id", "input-arrow")
-                .attr("viewBox", "0 0 10 10")
-                .attr("refX", -15)
-                .attr("refY", 5)
-                .attr("markerUnits", "strokeWidth")
-                .attr("markerWidth", 6)
-                .attr("markerHeight", 9)
-                .attr("orient", "auto")
-                .append("svg:path")
-                .attr("d", "M -2 5 L 8 0 L 8 10 z");
-
-    function update(source) {
-        // Compute the new height, function counts total children of root node and sets tree height accordingly.
-        // This prevents the layout looking squashed when new nodes are made visible or looking sparse when nodes are removed
-        // This makes the layout more consistent.
-        var levelWidth = [1];
-        var childCount = function(level, n) {
-
-            if (n.children && n.children.length > 0) {
-                if (levelWidth.length <= level + 1) levelWidth.push(0);
-
-                levelWidth[level + 1] += n.children.length;
-                n.children.forEach(function(d) {
-                    childCount(level + 1, d);
-                });
-            }
-        };
-        childCount(0, root);
-        tree = tree.nodeSize([50, 100]); 
-
-        // Compute the new tree layout.
-        var nodes = tree.nodes(root).reverse(),
-            links = tree.links(nodes);
-
-        // Set widths between levels based on maxLabelLength.
-        nodes.forEach(function(d) {
-            if(levelWidth.length > 1 && depthwidth === 10){
-               for(var o=0; o < levelWidth.length; o++){
-                  if(levelWidth[o] > 4 ) { depthwidth = 70;  break;}
-               }
-            }  
-            var maxLebal = maxLabelLength;
-            if(depthwidth === 10) { maxLebal = 20;}
-            d.y = (d.depth * (maxLebal * depthwidth));           
-        }); 
-
-        // Update the nodes…
-        node = svgGroup.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")
-            .call(dragListener)
-            .attr("class", "node")
-            .attr("transform", function() {
-                return "translate(" + source.y0 + "," + source.x0 + ")";
-            })
-            .on('click', click);
- 
-         nodeEnter.append("image")
-            .attr("class","nodeImage")
-            .attr("xlink:href", function(d) { 
-                return d.type === 'Table' ? '../img/tableicon.png' : '../img/process.png';
-            })
-            .on('mouseover', function(d) {
-                if (d.type === 'LoadProcess' || 'Table') {
-                    tooltip.show(d);
-                }
-            })
-            .on('mouseout', function(d) {
-                if (d.type === 'LoadProcess' || 'Table') {
-                    tooltip.hide(d);
-                }
-            })
-            .attr("x", "-18px")
-            .attr("y", "-18px")
-            .attr("width", "34px")
-            .attr("height", "34px");    
-
-        nodeEnter.append("text")
-            .attr("x", function(d) {
-                return d.children || d._children ? -10 : 10;
-            })
-            .attr("dx", function (d) { return d.children ? 50 : -50; })
-            .attr("dy", -24) 
-            .attr('class', 'place-label')
-            .attr("text-anchor", function(d) {
-                return d.children || d._children ? "end" : "start";
-            })
-            .text(function(d) {
-                var nameDis = (d.name.length > 15) ? d.name.substring(0,15) + "..." : d.name;
-                $(this).attr('title', d.name);
-                return nameDis;
-            })
-            .style("fill-opacity", 0); 
-
-        // Update the text to reflect whether node has children or not.
-        node.select('text')
-            .attr("x", function(d) {
-                return d.children || d._children ? -10 : 10;
-            })
-            .attr("text-anchor", function(d) {
-                return d.children || d._children ? "end" : "start";
-            })
-            .text(function(d) {
-                var nameDis = (d.name.length > 15) ? d.name.substring(0,15) + "..." : d.name;
-                $(this).attr('title', d.name);
-                return nameDis;
-            });
-
-        // Change the circle fill depending on whether it has children and is collapsed
-        // Change the circle fill depending on whether it has children and is collapsed
-        node.select("image.nodeImage")
-            .attr("r", 4.5)
-            .attr("xlink:href", function(d) { 
-                if(d._children){
-                    return d.type === 'Table' ? '../img/tableicon1.png' : '../img/process1.png';
-                }
-                return d.type === 'Table' ? '../img/tableicon.png' : '../img/process.png';
-            });
-
-
-        // Transition nodes to their new position.
-        var nodeUpdate = node.transition()
-            .duration(duration)
-            .attr("transform", function(d) {
-                return "translate(" + d.y + "," + d.x  + ")";
-            });
-
-        // Fade the text in
-        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() {
-                return "translate(" + source.y + "," + source.x + ")";
-            })
-            .remove();
-
-        nodeExit.select("circle")
-            .attr("r", 0);
-
-        nodeExit.select("text")
-            .style("fill-opacity", 0);
-
-        // Update the links…
-        var link = svgGroup.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")
-            .style('stroke', 'green') 
-            .attr("d", function() {
-                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);
-
-        // Transition exiting nodes to the parent's new position.
-        link.exit().transition()
-            .duration(duration)
-            .attr("d", function() {
-                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;
-        });
-
-        if ($scope.type === 'inputs') {
-            link.attr("marker-start", "url(#input-arrow)"); //if input
-        }  else {
-            link.attr("marker-end", "url(#arrow)"); //if input
-        }
-    }
-
-    // Append a group which holds all nodes and which the zoom Listener can act upon.
-    var svgGroup = baseSvg.append("g")
-                    .attr("transform", "translate(120 ," + heightg/2 + ")");
-
-    // Define the root
-    root = data;
-    root.x0 = viewerHeight / 2;
-    root.y0 = 0;
-
-    // Layout the tree initially and center on the root node.
-    update(root);
-    centerNode(root);
-    
-    var couplingParent1 = tree.nodes(root).filter(function(d) {
-            return d.name === 'cluster';
-        })[0];
-    var couplingChild1 = tree.nodes(root).filter(function(d) {
-            return d.name === 'JSONConverter';
-        })[0];
-    
-    multiParents = [{
-                    parent: couplingParent1,
-                    child: couplingChild1
-                }];
-    
-    multiParents.forEach(function() {
-            svgGroup.append("path", "g"); 
-        }); 
-
-           
-        }
-
-    }
-]);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c4eebe0e/dashboard/public/modules/lineage/lineage_ioController.js
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/lineage/lineage_ioController.js b/dashboard/public/modules/lineage/lineage_ioController.js
index 41f69c2..3f4e990 100644
--- a/dashboard/public/modules/lineage/lineage_ioController.js
+++ b/dashboard/public/modules/lineage/lineage_ioController.js
@@ -131,6 +131,8 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
         }
 
         $scope.onReset = function() {
+            $scope.height = $scope.initialHeight;
+            angular.element('.lineage-viz').height($scope.height);
             renderGraph($scope.lineageData, {
                 eleObj: $element,
                 element: $element[0],
@@ -237,9 +239,8 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
         function renderGraph(data, container) {
             // ************** Generate the tree diagram  *****************
             var element = d3.select(container.element),
-                widthg = Math.max(container.width, 1100),
-                heightg = Math.max((window.innerHeight - 400), 500),
-
+                widthg = container.width || 1100,
+                heightg = container.height || Math.max((window.innerHeight - 400), 300),
                 totalNodes = 0,
                 maxLabelLength = 0,
                 selectedNode = null,
@@ -258,7 +259,8 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
 
 
             var viewerWidth = widthg - 15,
-                viewerHeight = heightg;
+                viewerHeight = heightg,
+                center = [viewerWidth / 2, viewerHeight / 2];
 
             var tree = d3.layout.tree().size([viewerHeight, viewerWidth]);
             /*.size([viewerHeight, viewerWidth]);   nodeSize([100, 200]);*/
@@ -308,9 +310,9 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
             // Sort the tree initially incase the JSON isn't in a sorted order.
             sortTree();
 
-            // Define the zoom function for the zoomable tree  
+            // Define the zoom function for the zoomable tree
             function zoom() {
-                svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
+                d3.select('g').attr("transform", "translate(" + zoomListener.translate() + ")scale(" + zoomListener.scale() + ")");
             }
 
             // define the zoomListener which calls the zoom function on the "zoom" event constrained within the scaleExtents
@@ -334,6 +336,7 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
                 .attr("height", viewerHeight)
                 .attr("class", "overlay")
                 .call(zoomListener)
+                .call(zoomListener.event)
                 .on("dblclick.zoom", function() {
                     return null;
                 })
@@ -708,6 +711,45 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
             var svgGroup = baseSvg.append("g")
                 .attr("transform", "translate(0,0)");
 
+            // Simplest possible buttons
+            var intervalID;
+
+            d3.selectAll('.zoom-buttons').on('mousedown', function(){
+                d3.event.preventDefault();
+                $scope.factor = (this.id === 'zoom_in') ? 1.1 : 1/1.1;
+                intervalID = setInterval(zoom_by, 40, $scope.factor);
+            }).on('mouseup', function(){
+                d3.event.preventDefault();
+                clearInterval(intervalID);
+                intervalID = undefined;
+            });
+
+            function zoom_by(factor){
+                var scale = zoomListener.scale(),
+                    extent = zoomListener.scaleExtent(),
+                    translate = zoomListener.translate(),
+                    x = translate[0], y = translate[1],
+                    target_scale = scale * factor;
+
+                // If we're already at an extent, done
+                if (target_scale === extent[0] || target_scale === extent[1]) { return false; }
+                // If the factor is too much, scale it down to reach the extent exactly
+                var clamped_target_scale = Math.max(extent[0], Math.min(extent[1], target_scale));
+                if (clamped_target_scale !== target_scale){
+                    target_scale = clamped_target_scale;
+                    factor = target_scale / scale;
+                }
+
+                // Center each vector, stretch, then put back
+                x = (x - center[0]) * factor + center[0];
+                y = (y - center[1]) * factor + center[1];
+
+                // Enact the zoom immediately
+                zoomListener.scale(target_scale)
+                    .translate([x,y]);
+                zoom();
+            }
+
             // Define the root
             root = data;
             root.x0 = viewerWidth / 2;
@@ -716,6 +758,11 @@ angular.module('dgc.lineage').controller('Lineage_ioController', ['$element', '$
             // Layout the tree initially and center on the root node.
             update(root);
             centerNode(root);
+            if(!$scope.initialHeight){
+                $scope.initialHeight = angular.element('.lineage-viz').height();
+            }
+            angular.element('.lineage-viz').resizable({minWidth:1150, maxWidth:1150, maxHeight: angular.element('.lineage-viz').height(), minHeight:50
+            });
             $scope.requested = false;
             var couplingParent1 = tree.nodes(root).filter(function(d) {
                 return d.name === 'cluster';

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c4eebe0e/dashboard/public/modules/lineage/views/lineage_io.html
----------------------------------------------------------------------
diff --git a/dashboard/public/modules/lineage/views/lineage_io.html b/dashboard/public/modules/lineage/views/lineage_io.html
index 58f8f19..49a5d2a 100644
--- a/dashboard/public/modules/lineage/views/lineage_io.html
+++ b/dashboard/public/modules/lineage/views/lineage_io.html
@@ -20,6 +20,8 @@
     <button type="button" class="btn btn-primary pull-right" ng-click="onReset()">
         Reset
     </button>
+    <button type="button" class="btn btn-primary zoom-buttons pull-right" id="zoom_out"><i class="fa fa-minus"></i></button>
+    <button type="button" class="btn btn-primary zoom-buttons pull-right" id="zoom_in"><i class="fa fa-plus"></i> </button>
     <div class="graph">
       <h4 data-ng-if="!requested && !lineageData" class="alignLineage">No lineage data found</h4>
       <i data-ng-if="requested" class="fa fa-spinner fa-spin fa-5x"></i>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c4eebe0e/release-log.txt
----------------------------------------------------------------------
diff --git a/release-log.txt b/release-log.txt
index 7126845..f433865 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -6,6 +6,7 @@ INCOMPATIBLE CHANGES:
 ATLAS-379 Create sqoop and falcon metadata addons (venkatnrangan,bvellanki,sowmyaramesh via shwethags)
 
 ALL CHANGES:
+ATLAS-406 Resizing lineage window – should be an anchor on a corner – like ppt for graphic (sanjayp via shwethags)
 ATLAS-432 QuickStart lineage is broken (yhemanth via shwethags)
 ATLAS-421 typo in Architecture.twiki (dbist13 via shwethags)
 ATLAS-387 Running quick_start without a valid atlas endpoint in configuration or argument prints a spurious success message (yhemanth via shwethags)