G6
G2
G6
F2
L7
墨者学院
关于 G6
图表示例
API 文档
使用教程
返回旧版
树图
紧凑树
系统树
脑图树
辐射树
树图-边上显示label
文件系统
自定义树图
大数据量的树图
一般图
ER 图
流程图
流程图自定义元素
Force-directed 力导图
Fruchterman 布局参数变化
Dagre 参数变化
Circular 环图参数变化
Radial 布局参数变化
布局数据变化
Radial 交互扩展节点
布局的时机监听
自定义布局 - 二分图
子图布局
其他表达形式
Sankey 桑基图
Arc Diagram 弧线图
Cicular Arc Diagram 环形弧线图
Bubbles 力导气泡
树和气泡
元素
内置边
内置节点
节点-卡片
节点-环形柱状图
节点-面积图
节点-折线图
节点-列表
节点-饼图
节点-标注图
节点-多标签
节点-堆积柱状图
边-贝塞尔曲线
边-内置弧线
边-内置折线
边-自定义折线方法1
边-自定义折线方法2
边-多标签
箭头-内置
箭头-自定义边带有自定义箭头
文本-省略
文本-换行
交互
鼠标事件更新标签
高亮节点
切换节点图片
动态加载数据
动态加载多条数据
Circle节点分组
Rect节点分组
点击扩展节点
动画
状态切换
节点动画
默认动画
自定义动画
辅助工具
Tooltip 节点和边的提示框
Minimap 缩略图
Grid 网格
Edge Bundling 边绑定
Context Menu 右键菜单
响应节点区域事件
点击节点移动到中心
复杂案例
美国航线边绑定
北京地铁
聚类的折叠/扩展交互
自定义资金流转图
聚类的折叠/扩展交互
源码
复制成功
复制失败
全屏
复制
运行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>聚类的折叠/扩展交互</title> <style>::-webkit-scrollbar{display:none;}html,body{overflow:hidden;margin:0;}</style> </head> <body> <div id="mountNode"></div> <script>/*Fixing iframe window.innerHeight 0 issue in Safari*/document.body.clientHeight;</script> <script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-3.1.1/build/g6.js"></script> <script src="https://gw.alipayobjects.com/os/antv/assets/lib/jquery-3.2.1.min.js"></script> <style> .g6-tooltip { border: 1px solid #e2e2e2; border-radius: 4px; font-size: 12px; color: #545454; background-color: rgba(255, 255, 255, 0.9); padding: 10px 8px; box-shadow: rgb(174, 174, 174) 0px 0px 10px; } </style> <script> /** * 该示例演示 Fruchterman 布局算法的聚类效果,以及点击交互进行聚类的聚合和扩散效果 * by 十吾 */ var descriptionDiv = document.createElement("div"); descriptionDiv.innerHTML = '读取数据 & 布局中,请稍候......'; var graphDiv = document.getElementById("mountNode"); document.body.insertBefore(descriptionDiv, graphDiv); var colors = ['#f5222d', '#faad14', '#a0d911', '#13c2c2', '#1890ff', '#b37feb', '#eb2f96']; var beginColor = '#5b8c00'; // green var endColor = '#ff4d4f'; // red var testData = { nodes: [{ id: '0', cluster: 1, exportValue: 10000, x: 100, y: 200 // label: 0 }, { id: '1', cluster: 1, exportValue: 10000, x: 200, y: 200 // label: 1 }], edges: [{ source: '0', target: '1' }, { source: '1', target: '0' }] }; $.getJSON("https://gw.alipayobjects.com/os/basement_prod/7bacd7d1-4119-4ac1-8be3-4c4b9bcbc25f.json", function(data) { var nodes = data.nodes; var edges = data.edges; var nodeMap = new Map(); var clusterMap = new Map(); var cidx = 0; nodes.forEach(function(n) { nodeMap.set(n.id, n); var region = n.region.split(" "); if (n.region === 'East Asia') region = n.region; else region = region[region.length - 1]; if (clusterMap.get(region) === undefined) { clusterMap.set(region, cidx); cidx++; } var clusterId = clusterMap.get(region); var color = colors[clusterId % colors.length]; n.style = { color: color, fill: color, stroke: '#666', lineWidth: 0.6 }; n.cluster = clusterId; n.importValue = 0; n.exportValue = 0; }); // map the value of edges.forEach(function(e) { if (e.value === '') e.value = 0; var v = parseFloat(e.value); nodeMap.get(e.source).exportValue += v; nodeMap.get(e.target).importValue += v; }); mapValueToProp(nodes, 'exportValue', 'size', [2, 12]); var graph = new G6.Graph({ container: 'mountNode', width: window.innerWidth, height: window.innerHeight, layout: { type: 'fruchterman', maxIteration: 8000, gravity: 10, clustering: true, clusterGravity: 30 }, fitView: true, linkCenter: true, defaultNode: { shape: 'circle', size: 5 }, defaultEdge: { shape: 'quadratic' }, modes: { default: ['drag-node', 'drag-canvas', { type: 'tooltip', formatText: function formatText(model) { var name = ''; var countries = ''; if (model.name) name = model.name + '<br/>'; if (model.countries) countries = '<br/>Number of Countries: ' + model.countries; var text = name + 'Export Value: ' + model.exportValue + "(1000USD)" + '<br/>Region: ' + model.region + '<br/>Cluster: ' + model.cluster + countries; return text; }, shouldUpdate: function shouldUpdate(e) { return true; } }] } }); graph.on('afterlayout', function() { descriptionDiv.innerHTML = '布局完成!'; }); graph.data(data); graph.render(); var edgeItems = graph.getEdges(); edgeItems.forEach(function(e) { var lineWidth = 0.4; var strokeOpacity = 0.2; var stroke = 'l(0) 0:' + beginColor + ' 1:' + endColor; var sourceModel = e.getSource().getModel(); var targetModel = e.getTarget().getModel(); if (sourceModel.x > targetModel.x) { stroke = 'l(0) 0:' + endColor + ' 1:' + beginColor; } e.update({ style: { lineWidth: lineWidth, strokeOpacity: strokeOpacity, stroke: stroke } }); }); graph.paint(); graph.on('node:click', function(e) { var targetItem = e.item; var model = targetItem.getModel(); var graphEdges = graph.getEdges(); var graphNodes = graph.getNodes(); // click on the cluster node if (model.id.substr(0, 7) === 'cluster') { graphNodes.forEach(function(gn) { var gnModel = gn.getModel(); // show the common nodes if (gnModel.cluster === model.cluster && gnModel.id.substr(0, 7) != 'cluster') { gn.show(); } // remove the cluster nodes if (gnModel.id === model.id) graph.removeItem(gn); }); graphEdges.forEach(function(ge) { var sourceModel = ge.get('sourceNode').getModel(); var targetModel = ge.get('targetNode').getModel(); // show the common edges if (sourceModel.cluster === model.cluster && sourceModel.id.substr(0, 7) !== 'cluster' || targetModel.cluster === model.cluster && targetModel.id.substr(0, 7) !== 'cluster') { ge.show(); // add the edges to other cluster nodes if (!ge.get('sourceNode').get('visible') && sourceModel.cluster !== model.cluster) { var c1 = beginColor, c2 = endColor; if (model.x > targetModel.x) { c1 = endColor; c2 = beginColor; } graph.addItem('edge', { source: 'cluster' + sourceModel.cluster, target: targetModel.id, id: 'cluster-edge-' + ge.id, style: { stroke: 'l(0) 0:' + c1 + ' 1:' + c2, lineWidth: 0.4, strokeOpacity: 0.2 } }); } else if (ge.get('targetNode').get('visible') && targetModel.cluster !== model.cluster) { var _c = beginColor, _c2 = endColor; if (sourceModel.x > model.x) { _c = endColor; _c2 = beginColor; } graph.addItem('edge', { source: sourceModel.id, target: 'cluster' + targetModel.id, id: 'cluster-edge-' + ge.id, style: { stroke: 'l(0) 0:' + _c + ' 1:' + _c2, lineWidth: 0.4, strokeOpacity: 0.2 } }); } // hide the edges to the common nodes in other clusters if (!ge.get('sourceNode').get('visible') || !ge.get('targetNode').get('visible')) { ge.hide(); } } // remove the cluster edges if (sourceModel.id === model.id || targetModel.id === model.id) { graph.removeItem(ge); } }); } else { // click on the common node, cllapse them // calculate the cluster center var center = { x: 0, y: 0, count: 0, exportValue: 0 }; nodes.forEach(function(n) { if (n.cluster === model.cluster) { center.x += n.x; center.y += n.y; center.count++; center.exportValue += n.exportValue; } }); center.x /= center.count; center.y /= center.count; // add cluster node on the center var size = center.count * 1; var clusterNodeId = 'cluster' + model.cluster; var color = colors[model.cluster % colors.length]; var regionStrs = model.region.split(' '); var region = regionStrs[regionStrs.length - 1]; if (model.region === 'East Asia') region = model.region; var labelPosition = 'center'; if (region.length > size) labelPosition = 'left'; var clusterNode = graph.addItem('node', { x: center.x, y: center.y, id: clusterNodeId, cluster: model.cluster, region: region, countries: center.count, exportValue: center.exportValue, style: { color: color, fill: color, stroke: '#666', lineWidth: 0.6 }, size: size, label: region, labelCfg: { style: { fontSize: 8.5 }, position: labelPosition } }); // add edges about the cluster graphEdges.forEach(function(ge) { var sourceModel = ge.get('sourceNode').getModel(); var targetModel = ge.get('targetNode').getModel(); if (!ge.get('sourceNode').get('visible') || !ge.get('targetNode').get('visible')) return; if (sourceModel.cluster === model.cluster && targetModel.cluster !== model.cluster) { var c1 = beginColor, c2 = endColor; if (center.x > targetModel.x) { c1 = endColor; c2 = beginColor; } graph.addItem('edge', { source: clusterNodeId, target: targetModel.id, id: 'cluster-edge-' + ge.id, style: { stroke: 'l(0) 0:' + c1 + ' 1:' + c2, lineWidth: 0.4, strokeOpacity: 0.2 } }); } else if (targetModel.cluster === model.cluster && sourceModel.cluster !== model.cluster) { var _c3 = beginColor, _c4 = endColor; if (sourceModel.x > center.x) { _c3 = endColor; _c4 = beginColor; } graph.addItem('edge', { source: sourceModel.id, target: clusterNodeId, id: 'cluster-edge-' + ge.id, style: { stroke: 'l(0) 0:' + _c3 + ' 1:' + _c4, lineWidth: 0.4, strokeOpacity: 0.2 } }); } }); // hide the common nodes in the cluster graphNodes.forEach(function(gn) { if (gn.getModel().cluster === model.cluster && gn.getModel().id.substr(0, 7) !== 'cluster') gn.hide(); }); // hide the common edges about cluster graphEdges.forEach(function(ge) { if (!ge.get('sourceNode').get('visible') || !ge.get('targetNode').get('visible')) ge.hide(); }); } }); }); function mapValueToProp(items, valueName, propName, range) { var valueRange = [9999999999, -9999999999]; items.forEach(function(n) { if (n[valueName] > valueRange[1]) valueRange[1] = n[valueName]; if (n[valueName] < valueRange[0]) valueRange[0] = n[valueName]; }); var valueLength = valueRange[1] - valueRange[0]; var rLength = range[1] - range[0]; var propNameStrs = propName.split('.'); if (propNameStrs[0] === 'style' && propNameStrs.length > 1) { items.forEach(function(n) { if (n.style === undefined) n.style = {}; n.style[propNameStrs[1]] = rLength * (n[valueName] - valueRange[0]) / valueLength + range[0]; }); } else { items.forEach(function(n) { n[propNameStrs[0]] = rLength * (n[valueName] - valueRange[0]) / valueLength + range[0]; }); } } </script></body> </html>