@antv/g6
Version:
graph visualization frame work
258 lines (212 loc) • 6.39 kB
JavaScript
var Layout = require('../../layout');
var Util = require('../../util');
var LayoutController =
/*#__PURE__*/
function () {
function LayoutController(graph) {
this.graph = graph;
this.layoutCfg = graph.get('layout');
this.layoutType = this.layoutCfg ? this.layoutCfg.type : undefined;
this._initLayout();
}
var _proto = LayoutController.prototype;
_proto._initLayout = function _initLayout() {// no data before rendering
};
_proto.layout = function layout() {
var self = this;
var layoutType = self.layoutType;
var graph = self.graph; // const data = graph.get('data');
self.data = self.setDataFromGraph();
var nodes = self.data.nodes;
if (!nodes) {
return;
}
var width = graph.get('width');
var height = graph.get('height');
var layoutCfg = {};
Util.mix(layoutCfg, {
width: width,
height: height,
center: [width / 2, height / 2]
}, self.layoutCfg);
if (layoutType === undefined) {
if (nodes[0] && nodes[0].x === undefined) {
// 创建随机布局
layoutType = 'random';
} else {
// 若未指定布局且数据中有位置信息,则不进行布局,直接按照原数据坐标绘制。
return;
}
} else {
if (nodes[0] && nodes[0].x === undefined) {
// 初始化位置
self.initPositions(layoutCfg.center, nodes);
}
}
var layoutMethod = self.layoutMethod;
if (layoutMethod) {
layoutMethod.destroy();
}
if (layoutType === 'force') {
var onTick = layoutCfg.onTick;
var tick = function tick() {
onTick && onTick();
graph.refreshPositions();
};
layoutCfg.tick = tick;
var onLayoutEnd = layoutCfg.onLayoutEnd;
layoutCfg.onLayoutEnd = function () {
onLayoutEnd && onLayoutEnd();
graph.emit('afterlayout');
};
}
self.layoutCfg = layoutCfg;
try {
layoutMethod = new Layout[layoutType](layoutCfg);
} catch (e) {
console.warn('The layout method: ' + layoutCfg + ' does not exist! Please specify it first.');
return;
}
layoutMethod.init(self.data);
graph.emit('beforelayout');
layoutMethod.execute();
if (layoutType !== 'force') {
graph.emit('afterlayout');
}
self.layoutMethod = layoutMethod;
} // 绘制
;
_proto.refreshLayout = function refreshLayout() {
var self = this;
var graph = self.graph;
if (graph.get('animate')) {
graph.positionsAnimate();
} else {
graph.refreshPositions();
}
} // 更新布局参数
;
_proto.updateLayoutCfg = function updateLayoutCfg(cfg) {
var self = this;
var graph = self.graph;
self.layoutType = cfg.type;
var layoutMethod = self.layoutMethod;
self.data = self.setDataFromGraph();
layoutMethod.init(self.data);
layoutMethod.updateCfg(cfg);
graph.emit('beforelayout');
layoutMethod.execute();
if (self.layoutType !== 'force') {
graph.emit('afterlayout');
}
self.refreshLayout();
} // 更换布局
;
_proto.changeLayout = function changeLayout(layoutType) {
var self = this;
self.layoutType = layoutType;
self.layoutCfg = self.graph.get('layout') || {};
self.layoutCfg.type = layoutType;
var layoutMethod = self.layoutMethod;
layoutMethod && layoutMethod.destroy();
self.layout();
self.refreshLayout();
} // 更换数据
;
_proto.changeData = function changeData() {
var self = this;
var layoutMethod = self.layoutMethod;
layoutMethod && layoutMethod.destroy();
self.layout();
} // 从 this.graph 获取数据
;
_proto.setDataFromGraph = function setDataFromGraph() {
var self = this;
var nodes = [];
var edges = [];
var nodeItems = self.graph.getNodes();
var edgeItems = self.graph.getEdges();
nodeItems.forEach(function (nodeItem) {
var model = nodeItem.getModel();
nodes.push(model);
});
edgeItems.forEach(function (edgeItem) {
var model = edgeItem.getModel();
edges.push(model);
});
var data = {
nodes: nodes,
edges: edges
};
if (self.layoutType === 'fruchtermanGroup') {
// const groupsData = self.graph.get('groups');
// const customGroup = self.graph.get('customGroup');
// const groupController = self.graph.get('customGroupControll');
// data.groupsData = groupsData;
// data.customGroup = customGroup;
// data.groupController = groupController;
data.graph = self.graph;
}
return data;
} // 重新布局
;
_proto.relayout = function relayout() {
var self = this;
var graph = self.graph;
var layoutMethod = self.layoutMethod;
if (self.layoutType === 'force') {
layoutMethod.ticking = false;
layoutMethod.forceSimulation.stop();
}
graph.emit('beforelayout');
layoutMethod.execute();
if (self.layoutType !== 'force') {
graph.emit('afterlayout');
}
self.refreshLayout();
} // 控制布局动画
;
_proto.layoutAnimate = function layoutAnimate() {} // 根据 type 创建 Layout 实例
;
_proto._getLayout = function _getLayout() {} // 将当前节点的平均中心移动到原点
;
_proto.moveToZero = function moveToZero() {
var self = this;
var graph = self.graph;
var data = graph.get('data');
var nodes = data.nodes;
if (nodes[0].x === undefined || nodes[0].x === null || isNaN(nodes[0].x)) {
return;
}
var meanCenter = [0, 0];
nodes.forEach(function (node) {
meanCenter[0] += node.x;
meanCenter[1] += node.y;
});
meanCenter[0] /= nodes.length;
meanCenter[1] /= nodes.length;
nodes.forEach(function (node) {
node.x -= meanCenter[0];
node.y -= meanCenter[1];
});
} // 初始化节点到 center
;
_proto.initPositions = function initPositions(center, nodes) {
if (!nodes) {
return;
}
nodes.forEach(function (node) {
node.x = center[0] + Math.random();
node.y = center[1] + Math.random();
});
};
_proto.destroy = function destroy() {
var self = this;
self.graph = null;
var layoutMethod = self.layoutMethod;
layoutMethod && layoutMethod.destroy();
self.destroyed = true;
};
return LayoutController;
}();
module.exports = LayoutController;