Repository: incubator-atlas Updated Branches: refs/heads/master cf2c8bc0c -> ebd6d9e3c
ATLAS-204 Lineage I/O Lineage Enhancement (Anilsg via Suma Shivaprasad) Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/ebd6d9e3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/ebd6d9e3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/ebd6d9e3 Branch: refs/heads/master Commit: ebd6d9e3c754535d834cf262db2968d07547272a Parents: cf2c8bc Author: Suma Shivaprasad <[email protected]> Authored: Tue Oct 6 11:49:47 2015 +0530 Committer: Suma Shivaprasad <[email protected]> Committed: Tue Oct 6 11:49:47 2015 +0530 ---------------------------------------------------------------------- .../public/modules/details/detailsController.js | 6 +- .../public/modules/details/detailsModule.js | 2 +- .../public/modules/details/views/details.html | 5 +- .../modules/lineage/lineage_ioController.js | 749 ++++++++++++++++++ .../modules/lineage/views/lineage_io.html | 30 + .../public/modules/lineage_io/Find Results | 30 - .../modules/lineage_io/lineage_ioController.js | 750 ------------------- .../modules/lineage_io/lineage_ioModule.js | 21 - .../modules/lineage_io/lineage_ioResource.js | 23 - .../modules/lineage_io/views/lineage_io.html | 30 - release-log.txt | 1 + 11 files changed, 787 insertions(+), 860 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/dashboard/public/modules/details/detailsController.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/details/detailsController.js b/dashboard/public/modules/details/detailsController.js index 7bfed9b..c469c37 100644 --- a/dashboard/public/modules/details/detailsController.js +++ b/dashboard/public/modules/details/detailsController.js @@ -15,7 +15,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - 'use strict'; angular.module('dgc.details').controller('DetailsController', ['$window', '$scope', '$stateParams', 'DetailsResource', @@ -31,10 +30,11 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop $scope.schemas = data; $scope.tableName = data.values.name; $scope.isTable = data.typeName === 'Table'; + $scope.onActivate('io'); }); $scope.isNumber = angular.isNumber; - + $scope.isString = angular.isString; $scope.onActivate = function tabActivate(tabname) { @@ -49,4 +49,4 @@ angular.module('dgc.details').controller('DetailsController', ['$window', '$scop }; } -]); +]); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/dashboard/public/modules/details/detailsModule.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/details/detailsModule.js b/dashboard/public/modules/details/detailsModule.js index 8bc5b53..987750a 100644 --- a/dashboard/public/modules/details/detailsModule.js +++ b/dashboard/public/modules/details/detailsModule.js @@ -18,4 +18,4 @@ 'use strict'; -angular.module('dgc.details', ['dgc.lineage', 'dgc.lineage_io']); +angular.module('dgc.details', ['dgc.lineage']); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/dashboard/public/modules/details/views/details.html ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/details/views/details.html b/dashboard/public/modules/details/views/details.html index bdf1c57..26d81ec 100644 --- a/dashboard/public/modules/details/views/details.html +++ b/dashboard/public/modules/details/views/details.html @@ -23,6 +23,7 @@ <div role="tabpanel" class="col-lg-12"> <h2>Name: {{details.values.name}}</h2> <h4>Description: {{details.values.description}}</h4> + <h4>Lineage: <ng-include data-table-type="io" src="'/modules/lineage/views/lineage_io.html'"/></h4> <tabset> <tab heading="Details"> <table class="table table-bordered"> @@ -42,9 +43,9 @@ </table> </tab> <tab data-heading="Schema" data-ng-if="isTable"><ng-include src="'/modules/details/views/schema.html'"/></tab> - <tab data-heading="Output" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('outputs')"><ng-include data-table-type="outputs" src="'/modules/lineage/views/lineage.html'"/></tab> + <!-- <tab data-heading="Output" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('outputs')"><ng-include data-table-type="outputs" src="'/modules/lineage/views/lineage.html'"/></tab> <tab data-heading="Input" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('inputs')"><ng-include data-table-type="inputs" src="'/modules/lineage/views/lineage.html'"/></tab> - <tab data-heading="Lineage" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('io')"><ng-include data-table-type="io" src="'/modules/lineage_io/views/lineage_io.html'"/></tab> + <tab data-heading="Lineage" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('io')"><ng-include data-table-type="io" src="'/modules/lineage_io/views/lineage_io.html'"/></tab> --> </tabset> </div> </div> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/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 new file mode 100644 index 0000000..0a49ed0 --- /dev/null +++ b/dashboard/public/modules/lineage/lineage_ioController.js @@ -0,0 +1,749 @@ +/* + * 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('Lineage_ioController', ['$element', '$scope', '$state', '$stateParams', 'lodash', 'LineageResource', 'd3', 'DetailsResource', '$q', + function($element, $scope, $state, $stateParams, _, LineageResource, d3, DetailsResource, $q) { + var guidsList = []; + + function inVertObj(edgs) { + var newEdgsObj = {}; + + $.each(edgs, function(key, value) { + for (var k = 0; k < value.length; k++) { + newEdgsObj[value[k]] = newEdgsObj[value[k]] || []; + newEdgsObj[value[k]] = [key]; + } + }); + return newEdgsObj; + } + + function getCombinedLineageData(tableData, callRender) { + LineageResource.get({ + tableName: tableData.tableName, + type: 'outputs' + }, function lineageSuccess(response1) { + + LineageResource.get({ + tableName: tableData.tableName, + type: 'inputs' + }, function lineageSuccess(response) { + response.results.values.edges = inVertObj(response.results.values.edges); + + angular.forEach(response.results.values.edges, function(value, key) { + angular.forEach(response1.results.values.edges, function(value1, key1) { + if (key === key1) { + var array1 = value; + angular.forEach(value1, function(value2) { + array1.push(value2); + }); + response.results.values.edges[key] = array1; + response1.results.values.edges[key] = array1; + } + }); + }); + + angular.extend(response.results.values.edges, response1.results.values.edges); + angular.extend(response.results.values.vertices, response1.results.values.vertices); + + if (!_.isEmpty(response.results.values.vertices)) { + loadProcess(response.results.values.edges, response.results.values.vertices) + .then(function(res) { + guidsList = res; + + $scope.lineageData = transformData(response.results); + + if (callRender) { + render(); + } + }); + } 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 = true; + $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) { + if ($scope.type === 'io') { + console.log($scope.type); + getCombinedLineageData(lineageData, true); + } else { + getCombinedLineageData(lineageData, 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); + } + + var starTingObj = { + name: 'root', + guid: 'root', + children: [] + }; + + angular.forEach(nodes, function(value) { + if (!value.hasOwnProperty('parent')) { + starTingObj.children.push(value); + } + }); + + return starTingObj; + } + + 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), + + 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().size([viewerHeight, viewerWidth]); + /*.size([viewerHeight, viewerWidth]); nodeSize([100, 200]);*/ + + 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) + .on("dblclick.zoom", function() { + return null; + }) + .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 - 130; + 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(); + + nodes = _.uniq(nodes, 'guid'); + + _.each(nodes, function(o, i) { + var itemsOfTheSameDepth = _.where(nodes, { + depth: o.depth + }); + var indexOfCurrent = _.indexOf(itemsOfTheSameDepth, o); + var interval = viewerHeight / itemsOfTheSameDepth.length; + nodes[i].x = interval / 2 + (interval * indexOfCurrent); + }); + + var links = tree.links(nodes); + + _.each(links, function(o, i) { + //links[i].target = _.find(nodes, {guid: o.target.id}); + links[i].target = _.find(nodes, { + guid: o.target.guid + }); + }); + + // 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', function(d) { + if (d.guid === "root") { + return "hide"; + } else { + return ""; + } + }) + .classed('node', true) + .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('dblclick', function(d) { + $state.go("details", { + id: d.guid + }); + }) + .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); + // .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', function(d) { + if (d.source.guid === "root") { + return "hide"; + } else { + return ""; + } + }) + .classed('link', true) + .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(0,0)"); + + // Define the root + root = data; + root.x0 = viewerWidth / 2; + root.y0 = viewerHeight / 2; + + // Layout the tree initially and center on the root node. + update(root); + centerNode(root); + $scope.requested = false; + 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"); + }); + } + + } +]); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/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 new file mode 100644 index 0000000..377f273 --- /dev/null +++ b/dashboard/public/modules/lineage/views/lineage_io.html @@ -0,0 +1,30 @@ +<!-- + ~ 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. + --> + +<div class="lineage-viz table-bordered" data-ng-controller="Lineage_ioController"> + <button type="button" class="btn btn-primary pull-right" ng-click="onReset()"> + Reset + </button> + <div class="graph"> + <h4 data-ng-if="!requested && !lineageData">No lineage data found</h4> + <i data-ng-if="requested" class="fa fa-spinner fa-spin fa-5x"></i> + <svg > + <g/> + </svg> + </div> +</div> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/dashboard/public/modules/lineage_io/Find Results ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/lineage_io/Find Results b/dashboard/public/modules/lineage_io/Find Results deleted file mode 100644 index ba9fb32..0000000 --- a/dashboard/public/modules/lineage_io/Find Results +++ /dev/null @@ -1,30 +0,0 @@ -Searching 16184 files for "LineageController" - -/Users/anilgayakwad/MPR/Anil/incubator-atlas/dashboard/public/modules/lineage/lineageController.js: - 18 'use strict'; - 19 - 20: angular.module('dgc.lineage').controller('LineageController', ['$element', '$scope', '$state', '$stateParams', 'lodash', 'LineageResource', 'd3', 'DetailsResource', '$q', - 21 function($element, $scope, $state, $stateParams, _, LineageResource, d3, DetailsResource, $q) { - 22 var guidsList = []; - -/Users/anilgayakwad/MPR/Anil/incubator-atlas/dashboard/public/modules/lineage/views/lineage.html: - 17 --> - 18 - 19: <div class="lineage-viz" data-ng-controller="LineageController"> - 20 <button type="button" class="btn btn-primary pull-right" ng-click="onReset()"> - 21 Reset - -2 matches across 2 files - - -Searching 16184 files for "lineage.html" - -/Users/anilgayakwad/MPR/Anil/incubator-atlas/dashboard/public/modules/details/views/details.html: - 43 </tab> - 44 <tab data-heading="Schema" data-ng-if="isTable"><ng-include src="'/modules/details/views/schema.html'"/></tab> - 45: <tab data-heading="Output" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('outputs')"><ng-include data-table-type="outputs" src="'/modules/lineage/views/lineage.html'"/></tab> - 46: <tab data-heading="Input" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('inputs')"><ng-include data-table-type="inputs" src="'/modules/lineage/views/lineage.html'"/></tab> - 47 - 48 <tab data-heading="Lineage" data-ng-if="isTable" data-disable="!tableName" data-select="onActivate('io')"><ng-include data-table-type="io" src="'/modules/lineage_io/views/lineage_io.html'"/></tab> - -2 matches in 1 file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/dashboard/public/modules/lineage_io/lineage_ioController.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/lineage_io/lineage_ioController.js b/dashboard/public/modules/lineage_io/lineage_ioController.js deleted file mode 100644 index 11cefd7..0000000 --- a/dashboard/public/modules/lineage_io/lineage_ioController.js +++ /dev/null @@ -1,750 +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_io').controller('Lineage_ioController', ['$element', '$scope', '$state', '$stateParams', 'lodash', 'Lineage_ioResource', 'd3', 'DetailsResource', '$q', - function($element, $scope, $state, $stateParams, _, LineageResource, d3, DetailsResource, $q) { - var guidsList = []; - - function inVertObj(edgs) { - var newEdgsObj = {}; - - $.each(edgs, function(key, value) { - for (var k = 0; k < value.length; k++) { - newEdgsObj[value[k]] = newEdgsObj[value[k]] || []; - newEdgsObj[value[k]] = [key]; - } - }); - return newEdgsObj; - } - - function getCombinedLineageData(tableData, callRender) { - LineageResource.get({ - tableName: tableData.tableName, - type: 'outputs' - }, function lineageSuccess(response1) { - - LineageResource.get({ - tableName: tableData.tableName, - type: 'inputs' - }, function lineageSuccess(response) { - response.results.values.edges = inVertObj(response.results.values.edges); - - angular.forEach(response.results.values.edges, function(value, key) { - angular.forEach(response1.results.values.edges, function(value1, key1) { - if (key === key1) { - var array1 = value; - angular.forEach(value1, function(value2) { - array1.push(value2); - }); - response.results.values.edges[key] = array1; - response1.results.values.edges[key] = array1; - } - }); - }); - - angular.extend(response.results.values.edges, response1.results.values.edges); - angular.extend(response.results.values.vertices, response1.results.values.vertices); - - if (!_.isEmpty(response.results.values.vertices)) { - loadProcess(response.results.values.edges, response.results.values.vertices) - .then(function(res) { - guidsList = res; - - $scope.lineageData = transformData(response.results); - - if (callRender) { - render(); - } - }); - } - $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) { - if ($scope.type === 'io') { - console.log($scope.type); - getCombinedLineageData(lineageData, true); - } else { - getCombinedLineageData(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); - } - - var starTingObj = { - name: 'root', - guid: 'root', - children: [] - }; - - angular.forEach(nodes, function(value) { - if (!value.hasOwnProperty('parent')) { - starTingObj.children.push(value); - } - }); - - return starTingObj; - } - - function renderGraph(data, container) { - // ************** Generate the tree diagram ***************** - var element = d3.select(container.element), - widthg = Math.max(container.width, 1100), - //heightg = Math.max(container.height, 500), - heightg = Math.max((window.innerHeight - 380), 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().size([viewerHeight, viewerWidth]); - /*.size([viewerHeight, viewerWidth]); nodeSize([100, 200]);*/ - - 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) - .on("dblclick.zoom", function() { - return null; - }) - .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(); - - nodes = _.uniq(nodes, 'guid'); - - _.each(nodes, function(o, i) { - var itemsOfTheSameDepth = _.where(nodes, { - depth: o.depth - }); - var indexOfCurrent = _.indexOf(itemsOfTheSameDepth, o); - var interval = viewerHeight / itemsOfTheSameDepth.length; - nodes[i].x = interval / 2 + (interval * indexOfCurrent); - }); - - var links = tree.links(nodes); - - _.each(links, function(o, i) { - //links[i].target = _.find(nodes, {guid: o.target.id}); - links[i].target = _.find(nodes, { - guid: o.target.guid - }); - }); - - // 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', function(d) { - if (d.guid === "root") { - return "hide"; - } else { - return ""; - } - }) - .classed('node', true) - .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('dblclick', function(d) { - $state.go("details", { - id: d.guid - }); - }) - .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); - // .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', function(d) { - if (d.source.guid === "root") { - return "hide"; - } else { - return ""; - } - }) - .classed('link', true) - .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(0,0)"); - - // Define the root - root = data; - root.x0 = viewerWidth / 2; - root.y0 = viewerHeight / 2; - - // 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"); - }); - } - - } -]); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/dashboard/public/modules/lineage_io/lineage_ioModule.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/lineage_io/lineage_ioModule.js b/dashboard/public/modules/lineage_io/lineage_ioModule.js deleted file mode 100644 index a4b8ef6..0000000 --- a/dashboard/public/modules/lineage_io/lineage_ioModule.js +++ /dev/null @@ -1,21 +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_io', []); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/dashboard/public/modules/lineage_io/lineage_ioResource.js ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/lineage_io/lineage_ioResource.js b/dashboard/public/modules/lineage_io/lineage_ioResource.js deleted file mode 100644 index ba8f4b7..0000000 --- a/dashboard/public/modules/lineage_io/lineage_ioResource.js +++ /dev/null @@ -1,23 +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_io').factory('Lineage_ioResource', ['$resource', function($resource) { - return $resource('/api/atlas/lineage/hive/table/:tableName/:type/graph', {}); -}]); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/dashboard/public/modules/lineage_io/views/lineage_io.html ---------------------------------------------------------------------- diff --git a/dashboard/public/modules/lineage_io/views/lineage_io.html b/dashboard/public/modules/lineage_io/views/lineage_io.html deleted file mode 100644 index e7ac084..0000000 --- a/dashboard/public/modules/lineage_io/views/lineage_io.html +++ /dev/null @@ -1,30 +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. - --> - -<div class="lineage-viz" data-ng-controller="Lineage_ioController"> - <button type="button" class="btn btn-primary pull-right" ng-click="onReset()"> - Reset - </button> - <div class="graph"> - <h4 data-ng-if="!requested && !lineageData">No lineage data found</h4> - <i data-ng-if="requested" class="fa fa-spinner fa-spin fa-5x"></i> - <svg > - <g/> - </svg> - </div> -</div> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ebd6d9e3/release-log.txt ---------------------------------------------------------------------- diff --git a/release-log.txt b/release-log.txt index 4fa8339..db37eba 100644 --- a/release-log.txt +++ b/release-log.txt @@ -9,6 +9,7 @@ ATLAS-54 Rename configs in hive hook (shwethags) ATLAS-3 Mixed Index creation fails with Date types (suma.shivaprasad via shwethags) ALL CHANGES: +ATLAS-204 Lineage I/O Lineage Enhancement ( Anilsg via Suma Shivaprasad ) ATLAS-138 Combine Input/Output graph ( Anilsg via Suma Shivaprasad ) ATLAS-128 DSL - Add support for comparisions on list type (suma.shivaprasad via shwethags) ATLAS-168 Atlas UI - Max column in hive 4 (darshankumar89 via shwethags)
