Files
mosr-web/src/views/custom-query/topo/top/graph/index.js
2024-03-04 19:13:43 +08:00

163 lines
4.4 KiB
JavaScript

/**
* @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