【无标题】

ant G6 + element-ui 根据el-tree点击的子返回所有的父级数据进行展示

效果图

Video_2024-02-20_140319

业务分析

1.需要根据左边tree数据更新右边 ant G6
2.每次点击节点,需要获取所有父节点包括自己
3.难点就在于怎么去把数据处理成我们需要的

处理数据代码

 findNewTree(treeData, targetNode, newTree = {}) {
            let t = treeData
            
            if (!targetNode?.parentid) {
                return targetNode
            }
            // 里面定义一个函数用来递归
            function getParentsTree(treeData, targetNode,) {
                for (const item of treeData) {
                    // 判断点击的id是否相同
                    if (item.id === targetNode.parentid) {
                        // 直接让父级只有自己一个儿子
                        item.children = [targetNode]
                        // 把数据赋值方便返回
                        newTree = item
                        // 判断父亲有无父亲
                        if (item.parentid) {
                            // 有就找父亲的父亲
                            return getParentsTree(t, newTree)
                        } else {
                            // 没有说明到第一级了  直接返回
                            return newTree
                        }
                    }
                    //递归
                    if (item.children && item.children.length > 0) {
                        return getParentsTree(item.children, targetNode)
                    }
                }
            }
            getParentsTree(treeData, targetNode, {})
            // 返回父节点数组
            return newTree;
  },

全部代码

// 左侧树代码
<template>
    <div id="elTree">
        <el-tree :data="data" ref="tree" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
    </div>
</template>
  
<script>
import { mapState, mapMutations } from "vuex";
export default {
    data() {
        return {
            data: [
                {
                    id: 'root',
                    label: '利息收入',
                    subLabel: '3,283.456',
                    ratio: 3,
                    children: [
                        {
                            id: 'child-a',
                            parentid: 'root',
                            label: '平均利息',
                            subLabel: '9%',
                            ratio: 1,
                            increase: true,
                        },
                        {  //情况1
                            id: 'child-b',
                            parentid: 'root',
                            label: '贷款余额',
                            subLabel: '1,789,567',
                            ratio: 23,
                            increase: true,
                            children: [
                                {
                                    id: 'child-b-a',
                                    parentid: 'child-b',
                                    label: '投放金额111111111111',
                                    subLabel: '2,385,124',
                                    ratio: 17,
                                    increase: true,
                                    operator: '-',
                                    children: [
                                        {
                                            id: 'child-b-a-2',
                                            parentid: 'child-b-a',
                                            label: '投放金额222',
                                            subLabel: '2,385,124',
                                            ratio: 17,
                                            increase: true,
                                            operator: '-',

                                        }, {
                                            id: 'child-b-b-1',
                                            parentid: 'child-b-a',
                                            label: '投放金额222',
                                            subLabel: '595,557',
                                            ratio: 12,
                                            increase: true,
                                        }
                                    ]

                                }, {
                                    id: 'child-b-b2314',
                                    parentid: 'child-b',
                                    label: '还款金额',
                                    subLabel: '595,557',
                                    ratio: 12,
                                    increase: true,
                                }
                            ]
                        },

                    ]
                },
                {
                    id: 'root',
                    label: '利息收入',
                    subLabel: '3,283.456',
                    ratio: 3,
                    children: [
                        {
                            id: 'child-a',
                            parentid: 'root',
                            label: '平均利息',
                            subLabel: '9%',
                            ratio: 1,
                            increase: true,
                        },
                        {  //情况1
                            id: 'child-b',
                            parentid: 'root',
                            label: '贷款余额',
                            subLabel: '1,789,567',
                            ratio: 23,
                            increase: true,
                            children: [
                                {
                                    id: 'child-b-a',
                                    parentid: 'child-b',
                                    label: '投放金额111111111111',
                                    subLabel: '2,385,124',
                                    ratio: 17,
                                    increase: true,
                                    operator: '-',
                                    children: [
                                        {
                                            id: 'child-b-a-2',
                                            parentid: 'child-b-a',
                                            label: '投放金额222',
                                            subLabel: '2,385,124',
                                            ratio: 17,
                                            increase: true,
                                            operator: '-',

                                        }, {
                                            id: 'child-b-b-1',
                                            parentid: 'child-b-a',
                                            label: '投放金额222',
                                            subLabel: '595,557',
                                            ratio: 12,
                                            increase: true,
                                        }
                                    ]

                                }, {
                                    id: 'child-b-b2314',
                                    parentid: 'child-b',
                                    label: '还款金额',
                                    subLabel: '595,557',
                                    ratio: 12,
                                    increase: true,
                                }
                            ]
                        },

                    ]
                },
            ],
            defaultProps: {
                children: 'children',
                label: 'label'
            },

        };
    },
    mounted() {
    },
    methods: {
        ...mapMutations("decision", ["setData", "getData"]),
        handleNodeClick(node) {
            const data = JSON.parse(JSON.stringify(this.data))
            const newData = this.findNewTree(data, node)
            this.setData(newData)
        },

        findNewTree(treeData, targetNode, newTree = {}) {
            let t = treeData
            
            if (!targetNode?.parentid) {
                return targetNode
            }
            // 里面定义一个函数用来递归
            function getParentsTree(treeData, targetNode,) {
                for (const item of treeData) {
                    // 判断点击的id是否相同
                    if (item.id === targetNode.parentid) {
                        // 直接让父级只有自己一个儿子
                        item.children = [targetNode]
                        // 把数据赋值方便返回
                        newTree = item
                        // 判断父亲有无父亲
                        if (item.parentid) {
                            // 有就找父亲的父亲
                            return getParentsTree(t, newTree)
                        } else {
                            // 没有说明到第一级了  直接返回
                            return newTree
                        }
                    }
                    //递归
                    if (item.children && item.children.length > 0) {
                        return getParentsTree(item.children, targetNode)
                    }
                }
            }
            getParentsTree(treeData, targetNode, {})
            // 返回父节点数组
            return newTree;
        },
    },


};
</script>
  
<style scoped>
#elTree {
    width: 400px;
    border: 1px solid green;
    height: 100%;

}
</style>
  
  
// 右侧ant g6代码
<template>
    <div id="antTree">
    </div>
</template>
  
<script>
import G6 from '@antv/g6';

export default {
    data() {
        return {
            graph: null,
            g6Data: {
                id: 'root',
                label: '利息收入',
                subLabel: '3,283.456',
                ratio: 3,
                children: [{
                    id: 'child-a',
                    label: '平均利息',
                    subLabel: '9%',
                    ratio: 1,
                    increase: true,
                }, {
                    id: 'child-b',
                    label: '贷款余额',
                    subLabel: '1,789,567',
                    ratio: 23,
                    increase: true,
                    children: [{
                        id: 'child-b-a',
                        label: '投放金额',
                        subLabel: '2,385,124',
                        ratio: 17,
                        increase: true,
                        operator: '-',
                    }, {
                        id: 'child-b-b',
                        label: '还款金额',
                        subLabel: '595,557',
                        ratio: 12,
                        increase: true,
                    }
                    ]
                }, {
                    id: 'child-c',
                    label: '还款期限',
                    subLabel: '7',
                    ratio: 23,
                    increase: false,
                }
                ]
            }
        }
    },
    mounted() {
        this.init()
    },
    methods: {
        init() {
            if (this.graph) {
                this.graph.destroy();
            }
            // root node
            G6.registerNode('root', {
                draw: (cfg, group) => {
                    const size = [80, 30];
                    const keyShape = group.addShape('rect', {
                        attrs: {
                            width: size[0],
                            height: size[1],
                            x: -size[0] / 2,
                            y: -size[1] / 2,
                            fill: 'rgb(19, 33, 92)',
                            radius: 5
                        },
                        draggable: true,
                        name: 'root-keyshape'
                    });
                    group.addShape('text', {
                        attrs: {
                            text: `${cfg.ratio}%`,
                            fill: 'rgba(255, 255, 255, 0.85)',
                            fontSize: 6,
                            x: 10 - size[0] / 2,
                            y: 3,
                        },
                        draggable: true,
                        name: 'ratio-shape'
                    });
                    group.addShape('text', {
                        attrs: {
                            text: `${cfg.label}`,
                            fill: 'rgba(255, 255, 255, 0.85)',
                            fontSize: 9,
                            x: -6,
                            y: 0,
                        },
                        draggable: true,
                        name: 'label-shape'
                    });
                    group.addShape('line', {
                        attrs: {
                            x1: -6,
                            x2: 35,
                            y1: 2,
                            y2: 2,
                            stroke: 'rgba(255, 255, 255, 0.85)',
                            lineWidth: 0.5
                        },
                        draggable: true,
                        name: 'divider-shape'
                    });
                    group.addShape('text', {
                        attrs: {
                            text: `${cfg.subLabel}`,
                            fill: 'rgba(255, 255, 255, 0.65)',
                            fontSize: 6,
                            x: -6,
                            y: 10,
                        },
                        draggable: true,
                        name: 'sublabel-shape'
                    });
                    return keyShape;
                }
            });

            // level1 node
            G6.registerNode('level1node', {
                draw: (cfg, group) => {
                    const size = [60, 40]
                    const keyShape = group.addShape('rect', {
                        attrs: {
                            width: size[0],
                            height: size[1],
                            x: -size[0] / 2,
                            y: -size[1] / 2,
                            fill: 'rgb(213, 225, 247)',
                            radius: 5
                        },
                        draggable: true,
                        name: 'level1node-keyshape'
                    });
                    group.addShape('text', {
                        attrs: {
                            text: `${cfg.label}`,
                            fill: 'rgba(19, 33, 92, 0.65)',
                            fontSize: 6,
                            x: 0,
                            y: -6,
                            textAlign: 'center'
                        },
                        draggable: true,
                        name: 'label-shape'
                    });
                    group.addShape('text', {
                        attrs: {
                            text: `${cfg.subLabel}`,
                            fill: 'rgba(19, 33, 92, 0.65)',
                            fontSize: 8,
                            x: 0,
                            y: 6,
                            fontWeight: 800,
                            textAlign: 'center'
                        },
                        draggable: true,
                        name: 'sublabel-shape'
                    });
                    group.addShape('rect', {
                        attrs: {
                            x: -12,
                            y: 8,
                            width: 25,
                            height: 8,
                            radius: 4,
                            fill: cfg.increase ? 'rgb(127, 193, 193)' : 'rgb(220, 124, 125)'
                        },
                        draggable: true,
                        name: 'ratio-box',
                    })
                    group.addShape('text', {
                        attrs: {
                            text: `${cfg.ratio}%`,
                            fill: 'rgba(255, 255, 255, 0.85)',
                            fontSize: 6,
                            x: 0,
                            y: 9,
                            textAlign: 'center',
                            textBaseline: 'top'
                        },
                        draggable: true,
                        name: 'ratio-shape'
                    });
                    // edge end
                    group.addShape('line', {
                        attrs: {
                            x1: -size[0] / 2,
                            x2: -size[0] / 2 + 6,
                            y1: 0,
                            y2: 0,
                            lineWidth: 1,
                            stroke: 'rgb(19, 33, 92)',
                        }
                    });
                    group.addShape('circle', {
                        attrs: {
                            r: 2,
                            x: -size[0] / 2 + 6,
                            y: 0,
                            fill: 'rgb(19, 33, 92)',
                        }
                    })
                    return keyShape;
                },
                update: undefined,
            }, 'rect')

            // other node
            G6.registerNode('othernode', {
                draw: (cfg, group) => {
                    const size = [100, 30];
                    const keyShape = group.addShape('rect', {
                        attrs: {
                            width: size[0],
                            height: size[1],
                            x: -size[0] / 2,
                            y: -size[1] / 2,
                            fill: 'rgb(213, 225, 247)',
                            radius: 5
                        },
                        draggable: true,
                        name: 'level1node-keyshape'
                    });
                    group.addShape('text', {
                        attrs: {
                            text: `${cfg.label}`,
                            fill: 'rgba(19, 33, 92, 0.65)',
                            fontSize: 6,
                            x: 10 - size[0] / 2,
                            y: -2,
                            textAlign: 'left'
                        },
                        draggable: true,
                        name: 'label-shape'
                    });
                    group.addShape('text', {
                        attrs: {
                            text: `${cfg.subLabel}`,
                            fill: 'rgba(19, 33, 92, 0.65)',
                            fontSize: 8,
                            fontWeight: 800,
                            x: 10 - size[0] / 2,
                            y: 8,
                            textAlign: 'left'
                        },
                        draggable: true,
                        name: 'sublabel-shape'
                    });
                    group.addShape('rect', {
                        attrs: {
                            x: 12,
                            y: -4,
                            width: 25,
                            height: 8,
                            radius: 4,
                            fill: cfg.increase ? 'rgb(127, 193, 193)' : 'rgb(220, 124, 125)'
                        },
                        draggable: true,
                        name: 'ratio-box'
                    })
                    group.addShape('text', {
                        attrs: {
                            text: `${cfg.ratio}%`,
                            fill: 'rgba(255, 255, 255, 0.85)',
                            fontSize: 6,
                            x: 18,
                            y: -3,
                            textAlign: 'left',
                            textBaseline: 'top'
                        },
                        draggable: true,
                        name: 'ratio-shape'
                    });
                    if (cfg.operator) {
                        group.addShape('rect', {
                            attrs: {
                                x: -8,
                                y: 27,
                                width: 16,
                                height: 16,
                                lineWidth: 1,
                                stroke: '#aaa',
                                lineDash: [2, 1],
                                opacity: 0
                            },
                            name: 'operator-box'
                        });
                        group.addShape('circle', {
                            attrs: {
                                r: 6,
                                x: 0,
                                y: 35,
                                fill: 'rgba(240, 90, 109, 0.15)'
                            },
                            name: 'operator-circle'
                        });
                        group.addShape('text', {
                            attrs: {
                                text: cfg.operator,
                                x: 0,
                                y: 34,
                                fontSize: 12,
                                fill: 'rgba(240, 90, 109, 0.85)',
                                textAlign: 'center',
                                textBaseline: 'middle'
                            },
                            name: 'operator-symbol'
                        });
                    }

                    // edge end
                    group.addShape('line', {
                        attrs: {
                            x1: -size[0] / 2,
                            x2: -size[0] / 2 + 6,
                            y1: 0,
                            y2: 0,
                            lineWidth: 1,
                            stroke: 'rgb(19, 33, 92)',
                        }
                    });
                    group.addShape('circle', {
                        attrs: {
                            r: 2,
                            x: -size[0] / 2 + 6,
                            y: 0,
                            fill: 'rgb(19, 33, 92)',
                        }
                    })
                    return keyShape;
                },
                update: undefined
            }, 'rect')

            // edge
            G6.registerEdge('round-poly', {
                getControlPoints: (cfg) => {
                    const { startPoint, endPoint } = cfg;
                    return [
                        startPoint,
                        {
                            x: startPoint.x,
                            y: endPoint.y
                        },
                        endPoint
                    ];
                }
            }, 'polyline')


            G6.Util.traverseTree(this.g6Data, subtree => {
                if (subtree.level === undefined) subtree.level = 0;
                subtree.children?.forEach(child => child.level = subtree.level + 1);
                switch (subtree.level) {
                    case 0:
                        subtree.type = 'root';
                        break;
                    case 1:
                        subtree.type = 'level1node';
                        break;
                    default:
                        subtree.type = 'othernode';
                }
            });

            const antTree = document.getElementById('antTree')
            const graph = new G6.TreeGraph({
                container: antTree,
                width: document.getElementById("antTree").clientWidth,
                height: document.getElementById("antTree").clientHeight,
                fitView: true,
                layout: {
                    type: 'compactBox',
                    direction: 'LR',
                    getHGap: function getVGap() {
                        return 5;
                    },
                },
                defaultEdge: {
                    type: 'round-poly',
                    sourceAnchor: 0,
                    targetAnchor: 1,
                    style: {
                        radius: 8,
                        stroke: 'rgb(19, 33, 92)'
                    }
                },
                defaultNode: {
                    anchorPoints: [
                        [0.9, 0.5],
                        [0, 0.5]
                    ]
                },
                nodeStateStyles: {
                    hover: {
                        fill: '#fff',
                        shadowBlur: 30,
                        shadowColor: '#ddd',
                    },
                    operatorhover: {
                        'operator-box': {
                            opacity: 1
                        }
                    }
                },
                modes: {
                    default: ['zoom-canvas', 'drag-canvas', 'collapse-expand']
                }
            });
            this.graph = graph;
            graph.on('node:mouseenter', e => {
                if (e.target.get('name')?.includes('operator')) {
                    graph.setItemState(e.item, 'operatorhover', true);
                } else {
                    graph.setItemState(e.item, 'hover', true);
                }
            })
            graph.on('node:mouseleave', e => {
                graph.setItemState(e.item, 'operatorhover', false);
                graph.setItemState(e.item, 'hover', false);
            });

            graph.data(this.g6Data);
            graph.render();
            window.addEventListener("resize", () => {
                this.graph.changeSize(
                    document.body.clientWidth - 48,
                    document.body.clientHeight - 110
                );
            });
        },
    },
    watch: {
        dataTree(newData) {
            this.g6Data = newData
            this.init()
        }
    },
    computed: {
        dataTree() {
            return this.$store.state.decision.dataTree
        }
    },



};
</script>
  
<style scoped>
#antTree {
    flex: 1;
    border: 1px solid lemonchiffon;
    height: 100%;
    width: 100%;
}
</style>
  
  
// vuex代码
import Vue from 'vue'
import Vuex from 'vuex'
import decision from './decision'
Vue.use(Vuex)

const store = new Vuex.Store({
  state: {},
  getters: {},
  mutations: {},
  actions: {},
  modules: {
    decision
  }


})

export default store
// decision模块
export default ({
    namespaced: true,
    state: {
        dataTree: {}
    },
    getters: {},
    mutations: {
        setData(state, data) {
            state.dataTree = data || {}
        },

    },
    actions: {},

})
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值