diff --git a/html/admin/js/graphViewer/graph/zoomManager.js b/html/admin/js/graphViewer/graph/zoomManager.js index 690b37a4cd..ffc3a8807e 100644 --- a/html/admin/js/graphViewer/graph/zoomManager.js +++ b/html/admin/js/graphViewer/graph/zoomManager.js @@ -41,10 +41,10 @@ function ZoomManager(width, height, g, nodeShaper, edgeShaper, config) { if (g === undefined || g.node === undefined || g.node().tagName !== "G") { throw("A group has to be given."); } - if (nodeShaper === undefined || nodeShaper.activate === undefined) { + if (nodeShaper === undefined || nodeShaper.activateLabel === undefined) { throw("The Node shaper has to be given."); } - if (edgeShaper === undefined || edgeShaper.activate === undefined) { + if (edgeShaper === undefined || edgeShaper.activateLabel === undefined) { throw("The Edge shaper has to be given."); } @@ -54,9 +54,12 @@ function ZoomManager(width, height, g, nodeShaper, edgeShaper, config) { nodeRadius, labelToggle, currentZoom, + currentTranslation, currentLimit, currentDistortion, currentDistortionRadius, + baseDist, + baseDRadius, size = width * height, zoom, @@ -73,6 +76,12 @@ function ZoomManager(width, height, g, nodeShaper, edgeShaper, config) { } return Math.floor(size / div); }, + + calcDistortionValues = function () { + currentDistortion = baseDist / currentZoom - 0.99999999; // Always > 0 + currentDistortionRadius = baseDRadius / currentZoom; + }, + parseConfig = function (conf) { if (conf === undefined) { conf = {}; @@ -82,40 +91,32 @@ function ZoomManager(width, height, g, nodeShaper, edgeShaper, config) { fontMin = conf.minFont || 6, rMax = conf.maxRadius || 25, rMin = conf.minRadius || 1; + baseDist = conf.focusZoom || 1; + baseDRadius = conf.focusRadius || 100; fontSize = fontMax; nodeRadius = rMax; - labelToggle = 0; - currentDistortion = 0; - currentDistortionRadius = 100; - currentLimit = calcNodeLimit(); + labelToggle = fontMin / fontMax; currentZoom = 1; + calcDistortionValues(); + + currentLimit = calcNodeLimit(); + + zoom = d3.behavior.zoom() - .scaleExtent([rMin/rMax, 1]) - .on("zoom", function() { - // TODO: Still to be implemented - currentZoom = d3.event.scale; - currentLimit = calcNodeLimit(); - - //curTrans = $.extend({}, d3.event.translate); - /* - //curTrans[0] /= curZoom; - //curTrans[1] /= curZoom; - //console.log("here", d3.event.translate, d3.event.scale); - g.attr("transform", - "translate(" + d3.event.translate + ")" - + " scale(" + d3.event.scale + ")"); - if (d3.event.scale < stopLabel) { - test.remove(); - } - /* - fisheye - .distortion(1/d3.event.scale * fe_dist - 1); - */ - //.radius(1/d3.event.scale * fe_radius); - + .scaleExtent([rMin/rMax, 1]) + .on("zoom", function() { + currentZoom = d3.event.scale; + currentLimit = calcNodeLimit(); + nodeShaper.activateLabel(currentZoom >= labelToggle); + edgeShaper.activateLabel(currentZoom >= labelToggle); + calcDistortionValues(); + currentTranslation = $.extend({}, d3.event.translate); + g.attr("transform", + "translate(" + currentTranslation + ")" + + " scale(" + currentZoom + ")"); }); }; @@ -140,8 +141,12 @@ function ZoomManager(width, height, g, nodeShaper, edgeShaper, config) { self.mouseMoveHandle = function() { // TODO var focus = d3.mouse(this); - focus[0] += curTrans[0]; - focus[1] += curTrans[1]; + focus[0] -= currentTranslation[0]; + focus[0] /= currentZoom; + focus[1] -= currentTranslation[1]; + focus[1] /= currentZoom; + + fisheye.focus(focus); node.each(function(d) { d.fisheye = fisheye(d); }) diff --git a/html/admin/js/graphViewer/jasmine_test/helper/eventHelper.js b/html/admin/js/graphViewer/jasmine_test/helper/eventHelper.js index 37efab6755..53ff15f9fc 100644 --- a/html/admin/js/graphViewer/jasmine_test/helper/eventHelper.js +++ b/html/admin/js/graphViewer/jasmine_test/helper/eventHelper.js @@ -57,7 +57,7 @@ var helper = helper || {}; var evt = document.createEvent("MouseEvents"), testee = document.getElementById(objectId); evt.initMouseEvent("DOMMouseScroll", true, true, window, - -10, 0, 0, 0, 0, false, false, false, false, 0, null); + 10, 0, 0, 0, 0, false, false, false, false, 0, null); testee.dispatchEvent(evt); }; @@ -65,7 +65,7 @@ var helper = helper || {}; var evt = document.createEvent("MouseEvents"), testee = document.getElementById(objectId); evt.initMouseEvent("DOMMouseScroll", true, true, window, - 10, 0, 0, 0, 0, false, false, false, false, 0, null); + -10, 0, 0, 0, 0, false, false, false, false, 0, null); testee.dispatchEvent(evt); }; diff --git a/html/admin/js/graphViewer/jasmine_test/specZoomManager/zoomManagerSpec.js b/html/admin/js/graphViewer/jasmine_test/specZoomManager/zoomManagerSpec.js index 3c8b05aa53..cb9d30f2ae 100644 --- a/html/admin/js/graphViewer/jasmine_test/specZoomManager/zoomManagerSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specZoomManager/zoomManagerSpec.js @@ -1,6 +1,6 @@ /*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */ /*global beforeEach, afterEach, jasmine */ -/*global describe, it, expect */ +/*global describe, it, expect, spyOn */ /*global window, eb, loadFixtures, document */ /*global $, _, d3*/ /*global helper*/ @@ -49,6 +49,22 @@ simulateZoomIn = function () { helper.simulateScrollDownMouseEvent("svg"); + }, + + lastNodeShaperCall = function() { + return nodeShaperMock.activateLabel.mostRecentCall.args[0]; + }, + + lastEdgeShaperCall = function() { + return edgeShaperMock.activateLabel.mostRecentCall.args[0]; + }, + + labelsAreInvisible = function () { + return lastNodeShaperCall() === false; + }, + + labelsAreVisible = function () { + return lastNodeShaperCall() === true; }; beforeEach(function () { @@ -162,7 +178,7 @@ }); - describe('default values', function() { + describe('checking the value propagation', function() { var fontMax, fontMin, @@ -172,7 +188,9 @@ nodeMaxNoLabel, nodeMinLabel, nodeMin, - distRBase; + distRBase, + minScale, + toggleScale; beforeEach(function() { @@ -187,6 +205,8 @@ radMax = 25; radMin = 1; distRBase = 100; + minScale = radMin / radMax; + toggleScale = fontMin / fontMax; nodeMax = Math.floor(w * h / labelSize(fontMax)); nodeMinLabel = Math.floor(w * h / labelSize(fontMin)); nodeMaxNoLabel = Math.floor(w * h / circleSize((radMax - radMin) / 2 + radMin)); @@ -199,6 +219,32 @@ expect(manager.getDistortionRadius()).toEqual(distRBase); }); + it('should trigger the activateLabel function on each zoom-in event', function() { + simulateZoomIn(); + expect(nodeShaperMock.activateLabel).toHaveBeenCalled(); + expect(edgeShaperMock.activateLabel).toHaveBeenCalled(); + }); + + it('the zoom-out event should decrease the scale', function() { + var oldSF = manager.scaleFactor(); + simulateZoomOut(); + expect(manager.scaleFactor()).toBeLessThan(oldSF); + }); + + it('the zoom-in event should increase the scale', function() { + simulateZoomOut(); + simulateZoomOut(); + var oldSF = manager.scaleFactor(); + simulateZoomIn(); + expect(manager.scaleFactor()).toBeGreaterThan(oldSF); + }); + + it('should trigger the activateLabel function on each zoom-out event', function() { + simulateZoomOut(); + expect(nodeShaperMock.activateLabel).toHaveBeenCalled(); + expect(edgeShaperMock.activateLabel).toHaveBeenCalled(); + }); + it('should not be possible to zoom in if max-zoom is reached', function() { var oldNL = manager.getNodeLimit(), oldD = manager.getDistortion(), @@ -209,6 +255,7 @@ expect(manager.getDistortion()).toEqual(oldD); expect(manager.getDistortionRadius()).toEqual(oldDR); expect(manager.scaleFactor()).not.toBeLessThan(oldSF); + }); it('should be possible to zoom-out until labels are removed', function() { @@ -217,7 +264,7 @@ oldD, oldDR, loopCounter = 0; - while (manager.getFontSize() > fontMin && manager.getFontSize() !== null) { + do { oldNL = manager.getNodeLimit(); oldD = manager.getDistortion(); oldDR = manager.getDistortionRadius(); @@ -226,18 +273,14 @@ expect(manager.getNodeLimit()).not.toBeLessThan(oldNL); expect(manager.getDistortion()).toBeGreaterThan(oldD); expect(manager.getDistortionRadius()).toBeGreaterThan(oldDR); - expect(manager.scaleFactor()).not.toBeLessThan(oldSF); + expect(manager.scaleFactor()).toBeLessThan(oldSF); loopCounter++; if (loopCounter === 1000) { this.fail(new Error('The minimal font-size should have been reached')); break; } - } - if (manager.getFontSize() === null) { - simulateZoomIn(); - } - expect(manager.getFontSize()).toBeCloseTo(fontMin, 6); - expect(manager.getRadius()).toBeCloseTo((radMax-radMin) / 2 + radMin, 6); + } while (labelsAreVisible()); + simulateZoomIn(); expect(manager.getNodeLimit()).toBeCloseTo(nodeMinLabel, 6); //expect(manager.getDistortion()).toBeCloseTo(0, 6); }); @@ -246,50 +289,49 @@ beforeEach(function() { var loopCounter = 0; - while (manager.getFontSize() > fontMin && manager.getFontSize() !== null) { + do { simulateZoomOut(); loopCounter++; if (loopCounter === 1000) { this.fail(new Error('The minimal font-size should have been reached')); break; } - } - if (manager.getFontSize() === null) { - simulateZoomIn(); - } + } while (labelsAreVisible()); + simulateZoomIn(); }); it('should be able to zoom-in again', function() { - var oldFS, - oldR, - oldNL, + var oldNL, oldD, + oldDR, + oldSF, loopCounter = 0; - while (manager.getFontSize() < fontMax) { - oldFS = manager.getFontSize(); - oldR = manager.getRadius(); + while (manager.scaleFactor() < 1) { oldNL = manager.getNodeLimit(); oldD = manager.getDistortion(); + oldDR = manager.getDistortionRadius(); + oldSF = manager.scaleFactor(); simulateZoomIn(); - expect(manager.getFontSize()).toBeGreaterThan(oldFS); - expect(manager.getRadius()).toBeGreaterThan(oldR); expect(manager.getNodeLimit()).not.toBeGreaterThan(oldNL); expect(manager.getDistortion()).toBeLessThan(oldD); + expect(manager.getDistortionRadius()).toBeLessThan(oldDR); + expect(manager.scaleFactor()).toBeGreaterThan(oldSF); loopCounter++; if (loopCounter === 1000) { this.fail(new Error('The maximal font-size should have been reached')); break; } } - expect(manager.getFontSize()).toEqual(fontMax); - expect(manager.getRadius()).toEqual(radMax); + expect(manager.scaleFactor()).toEqual(1); expect(manager.getNodeLimit()).toEqual(nodeMax); expect(manager.getDistortion()).toBeCloseTo(0, 6); + expect(manager.getDistortionRadius()).toEqual(distRBase); }); - it('should return null for font-size if further zoomed out', function() { + it('should remove the labels if further zoomed out', function() { simulateZoomOut(); - expect(manager.getFontSize()).toEqual(null); + expect(lastNodeShaperCall()).toBeFalsy(); + expect(lastEdgeShaperCall()).toBeFalsy(); }); it('should significantly increase the node limit if further zoomed out', function() { @@ -298,28 +340,29 @@ }); it('should be able to zoom-out until minimal node radius is reached', function() { - var oldR, - oldNL, + var oldNL, oldD, + oldDR, + oldSF, loopCounter = 0; - while (manager.getRadius() > radMin) { - oldR = manager.getRadius(); + while (manager.scaleFactor() > minScale) { oldNL = manager.getNodeLimit(); oldD = manager.getDistortion(); + oldDR = manager.getDistortionRadius(); + oldSF = manager.scaleFactor(); simulateZoomOut(); - expect(manager.getFontSize()).toEqual(null); - expect(manager.getRadius()).toBeLessThan(oldR); expect(manager.getNodeLimit()).not.toBeLessThan(oldNL); expect(manager.getDistortion()).toBeGreaterThan(oldD); + expect(manager.getDistortionRadius()).toBeGreaterThan(oldDR); + expect(manager.scaleFactor()).toBeLessThan(oldSF); loopCounter++; if (loopCounter === 1000) { this.fail(new Error('The minimal font-size should have been reached')); break; } } - expect(manager.getRadius()).toEqual(radMin); expect(manager.getNodeLimit()).toEqual(nodeMin); - //expect(manager.getDistortion()).toBeCloseTo(0, 6); + expect(manager.scaleFactor()).toEqual(minScale); }); }); @@ -328,7 +371,7 @@ beforeEach(function() { var loopCounter = 0; - while (manager.getRadius() > radMin) { + while (manager.scaleFactor() > minScale) { simulateZoomOut(); loopCounter++; if (loopCounter === 2000) { @@ -339,38 +382,39 @@ }); it('should not be able to further zoom out', function() { - var oldR = manager.getRadius(), - oldNL = manager.getNodeLimit(), - oldD = manager.getDistortion(); + var oldNL = manager.getNodeLimit(), + oldD = manager.getDistortion(), + oldDR = manager.getDistortionRadius(), + oldSF = manager.scaleFactor(); simulateZoomOut(); - expect(manager.getRadius()).toEqual(oldR); expect(manager.getNodeLimit()).toEqual(oldNL); expect(manager.getDistortion()).toEqual(oldD); + expect(manager.getDistortionRadius()).toEqual(oldDR); + expect(manager.scaleFactor()).toEqual(oldSF); }); it('should be able to zoom-in again', function() { - var oldR, - oldNL, + var oldNL, oldD, + oldDR, + oldSF, loopCounter = 0; - while (manager.getFontSize() === null) { - oldR = manager.getRadius(); + while (labelsAreInvisible()) { oldNL = manager.getNodeLimit(); oldD = manager.getDistortion(); + oldDR = manager.getDistortionRadius(); + oldSF = manager.scaleFactor(); simulateZoomIn(); - expect(manager.getRadius()).toBeGreaterThan(oldR); expect(manager.getNodeLimit()).not.toBeGreaterThan(oldNL); expect(manager.getDistortion()).toBeLessThan(oldD); + expect(manager.getDistortionRadius()).toBeLessThan(oldDR); + expect(manager.scaleFactor()).toBeGreaterThan(oldSF); loopCounter++; if (loopCounter === 1000) { this.fail(new Error('The minimal font-size should have been reached')); break; } } - expect(manager.getFontSize()).toBeCloseTo(fontMin, 6); - expect(manager.getRadius()).toBeCloseTo((radMax-radMin) / 2 + radMin, 6); - expect(manager.getNodeLimit()).toBeCloseTo(nodeMinLabel, 6); - //expect(manager.getDistortion()).toBeCloseTo(0, 6); }); });