2018-07-10 11:08:57 +08:00
|
|
|
/**
|
|
|
|
* @fileOverview force atlas 2
|
|
|
|
* @author shiwu.wyy@antfin.com
|
|
|
|
*/
|
|
|
|
const G6 = require('@antv/g6');
|
|
|
|
const Util = G6.Util;
|
|
|
|
|
|
|
|
class Tool {
|
|
|
|
constructor(options) {
|
|
|
|
Util.mix(this, {
|
|
|
|
/**
|
|
|
|
* radius
|
|
|
|
* @type {number}
|
|
|
|
*/
|
2018-07-18 11:46:13 +08:00
|
|
|
radius: 200,
|
2018-07-10 11:08:57 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* defualt zoom center
|
2018-08-08 10:08:34 +08:00
|
|
|
* @type {array}
|
2018-07-10 11:08:57 +08:00
|
|
|
*/
|
|
|
|
center: [ 0, 0 ],
|
|
|
|
|
|
|
|
/**
|
|
|
|
* defualt magnification factor
|
2018-08-08 10:08:34 +08:00
|
|
|
* @type {number}
|
2018-07-10 11:08:57 +08:00
|
|
|
*/
|
|
|
|
d: 1.0
|
|
|
|
}, options);
|
|
|
|
}
|
|
|
|
zoom(centerx, centery) {
|
|
|
|
const {
|
|
|
|
graph,
|
|
|
|
radius,
|
|
|
|
d
|
|
|
|
} = this;
|
|
|
|
const center = [ centerx, centery ];
|
|
|
|
const nodes = graph.getNodes();
|
|
|
|
const size = nodes.length;
|
|
|
|
// pick out the nodes inside the radius
|
|
|
|
for (let i = 0; i < size; i += 1) {
|
|
|
|
const node = nodes[i].getModel();
|
|
|
|
const dist = Math.hypot(node.x - center[0], node.y - center[1]);
|
|
|
|
if (dist < radius) {
|
|
|
|
// take the center as the origin
|
2018-08-06 11:56:17 +08:00
|
|
|
const movedCoords = [ node.x - center[0], node.y - center[1] ];
|
2018-07-10 11:08:57 +08:00
|
|
|
// transform to polar coordinates
|
2018-08-06 11:56:17 +08:00
|
|
|
const { p, theta } = Rect2Polar(movedCoords[0], movedCoords[1]);
|
2018-07-10 11:08:57 +08:00
|
|
|
const pf = radius * (((d + 1) * (p / radius)) / (d * (p / radius) + 1)); // after fisheye zooming
|
|
|
|
// transform to rect coordinates
|
|
|
|
const { x, y } = Polar2Rect(pf, theta);
|
|
|
|
// move back to the original origin
|
|
|
|
nodes[i].getModel().x = x + center[0];
|
|
|
|
nodes[i].getModel().y = y + center[1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function Rect2Polar(x, y) {
|
|
|
|
const p = Math.hypot(x, y);
|
|
|
|
let theta;
|
|
|
|
if (y >= 0) {
|
|
|
|
if (x === 0) {
|
|
|
|
theta = Math.PI / 2; // 90°
|
|
|
|
} else {
|
|
|
|
theta = Math.acos(x / p);
|
|
|
|
}
|
|
|
|
} else if (y < 0) {
|
|
|
|
if (x === 0) {
|
|
|
|
theta = 3 * Math.PI / 2; // 270°
|
|
|
|
} else {
|
|
|
|
theta = 2 * Math.PI - Math.acos(x / p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return { p, theta };
|
|
|
|
}
|
|
|
|
function Polar2Rect(p, theta) {
|
|
|
|
const x = p * Math.cos(theta);
|
|
|
|
const y = p * Math.sin(theta);
|
|
|
|
return { x, y };
|
|
|
|
}
|
|
|
|
module.exports = Tool;
|