antvis/G6






The issue has been closed
force2如何让节点保持不动 #4651
CodingJzy posted onGitHub
问题描述
接口返回的数据不变的,但是force渲染后效果不太好,我们是定时获取数据、渲染。导致每次定时获取到数据后会有个过度动画一样,一闪一闪的,不过force的节点位置是不会改变。 使用force2之后,渲染数据后不会闪一下,但是节点位置会变。
force效果
force2效果(可以看到刷新后,节点名称变了。而force是不变的)
重现链接
1
重现步骤
<script lang="ts" setup>
import G6, { Graph } from '@antv/g6'
import { computed, onMounted, ref, watch } from 'vue'
import { useMonitorXdrStore } from '@/store/monitor/xdr'
import { storeToRefs } from 'pinia'
import { StatusHandler } from '@/tools/systemDashboard'
import { Substr } from '@/tools/tools'
import { monitorXdrServicesResp } from '@/types/monitor/xdr'
const { xdrServiceData } = storeToRefs(useMonitorXdrStore())
onMounted(() => {
setTimeout(() => {
initG6()
}, 1000)
})
const emits = defineEmits(['nodeClick'])
const graphData = computed(() => {
const nodes = xdrServiceData.value?.node.map((item) => {
return {
id: item.service_name,
label: Substr(item.service_name, 10),
type: 'node',
version: item.version,
business: item.namespace,
commit_hash: item.commit_hash,
style: {
fill: StatusHandler(item.status).color,
stroke: StatusHandler(item.status).color,
// lineWidth: 2,
// radius: 5,
},
}
})
const edges = xdrServiceData.value?.edge.map((item) => {
return {
source: item.source,
target: item.target,
type: 'circle-running',
style: {
stroke: StatusHandler(item.status).color,
lineWidth: 2,
endArrow: {
path: 'M 0,0 L 8,4 L 8,-4 Z',
fill: StatusHandler(item.status).color,
},
// curveOffset: 30,
},
}
})
return {
nodes,
edges,
}
})
const graph = ref<Graph>()
const tooltipHandler = (obj: any) => {
let base = `
<h4>APP信息:</h4>
APP名称: <span style='color: red'>${obj.node}</span></br>`
if (obj.business) {
return (
base + `业务线: <span style='color: red'>${obj.business}</span></br>`
)
}
if (obj.commit_hash) {
return (
base +
`commitHash: <span style='color: red'>${obj.commit_hash}</span></br>`
)
}
if (obj.version) {
return base + `版本: <span style='color: red'>${obj.version}</span></br>`
}
return base
}
const initG6 = () => {
if (xdrServiceData.value?.node.length == 0) {
return
}
const tooltip = new G6.Tooltip({
offsetX: 10,
offsetY: 20,
getContent(e: any) {
const outDiv = document.createElement('div')
outDiv.style.width = '200px'
outDiv.innerHTML = tooltipHandler({
node: e.item.getModel().id,
business: e.item._cfg.model.business,
commit_hash: e.item._cfg.model.commit_hash,
version: e.item._cfg.model.version,
})
return outDiv
},
itemTypes: ['node'],
})
graph.value = new G6.Graph({
plugins: [tooltip],
container: 'mountNode',
width: 1660,
height: window.innerHeight - 260,
// fitView: true, // 画布自适应
fitCenter: true, // 画布居中
// linkCenter:true ,
defaultEdge: {
style: {
radius: 10,
offset: 10,
lineWidth: 2,
stroke: 'steelblue',
},
type: 'circle-running',
},
defaultNode: {
style: { fill: '#A9D18E', stroke: '#000', lineWidth: 1, radius: 5 },
type: 'circle', // 圆形
size: 50, // node 大小
labelCfg: {
// position: 'bottom',
// offset: 5,
style: {
fontSize: 10,
},
},
},
// https://g6.antv.antgroup.com/manual/middle/states/mode
modes: {
// default: ['drag-node'],
default: ['drag-canvas'],
},
// animate:false,
layout: {
type: 'force2',
preventOverlap: true,
linkDistance: 150,
strictRadial: true,
},
// https://g6.antv.antgroup.com/manual/middle/states/state#%E9%85%8D%E7%BD%AE-state-%E6%A0%B7%E5%BC%8F
nodeStateStyles: {
// 二值状态 hover 为 true 时的样式
hover: {
fill: '#FFF',
stroke: '#40A9FF',
labelCfg: {
style: {
fontSize: 100,
},
},
},
},
// edgeStateStyles: {
// // 二值状态 hover 为 true 时的样式
// hover: {
// fill: '#40A9FF',
// },
//
// },
})
const lineDash = [4, 2, 1, 2]
G6.registerEdge(
'circle-running',
{
afterDraw(cfg: any, group: any) {
// get the first shape in the group, it is the edge's path here=
const shape = group.get('children')[0]
let index = 0
// Define the animation
shape.animate(
() => {
index++
if (index > 9) {
index = 0
}
return {
lineDash,
lineDashOffset: -index,
}
},
{
repeat: true, // plugins executes the animation repeatly
duration: 3000, // the duration for executing once
},
)
},
},
'cubic', // extend the built-in edge 'cubic'
)
graph.value.on('node:dragstart', function (e) {
graph.value?.layout()
refreshDragedNodePosition(e)
})
graph.value.on('node:drag', function (e) {
const forceLayout = graph.value?.get('layoutController').layoutMethods[0]
forceLayout.execute()
refreshDragedNodePosition(e)
})
graph.value.on('node:dragend', function (e: any) {
e.item.get('model').fx = null
e.item.get('model').fy = null
})
graph.value.on('node:click', async (evt: any) => {
emits('nodeClick', evt.item._cfg.id)
})
// console.log(graphData)
graph.value.data(graphData)
graph.value.render()
// this.setItemState2Offline("fc-gateway")
// setItemState('fc-gateway', '内存占用高')
}
function refreshDragedNodePosition(e: any) {
const model = e.item.get('model')
model.fx = e.x
model.fy = e.y
}
watch(
() => graphData.value,
(neVal) => {
if (neVal) {
graph.value?.read(graphData)
}
},
)
</script>
<template>
<div>
<div
v-if="(xdrServiceData as monitorXdrServicesResp)?.node.length >0"
id="mountNode"
/>
<a-empty v-else style="width: 100%" />
</div>
</template>
<style scoped></style>
预期行为
1
平台
- 操作系统: [macOS, Windows, Linux, React Native ...]
- 网页浏览器: [Google Chrome, Safari, Firefox]
- G6 版本: [4.5.1 ... ]
屏幕截图或视频(可选)
1
补充说明(可选)
No response