Commit 674d8073 by Vishal Kadam

Added directed edges and process icon

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