butterfly-dag
Version:
一个基于数据驱动的节点式编排组件库,让你有方便快捷定制可视化流程图表
76 lines (63 loc) • 2.18 kB
JavaScript
const d3 = require('d3-force');
// 离散布局
function forceLayout(param) {
let opts = param.opts;
let data = _.cloneDeep(param.data);
// 处理groups的布局,把group当成一个节点
let nodes = data.nodes.filter((item) => {
return !item.group;
});
let groupNodes = data.nodes.filter((item) => {
return item.group;
});
nodes = nodes.concat(data.groups);
// 在group内先random布局一下
groupNodes.forEach((item) => {
let group = _.find(data.groups, (_group) => {
return _group.id === item.group;
});
item.x = Math.random() * (group.width || 150);
item.y = Math.random() * (group.height || 120);
});
let edges = data.edges.map((_edge) => {
let souceNode = _.find(groupNodes, (_node) => {
return _node.source === _edge.id;
});
if (souceNode) {
_edge.source = souceNode.group;
}
let targetNode = _.find(groupNodes, (_node) => {
return _node.target === _edge.id;
});
if (targetNode) {
_edge.target = souceNode.group;
}
return _edge;
});
let simulation = d3.forceSimulation(nodes)
.force('charge', (() => {
if (opts.chargeStrength) {
return d3.forceManyBody().strength(opts.chargeStrength);
} else {
return d3.forceManyBody();
}
})())
.force('center', d3.forceCenter(opts.width / 2, opts.height / 2))
.force('link', d3.forceLink(edges).id((node) => {
return node[_.get(opts.link, 'id', 'id')];
}).distance(opts.link.distance).strength(opts.link.strength))
.stop();
for (var i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())); i < n; ++i) {
simulation.tick();
}
param.data.nodes.forEach((node, index) => {
node.top = data.nodes[index].y;
node.left = data.nodes[index].x;
});
param.data.groups.forEach((group, index) => {
group.top = data.groups[index].y;
group.left = data.groups[index].x;
});
// 后续需要考虑group的布局
}
module.exports = forceLayout