antvis/G6

Custom ContextMenu (Submenu) #5795

RackweLLizm posted onGitHub

问题描述

Can we create submenu, that is, children, using the contextmenu plugin?

{
 type: 'contextmenu',
 trigger: 'contextmenu', // 'click' or 'contextmenu'
 onClick: (v) => {
 alert('You have clicked the「' + v + '」item');
 },
 getItems: () => {
 return [
 { name: 'Option 1', value: 'option1' },
 {
 name: 'Option 2',
 value: 'option2',
 children: [
 { name: 'Sub Option 1', value: 'suboption1' },
 { name: 'Sub Option 2', value: 'suboption2' }
 ]
 },
 { name: 'Option 3', value: 'option3' }
 ];
 },
 enable: (e) => e.targetType === 'node',
 },

like in the example above.

Or can I integrate a menu I created myself into Antv G6 v5?

I could previously do this in Graphin via the library below.

import { ContextMenu } from '@antv/graphin-components';
<ContextMenu bindType="node"
 >
 <Menu
 options={optionsNode.map(item => {
 return { ...item, name: `${item.name}` };
 })}
 onChange={handleChangeNodeGraphinMenu}
 bindType="node"
 />
 </ContextMenu>

Any help is appreciated. Thanks

重现链接

notFound

重现步骤

notFound

预期行为

NotFound

平台

Windows Chrome 124 "@antv/g6": "^5.0.0-beta.37",

屏幕截图或视频(可选)

No response

补充说明(可选)

No response


You can use getContent to return your DOM element. https://g6-next.antv.antgroup.com/api/plugins/contextmenu

posted by hustcc 11 months ago

Maybe it will be useful to others. ContextMenu example prepared with React 18 on Antv G6 v5. ContextMenu React Component.

import { Dropdown, Menu } from "antd";
import SubMenu from "antd/es/menu/SubMenu";
import { useEffect, useState } from "react";
import { createPortal } from "react-dom";

const SorguYapContextMenu = ({ x, y, id, targetType, onClose }) => {
    console.log("id, click element id", id);
    console.log("targetType node,edge or canvas", targetType);
    const [visible, setVisible] = useState(true);
    useEffect(() => {
        const handleClickOutside = (event) => {
            if (!event.target.closest('.g6-contextmenu')) {
                setTimeout(() => {
                    setVisible(false);
                    onClose();
                }, 150)
            }
        };

        const timer = setTimeout(() => {
            document.addEventListener('mousedown', handleClickOutside);
        }, 0);

        return () => {
            clearTimeout(timer);
            document.removeEventListener('mousedown', handleClickOutside);
        };
    }, [onClose]);



    const menu = (): JSX.Element => {
        if (targetType === "node") {
            return <Menu triggerSubMenuAction={"hover"} onClick={(e) => console.log("click", e)}>
                <Menu.Item key="1">node 1</Menu.Item>
                <Menu.Item key="2">Option 2</Menu.Item>
                <Menu.Item key="3">Option 3</Menu.Item>
                <SubMenu onTitleClick={(e) => e.domEvent.stopPropagation()} key="sub1" title="Submenu 1">
                    <Menu.Item key="5">Option 5</Menu.Item>
                    <Menu.Item key="6">Option 6</Menu.Item>
                </SubMenu>
            </Menu>
        }
        else if (targetType === "edge") {
            return <Menu triggerSubMenuAction={"hover"} onClick={(e) => console.log("click", e)}>
                <Menu.Item key="1">edge 1</Menu.Item>
                <Menu.Item key="2">Option 2</Menu.Item>
                <Menu.Item key="3">Option 3</Menu.Item>
                <SubMenu onTitleClick={(e) => e.domEvent.stopPropagation()} key="sub1" title="Submenu 1">
                    <Menu.Item key="5">Option 5</Menu.Item>
                    <Menu.Item key="6">Option 6</Menu.Item>
                </SubMenu>
            </Menu>
        }
        else if (targetType === "canvas") {
            return <Menu triggerSubMenuAction={"hover"} onClick={(e) => console.log("click", e)}>
                <Menu.Item key="1">canvas 1</Menu.Item>
                <Menu.Item key="2">Option 2</Menu.Item>
                <Menu.Item key="3">Option 3</Menu.Item>
                <SubMenu onTitleClick={(e) => e.domEvent.stopPropagation()} key="sub1" title="Submenu 1">
                    <Menu.Item key="5">Option 5</Menu.Item>
                    <Menu.Item key="6">Option 6</Menu.Item>
                </SubMenu>
            </Menu>
        }
        return <></>;
    }

    return createPortal(
        <Dropdown overlay={menu} visible={visible}>
            <div className="g6-contextmenu" style={{ position: 'absolute', left: x, top: y, zIndex: 1000 }} />
        </Dropdown>,
        document.body
    );
};
export default SorguYapContextMenu

Graph Plugins ContextMenu

            plugins: [
                {
                    type: 'contextmenu',
                    trigger: 'contextmenu', // 'click' or 'contextmenu'
                    getContent: (e) => {
                        const container = document.createElement('div');
                        document.body.appendChild(container);
                        const root = createRoot(container);

                        const closeContextMenu = () => {
                            root.unmount();
                            if (container.parentNode) {
                                container.parentNode.removeChild(container);
                            }
                        };
                        console.log("targetType",e.targetType)

                        root.render(<SorguYapContextMenu x={e.client.x} y={e.client.y} id={e.target.id} targetType={e.targetType} onClose={closeContextMenu} />);

                        return container;
                    },
                    enable: 'always',
                },
]
posted by RackweLLizm 11 months ago

Fund this Issue

$0.00
Funded

Pull requests