g6/demos/tree-node-issue.html
2019-10-10 20:01:23 +08:00

968 lines
27 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="mountNode"></div>
<script src="../build/g6.js"></script>
<script>
const data = {
name: 'Nat网关',
children: [
{
name: '产品功能',
children: [
{
name: '高可用能力',
children: [
{
name: '同AZ主备容灾',
children: [
{
name: '是否支持',
children: [
{
name: 'bool',
},
],
nodeIndex: 'Nat4',
},
],
nodeIndex: 'Nat3',
},
{
name: '跨AZ容灾',
children: [
{
name: '是否支持',
children: [
{
name: 'bool',
},
],
nodeIndex: 'Nat7',
},
],
nodeIndex: 'Nat6',
},
],
nodeIndex: 'Nat2',
},
{
name: '监控能力',
children: [
{
name: '流量监控',
children: [
{
name: '从VPC流出的字节数量单位 字节)',
children: [],
nodeIndex: 'Nat11',
},
{
name: '从Internet流入VPC的字节数量单位 字节)',
children: [],
nodeIndex: 'Nat12',
},
{
name: '从VPC流出的数据包的数量单位 个)',
children: [],
nodeIndex: 'Nat13',
},
{
name: '从Internet流入VPC的数据包的数量单位 个)',
children: [],
nodeIndex: 'Nat14',
},
{
name: '丢弃流出的字节数量(单位 字节)',
children: [],
nodeIndex: 'Nat15',
},
{
name: '丢弃流入的字节数量(单位 字节)',
children: [],
nodeIndex: 'Nat16',
},
{
name: '丢弃流出的数据包数量(单位 个)',
children: [],
nodeIndex: 'Nat17',
},
{
name: '丢弃流入的数据包数量(单位 个)',
children: [],
nodeIndex: 'Nat18',
},
],
nodeIndex: 'Nat10',
},
{
name: '连接监控',
children: [
{
name: '最大连接丢弃监控(单位 个/s)',
children: [],
nodeIndex: 'Nat20',
},
{
name: '最大连接监控(单位个)',
children: [],
nodeIndex: 'Nat21',
},
{
name: '新建连接丢弃监控(单位 个/s)',
children: [],
nodeIndex: 'Nat22',
},
{
name: '新建连接监控(单位 个/s)',
children: [],
nodeIndex: 'Nat23',
},
],
nodeIndex: 'Nat19',
},
{
name: '阈值报警管理',
children: [
{
name: '设置关联资源',
children: [
{
name: '产品',
},
{
name: '资源范围',
},
{
name: '地域',
},
{
name: '实例',
},
],
nodeIndex: 'Nat25',
},
{
name: '设置报警规则',
children: [
{
name: '规则名称',
},
{
name: '规则描述',
},
{
name: '生效时间',
},
{
name: '通道沉默周期',
},
{
name: '规则数量',
},
],
nodeIndex: 'Nat34',
},
{
name: '通知方式',
children: [
{
name: '联系人通知组',
},
{
name: '告警级别',
},
{
name: '弹性伸缩设置',
},
{
name: '通知邮件',
},
],
nodeIndex: 'Nat45',
},
],
nodeIndex: 'Nat24',
},
{
name: '监控日志查询',
children: [
{
name: '查看实例网关、连接的监控信息',
children: [],
nodeIndex: 'Nat54',
},
{
name: '查看网关日志',
children: [],
nodeIndex: 'Nat55',
},
{
name: '后台运维变更',
children: [],
nodeIndex: 'Nat56',
},
],
nodeIndex: 'Nat53',
},
{
name: '数据分析及处理',
children: [
{
name: '连接数 Top ECS分析',
children: [],
nodeIndex: 'Nat58',
},
{
name: '流量数 Top ECS分析',
children: [],
nodeIndex: 'Nat59',
},
{
name: 'Top ECS 流控限速配置',
children: [],
nodeIndex: 'Nat60',
},
],
nodeIndex: 'Nat57',
},
{
name: '操作日志',
children: [
{
name: '网关操作日志',
children: [],
nodeIndex: 'Nat62',
},
{
name: 'SNAT规则操作日志',
children: [],
nodeIndex: 'Nat63',
},
{
name: 'DNAT规则操作日志',
children: [],
nodeIndex: 'Nat64',
},
],
nodeIndex: 'Nat61',
},
],
nodeIndex: 'Nat9',
},
{
name: '生命周期管理能力',
children: [
{
name: '创建实例',
children: [
{
name: '地域',
children: [
{
name: '枚举',
},
],
nodeIndex: 'Nat67',
},
{
name: '规格',
children: [
{
name: '枚举',
},
],
nodeIndex: 'Nat69',
},
{
name: '关联的VPC',
children: [
{
name: 'string',
},
],
nodeIndex: 'Nat71',
},
{
name: '关联的子网vswitch',
children: [
{
name: 'string',
},
],
nodeIndex: 'Nat73',
},
],
nodeIndex: 'Nat66',
},
{
name: '配置实例名称',
children: [
{
name: '名称',
children: [
{
name: 'String',
},
],
nodeIndex: 'Nat76',
},
],
nodeIndex: 'Nat75',
},
{
name: '配置实例描述',
children: [
{
name: '描述',
children: [
{
name: 'String',
},
],
nodeIndex: 'Nat79',
},
],
nodeIndex: 'Nat78',
},
{
name: '绑定公网IP',
children: [
{
name: 'EIP',
children: [
{
name: 'string',
},
],
nodeIndex: 'Nat82',
},
],
nodeIndex: 'Nat81',
},
{
name: '绑定共享流量包',
children: [
{
name: '属性',
children: [
{
name: 'string',
},
],
nodeIndex: 'Nat85',
},
],
nodeIndex: 'Nat84',
},
{
name: '删除实例',
children: [],
nodeIndex: 'Nat87',
},
{
name: '升降配',
children: [
{
name: '规格',
children: [
{
name: '枚举',
},
],
nodeIndex: 'Nat89',
},
],
nodeIndex: 'Nat88',
},
{
name: '快速搜索实例',
children: [],
nodeIndex: 'Nat91',
},
{
name: '查看全量配置信息',
children: [],
nodeIndex: 'Nat92',
},
{
name: '查看实例账单信息',
children: [],
nodeIndex: 'Nat93',
},
{
name: '导出对账单按CU按量计费',
children: [],
nodeIndex: 'Nat94',
},
{
name: '老实例迁移到新实例规格',
children: [],
nodeIndex: 'Nat95',
},
],
nodeIndex: 'Nat65',
},
{
name: 'Feature',
children: [
{
name: 'SNAT功能',
children: [
{
name: '配置转发条目',
children: [
{
name: '公网IP地址',
},
{
name: '私网IP地址',
},
{
name: '公网端口',
},
{
name: '私网端口',
},
{
name: '协议类型',
},
{
name: '条目名称',
},
{
name: '配置数量',
},
],
nodeIndex: 'Nat98',
},
{
name: '连接能力',
children: [
{
name: '最大连接数',
},
],
nodeIndex: 'Nat113',
},
{
name: '新建连接能力',
children: [
{
name: '每秒新建连接数',
},
],
nodeIndex: 'Nat116',
},
{
name: '导出转发条目',
children: [
{
name: '导出类型',
},
],
nodeIndex: 'Nat119',
},
],
nodeIndex: 'Nat97',
},
{
name: 'DNAT功能',
children: [
{
name: '配置转发条目',
children: [
{
name: '配置类型',
},
{
name: '配置数量',
},
{
name: '交换机名称',
},
{
name: '公网IP地址',
},
{
name: '条目名称',
},
{
name: 'ECS名称',
},
],
nodeIndex: 'Nat123',
},
{
name: '导出转发条目',
children: [
{
name: '导出类型',
},
],
nodeIndex: 'Nat134',
},
],
nodeIndex: 'Nat122',
},
{
name: '安全访问策略',
children: [
{
name: '配置acl',
children: [],
nodeIndex: 'Nat138',
},
],
nodeIndex: 'Nat137',
},
{
name: '流日志功能',
children: [
{
name: '配置flowlog',
children: [],
nodeIndex: 'Nat140',
},
],
nodeIndex: 'Nat139',
},
{
name: '单VPC多实例',
children: [
{
name: '是否支持',
children: [],
nodeIndex: 'Nat142',
},
],
nodeIndex: 'Nat141',
},
{
name: '单EIP同时支持snat和dnat',
children: [
{
name: '是否支持',
children: [],
nodeIndex: 'Nat144',
},
],
nodeIndex: 'Nat143',
},
{
name: '跨域流量通过natgw出公网包括线下IDC',
children: [
{
name: '是否支持',
children: [],
nodeIndex: 'Nat146',
},
],
nodeIndex: 'Nat145',
},
{
name: '跨VPC迁移实例',
children: [
{
name: '是否支持',
children: [],
nodeIndex: 'Nat148',
},
],
nodeIndex: 'Nat147',
},
],
nodeIndex: 'Nat96',
},
],
nodeIndex: 'Nat1',
},
{
name: '产品限制',
children: [
{
name: '性能',
children: [
{
name: 'CPS新建速率',
children: [],
nodeIndex: 'Nat151',
},
{
name: '最大带宽处理能力',
children: [
{
name: '默认5G可申请弹性扩容',
children: [
{
name: '支持',
},
],
nodeIndex: 'Nat153',
},
],
nodeIndex: 'Nat152',
},
{
name: 'concurrent并发能力-支持的最大连接数',
children: [
{
name: '无限制',
children: [
{
name: '支持',
},
],
nodeIndex: 'Nat156',
},
],
nodeIndex: 'Nat155',
},
],
nodeIndex: 'Nat150',
},
{
name: '配额',
children: [],
nodeIndex: 'Nat158',
},
],
nodeIndex: 'Nat149',
},
{
name: '计费',
children: [
{
name: '后付费',
children: [
{
name: '支持按CU计费',
children: [
{
name: '是否支持',
children: [
{
name: 'bool',
},
],
nodeIndex: 'Nat162',
},
],
nodeIndex: 'Nat161',
},
{
name: '实例闲置费',
children: [],
nodeIndex: 'Nat164',
},
],
nodeIndex: 'Nat160',
},
{
name: '预付费',
children: [
{
name: '支持CU资源包+后付费',
children: [],
nodeIndex: 'Nat166',
},
],
nodeIndex: 'Nat165',
},
],
nodeIndex: 'Nat159',
},
{
name: 'SLA',
children: [],
nodeIndex: 'Nat167',
},
{
name: '安全合规能力',
children: [
{
name: 'SPLC',
children: [],
nodeIndex: 'Nat169',
},
{
name: '法务',
children: [],
nodeIndex: 'Nat170',
},
],
nodeIndex: 'Nat168',
},
{
name: '售后运维管理',
children: [
{
name: '一键诊断',
children: [
{
name: '一键诊断后台运维变更',
children: [],
nodeIndex: 'Nat173',
},
{
name: '一键诊断配置检查',
children: [],
nodeIndex: 'Nat174',
},
{
name: '一键诊断异常日志检查',
children: [],
nodeIndex: 'Nat175',
},
{
name: '一键诊断操作日志检查',
children: [],
nodeIndex: 'Nat176',
},
{
name: '一键诊断运维变更',
children: [],
nodeIndex: 'Nat177',
},
],
nodeIndex: 'Nat172',
},
{
name: '库存管理能力',
children: [],
nodeIndex: 'Nat178',
},
],
nodeIndex: 'Nat171',
},
],
};
function formatData(data) {
let index = 0
const recursiveTraverse = (node, level = 0) => {
const targetNode = {
id: (index++) + "",
name: node.name
};
if (node.children) {
targetNode.children = [];
node.children.forEach(item => {
targetNode.children.push(recursiveTraverse(item, level + 1));
});
}
return targetNode;
};
const result = recursiveTraverse(data);
return result;
}
const COLLAPSE_ICON = function COLLAPSE_ICON(x, y, r) {
return [
['M', x, y],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 3, y],
['L', x + 2 * r - 3, y],
];
};
const EXPAND_ICON = function EXPAND_ICON(x, y, r) {
return [
['M', x, y],
['a', r, r, 0, 1, 0, r * 2, 0],
['a', r, r, 0, 1, 0, -r * 2, 0],
['M', x + 3, y],
['L', x + 2 * r - 3, y],
['M', x + r, y - r + 3],
['L', x + r, y + r - 3],
];
};
let CANVAS_WIDTH = 500;
let CANVAS_HEIGHT = 500;
let graph;
const _this = window;
G6.registerNode(
'tree-node',
{
drawShape: function drawShape(cfg, group) {
const rect = group.addShape('rect', {
attrs: {
fill: '#fff',
stroke: '#fff',
},
});
const content = (cfg.name || '').replace(/(.{19})/g, '$1\n');
const text = group.addShape('text', {
attrs: {
text: content,
x: 0,
y: 0,
textAlign: 'left',
textBaseline: 'middle',
fill: '#0A1F39',
},
});
const bbox = text.getBBox();
const hasChildren = cfg.children && cfg.children.length > 0;
if (hasChildren) {
group.addShape('marker', {
attrs: {
x: bbox.maxX + 16 + 2,
y: bbox.minX + bbox.height / 2 - 6,
r: 6,
symbol: COLLAPSE_ICON,
stroke: '#C4D9E9',
lineWidth: 1,
},
className: 'collapse-icon',
});
}
const hasBorder = cfg.depth <= 2;
if (hasBorder) {
// 前面的产品名/一级类目/二级类目
group.addShape('rect', {
attrs: {
fill: 'rgba(0,0,0,0)',
stroke: '#0093ee',
x: bbox.minX - 14,
y: bbox.minY - 6,
width: bbox.width + 30,
height: bbox.height + 12,
radius: [4],
},
});
rect.attr({
x: bbox.minX - 16,
y: bbox.minY - 6,
width: bbox.width + (hasChildren ? 49 : 32),
// width: bbox.width + 34,
height: bbox.height + 12,
});
} else {
// 后面两级的节点
text.attr({ y: -(bbox.height / 2 + 3) });
const lineX = bbox.minX - 18;
const lineY = bbox.minY + bbox.height / 2;
group.addShape('path', {
attrs: {
path: [['M', lineX, lineY], ['L', lineX + bbox.width + 32, lineY]],
stroke: '#C4D9E9',
lineWidth: 2,
},
});
rect.attr({
fill: 'rgba(0,0,0,0)',
stroke: 'rgba(0,0,0,0)',
x: bbox.minX - 16,
y: bbox.minY - 6,
width: bbox.width + (hasChildren ? 49 : 32),
// width: bbox.width + 34,
height: bbox.height + 12,
});
}
return rect;
},
},
'node'
);
const defaultOptions = {
minZoom: 0.3,
maxZoom: 1.5,
modes: {
default: [
{
type: 'collapse-expand',
onChange: function onChange(item, collapsed) {
// const data = item.getModel();
// const { id } = data;
// graph.focusItem(item);
// graph.clear(); // 只能使用clear来hack否则展开会使得数据重复
// const group = item.get('group');
// const icon = group.findByClassName('collapse-icon');
// if (collapsed) {
// icon.attr('symbol', EXPAND_ICON);
// } else {
// icon.attr('symbol', COLLAPSE_ICON);
// }
data.collapsed = collapsed;
// return null;
var icon = item.get("group").findByClassName("collapse-icon");
if (collapsed) {
icon.attr("symbol", EXPAND_ICON);
} else {
icon.attr("symbol", COLLAPSE_ICON);
}
},
},
{
type: 'drag-canvas',
shouldUpdate: function shouldUpdate() {
return false;
},
shouldEnd: function shouldUpdate() {
return false;
},
},
],
},
defaultNode: {
shape: 'tree-node',
anchorPoints: [[0, 0.5], [1, 0.5]],
},
defaultEdge: {
shape: 'cubic-horizontal',
style: {
stroke: '#C4D9E9',
lineWidth: 2,
}
},
layout: {
type: 'compactBox', // dendrogram compactBox
direction: 'LR',
getId: function getId(d) {
debugger
return d.id;
},
getHeight: function getHeight() {
return 26;
},
getWidth: function getWidth() {
return 26;
},
getVGap: function getVGap() {
return 10;
},
getHGap: function getHGap() {
return 110;
},
},
fixedRoot: true,
};
CANVAS_HEIGHT = 800;
CANVAS_WIDTH = 1200;
const params = Object.assign(
{
container: 'mountNode',
width: CANVAS_WIDTH,
height: CANVAS_HEIGHT,
// animate: false, // 开启这个[关闭动画]选项,自定义节点就会错位
},
defaultOptions
);
graph = new G6.TreeGraph(params);
graph.data(formatData(data));
graph.render();
graph.fitView(20);
</script>