G6实现自定义节点

通过G6实现自定义节点

因为原先用的可视化不支持自定义节点的操作所以在想用别的可视化来实现这个效果。之前有调研过G6也研究过它的源码,所以第一时间想到的就是G6。
G6的API用起来就挺舒服的,哈哈哈。

在这里插入图片描述

// 模拟数据  !!!注意属性里不能有type,会渲染不出来。原因是type是G6的保留字符. 
        const data = {
            nodes: [{
                    id: 'node1',
                    dataType: 'REDCODE',
                    keyInfo: '男 / 22岁',
                    name: "Sing"
                },
                {
                    id: 'node2',
                    dataType: 'YELLOWCODE',
                    keyInfo: '男 / 22岁',
                    name: "Sing"
                },
                {
                    id: 'node3',
                    dataType: 'YELLOWCODE',
                    keyInfo: '男 / 22岁',
                    name: "Sing"
                },
                {
                    id: 'node4',
                    dataType: 'YELLOWCODE',
                    keyInfo: '男 / 22岁',
                    name: "Sing"
                },
                {
                    id: 'node5',
                    dataType: 'YELLOWCODE',
                    keyInfo: '男 / 22岁',
                    name: "Sing"
                },
            ],
            edges: [{
                    source: 'node1',
                    target: 'node2'
                },
                {
                    source: 'node1',
                    target: 'node3'
                },
                {
                    source: 'node1',
                    target: 'node4'
                }, 
                {
                    source: 'node1',
                    target: 'node5'
                },
            ],
        };
        // 点配置
        const CODES = {
            REDCODE: "#F5222D",
            YELLOWCODE: "#f7dc6f",
            GREENCODE: "#41912b"
        };
        const getNodeConfig = (node) => {
            return {
                fontColor: "#000", // 文字颜色
                bgColor: CODES[node.dataType] || "#41912b", // 背景颜色
                mainColor: "#fff", // 信息内容的背景颜色
                fontSize: 16, // 字体大小
            }
        }
        // 基准绘制方法
        const boxHeight = 80,
            boxWidth = 180,
            padding_Top = 10,
            padding_Left = -10,
            mainWidth = 90,
            imageRect = 60;
        const nodeBasicMethod = {
            // 创建点位置
            createNodeBox: (group, config, width, height) => {
                // 父级容器
                const container = group.addShape('rect', {
                    attr: {
                        x: 0,
                        y: 0,
                        width,
                        height
                    },
                    name: 'father-shape',
                    draggable: true,
                });
                // 主体
                group.addShape('rect', {
                    attrs: {
                        x: -width / 2,
                        y: 0,
                        width,
                        height,
                        fill: config.bgColor,
                        stroke: config.bgColor,
                        radius: 10,
                        cursor: 'pointer',
                    },
                    name: 'main-shape',
                    draggable: true,
                });
                // 文字部分
                group.addShape('rect', {
                    attrs: {
                        x: padding_Left,
                        y: padding_Top,
                        width: mainWidth,
                        height: boxHeight - padding_Top * 2,
                        fill: config.mainColor,
                        stroke: config.mainColor,
                        radius: 2,
                        cursor: 'pointer',
                    },
                    name: 'text-shape',
                    draggable: true,
                });
                return container;
            },
            // 做一些预处理,和初始化设置
            setState: (name, value, item) => {
                const group = item.getContainer();

            },
            afterDraw: (cfg, group) => {
                group.on('click', (e) => {
                    console.log('you click: ' + cfg.id)
                })
            }
        }
        // 自定义节点样式 
        G6.registerNode('card-node', {
            draw: (cfg, group) => {
                const config = getNodeConfig(cfg);
                const container = nodeBasicMethod.createNodeBox(group, config, boxWidth, boxHeight);
                // 文字添加
                group.addShape('text', {
                    attrs: {
                        text: cfg.name,
                        x: 0,
                        y: boxHeight / 2 - config.fontSize,
                        fontSize: config.fontSize,
                        textAlign: 'left',
                        textBaseline: 'middle',
                        fill: config.fontColor,
                    },
                    name: 'name-text-shape',
                    draggable: true,
                });
                group.addShape('text', {
                    attrs: {
                        text: cfg.keyInfo,
                        x: 0,
                        y: boxHeight / 2 + config.fontSize,
                        fontSize: config.fontSize,
                        textAlign: 'left',
                        textBaseline: 'middle',
                        fill: config.fontColor,
                    },
                    name: 'keyInfo-text-shape',
                    draggable: true,
                });
                // 头像
                group.addShape('image', {
                    attrs: {
                        x: padding_Left - imageRect - 5,
                        y: boxHeight / 2 - imageRect / 2,
                        img: 'https://g.alicdn.com/cm-design/arms-trace/1.0.155/styles/armsTrace/images/TAIR.png',
                        width: imageRect,
                        height: imageRect
                    },
                    name: 'image-shape',
                    draggable: true,
                });
                return container
            },
            setState: nodeBasicMethod.setState,
            afterDraw: nodeBasicMethod.afterDraw
        })
        // 生成G6实例,如果要使用树形布局使用 `new G6.TreeGraph` 的方式生成实例
        const graph = new G6.Graph({
            container: 'container',
            width: 1200,
            height: 800,
            fitCenter: true,
            fitView: true,
            modes: {
                default: ['zoom-canvas', 'drag-canvas', 'drag-node'],
            },
            layout: {
                type: 'dagre',
                nodeSize: [boxWidth, boxHeight],
                nodesep: 60,
                ranksep: 60,
            },
            // 节点样式修改
            defaultNode: {
                type: 'card-node',
            },
            // 边样式修改
            defaultEdge: {
                size: 1,
                color: '#e2e2e2',
                style: {
                    endArrow: {
                        path: 'M 0,0 L 8,4 L 8,-4 Z',
                        fill: '#e2e2e2',
                    },
                },
            }
        });
        graph.data(data);
        graph.render();
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值