Skip to content

1. 布局

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

1.1. 网格布局(GridLayout)

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

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

const nodes = [];

// 生成节点
let rows = 6;
let cols = 6;
for (var i = 0; i < rows * cols; i++) {
    var node = new Node('' + i);
    node.resizeTo(32, 32);
    node.textOffsetY = 2;
    node.style.fillStyle = randomColor();
    nodes.push(node);
    layer.addChild(node);
}

// 生成一个网格‘形状' (这里生成的是6x6网格的形状,可以是其它形状:三角形、五角型、Cos函数曲线也是可以的...)
// 形状对象参考:‘图形’ 章节
let shape = Shape.innerGrid(rows, cols);

// 根据形状生成’Shape布局‘对象
let layout = stage.layoutSystem.shapeLayout(nodes, shape);

// 设置布局的尺寸
layout.resizeTo(500, 250);

// 对布局进行旋转操作
layout.rotate(Math.PI / 4);

// 执行布局,可以带动画参数
layout.doLayout({
    effect: 'easeInQuart',
    duration: 3000,
});

效果参考:

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.addChild(layer);

// 容器的边界和尺寸,会随着子节点自动变化
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.resizeTo(32, 32);
    node.css('background', randomColor());
    group.addChild(node);
}

NodeHelper.sizeFitToChildren(group);

stage.inputSystem.on('mousemove', 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();

效果: