点击自定义节点中的按钮去更新视图,主要采用callback 回调方式调用
一、案例效果
未点击【上面】按钮之前
点击之后
二、案例代码
- 自定义节点内容 NodeHtml.vue
<template>
<div class="status-node">
<div v-if="nodeInfo?.isUpstreamExpandable" class="text-[#f00]" @click="upstreamHandleFn">上面</div>
<div class="content" @click="handleClick">{{ nodeInfo?.label }}</div>
<div v-if="nodeInfo?.isDownstreamExpandable" class="text-[#00f]">下面</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
const props = defineProps({
nodeElementItem: {
type: Object,
required: true,
},
upstreamHandle: {
type: Function,
required: true,
},
});
const nodeInfo = ref();
const handleClick = () => {
console.log('---handleClick');
};
const initNodeData = () => {
nodeInfo.value = props.nodeElementItem.store.data;
console.log(' nodeInfo.value ', nodeInfo.value);
};
const upstreamHandleFn = () => {
props.upstreamHandle();
};
onMounted(() => {
initNodeData();
});
</script>
<style lang="less" scoped>
.status-node {
height: 50px;
width: 200px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #8f8f8fa1;
box-shadow: 0 0 6px rgba(0, 0, 0, 0.1);
z-index: 999;
}
.content {
color: #000;
font-size: 14px;
}
</style>
- 传入props.upstreamHandle 方法 attrConfig.ts
import { streamData } from '@/common/components/topologyToolKit/data';
import NodeElement from '@/views/featureManage/featureList/topologyToolKit/NodeHtml.vue';
import { h } from 'vue';
import { formatNodeData } from './topology';
const upstreamHandle = (originalNodeData: any, callback: (data: any) => void) => {
console.log('Upstream handle triggered', originalNodeData);
const streamFormatData = formatNodeData(streamData);
originalNodeData.nodes = [...originalNodeData.nodes, ...streamFormatData.nodes];
originalNodeData.edges = [...originalNodeData.edges, ...streamFormatData.edges];
// 调用回调函数,传递更新后的 originalNodeData
callback(originalNodeData);
};
/**
* 自定义注册节点配置
*/
export const registerOption = (originalNodeData: any, callback: (data: any) => void) => ({
shape: 'vue-shape',
width: 100,
height: 100,
component: ({ node }: { node: any }) => {
console.log('1666-originalNodeData', originalNodeData);
// 将 node 数据传递给 NodeElement 组件
return h(NodeElement, { nodeElementItem: node, upstreamHandle: () => upstreamHandle(originalNodeData, callback) });
},
});
- 触发upstreamHandle 回调callback -TopologyDependent.vue
<template>
<div :id="domId" class="w-full h-[95%]"></div>
</template>
<script setup lang="ts">
import { registerOption } from '@/views/featureManage/featureList/topologyToolKit/attrConfig';
import { DagreLayout, DagreLayoutOptions } from '@antv/layout';
import { Graph } from '@antv/x6';
import { register } from '@antv/x6-vue-shape';
import { computed, nextTick, onMounted, ref, toRaw } from 'vue';
import { initDependOption } from './initDependConfig';
const props = defineProps({
domId: {
type: String,
default: '',
},
nodeData: {
type: Object,
},
targetIdData: {
type: Array as () => number[],
required: false,
},
});
const container = ref<any>();
const nodeUpdateData = computed(() => {
return props.nodeData;
});
const initGraph = (data: any) => {
console.log('-8888---data', data);
container.value = document.getElementById(props.domId);
const width = container.value?.scrollWidth;
const height = container.value?.scrollHeight || 800;
const graph = new Graph({
container: container.value,
width, // 设置图形的宽度
height, // 设置图形的高度
...initDependOption.option,
});
const dagreLayout = new DagreLayout({ ...(initDependOption.layout as DagreLayoutOptions) });
const model = dagreLayout.layout(data);
console.log('111==data', data, model);
graph.fromJSON(model);
graph.on('node:click', ({ e, x, y, node, view }) => {
console.log('---115-e, x, y, node, view', e, x, y, node, view);
});
};
const handleUpdateNodeData = (updatedNodeData: any) => {
const rawNodeData = toRaw(updatedNodeData); // 获取原始对象
initGraph(rawNodeData);
console.log('333333======Updated originalNodeData:', updatedNodeData);
};
onMounted(() => {
nextTick(() => {
if (props.domId && document.getElementById(props.domId)) {
const rawNodeData = toRaw(nodeUpdateData.value); // 获取原始对象
initGraph(rawNodeData);
register({ ...registerOption(rawNodeData, handleUpdateNodeData) });
}
});
});
</script>
- 父组件 BloodTopology.vue
<template>
<div>
<TopologyCompact>
<template #main-board-box>
<TopologyDependent domId="featureBloodContainer" :nodeData="originalNodeData" />
</template>
<template #right-drawer-box>
<RightDrawer :width="350">
<template #rightContent> rightContent </template>
</RightDrawer>
</template>
</TopologyCompact>
</div>
</template>
<script lang="ts" setup>
import { bloodData } from '@/common/components/topologyToolKit/data';
import RightDrawer from '@/common/components/topologyToolKit/RightDrawer.vue';
import TopologyCompact from '@/common/components/topologyToolKit/TopologyCompact.vue';
import TopologyDependent from '@/common/components/topologyToolKit/TopologyDependent.vue';
import { onMounted, ref } from 'vue';
import { formatNodeData } from '../topologyToolKit/topology';
const originalNodeData = ref({
nodes: [],
edges: [],
});
const initNodeData = () => {
originalNodeData.value = formatNodeData(bloodData);
};
onMounted(() => {
initNodeData();
});
</script>
- mock 数据 @/common/components/topologyToolKit/data
export const bloodData = {
nodes: [
{
featureId: '12345',
featureNameCn: '订单金额总和',
featureNameEn: 'orderAmountSum',
isUpstreamExpandable: true,
isDownstreamExpandable: true,
upstreamFeatureIds: ['55555'],
downstreamFeatureIds: ['67890', '54321'],
},
{
featureId: '67890',
featureNameCn: '单品订单金额',
featureNameEn: 'singleItemOrderAmount',
isUpstreamExpandable: false,
isDownstreamExpandable: true,
upstreamFeatureIds: ['12345'],
downstreamFeatureIds: ['23456'],
},
{
featureId: '54321',
featureNameCn: '订单数量',
featureNameEn: 'orderQuantity',
isUpstreamExpandable: false,
isDownstreamExpandable: false,
upstreamFeatureIds: ['12345'],
downstreamFeatureIds: [],
},
],
edges: [
{
source: '12345',
target: '67890',
},
{
source: '12345',
target: '54321',
},
],
};
export const streamData = {
nodes: [
{
featureId: '23456',
featureNameCn: '平均订单金额',
featureNameEn: 'averageOrderAmount',
isUpstreamExpandable: true,
isDownstreamExpandable: true,
upstreamFeatureIds: ['67890'],
downstreamFeatureIds: ['33333'],
},
{
featureId: '34567',
featureNameCn: '大额订单数量',
featureNameEn: 'largeOrderQuantity',
isUpstreamExpandable: true,
isDownstreamExpandable: false,
upstreamFeatureIds: ['67890'],
downstreamFeatureIds: [],
},
],
edges: [
{
source: '67890',
target: '23456',
},
{
source: '67890',
target: '34567',
},
],
};