You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue中GoJS图表事务提交后未更新,搜索高亮不生效

Vue集成GoJS图表搜索高亮不即时更新问题

我在Vue应用里集成GoJS图表,想实现搜索功能,高亮匹配指定文本的节点。但触发按名称搜索函数、设置节点高亮状态后,图表不会立即更新,只有移动应高亮的元素时,边框颜色才会变化。

我的代码

图表初始化代码

const myDiagram = $(go.Diagram, this.$refs.goJsDiagram, {
    initialContentAlignment: go.Spot.Top,
    "undoManager.isEnabled": false,
    layout: $(CustomLayeredDigraphLayout,
        {
            direction: 90, // 90度为从上到下布局
            layerSpacing: 50 // 调整层间距
        })
});

myDiagram.nodeTemplate =
    $(go.Node, "Vertical",                   
        $(go.Panel, "Auto",   
            $(go.Shape, "Rectangle", {
                strokeWidth: 2,
                fill: "white"
            },
                new go.Binding("stroke", "", (data) => this.getStroke(data)).ofObject()
            ),
            $(go.TextBlock, {
                margin: new go.Margin(28, 22, 28, 22),
                font: "bold 22px sans-serif",
                stroke: "black"                            
            },
                new go.Binding("text", "Name")
            )
        )
    );

自定义边框颜色函数

getStroke(node) {
    if (node.data.IsHighlighted) {
        return "yellow"; // 高亮节点颜色
    }
    if (node.data.IsSelected) {
        return "green"; // 选中节点颜色
    }
    return "black"; // 默认颜色          
}

节点搜索函数

findNodeByName(name) {
    let foundNode = false;

    this.myDiagram.nodes.each((node) => {
        if (name && node.data.Name.toLowerCase().includes(name.toLowerCase())) {
            if (!node.data.IsHighlighted) {
                node.diagram.startTransaction('selected');
                node.diagram.model.setDataProperty(node.data, "IsHighlighted", true);
                node.diagram.startTransaction('selected');
            }
            foundNode = true;
        } else {
            if (node.data.IsHighlighted) {
                node.diagram.startTransaction('selected');
                node.diagram.model.setDataProperty(node.data, "IsHighlighted", false);
                node.diagram.startTransaction('selected');
            }
        }
    });

    return foundNode;
}

问题根源

  1. 事务使用错误:重复调用startTransaction却未提交事务,GoJS无法触发视图更新。正确流程是开启一次事务,所有修改完成后提交事务。
  2. Binding未声明依赖属性:stroke的Binding没有指定依赖的IsHighlighted和IsSelected,GoJS不知道这些属性变化时需要重新计算边框颜色。

修复方案

1. 修正事务逻辑

将搜索函数中的事务改为"开启一次 + 提交一次"的模式:

findNodeByName(name) {
    let foundNode = false;
    // 开启事务
    this.myDiagram.startTransaction('highlight-nodes');

    this.myDiagram.nodes.each((node) => {
        const shouldHighlight = name && node.data.Name.toLowerCase().includes(name.toLowerCase());
        // 仅当状态变化时才修改
        if (node.data.IsHighlighted !== shouldHighlight) {
            this.myDiagram.model.setDataProperty(node.data, "IsHighlighted", shouldHighlight);
        }
        if (shouldHighlight) foundNode = true;
    });

    // 提交事务,触发视图更新
    this.myDiagram.commitTransaction('highlight-nodes');
    return foundNode;
}

2. 明确Binding依赖

修改节点Shape的Binding,声明依赖IsHighlighted和IsSelected,让GoJS在属性变化时自动更新样式:

$(go.Shape, "Rectangle", {
    strokeWidth: 2,
    fill: "white"
},
    new go.Binding("stroke", "", (data) => this.getStroke(data))
        .ofObject()
        // 声明依赖的属性,当这些属性变化时重新计算stroke
        .bindingsArray([
            new go.Binding("IsHighlighted"),
            new go.Binding("IsSelected")
        ])
)

或者直接把颜色逻辑写在Binding里,更简洁:

$(go.Shape, "Rectangle", {
    strokeWidth: 2,
    fill: "white"
},
    new go.Binding("stroke", "IsHighlighted", (highlighted, data) => {
        if (highlighted) return "yellow";
        if (data.IsSelected) return "green";
        return "black";
    }).bindingsArray([new go.Binding("IsSelected")])
)

3. 确认模型类型

确保你的GoJS模型是go.Model或其子类(如go.GraphLinksModel),这些模型内置了数据变化通知机制,是视图更新的基础。

内容的提问来源于stack exchange,提问作者Kijok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 12:30:31