/** * @author: clay * @data: 2019/07/05 * @description: 图的布局方式/图的初始化 */ // import d3 from '../plugins/d3-installer' import * as d3 from 'd3' import theme from '../theme' /** * 图的布局方式/图的初始化 * @type {{commonGraph: (function(*, *): G6.Graph)}} */ const initGraph = { /** * 一般布局 * @param G6 * @param options * @returns {G6.Graph} */ commonGraph: function(G6, options) { let graphData = options.graphData let themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体 // 生成G6实例 let graph = new G6.Graph({ plugins: options.plugins,//向 graph 注册插件 container: options.container,//图的 DOM 容器,可以传入该 DOM 的 id 或者直接传入容器的 HTML 节点对象。 width: options.width,//指定画布宽度,单位为 'px',默认为画布容器宽度。 height: options.height,//指定画布高度 // layout: { // type: 'random', // width: options.width, // height: options.height // }, defaultNode: {//默认状态下节点的配置 type: 'dice-er-box', labelCfg: { position: 'bottom' } }, defaultEdge: {//默认状态下线的配置 type: 'top-cubic', labelCfg: { position: 'center', autoRotate: false } }, nodeStateStyles: themeStyle.nodeStyle,//各个状态下节点的样式 // nodeStyle: { // selected: { // shadowColor: '#626262', // shadowBlur: 8, // shadowOffsetX: -1, // shadowOffsetY: 3 // } // }, edgeStateStyles:{ edgeStyle: { default: { stroke: '#e2e2e2', lineWidth: 3, lineAppendWidth: 10 }, selected: { shadowColor: '#626262', shadowBlur: 3 } }, },//各个状态下边的样式 modes: options.modes//设置画布的交互模式 }) // 将 read 方法分解成 data() 和 render 方法,便于整个生命周期的管理 graph.read(graphData) // 渲染图 graph.render() // 返回G6实例 return graph }, /** * 力导布局 * @param G6 * @param options * @returns {*} */ forceLayoutGraph: function(resolve, G6, options) { let graphData = options.graphData let themeStyle = theme.defaultStyle // todo...先使用默认主题,后期可能增加其它风格的主体 // 生成G6实例 let graph = new G6.Graph({ container: options.container, width: options.width, height: options.height, nodeStateStyles: themeStyle.nodeStyle, edgeStateStyles: themeStyle.edgeStyle }) // 初始化力导布局 let simulation = d3 .forceSimulation() .force( 'link', d3 .forceLink() .id(function(d) { return d.id }) .distance(linkDistance) .strength(0.5) ) .force('charge', d3.forceManyBody().strength(-500).distanceMax(500).distanceMin(100)) .force('center', d3.forceCenter(options.width / 2, options.height / 2)) // 定义节点数据 simulation.nodes(graphData.nodes).on('tick', ticked) // 定义连线数据 let edges = [] for (let i = 0; i < graphData.edges.length; i++) { edges.push({ id: graphData.edges[i].id, source: graphData.edges[i].source, target: graphData.edges[i].target }) } simulation.force('link').links(edges) graph.data(graphData) graph.render() function linkDistance(d) { return 150 } function ticked() { // protect: planA: 移除事件监听器 planB: 手动停止力模拟 if (graph.destroyed) { // simulation.nodes(graphData.nodes).on('tick', null) simulation.stop() return } if (!graph.get('data')) { // 若是第一次渲染,定义数据,渲染 graph.data(graphData) graph.render() } else { // 后续渲染,直接刷新所有点和边的位置 graph.refreshPositions() } } // 控制时间: 只布局10秒 let t = setTimeout(function() { simulation.stop() resolve(graph) }, 10000) // 判断force-layout结束 simulation.on('end', () => { clearTimeout(t) resolve(graph) }) } } export default initGraph