Skip to content

1. 布局

布局功能允许用户把Node和Link按照一定形式调整相对坐标

1.1. 网格布局(GridLayout)

网格布局是较为简单的一种布局,把Node对象按照行、列的方式摆放

js
import {Shape, Node} from '@jtopo/core';

// ---- 生成节点
const nodes = [];
const rows = 6;
const cols = 6;
for (let i = 0; i < rows * cols; i++) {
    const node = new EllipseNode('' + i);
    node.resize(30, 30);
    node.addClass('.ball');
    nodes.push(node);
    layer.addChild(node);
}

// 生成一个网格‘形状'
const gridPoints = Shape.grid(rows, cols);

// 根据形状生成’布局‘对象
const layout = layoutSystem.pointsLayout(nodes, gridPoints);
// 设置尺寸
layout.resize(300, 300);

// 执行布局,带动画参数
stage.animationSystem.anime({
    // 角度, 缩放, 平移
    from: [0, 0.1, 600, -600],
    to: [2 * Math.PI, 1, 0, 0],

    update: (arr) => {
        // 变换
        layout.scale(arr[1], arr[1])
        layout.rotate(arr[0]);
        layout.translate(arr[2], arr[3]);

        // 执行布局
        layout.doLayout();
    },
    duration: 1000,
    effect: 'easeOutCubic'
}).play();

效果参考:

1.2. 树形布局(TreeLayout)

1. 将Node和Link对象集合(数组)转成 *图对象*
2. 将 *图对象* 转成布局实例
3. 布局实例可以变换(平移、缩放、旋转)
js

// 生成图数据;
let graphArr = stage.graphSystem.objectsToGraphs(layer.children);

// 取第一个是树形的图对象, 这里假设给的数据肯定存在一颗'树'
let treeGraph = graphArr.filter(g => g.isTree())[0];

// 将图对象转成 '树形布局' 实例
let layout = stage.layoutSystem.treeLayout(treeGraph);

// 设置整个布局的中心
layout.translate(0, 0);

// 可以对布局缩放
layout.scale(1, 1);

// 可以对布局旋转
layout.rotate(Math.PI);

// 布局
layout.doLayout();

效果:

自动边界布局

容器的边界和尺寸会随着多个子节点而自动变化

js
import {
    Stage,
    Layer,
    Node,
    NodeHelper,
    randomColor,
} from '@jtopo/core';


const stage = new Stage('divId');
var layer = new Layer(stage);

// 容器的边界和尺寸,会随着子节点自动变化
var group = new Node('Group', 0, 0, 100, 100);
group.css({
    'border': '1px dashed gray',
    'shadowColor': '#E0E0E0',
    'shadowBlur': 7,
    'shadowOffsetX': 2,
    'shadowOffsetY': 2,
    'font': 'bold 10px arial',
    'background': "white url('./assets/img/grid.png') repeat",
});
layer.addChild(group);

for (var i = 0; i < 5; i++) {
    var node = new Node();
    node.setXY(stage.rand(-200, 200), stage.rand(-200, 200));
    node.resize(32, 32);
    node.setStyles('background', randomColor());
    group.addChild(node);
}

NodeHelper.sizeFitToChildren(group);

stage.inputSystem.on('pointermove', function () {
    // 拖拽中
    if (stage.inputSystem.isDraging) {
        NodeHelper.sizeFitToChildren(group);
    }
});

stage.show();

效果参考:

1.5. 力导向布局(ForceDirectLayout)

模拟斥力物理性质(质量,斥力和张力), 各个节点在力的相互作用下不断运动,直至最终达到力的平衡,完成自动布局.

js

var layout = new ForceDirectLayout(rootNode, stage.width, stage.height);

// 需要多次调用applyForce迭代
layout.applyForce();

效果: