当前位置: 首页 > 工具软件 > GoJS > 使用案例 >

前端gojs各属性使用示例

惠翰藻
2023-12-01

示例中Gojs版本参考 GoJS v2.2.22

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="go.js"></script>
    <style>
        #myDiagramDiv {
            width: 100%;
            height: 900px;
            background-color: #DAE4E4;
        }
    </style>
</head>

<body>
    <div id="myDiagramDiv"></div>
</body>
<script>
    // 1.如果只是树形图表 接口只返回nodeDataArray就够了 linkDatasArray可以在前端拼接


    var $ = go.GraphObject.make;
    // link_color: 'red' //线条颜色
    // figure: 'Ellipse'//形状 圆形 Ellipse
    // isg 是否是根节点 (对接口时不需要设置该属性)
    var nodeDataArray = [
        { key: "start", text: '根节点', isg: true },
        { key: "1", text: '节点1', parent: 'start'},
        { key: "2", text: '节点2', parent: 'start'},
        { key: "3", text: '节点3', parent: 'start'},
        { key: "4", text: '节点4', parent: 'start'},
        { key: "4.1", text: '节点4.1', parent: '4'},
        { key: "4.2", text: '节点4.2', parent: '4'},
        { key: "4.3", text: '节点4.3', parent: '4'},
        { key: "4.4", text: '节点4.4', parent: '4'},
        { key: "4.5", text: '节点4.5', parent: '4'},
    ];
    var linkDatasArray = [
        {from: 'start', to: '1'},
        {from: 'start', to: '2'},
        {from: 'start', to: '3'},
        {from: 'start', to: '4'},
        {from: '4', to: '4.1'},
        {from: '4', to: '4.2'},
        {from: '4', to: '4.3'},
        {from: '4', to: '4.4'},
        {from: '4', to: '4.5'},
    ]

    /** 右键菜单按钮样式 */
    const buttonStyle = {
        "ButtonBorder.fill": "white",
        // "ButtonBorder.stroke": "darkcyan",
        // "ButtonBorder.strokeWidth": 3,
        "_buttonFillOver": "#E9F5FF",
        "_buttonStrokeOver": "darkcyan",
        "_buttonStrokePressed": "darkcyan",
        "_buttonFillPressed": "pink",
        visible: true,
        margin: new go.Margin(0, 0, 0, 0),
    }
    /** 右键功能配置 */
    var myContextMenu = $("ContextMenu", "Vertical",
        {
            background: "transparent",
            width: 100,
        },
        $("ContextMenuButton",
            {...buttonStyle},
            $(go.TextBlock, {
                text: "新增子节点",
                margin: new go.Margin(10, 0, 10, 0),
            }),
            {
                cursor: "pointer",
                click: (e, obj) => {
                    const key = obj.part.data.key
                    console.log(key)
                    var node = {
                        parent: key,
                        key: nodeDataArray.length+1,
                        text: `子节点${nodeDataArray.length+1}`,
                        // loc: '0 0',//节点位置
                    }
                    var linknode = {
                        from: key,
                        to: nodeDataArray.length+1
                    }
                    diagram.model.addNodeData(node);
                    diagram.model.addLinkData(linknode);
                },
            }
        ),
        $("ContextMenuButton",
            {...buttonStyle},
            $(go.TextBlock, {
                text: "删除节点",
                margin: new go.Margin(10, 0, 10, 0),
            }),
            {
                cursor: "pointer",
                click: (e, obj) => {
                    const key = obj.part.data.key

                    // 删除功能应该走接口的 以下代码只是在不对后端接口情况下的效果
                        // 先删线
                        delLinks(key)
                        // 再删除单个节点
                        var nodeData = diagram.model.findNodeDataForKey(key);
                        diagram.model.removeNodeData(nodeData);
                        delNodeLoop()
                },
            }
        ),
    )
    /** 需要一层一层删除 每次只删除没有父级的节点 */
    function delNodeLoop(){
        var removenodes=[];//需要删除的节点
        const keylist = []//所以节点的key
        diagram.model.nodeDataArray.map(item=>{
            keylist.push(item.key)
        })
        diagram.model.nodeDataArray.map(item=>{
            //如果找不到当前节点父级 && 当前节点不是跟节点
            if(!keylist.includes(item.parent) && !item.isg){
                removenodes.push(item)
                delLinks(item.key)
            }
        })
        diagram.model.removeNodeDataCollection(removenodes);
        if(removenodes.length>0){
            delNodeLoop()
        }
    }

    /** 删除单个节点关联的线(删线条时,节点必须存在) */
    function delLinks(key){
        
        //删除单个节点关联的线
        var removeLinks=[];
        //首先拿到这个节点的对象
        var node = diagram.findNodeForKey(key);
        
        node.findLinksConnected().each(function(link) { 
            removeLinks.push(link.data);
        });
        diagram.model.removeLinkDataCollection(removeLinks);
    }
    /** 节点点击 */
    function nodeClicked(e, obj){
        // var key='1';//节点key
        // var nodeData = diagram.model.findNodeDataForKey(key);
        // nodeData.text = '666';//text 是节点data中的一个属性
        // diagram.model.updateTargetBindings(nodeData);

    }
    /** 节点点击 */
    function nodeContextmenu(e, obj){
        console.log('1111')
        // var key='1';//节点key
        // var nodeData = diagram.model.findNodeDataForKey(key);
        // nodeData.text = '666';//text 是节点data中的一个属性
        // diagram.model.updateTargetBindings(nodeData);

    }
    /** 线条点击 */
    function linkClicked(e, obj){
    }

    var diagram = $(go.Diagram, "myDiagramDiv", {
        layout: $(go.TreeLayout, {
            angle: 0,
            nodeSpacing: 20,
            layerSpacing: 70
        }),
        isReadOnly: false, // 是否禁用编辑
        "toolManager.mouseWheelBehavior": go.ToolManager.WheelNone,//画布禁止鼠标滚轮事件
    });

    // diagram.layout.isOngoing = false//操作后是否允许节点自动布局 [禁止后会影响新建节点]
    function makePort(name, spot, outinput, input){
        return $(
            go.Shape,
            'Circle', {
                fill: null,
                stroke: null,
                desiredSize: new go.Size(7, 7),
                alignment: spot,
                portId: name,
                fromSpot: spot,
                toSpot: spot,
                fromLinkable: outinput,
                toLinkable: input,
                cursor: 'pointer'
            }
        )
    }
    function showSmallPorts(node, show){
        node.ports.each(function(port){
            port.fill = show?'#fff':null
        })
    }
    // 创建一个节点模版
    diagram.nodeTemplate = $(go.Node, "Auto",
        { contextMenu: myContextMenu },
        $(go.Shape, {
            figure: "RoundedRectangle",
            fill: '#022b4d',//背景
            stroke: '#0f68b7',//边框
            strokeWidth: 2//边框宽度
        }, new go.Binding("figure", "figure"), new go.Binding("fill", "color"), new go.Binding("stroke", "color")),
        $(go.TextBlock, {
            margin: 8,
            stroke: '#fff',//文字颜色
            editable: true,
        }, new go.Binding("text", "", (e)=>{
            console.log('e', e)
            // 纵向排列文字
            return e.text.split('').join('\n')
        })),
        {
            click: nodeClicked,
        },
        // 连线功能 因为是树形的节点图 不需要自己再加线
        makePort('T', go.Spot.Top, true, true),
        makePort('L', go.Spot.Left, true, true),
        makePort('R', go.Spot.Right, true, true),
        makePort('B', go.Spot.Bottom, true, true),
        {
            mouseEnter:(e, node)=>{
                showSmallPorts(node, true)
            },
            mouseLeave:(e, node)=>{
                showSmallPorts(node, false)
            }
        }
    );
    // 创建一个箭头模版
    diagram.linkTemplate = $(go.Link,
        {
            routing: go.Link.Orthogonal,// go.Link.Normal 直线 go.Link.Orthogonal 折线
            corner: 10,//折线圆角
            curve: go.Link.JumpOver,// go.Link.Bezier 曲线
        },
        $(go.Shape, { stroke: '#000', strokeWidth: 2,}, new go.Binding('stroke', 'link_color')),//线条
        $(go.Shape, { stroke: '#000', strokeWidth: 2, toArrow: "OpenTriangle" }, new go.Binding('stroke', 'link_color')),//箭头
        {
            click: linkClicked
        }
    );
    // diagram.toolManager.contextMenuTool.showContextMenu = (cm, obj) => {
    //     go.ContextMenuTool.prototype.showContextMenu.call(diagram.toolManager.contextMenuTool, cm, obj);
    //     const curCM = this.diagram.toolManager.contextMenuTool.currentContextMenu;
    //     if (curCM instanceof go.Adornment && curCM.adornedPart) {
    //         const shape = curCM.adornedPart.elt(0);
    //         if (shape instanceof go.Shape) {
    //             shape.stroke = "red";
    //             shape.fill = "green";
    //         }
    //     }
    // };

    // diagram.toolManager.contextMenuTool.hideContextMenu = () => {
    //     const curCM = this.diagram.toolManager.contextMenuTool.currentContextMenu;
    //     if (curCM instanceof go.Adornment && curCM.adornedPart) {
    //         const shape = curCM.adornedPart.elt(0);
    //         if (shape instanceof go.Shape) {
    //             shape.stroke = "green";
    //             shape.fill = "red";
    //         }
    //     }
    //     go.ContextMenuTool.prototype.hideContextMenu.call(diagram.toolManager.contextMenuTool);
    // };
    // 这里的数据后期就可以通过后端来获取
    diagram.model = new go.GraphLinksModel(nodeDataArray, linkDatasArray)
    // diagram.model = new go.TreeModel(nodeDataArray);

    diagram.commandHandler.canDeleteSelection = function(e) { 
        //用例获取选中的节点或线 
        return diagram.selection.all(function(nodeOrLink) { 
            console.log(nodeOrLink.data); 
            //判断是否存在不允许删除的节点或线 
            return false;
        }); 
    }
    // 动态控制节点颜色变化
    // var node = diagram.model.findNodeDataForKey("zip");
    // diagram.model.setDataProperty(node, "color", "lightgreen");
</script>
</html>
 类似资料: