Commit 674d8073 by Vishal Kadam

Added directed edges and process icon

parent c58482d7
.node circle {
g circle {
cursor: pointer;
stroke: green;
stroke-width: 2px;
fill: #1cef3d;
fill: url(#process-image);
}
.node circle.empty {
g circle.empty {
fill: #fdd916;
}
.node text {
font: 15px sans-serif;
pointer-events: none;
text-anchor: middle;
}
line.link {
.link {
fill: none;
stroke: green;
stroke-width: 2px;
}
g text {
pointer-events: none;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
}
.d3-tip pre {
max-width: 400px;
}
......
'use strict';
angular.module('dgc.lineage').controller('LineageController', ['$element', '$scope', '$state', '$stateParams', 'LineageResource', 'd3',
function($element, $scope, $state, $stateParams, LineageResource, d3) {
angular.module('dgc.lineage').controller('LineageController', ['$element', '$scope', '$state', '$stateParams', 'lodash', 'LineageResource', 'd3',
function($element, $scope, $state, $stateParams, _, LineageResource, d3) {
function render(nodes) {
var links = d3.layout.tree().links(nodes);
// Restart the force layout.
force.nodes(nodes)
.links(links)
.start();
// Update links.
link = link.data(links, function(d) {
return d.target.__id;
});
link.exit().remove();
link.enter().insert('line', '.node')
.attr('class', 'link');
// Update nodes.
node = node.data(nodes, function(d) {
return d.__id;
});
node.exit().remove();
var nodeEnter = node.enter().append('g')
.attr('class', 'node')
.on('click', click)
.on('mouseover', tooltip.show)
.on('mouseout', tooltip.hide)
.call(force.drag);
$scope.lineageData = LineageResource.get({
id: $stateParams.id
}, function(data) {
var nodes = {};
nodeEnter.append('circle')
.attr('class', function(d) {
return d.children ? '' : 'empty';
}).attr('r', 9);
function getNode(nodeId) {
if (!nodes[nodeId]) {
var node;
if (data.vertices[nodeId]) {
node = angular.copy(data.vertices[nodeId]);
node.__key = nodeId;
node.__name = node['hive_table.name'] || node.__key;
node.__tooltip = node['hive_table.description'] || node['HiveLineage.query'];
} else {
node = {};
node.__key = nodeId;
node.__tooltip = node.__name = nodeId + ', Node Missing';
}
nodes[nodeId] = node;
}
return nodes[nodeId];
}
nodeEnter.append('text')
.attr('dy', '2em')
.text(function(d) {
//return d.name;
return d.__name || d.__key;
});
var edges = [],
edgeTypes = [];
/*node.select('circle')
.style('fill', color);*/
}
angular.forEach(data.edges, function(edge) {
/* Put the head (edge) inside tail (edge)
* Tail is parent
* Head is child
* */
var parentNode = getNode(edge.tail);
edge.source = parentNode;
edge.target = getNode(edge.head);
function click(node) {
$state.go('details', {
id: node.guid
}, {
location: 'replace'
});
}
parentNode.__hasChild = true;
function tick() {
link.attr('x1', function(d) {
return d.source.x;
}).attr('y1', function(d) {
return d.source.y;
}).attr('x2', function(d) {
return d.target.x;
}).attr('y2', function(d) {
return d.target.y;
edge.__type = edge.label;
edgeTypes.push(edge.label);
edges.push(edge);
});
edgeTypes = _.uniq(edgeTypes);
render(nodes, edges, edgeTypes);
});
node.attr('transform', function(d) {
return 'translate(' + d.x + ',' + d.y + ')';
});
}
function render(nodes, links, linkTypes) {
// Use elliptical arc path segments to doubly-encode directionality.
function click(node) {
if (node.guid) {
$state.go('details', {
id: node.guid
}, {
location: 'replace'
});
}
}
var width = Math.max($element[0].offsetWidth, 960),
height = Math.max($element[0].offsetHeight, 350);
function tick() {
path.attr("d", linkArc);
circle.attr("transform", transform);
text.attr("transform", transform);
}
var force = d3.layout.force()
.linkDistance(200)
.charge(-120)
.gravity(0.05)
.size([width, height])
.on('tick', tick);
function linkArc(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}
var svg = d3.select($element[0]).select('svg')
.attr('width', width)
.attr('height', height);
function transform(d) {
return "translate(" + d.x + "," + d.y + ")";
}
var link = svg.selectAll('.link'),
node = svg.selectAll('.node');
var width = Math.max($element[0].offsetWidth, 960),
height = Math.max($element[0].offsetHeight, 350);
/* Initialize tooltip */
var tooltip = d3.tip()
.attr('class', 'd3-tip')
.html(function(d) {
return '<pre class="alert alert-success">' + d.__tooltip + '</pre>';
});
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(200)
.charge(-120)
.gravity(0.05)
.on("tick", tick)
.start();
/* Invoke the tip in the context of your visualization */
svg.call(tooltip);
var svg = d3.select($element[0]).select('svg')
.attr("width", width)
.attr("height", height);
$scope.lineageData = LineageResource.get({
id: $stateParams.id
}, function(data) {
var nodes = {};
/* Initialize tooltip */
var tooltip = d3.tip()
.attr('class', 'd3-tip')
.html(function(d) {
return '<pre class="alert alert-success">' + d.__tooltip + '</pre>';
});
function getNode(nodeId) {
if (!nodes[nodeId] && data.vertices[nodeId]) {
nodes[nodeId] = angular.copy(data.vertices[nodeId]);
}
return nodes[nodeId];
}
/* Invoke the tip in the context of your visualization */
svg.call(tooltip);
// Per-type markers, as they don't inherit styles.
var defs = svg.append("defs");
var imageDim = 10;
defs.append('svg:pattern')
.attr('id', 'process-image')
.attr('patternUnits', 'userSpaceOnUse')
.attr('width', imageDim)
.attr('height', imageDim)
.append('svg:image')
.attr('xlink:href', '/img/process.png')
.attr('x', 0)
.attr('y', 0)
.attr('width', imageDim)
.attr('height', imageDim);
defs.selectAll("marker")
.data(linkTypes)
.enter().append("marker")
.attr("id", function(d) {
return d;
})
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", -1.5)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) {
return "link " + d.__type;
})
.attr("marker-end", function(d) {
return "url(#" + d.__type + ")";
});
angular.forEach(data.edges, function(node) {
/* Put the head (node) inside tail (node)
* Tail is parent
* Head is child
* */
var parentId = node.tail,
parentNode = getNode(parentId);
if (!parentNode) {
console.log('Parent Node not found id', parentId);
} else {
var childId = node.head,
childNode = getNode(childId);
if (childNode) {
if (!parentNode.children) {
parentNode.children = [];
}
parentNode.children.push(childNode);
} else {
console.log('Child Node not found id', childId);
}
}
});
var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.on('click', click)
.on('mouseover', tooltip.show)
.on('mouseout', tooltip.hide)
.attr('class', function(d) {
return d.__hasChild ? '' : 'empty';
})
.attr("r", function(d) {
return d.__hasChild ? 15 : 10;
})
.call(force.drag);
var id = 0,
returnArray = [];
var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr('dy', '2em')
.text(function(d) {
return d.__name;
});
}
angular.forEach(nodes, function(node, key) {
node.__id = id++;
node.__key = key;
node.__name = node['hive_table.name'];
node.__tooltip = node['hive_table.description'] || node['HiveLineage.query'];
returnArray.push(node);
});
render(returnArray);
});
}
]);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment