mirror of https://gitee.com/bigwinds/arangodb
GraphViewer: Started with new interface for zoommanager with better integration of D3 and Fisheye
This commit is contained in:
parent
ee9473adbd
commit
169dcfeb66
|
@ -29,7 +29,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
function ZoomManager(width, height, config) {
|
function ZoomManager(width, height, g, nodeShaper, edgeShaper, config) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
if (width === undefined || width < 0) {
|
if (width === undefined || width < 0) {
|
||||||
|
@ -38,125 +38,134 @@ function ZoomManager(width, height, config) {
|
||||||
if (height === undefined || height < 0) {
|
if (height === undefined || height < 0) {
|
||||||
throw("A height has to be given.");
|
throw("A height has to be given.");
|
||||||
}
|
}
|
||||||
|
if (g === undefined || g.node === undefined || g.node().tagName !== "G") {
|
||||||
|
throw("A group has to be given.");
|
||||||
|
}
|
||||||
|
if (nodeShaper === undefined || nodeShaper.activate === undefined) {
|
||||||
|
throw("The Node shaper has to be given.");
|
||||||
|
}
|
||||||
|
if (edgeShaper === undefined || edgeShaper.activate === undefined) {
|
||||||
|
throw("The Edge shaper has to be given.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var self = this,
|
var self = this,
|
||||||
fontMax,
|
fontSize,
|
||||||
fontMin,
|
nodeRadius,
|
||||||
rMax,
|
labelToggle,
|
||||||
rMin,
|
|
||||||
rMid,
|
|
||||||
|
|
||||||
radiusStep,
|
|
||||||
fontStep,
|
|
||||||
distortionStep,
|
|
||||||
|
|
||||||
currentZoom,
|
currentZoom,
|
||||||
currentFont,
|
|
||||||
currentRadius,
|
|
||||||
currentLimit,
|
currentLimit,
|
||||||
currentDistortion,
|
currentDistortion,
|
||||||
|
currentDistortionRadius,
|
||||||
size = width * height,
|
size = width * height,
|
||||||
|
zoom,
|
||||||
|
|
||||||
calcNodeLimit = function () {
|
calcNodeLimit = function () {
|
||||||
var div;
|
var div, reqSize;
|
||||||
if (currentFont !== null) {
|
if (currentZoom >= labelToggle) {
|
||||||
div = 60 * currentFont * currentFont;
|
reqSize = fontSize * currentZoom;
|
||||||
|
reqSize *= reqSize;
|
||||||
|
div = 60 * reqSize;
|
||||||
} else {
|
} else {
|
||||||
div = 4 * currentRadius * currentRadius * Math.PI;
|
reqSize = nodeRadius * currentZoom;
|
||||||
|
reqSize *= reqSize;
|
||||||
|
div = 4 * Math.PI * reqSize;
|
||||||
}
|
}
|
||||||
return Math.floor(size / div);
|
return Math.floor(size / div);
|
||||||
},
|
},
|
||||||
parseConfig = function (conf) {
|
parseConfig = function (conf) {
|
||||||
fontMax = 16;
|
if (conf === undefined) {
|
||||||
fontMin = 6;
|
conf = {};
|
||||||
rMax = 25;
|
|
||||||
rMin = 1;
|
|
||||||
rMid = (rMax - rMin) / 2 + rMin;
|
|
||||||
|
|
||||||
fontStep = (fontMax - fontMin) / 100;
|
|
||||||
radiusStep = (rMax - rMin) / 200;
|
|
||||||
distortionStep = 0.001; // TODO!
|
|
||||||
|
|
||||||
currentFont = fontMax;
|
|
||||||
currentRadius = rMax;
|
|
||||||
currentDistortion = 0;
|
|
||||||
currentLimit = calcNodeLimit();
|
|
||||||
currentZoom = 0;
|
|
||||||
},
|
|
||||||
adjustValues = function (out) {
|
|
||||||
if (out) {
|
|
||||||
currentZoom++;
|
|
||||||
if (currentZoom > 100) {
|
|
||||||
currentFont = null;
|
|
||||||
if (currentZoom === 200) {
|
|
||||||
currentRadius = rMin;
|
|
||||||
} else {
|
|
||||||
currentRadius -= radiusStep;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (currentZoom === 100) {
|
|
||||||
currentFont = fontMin;
|
|
||||||
currentRadius = rMid;
|
|
||||||
} else {
|
|
||||||
currentRadius -= radiusStep;
|
|
||||||
currentFont -= fontStep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentDistortion += distortionStep;
|
|
||||||
} else {
|
|
||||||
currentZoom--;
|
|
||||||
if (currentZoom < 100) {
|
|
||||||
if (currentZoom === 0) {
|
|
||||||
currentFont = fontMax;
|
|
||||||
currentRadius = rMax;
|
|
||||||
} else {
|
|
||||||
currentFont += fontStep;
|
|
||||||
currentRadius += radiusStep;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (currentZoom === 100) {
|
|
||||||
currentFont = fontMin;
|
|
||||||
currentRadius = rMid;
|
|
||||||
} else {
|
|
||||||
currentRadius += radiusStep;
|
|
||||||
currentFont = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentDistortion -= distortionStep;
|
|
||||||
}
|
}
|
||||||
|
var
|
||||||
|
fontMax = conf.maxFont || 16,
|
||||||
|
fontMin = conf.minFont || 6,
|
||||||
|
rMax = conf.maxRadius || 25,
|
||||||
|
rMin = conf.minRadius || 1;
|
||||||
|
|
||||||
|
fontSize = fontMax;
|
||||||
|
nodeRadius = rMax;
|
||||||
|
|
||||||
|
labelToggle = 0;
|
||||||
|
currentDistortion = 0;
|
||||||
|
currentDistortionRadius = 100;
|
||||||
currentLimit = calcNodeLimit();
|
currentLimit = calcNodeLimit();
|
||||||
|
currentZoom = 1;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
parseConfig(config);
|
parseConfig(config);
|
||||||
|
|
||||||
self.getFontSize = function() {
|
g.call(zoom);
|
||||||
return currentFont;
|
|
||||||
|
|
||||||
|
self.translation = function() {
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getRadius = function() {
|
self.scaleFactor = function() {
|
||||||
return currentRadius;
|
return currentZoom;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.scaledMouse = function() {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.mouseMoveHandle = function() {
|
||||||
|
// TODO
|
||||||
|
var focus = d3.mouse(this);
|
||||||
|
focus[0] += curTrans[0];
|
||||||
|
focus[1] += curTrans[1];
|
||||||
|
fisheye.focus(focus);
|
||||||
|
|
||||||
|
node.each(function(d) { d.fisheye = fisheye(d); })
|
||||||
|
.attr("cx", function(d) { return d.fisheye.x; })
|
||||||
|
.attr("cy", function(d) { return d.fisheye.y; })
|
||||||
|
.attr("r", function(d) { return d.fisheye.z * 25; });
|
||||||
|
|
||||||
|
link.attr("x1", function(d) { return d.source.fisheye.x; })
|
||||||
|
.attr("y1", function(d) { return d.source.fisheye.y; })
|
||||||
|
.attr("x2", function(d) { return d.target.fisheye.x; })
|
||||||
|
.attr("y2", function(d) { return d.target.fisheye.y; });
|
||||||
|
};
|
||||||
|
|
||||||
self.getDistortion = function() {
|
self.getDistortion = function() {
|
||||||
return currentDistortion;
|
return currentDistortion;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.getDistortionRadius = function() {
|
||||||
|
return currentDistortionRadius;
|
||||||
|
};
|
||||||
|
|
||||||
self.getNodeLimit = function() {
|
self.getNodeLimit = function() {
|
||||||
return currentLimit;
|
return currentLimit;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.zoomIn = function() {
|
|
||||||
if (currentZoom === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adjustValues(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
self.zoomOut = function() {
|
|
||||||
if (currentZoom === 200) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adjustValues(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -53,4 +53,20 @@ var helper = helper || {};
|
||||||
testee.dispatchEvent(evt);
|
testee.dispatchEvent(evt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
helper.simulateScrollUpMouseEvent = function (objectId) {
|
||||||
|
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);
|
||||||
|
testee.dispatchEvent(evt);
|
||||||
|
};
|
||||||
|
|
||||||
|
helper.simulateScrollDownMouseEvent = function (objectId) {
|
||||||
|
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);
|
||||||
|
testee.dispatchEvent(evt);
|
||||||
|
};
|
||||||
|
|
||||||
}());
|
}());
|
|
@ -38,11 +38,32 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
describe('Zoom Manager', function () {
|
describe('Zoom Manager', function () {
|
||||||
var svg;
|
var svg,
|
||||||
|
g,
|
||||||
|
nodeShaperMock,
|
||||||
|
edgeShaperMock,
|
||||||
|
|
||||||
|
simulateZoomOut = function () {
|
||||||
|
helper.simulateScrollUpMouseEvent("svg");
|
||||||
|
},
|
||||||
|
|
||||||
|
simulateZoomIn = function () {
|
||||||
|
helper.simulateScrollDownMouseEvent("svg");
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
svg = document.createElement("svg");
|
svg = document.createElement("svg");
|
||||||
document.body.appendChild(svg);
|
document.body.appendChild(svg);
|
||||||
|
g = d3.select("svg").append("g");
|
||||||
|
g.attr("id", "svg");
|
||||||
|
nodeShaperMock = {
|
||||||
|
activateLabel: function() {}
|
||||||
|
};
|
||||||
|
edgeShaperMock = {
|
||||||
|
activateLabel: function() {}
|
||||||
|
};
|
||||||
|
spyOn(nodeShaperMock, "activateLabel");
|
||||||
|
spyOn(edgeShaperMock, "activateLabel");
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
|
@ -63,172 +84,149 @@
|
||||||
}).toThrow("A height has to be given.");
|
}).toThrow("A height has to be given.");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not throw an error if mandatory information is given', function() {
|
it('should throw an error if the group is not given', function() {
|
||||||
expect(function() {
|
expect(function() {
|
||||||
var s = new ZoomManager(10, 10);
|
var s = new ZoomManager(10, 10);
|
||||||
|
}).toThrow("A group has to be given.");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if the node shaper is not given', function() {
|
||||||
|
expect(function() {
|
||||||
|
var s = new ZoomManager(10, 10, g);
|
||||||
|
}).toThrow("The Node shaper has to be given.");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if the edge shaper is not given', function() {
|
||||||
|
expect(function() {
|
||||||
|
var s = new ZoomManager(10, 10, g, nodeShaperMock);
|
||||||
|
}).toThrow("The Edge shaper has to be given.");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should not throw an error if mandatory information is given', function() {
|
||||||
|
expect(function() {
|
||||||
|
var s = new ZoomManager(10, 10, g, nodeShaperMock, edgeShaperMock);
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('setup with default values', function() {
|
describe('setup with default values', function() {
|
||||||
|
|
||||||
var w,
|
var w,
|
||||||
h,
|
h,
|
||||||
manager;
|
manager;
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
w = 200;
|
|
||||||
h = 200;
|
|
||||||
manager = new ZoomManager(w, h);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('the interface', function() {
|
|
||||||
|
|
||||||
it('should offer a function handle for zoom', function() {
|
|
||||||
expect(manager.zoomHandle).toBeDefined();
|
|
||||||
expect(manager.zoomHandle).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should offer a function to get the current scale factor', function() {
|
|
||||||
expect(manager.scaleFactor).toBeDefined();
|
|
||||||
expect(manager.scaleFactor).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should offer a function to get the current translation', function() {
|
|
||||||
expect(manager.translation).toBeDefined();
|
|
||||||
expect(manager.translation).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should offer a function to get scaled mouse position', function() {
|
|
||||||
expect(manager.scaledMouse).toBeDefined();
|
|
||||||
expect(manager.scaledMouse).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should offer a function to get the distortion', function() {
|
|
||||||
expect(manager.getDistortion).toBeDefined();
|
|
||||||
expect(manager.getDistortion).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should offer a function to get the distortion radius', function() {
|
|
||||||
expect(manager.getDistortionRadius).toBeDefined();
|
|
||||||
expect(manager.getDistortionRadius).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should offer a function to get the node limit', function() {
|
|
||||||
expect(manager.getNodeLimit).toBeDefined();
|
|
||||||
expect(manager.getNodeLimit).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Old interface might be unused!
|
|
||||||
|
|
||||||
it('should offer a function to get the current font-size', function() {
|
|
||||||
expect(manager.getFontSize).toBeDefined();
|
|
||||||
expect(manager.getFontSize).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should offer a function to get the current node-radius', function() {
|
|
||||||
expect(manager.getRadius).toBeDefined();
|
|
||||||
expect(manager.getRadius).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should offer a function for zoom-in', function() {
|
|
||||||
expect(manager.zoomIn).toBeDefined();
|
|
||||||
expect(manager.zoomIn).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should offer a function for zoom-out', function() {
|
|
||||||
expect(manager.zoomOut).toBeDefined();
|
|
||||||
expect(manager.zoomOut).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('default values', function() {
|
|
||||||
|
|
||||||
var fontMax,
|
|
||||||
fontMin,
|
|
||||||
radMax,
|
|
||||||
radMin,
|
|
||||||
nodeMax,
|
|
||||||
nodeMaxNoLabel,
|
|
||||||
nodeMinLabel,
|
|
||||||
nodeMin;
|
|
||||||
|
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
var labelSize = function (font) {
|
w = 200;
|
||||||
return 60 * font * font;
|
h = 200;
|
||||||
},
|
manager = new ZoomManager(w, h, g, nodeShaperMock, edgeShaperMock);
|
||||||
circleSize = function (radius) {
|
|
||||||
return 4 * radius * radius * Math.PI;
|
|
||||||
};
|
|
||||||
fontMax = 16;
|
|
||||||
fontMin = 6;
|
|
||||||
radMax = 25;
|
|
||||||
radMin = 1;
|
|
||||||
nodeMax = Math.floor(w * h / labelSize(fontMax));
|
|
||||||
nodeMinLabel = Math.floor(w * h / labelSize(fontMin));
|
|
||||||
nodeMaxNoLabel = Math.floor(w * h / circleSize((radMax - radMin) / 2 + radMin));
|
|
||||||
nodeMin = Math.floor(w * h / circleSize(radMin));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('the interface', function() {
|
||||||
|
|
||||||
|
it('should offer a function handle for the mouse movement', function() {
|
||||||
|
expect(manager.mouseMoveHandle).toBeDefined();
|
||||||
|
expect(manager.mouseMoveHandle).toEqual(jasmine.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should offer a function to get the current scale factor', function() {
|
||||||
|
expect(manager.scaleFactor).toBeDefined();
|
||||||
|
expect(manager.scaleFactor).toEqual(jasmine.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should offer a function to get the current translation', function() {
|
||||||
|
expect(manager.translation).toBeDefined();
|
||||||
|
expect(manager.translation).toEqual(jasmine.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should offer a function to get scaled mouse position', function() {
|
||||||
|
expect(manager.scaledMouse).toBeDefined();
|
||||||
|
expect(manager.scaledMouse).toEqual(jasmine.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should offer a function to get the distortion', function() {
|
||||||
|
expect(manager.getDistortion).toBeDefined();
|
||||||
|
expect(manager.getDistortion).toEqual(jasmine.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should offer a function to get the distortion radius', function() {
|
||||||
|
expect(manager.getDistortionRadius).toBeDefined();
|
||||||
|
expect(manager.getDistortionRadius).toEqual(jasmine.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should offer a function to get the node limit', function() {
|
||||||
|
expect(manager.getNodeLimit).toBeDefined();
|
||||||
|
expect(manager.getNodeLimit).toEqual(jasmine.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
it('should offer maximized values if no zoom happens', function() {
|
|
||||||
expect(manager.getFontSize()).toEqual(fontMax);
|
|
||||||
expect(manager.getRadius()).toEqual(radMax);
|
|
||||||
expect(manager.getNodeLimit()).toEqual(nodeMax);
|
|
||||||
expect(manager.getDistortion()).toBeCloseTo(0, 6);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('default values', function() {
|
||||||
|
|
||||||
|
var fontMax,
|
||||||
|
fontMin,
|
||||||
|
radMax,
|
||||||
|
radMin,
|
||||||
|
nodeMax,
|
||||||
|
nodeMaxNoLabel,
|
||||||
|
nodeMinLabel,
|
||||||
|
nodeMin,
|
||||||
|
distRBase;
|
||||||
|
|
||||||
it('should not be possible to zoom in if max-zoom is reached', function() {
|
|
||||||
var oldFS = manager.getFontSize(),
|
|
||||||
oldR = manager.getRadius(),
|
|
||||||
oldNL = manager.getNodeLimit(),
|
|
||||||
oldD = manager.getDistortion();
|
|
||||||
manager.zoomIn();
|
|
||||||
expect(manager.getFontSize()).toEqual(oldFS);
|
|
||||||
expect(manager.getRadius()).toEqual(oldR);
|
|
||||||
expect(manager.getNodeLimit()).toEqual(oldNL);
|
|
||||||
expect(manager.getDistortion()).toEqual(oldD);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be possible to zoom-out until minimal font-size is reached', function() {
|
|
||||||
var oldFS,
|
|
||||||
oldR,
|
|
||||||
oldNL,
|
|
||||||
oldD,
|
|
||||||
loopCounter = 0;
|
|
||||||
while (manager.getFontSize() > fontMin && manager.getFontSize() !== null) {
|
|
||||||
oldFS = manager.getFontSize();
|
|
||||||
oldR = manager.getRadius();
|
|
||||||
oldNL = manager.getNodeLimit();
|
|
||||||
oldD = manager.getDistortion();
|
|
||||||
manager.zoomOut();
|
|
||||||
expect(manager.getFontSize()).toBeLessThan(oldFS);
|
|
||||||
expect(manager.getRadius()).toBeLessThan(oldR);
|
|
||||||
expect(manager.getNodeLimit()).not.toBeLessThan(oldNL);
|
|
||||||
expect(manager.getDistortion()).toBeGreaterThan(oldD);
|
|
||||||
loopCounter++;
|
|
||||||
if (loopCounter === 1000) {
|
|
||||||
this.fail(new Error('The minimal font-size should have been reached'));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (manager.getFontSize() === null) {
|
|
||||||
manager.zoomIn();
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with zoomlevel adjusted to minimal font-size', function() {
|
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
var loopCounter = 0;
|
var labelSize = function (font) {
|
||||||
|
return 60 * font * font;
|
||||||
|
},
|
||||||
|
circleSize = function (radius) {
|
||||||
|
return 4 * radius * radius * Math.PI;
|
||||||
|
};
|
||||||
|
fontMax = 16;
|
||||||
|
fontMin = 6;
|
||||||
|
radMax = 25;
|
||||||
|
radMin = 1;
|
||||||
|
distRBase = 100;
|
||||||
|
nodeMax = Math.floor(w * h / labelSize(fontMax));
|
||||||
|
nodeMinLabel = Math.floor(w * h / labelSize(fontMin));
|
||||||
|
nodeMaxNoLabel = Math.floor(w * h / circleSize((radMax - radMin) / 2 + radMin));
|
||||||
|
nodeMin = Math.floor(w * h / circleSize(radMin));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should offer maximized values if no zoom happens', function() {
|
||||||
|
expect(manager.getNodeLimit()).toEqual(nodeMax);
|
||||||
|
expect(manager.getDistortion()).toBeCloseTo(0, 6);
|
||||||
|
expect(manager.getDistortionRadius()).toEqual(distRBase);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be possible to zoom in if max-zoom is reached', function() {
|
||||||
|
var oldNL = manager.getNodeLimit(),
|
||||||
|
oldD = manager.getDistortion(),
|
||||||
|
oldDR = manager.getDistortionRadius(),
|
||||||
|
oldSF = manager.scaleFactor();
|
||||||
|
simulateZoomIn();
|
||||||
|
expect(manager.getNodeLimit()).toEqual(oldNL);
|
||||||
|
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() {
|
||||||
|
var oldNL,
|
||||||
|
oldSF,
|
||||||
|
oldD,
|
||||||
|
oldDR,
|
||||||
|
loopCounter = 0;
|
||||||
while (manager.getFontSize() > fontMin && manager.getFontSize() !== null) {
|
while (manager.getFontSize() > fontMin && manager.getFontSize() !== null) {
|
||||||
manager.zoomOut();
|
oldNL = manager.getNodeLimit();
|
||||||
|
oldD = manager.getDistortion();
|
||||||
|
oldDR = manager.getDistortionRadius();
|
||||||
|
oldSF = manager.scaleFactor();
|
||||||
|
simulateZoomOut();
|
||||||
|
expect(manager.getNodeLimit()).not.toBeLessThan(oldNL);
|
||||||
|
expect(manager.getDistortion()).toBeGreaterThan(oldD);
|
||||||
|
expect(manager.getDistortionRadius()).toBeGreaterThan(oldDR);
|
||||||
|
expect(manager.scaleFactor()).not.toBeLessThan(oldSF);
|
||||||
loopCounter++;
|
loopCounter++;
|
||||||
if (loopCounter === 1000) {
|
if (loopCounter === 1000) {
|
||||||
this.fail(new Error('The minimal font-size should have been reached'));
|
this.fail(new Error('The minimal font-size should have been reached'));
|
||||||
|
@ -236,130 +234,155 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (manager.getFontSize() === null) {
|
if (manager.getFontSize() === null) {
|
||||||
manager.zoomIn();
|
simulateZoomIn();
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to zoom-in again', function() {
|
|
||||||
var oldFS,
|
|
||||||
oldR,
|
|
||||||
oldNL,
|
|
||||||
oldD,
|
|
||||||
loopCounter = 0;
|
|
||||||
while (manager.getFontSize() < fontMax) {
|
|
||||||
oldFS = manager.getFontSize();
|
|
||||||
oldR = manager.getRadius();
|
|
||||||
oldNL = manager.getNodeLimit();
|
|
||||||
oldD = manager.getDistortion();
|
|
||||||
manager.zoomIn();
|
|
||||||
expect(manager.getFontSize()).toBeGreaterThan(oldFS);
|
|
||||||
expect(manager.getRadius()).toBeGreaterThan(oldR);
|
|
||||||
expect(manager.getNodeLimit()).not.toBeGreaterThan(oldNL);
|
|
||||||
expect(manager.getDistortion()).toBeLessThan(oldD);
|
|
||||||
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.getNodeLimit()).toEqual(nodeMax);
|
|
||||||
expect(manager.getDistortion()).toBeCloseTo(0, 6);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return null for font-size if further zoomed out', function() {
|
|
||||||
manager.zoomOut();
|
|
||||||
expect(manager.getFontSize()).toEqual(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should significantly increase the node limit if further zoomed out', function() {
|
|
||||||
manager.zoomOut();
|
|
||||||
expect(manager.getNodeLimit()).toBeGreaterThan(nodeMaxNoLabel);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to zoom-out until minimal node radius is reached', function() {
|
|
||||||
var oldR,
|
|
||||||
oldNL,
|
|
||||||
oldD,
|
|
||||||
loopCounter = 0;
|
|
||||||
while (manager.getRadius() > radMin) {
|
|
||||||
oldR = manager.getRadius();
|
|
||||||
oldNL = manager.getNodeLimit();
|
|
||||||
oldD = manager.getDistortion();
|
|
||||||
manager.zoomOut();
|
|
||||||
expect(manager.getFontSize()).toEqual(null);
|
|
||||||
expect(manager.getRadius()).toBeLessThan(oldR);
|
|
||||||
expect(manager.getNodeLimit()).not.toBeLessThan(oldNL);
|
|
||||||
expect(manager.getDistortion()).toBeGreaterThan(oldD);
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with zoomlevel adjusted to maximal zoom out', function() {
|
|
||||||
|
|
||||||
beforeEach(function() {
|
|
||||||
var loopCounter = 0;
|
|
||||||
while (manager.getRadius() > radMin) {
|
|
||||||
manager.zoomOut();
|
|
||||||
loopCounter++;
|
|
||||||
if (loopCounter === 2000) {
|
|
||||||
this.fail(new Error('The minimal zoom level should have been reached'));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not be able to further zoom out', function() {
|
|
||||||
var oldR = manager.getRadius(),
|
|
||||||
oldNL = manager.getNodeLimit(),
|
|
||||||
oldD = manager.getDistortion();
|
|
||||||
manager.zoomOut();
|
|
||||||
expect(manager.getRadius()).toEqual(oldR);
|
|
||||||
expect(manager.getNodeLimit()).toEqual(oldNL);
|
|
||||||
expect(manager.getDistortion()).toEqual(oldD);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to zoom-in again', function() {
|
|
||||||
var oldR,
|
|
||||||
oldNL,
|
|
||||||
oldD,
|
|
||||||
loopCounter = 0;
|
|
||||||
while (manager.getFontSize() === null) {
|
|
||||||
oldR = manager.getRadius();
|
|
||||||
oldNL = manager.getNodeLimit();
|
|
||||||
oldD = manager.getDistortion();
|
|
||||||
manager.zoomIn();
|
|
||||||
expect(manager.getRadius()).toBeGreaterThan(oldR);
|
|
||||||
expect(manager.getNodeLimit()).not.toBeGreaterThan(oldNL);
|
|
||||||
expect(manager.getDistortion()).toBeLessThan(oldD);
|
|
||||||
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.getFontSize()).toBeCloseTo(fontMin, 6);
|
||||||
expect(manager.getRadius()).toBeCloseTo((radMax-radMin) / 2 + radMin, 6);
|
expect(manager.getRadius()).toBeCloseTo((radMax-radMin) / 2 + radMin, 6);
|
||||||
expect(manager.getNodeLimit()).toBeCloseTo(nodeMinLabel, 6);
|
expect(manager.getNodeLimit()).toBeCloseTo(nodeMinLabel, 6);
|
||||||
//expect(manager.getDistortion()).toBeCloseTo(0, 6);
|
//expect(manager.getDistortion()).toBeCloseTo(0, 6);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('with zoomlevel adjusted to minimal font-size', function() {
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
var loopCounter = 0;
|
||||||
|
while (manager.getFontSize() > fontMin && manager.getFontSize() !== null) {
|
||||||
|
simulateZoomOut();
|
||||||
|
loopCounter++;
|
||||||
|
if (loopCounter === 1000) {
|
||||||
|
this.fail(new Error('The minimal font-size should have been reached'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (manager.getFontSize() === null) {
|
||||||
|
simulateZoomIn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to zoom-in again', function() {
|
||||||
|
var oldFS,
|
||||||
|
oldR,
|
||||||
|
oldNL,
|
||||||
|
oldD,
|
||||||
|
loopCounter = 0;
|
||||||
|
while (manager.getFontSize() < fontMax) {
|
||||||
|
oldFS = manager.getFontSize();
|
||||||
|
oldR = manager.getRadius();
|
||||||
|
oldNL = manager.getNodeLimit();
|
||||||
|
oldD = manager.getDistortion();
|
||||||
|
simulateZoomIn();
|
||||||
|
expect(manager.getFontSize()).toBeGreaterThan(oldFS);
|
||||||
|
expect(manager.getRadius()).toBeGreaterThan(oldR);
|
||||||
|
expect(manager.getNodeLimit()).not.toBeGreaterThan(oldNL);
|
||||||
|
expect(manager.getDistortion()).toBeLessThan(oldD);
|
||||||
|
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.getNodeLimit()).toEqual(nodeMax);
|
||||||
|
expect(manager.getDistortion()).toBeCloseTo(0, 6);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null for font-size if further zoomed out', function() {
|
||||||
|
simulateZoomOut();
|
||||||
|
expect(manager.getFontSize()).toEqual(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should significantly increase the node limit if further zoomed out', function() {
|
||||||
|
simulateZoomOut();
|
||||||
|
expect(manager.getNodeLimit()).toBeGreaterThan(nodeMaxNoLabel);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to zoom-out until minimal node radius is reached', function() {
|
||||||
|
var oldR,
|
||||||
|
oldNL,
|
||||||
|
oldD,
|
||||||
|
loopCounter = 0;
|
||||||
|
while (manager.getRadius() > radMin) {
|
||||||
|
oldR = manager.getRadius();
|
||||||
|
oldNL = manager.getNodeLimit();
|
||||||
|
oldD = manager.getDistortion();
|
||||||
|
simulateZoomOut();
|
||||||
|
expect(manager.getFontSize()).toEqual(null);
|
||||||
|
expect(manager.getRadius()).toBeLessThan(oldR);
|
||||||
|
expect(manager.getNodeLimit()).not.toBeLessThan(oldNL);
|
||||||
|
expect(manager.getDistortion()).toBeGreaterThan(oldD);
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with zoomlevel adjusted to maximal zoom out', function() {
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
var loopCounter = 0;
|
||||||
|
while (manager.getRadius() > radMin) {
|
||||||
|
simulateZoomOut();
|
||||||
|
loopCounter++;
|
||||||
|
if (loopCounter === 2000) {
|
||||||
|
this.fail(new Error('The minimal zoom level should have been reached'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be able to further zoom out', function() {
|
||||||
|
var oldR = manager.getRadius(),
|
||||||
|
oldNL = manager.getNodeLimit(),
|
||||||
|
oldD = manager.getDistortion();
|
||||||
|
simulateZoomOut();
|
||||||
|
expect(manager.getRadius()).toEqual(oldR);
|
||||||
|
expect(manager.getNodeLimit()).toEqual(oldNL);
|
||||||
|
expect(manager.getDistortion()).toEqual(oldD);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to zoom-in again', function() {
|
||||||
|
var oldR,
|
||||||
|
oldNL,
|
||||||
|
oldD,
|
||||||
|
loopCounter = 0;
|
||||||
|
while (manager.getFontSize() === null) {
|
||||||
|
oldR = manager.getRadius();
|
||||||
|
oldNL = manager.getNodeLimit();
|
||||||
|
oldD = manager.getDistortion();
|
||||||
|
simulateZoomIn();
|
||||||
|
expect(manager.getRadius()).toBeGreaterThan(oldR);
|
||||||
|
expect(manager.getNodeLimit()).not.toBeGreaterThan(oldNL);
|
||||||
|
expect(manager.getDistortion()).toBeLessThan(oldD);
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('testing user-defined values', function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('testing user-defined values', function() {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}());
|
}());
|
Loading…
Reference in New Issue