diff --git a/html/admin/js/graphViewer/graph/edgeShaper.js b/html/admin/js/graphViewer/graph/edgeShaper.js index 4b5ee2e916..753b12dc45 100644 --- a/html/admin/js/graphViewer/graph/edgeShaper.js +++ b/html/admin/js/graphViewer/graph/edgeShaper.js @@ -107,14 +107,14 @@ function EdgeShaper(parent, flags, idfunc) { addPosition = function (line, g) { g.attr("transform", function(d) { return "translate(" - + d.source.x + ", " - + d.source.y + ")" + + d.source.position.x + ", " + + d.source.position.y + ")" + "rotate(" - + getCorner(d.source, d.target) + + getCorner(d.source.position, d.target.position) + ")"; }); line.attr("x2", function(d) { - return getDistance(d.source, d.target); + return getDistance(d.source.position, d.target.position); }); }, @@ -206,7 +206,7 @@ function EdgeShaper(parent, flags, idfunc) { edges.select("text") .attr("transform", function(d) { return "translate(" - + getDistance(d.source, d.target) / 2 + + getDistance(d.source.position, d.target.position) / 2 + ", -3)"; }); }; diff --git a/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperSpec.js b/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperSpec.js index e574298eb5..bc8bc2526f 100644 --- a/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperSpec.js @@ -38,10 +38,15 @@ describe('Edge Shaper', function() { - var svg; + var svg, defaultPosition; beforeEach(function () { svg = document.createElement("svg"); + defaultPosition = { + x: 1, + y: 1, + z: 1 + }; document.body.appendChild(svg); }); @@ -52,10 +57,12 @@ it('should be able to draw an edge', function () { var source = { - "_id": 1 + "_id": 1, + position: defaultPosition }, target = { - "_id": 2 + "_id": 2, + position: defaultPosition }, edges = [ { @@ -72,16 +79,20 @@ it('should be able to draw many edges', function () { var one = { - "_id": 1 + "_id": 1, + position: defaultPosition }, two = { - "_id": 2 + "_id": 2, + position: defaultPosition }, three = { - "_id": 3 + "_id": 3, + position: defaultPosition }, four = { - "_id": 4 + "_id": 4, + position: defaultPosition }, edges = [ { @@ -108,16 +119,20 @@ it('should be able to add an event', function () { var one = { - "_id": 1 + "_id": 1, + position: defaultPosition }, two = { - "_id": 2 + "_id": 2, + position: defaultPosition }, three = { - "_id": 3 + "_id": 3, + position: defaultPosition }, four = { - "_id": 4 + "_id": 4, + position: defaultPosition }, edges = [ { @@ -159,16 +174,20 @@ it('should be able to unbind all events', function() { var one = { - "_id": 1 + "_id": 1, + position: defaultPosition }, two = { - "_id": 2 + "_id": 2, + position: defaultPosition }, three = { - "_id": 3 + "_id": 3, + position: defaultPosition }, four = { - "_id": 4 + "_id": 4, + position: defaultPosition }, edges = [ { @@ -216,10 +235,12 @@ it('should be able to add an arrow on target side', function() { var one = { - "_id": 1 + "_id": 1, + position: defaultPosition }, two = { - "_id": 2 + "_id": 2, + position: defaultPosition }, edges = [ { @@ -244,28 +265,38 @@ it('should position the edges correctly', function() { var center = { _id: 1, - x: 20, - y: 20 + position: { + x: 20, + y: 20 + } }, NE = { _id: 2, - x: 30, - y: 10 + position: { + x: 30, + y: 10 + } }, SE = { _id: 3, - x: 40, - y: 30 + position: { + x: 40, + y: 30 + } }, SW = { _id: 4, - x: 10, - y: 40 + position: { + x: 10, + y: 40 + } }, NW = { _id: 5, - x: 0, - y: 0 + position: { + x: 0, + y: 0 + } }, edges = [ { @@ -308,7 +339,15 @@ describe('testing for colours', function() { it('should have a default colouring of no colour flag is given', function() { - var nodes = [{_id: 1}, {_id: 2}], + var nodes = [ + { + _id: 1, + position: defaultPosition + }, { + _id: 2, + position: defaultPosition + } + ], edges = [{ source: nodes[0], target: nodes[1] @@ -324,8 +363,14 @@ }); it('should be able to use the same colour for all edges', function() { - var s = {_id: 1}, - t = {_id: 2}, + var s = { + _id: 1, + position: defaultPosition + }, + t = { + _id: 2, + position: defaultPosition + }, edges = [{ source: s, target: t @@ -348,10 +393,22 @@ }); it('should be able to use a colour based on attribute value', function() { - var n1 = {_id: 1}, - n2 = {_id: 2}, - n3 = {_id: 3}, - n4 = {_id: 4}, + var n1 = { + _id: 1, + position: defaultPosition + }, + n2 = { + _id: 2, + position: defaultPosition + }, + n3 = { + _id: 3, + position: defaultPosition + }, + n4 = { + _id: 4, + position: defaultPosition + }, edges = [{ source: n1, target: n2, @@ -407,8 +464,14 @@ }); it('should be able to use a gradient colour', function() { - var s = {_id: 1}, - t = {_id: 2}, + var s = { + _id: 1, + position: defaultPosition + }, + t = { + _id: 2, + position: defaultPosition + }, edges = [{ source: s, target: t @@ -455,10 +518,12 @@ beforeEach(function() { var one = { - "_id": 1 + "_id": 1, + position: defaultPosition }, two = { - "_id": 2 + "_id": 2, + position: defaultPosition }, edges = [ { @@ -511,7 +576,24 @@ shaper; beforeEach(function() { - nodes = [{_id: 1}, {_id: 2}, {_id: 3}, {_id: 4}]; + nodes = [ + { + _id: 1, + position: defaultPosition + }, + { + _id: 2, + position: defaultPosition + }, + { + _id: 3, + position: defaultPosition + }, + { + _id: 4, + position: defaultPosition + } + ]; edges = [ {_id: 1, source: nodes[0], target: nodes[1]}, {_id: 2, source: nodes[1], target: nodes[2]}, @@ -589,7 +671,21 @@ }); it('should display the correct label', function() { - var nodes = [{"_id": 1}, {"_id": 2}, {"_id": 3}, {"_id": 4}], + var nodes = [ + { + "_id": 1, + position: defaultPosition + }, { + "_id": 2, + position: defaultPosition + }, { + "_id": 3, + position: defaultPosition + }, { + "_id": 4, + position: defaultPosition + } + ], edges = [ { "source": nodes[0], @@ -634,13 +730,17 @@ var nodes = [ { _id: 1, - x: 20, - y: 20 + position: { + x: 20, + y: 20 + } }, { _id: 2, - x: 100, - y: 20 + position: { + x: 100, + y: 20 + } } ], edges = [ @@ -658,7 +758,21 @@ }); it('should ignore other attributes', function() { - var nodes = [{"_id": 1}, {"_id": 2}, {"_id": 3}, {"_id": 4}], + var nodes = [ + { + "_id": 1, + position: defaultPosition + }, { + "_id": 2, + position: defaultPosition + }, { + "_id": 3, + position: defaultPosition + }, { + "_id": 4, + position: defaultPosition + } + ], edges = [ { "source": nodes[0], @@ -698,7 +812,15 @@ }); it('should be able to switch to another label', function() { - var nodes = [{"_id": 1}, {"_id": 2}], + var nodes = [ + { + "_id": 1, + position: defaultPosition + }, { + "_id": 2, + position: defaultPosition + } + ], edges = [ { "source": nodes[0], @@ -746,7 +868,21 @@ }); it('should display the correct label', function() { - var nodes = [{"_id": 1}, {"_id": 2}, {"_id": 3}, {"_id": 4}], + var nodes = [ + { + "_id": 1, + position: defaultPosition + }, { + "_id": 2, + position: defaultPosition + }, { + "_id": 3, + position: defaultPosition + }, { + "_id": 4, + position: defaultPosition + } + ], edges = [ { "source": nodes[0], @@ -782,7 +918,21 @@ beforeEach(function () { shaper = new EdgeShaper(d3.select("svg")); - nodes = [{"_id": 1}, {"_id": 2}, {"_id": 3}, {"_id": 4}]; + nodes = [ + { + "_id": 1, + position: defaultPosition + }, { + "_id": 2, + position: defaultPosition + }, { + "_id": 3, + position: defaultPosition + }, { + "_id": 4, + position: defaultPosition + } + ]; edges = [ { "source": nodes[0], @@ -873,10 +1023,12 @@ .append("g"), shaper = new EdgeShaper(internalObject), source = { - "_id": 1 + "_id": 1, + position: defaultPosition }, target = { - "_id": 2 + "_id": 2, + position: defaultPosition }, edges = [ { diff --git a/html/admin/js/lib/d3.fisheye.js b/html/admin/js/lib/d3.fisheye.js new file mode 100644 index 0000000000..eb5178839a --- /dev/null +++ b/html/admin/js/lib/d3.fisheye.js @@ -0,0 +1,85 @@ +(function() { + d3.fisheye = { + scale: function(scaleType) { + return d3_fisheye_scale(scaleType(), 3, 0); + }, + circular: function() { + var radius = 200, + distortion = 2, + k0, + k1, + focus = [0, 0]; + + function fisheye(d) { + var dx = d.x - focus[0], + dy = d.y - focus[1], + dd = Math.sqrt(dx * dx + dy * dy); + if (!dd || dd >= radius) return {x: d.x, y: d.y, z: 1}; + var k = k0 * (1 - Math.exp(-dd * k1)) / dd * .75 + .25; + return {x: focus[0] + dx * k, y: focus[1] + dy * k, z: Math.min(k, 10)}; + } + + function rescale() { + k0 = Math.exp(distortion); + k0 = k0 / (k0 - 1) * radius; + k1 = distortion / radius; + return fisheye; + } + + fisheye.radius = function(_) { + if (!arguments.length) return radius; + radius = +_; + return rescale(); + }; + + fisheye.distortion = function(_) { + if (!arguments.length) return distortion; + distortion = +_; + return rescale(); + }; + + fisheye.focus = function(_) { + if (!arguments.length) return focus; + focus = _; + return fisheye; + }; + + return rescale(); + } + }; + + function d3_fisheye_scale(scale, d, a) { + + function fisheye(_) { + var x = scale(_), + left = x < a, + range = d3.extent(scale.range()), + min = range[0], + max = range[1], + m = left ? a - min : max - a; + if (m == 0) m = max - min; + return (left ? -1 : 1) * m * (d + 1) / (d + (m / Math.abs(x - a))) + a; + } + + fisheye.distortion = function(_) { + if (!arguments.length) return d; + d = +_; + return fisheye; + }; + + fisheye.focus = function(_) { + if (!arguments.length) return a; + a = +_; + return fisheye; + }; + + fisheye.copy = function() { + return d3_fisheye_scale(scale.copy(), d, a); + }; + + fisheye.nice = scale.nice; + fisheye.ticks = scale.ticks; + fisheye.tickFormat = scale.tickFormat; + return d3.rebind(fisheye, scale, "domain", "range"); + } +}()); \ No newline at end of file