mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into devel
This commit is contained in:
commit
79eeea28dd
|
@ -0,0 +1,162 @@
|
||||||
|
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
|
||||||
|
/*global $, _, d3*/
|
||||||
|
/*global ColourMapper*/
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Graph functionality
|
||||||
|
///
|
||||||
|
/// @file
|
||||||
|
///
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Michael Hackstein
|
||||||
|
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
function ZoomManager(width, height, config) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
if (width === undefined || width < 0) {
|
||||||
|
throw("A width has to be given.");
|
||||||
|
}
|
||||||
|
if (height === undefined || height < 0) {
|
||||||
|
throw("A height has to be given.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var self = this,
|
||||||
|
fontMax,
|
||||||
|
fontMin,
|
||||||
|
rMax,
|
||||||
|
rMin,
|
||||||
|
rMid,
|
||||||
|
|
||||||
|
radiusStep,
|
||||||
|
fontStep,
|
||||||
|
distortionStep,
|
||||||
|
|
||||||
|
currentZoom,
|
||||||
|
currentFont,
|
||||||
|
currentRadius,
|
||||||
|
currentLimit,
|
||||||
|
currentDistortion,
|
||||||
|
size = width * height,
|
||||||
|
calcNodeLimit = function () {
|
||||||
|
var div;
|
||||||
|
if (currentFont !== null) {
|
||||||
|
div = 60 * currentFont * currentFont;
|
||||||
|
} else {
|
||||||
|
div = 4 * currentRadius * currentRadius * Math.PI;
|
||||||
|
}
|
||||||
|
return Math.floor(size / div);
|
||||||
|
},
|
||||||
|
parseConfig = function (conf) {
|
||||||
|
fontMax = 16;
|
||||||
|
fontMin = 6;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
currentLimit = calcNodeLimit();
|
||||||
|
};
|
||||||
|
|
||||||
|
parseConfig(config);
|
||||||
|
|
||||||
|
self.getFontSize = function() {
|
||||||
|
return currentFont;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.getRadius = function() {
|
||||||
|
return currentRadius;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.getDistortion = function() {
|
||||||
|
return currentDistortion;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.getNodeLimit = function() {
|
||||||
|
return currentLimit;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.zoomIn = function() {
|
||||||
|
if (currentZoom === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
adjustValues(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.zoomOut = function() {
|
||||||
|
if (currentZoom === 200) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
adjustValues(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
<li><a href="runnerEventDispatcher.html">Event Dispatcher</a></li>
|
<li><a href="runnerEventDispatcher.html">Event Dispatcher</a></li>
|
||||||
<li><a href="runnerEventLibrary.html">Event Library</a></li>
|
<li><a href="runnerEventLibrary.html">Event Library</a></li>
|
||||||
<li><a href="runnerColourMapper.html">Colour Mapper</a></li>
|
<li><a href="runnerColourMapper.html">Colour Mapper</a></li>
|
||||||
|
<li><a href="runnerZoomManager.html">Zoom Manager</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
|
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
|
||||||
/*global beforeEach, afterEach */
|
/*global beforeEach, afterEach, jasmine */
|
||||||
/*global describe, it, expect */
|
/*global describe, it, expect */
|
||||||
/*global window, eb, loadFixtures, document */
|
/*global window, eb, loadFixtures, document */
|
||||||
/*global $, _, d3*/
|
/*global $, _, d3*/
|
||||||
|
@ -72,36 +72,265 @@
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setup correctly', function() {
|
describe('setup with default values', function() {
|
||||||
|
|
||||||
var manager;
|
var w,
|
||||||
|
h,
|
||||||
|
manager;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
manager = new ZoomManager(10, 10);
|
w = 200;
|
||||||
|
h = 200;
|
||||||
|
manager = new ZoomManager(w, h);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('the interface', function() {
|
||||||
it('should offer a function to get the current font-size', function() {
|
it('should offer a function to get the current font-size', function() {
|
||||||
expect(manager.getFontSize).toBeDefined();
|
expect(manager.getFontSize).toBeDefined();
|
||||||
expect(manager.getFontSize).toEqual(Jasmine.any(Function));
|
expect(manager.getFontSize).toEqual(jasmine.any(Function));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should offer a function to get the current node-radius', function() {
|
it('should offer a function to get the current node-radius', function() {
|
||||||
expect(manager.getRadius).toBeDefined();
|
expect(manager.getRadius).toBeDefined();
|
||||||
expect(manager.getRadius).toEqual(Jasmine.any(Function));
|
expect(manager.getRadius).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 a function to get the distortion', function() {
|
||||||
|
expect(manager.getDistortion).toBeDefined();
|
||||||
|
expect(manager.getDistortion).toEqual(jasmine.any(Function));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should offer a function for zoom-in', function() {
|
it('should offer a function for zoom-in', function() {
|
||||||
expect(manager.zoomIn).toBeDefined();
|
expect(manager.zoomIn).toBeDefined();
|
||||||
expect(manager.zoomIn).toEqual(Jasmine.any(Function));
|
expect(manager.zoomIn).toEqual(jasmine.any(Function));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should offer a function for zoom-out', function() {
|
it('should offer a function for zoom-out', function() {
|
||||||
expect(manager.zoomOut).toBeDefined();
|
expect(manager.zoomOut).toBeDefined();
|
||||||
expect(manager.zoomOut).toEqual(Jasmine.any(Function));
|
expect(manager.zoomOut).toEqual(jasmine.any(Function));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('default values', function() {
|
||||||
|
|
||||||
|
var fontMax,
|
||||||
|
fontMin,
|
||||||
|
radMax,
|
||||||
|
radMin,
|
||||||
|
nodeMax,
|
||||||
|
nodeMaxNoLabel,
|
||||||
|
nodeMinLabel,
|
||||||
|
nodeMin;
|
||||||
|
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
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;
|
||||||
|
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.getFontSize()).toEqual(fontMax);
|
||||||
|
expect(manager.getRadius()).toEqual(radMax);
|
||||||
|
expect(manager.getNodeLimit()).toEqual(nodeMax);
|
||||||
|
expect(manager.getDistortion()).toBeCloseTo(0, 6);
|
||||||
|
});
|
||||||
|
|
||||||
|
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() {
|
||||||
|
var loopCounter = 0;
|
||||||
|
while (manager.getFontSize() > fontMin && manager.getFontSize() !== null) {
|
||||||
|
manager.zoomOut();
|
||||||
|
loopCounter++;
|
||||||
|
if (loopCounter === 1000) {
|
||||||
|
this.fail(new Error('The minimal font-size should have been reached'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (manager.getFontSize() === null) {
|
||||||
|
manager.zoomIn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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.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() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue