GoJS 管道示例添加文本块

GoJS Pipe Example Add TextBlock

我不清楚如何编辑 GoJS Pipes example here so that I can display text within the "pipes" without messing up the layout. I am trying to apply the answer to the same question given here,但它太旧了,可能已经过时了,或者它可能不够明确,我无法以有限的能力正确理解它这个库的知识。

我已经启动了一个硬编码管道,如下所示:

流水线代码:

const base = 15;
const minLen = base * 2;
const maxLen = base * 6;

const minInc1 = minLen + base;
const minInc2 = minLen * 2;
const minInc3 = minLen + (base * 3);

interface IShapeParams {
    angle?: number
    text?: string
    key: number
}

const createShapeI = (params: IShapeParams): ObjectData => ({
    geo: `F1 M0 0 L${minLen} 0 ${minLen} ${maxLen} 0 ${maxLen}z`,
    ports: [
        { id: "U1", spot: "0.5 0 0 0.5" },
        { id: "U2", spot: "0.5 1 0 -0.5" }
    ],
    ...params
});


const startHorz = 0;
const startVert = 0;

export const pipeline = {
    "class": "go.GraphLinksModel",
    "copiesArrays": true,
    "copiesArrayObjects": true,
    "linkFromPortIdProperty": "fid",
    "linkToPortIdProperty": "tid",
    "nodeDataArray": [
        {
            ...createShapeI({ key: 1, text: "Pipe 1", angle: 90 }),
            "loc": `${startHorz} ${startVert}`
        },
        {
            ...createShapeI({ key: 2, text: "Pipe 2", angle: 90 }),
            "loc": `${startHorz - maxLen} ${startVert}`
        }
    ],
    "linkDataArray": [
        { "from": 1, "to": 2, "fid": "U2", "tid": "U1" }
    ]
};

原始nodeTemplate来自管道源代码:

    myDiagram.nodeTemplate =
        $(go.Node, "Spot",
            {
                locationObjectName: "SHAPE",
                locationSpot: go.Spot.Center,
                selectionAdorned: false,  // use a Binding on the Shape.stroke to show selection
                itemTemplate:
                // each port is an "X" shape whose alignment spot and port ID are given by the item data
                    $(go.Panel,
                        new go.Binding("portId", "id"),
                        new go.Binding("alignment", "spot", go.Spot.parse),
                        $(go.Shape, "XLine",
                            { width: 6, height: 6, background: "transparent", fill: null, stroke: "gray" },
                            new go.Binding("figure", "id", portFigure),  // portFigure converter is defined below
                            new go.Binding("angle", "angle"))
                    ),
                // hide a port when it is connected
                linkConnected: (node, link, port) => {
                    if (link.category === "") {
                        port.visible = false;
                    }
                },
                linkDisconnected: (node, link, port) => {
                    if (link.category === "") {
                        port.visible = true;
                    }
                }
            },
            // this creates the variable number of ports for this Spot Panel, based on the data
            new go.Binding("itemArray", "ports"),
            // remember the location of this Node
            new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
            // remember the angle of this Node
            new go.Binding("angle", "angle").makeTwoWay(),
            // move a selected part into the Foreground layer, so it isn't obscured by any non-selected parts
            new go.Binding("layerName", "isSelected", function(s) {
                return s ? "Foreground" : "";
            }).ofObject(),
            $(go.Shape,
                {
                    name: "SHAPE",
                    // the following are default values;
                    // actual values may come from the node data object via data binding
                    geometryString: "F1 M0 0 L20 0 20 20 0 20 z",
                    fill: "rgba(128, 128, 128, 0.5)"
                },
                // this determines the actual shape of the Shape
                new go.Binding("geometryString", "geo"),
                // selection causes the stroke to be blue instead of black
                new go.Binding("stroke", "isSelected", (s) => {
                    return s ? "dodgerblue" : "black";
                }).ofObject())
        );

现在,当我尝试应用 solution given on the referenced thread 时,我最终得到 nodeTemplate,如下所示:

    myDiagram.nodeTemplate =
        $(go.Node, "Spot",
            {
                locationObjectName: "SHAPE",
                locationSpot: go.Spot.Center,
                selectionAdorned: false,  // use a Binding on the Shape.stroke to show selection
                // hide a port when it is connected
                linkConnected: (node, link, port) => {
                    if (link.category === "") {
                        port.visible = false;
                    }
                },
                linkDisconnected: (node, link, port) => {
                    if (link.category === "") {
                        port.visible = true;
                    }
                }
            },
            $(go.Panel, "Spot",
                {
                    itemTemplate:
                    // each port is an "X" shape whose alignment spot and port ID are given by the item data
                        $(go.Panel,
                            new go.Binding("portId", "id"),
                            new go.Binding("alignment", "spot", go.Spot.parse),
                            $(go.Shape, "XLine",
                                { width: 6, height: 6, background: "transparent", fill: null, stroke: "gray" },
                                new go.Binding("figure", "id", portFigure),  // portFigure converter is defined below
                                new go.Binding("angle", "angle"))
                        )
                },
                // this creates the variable number of ports for this Spot Panel, based on the data
                new go.Binding("itemArray", "ports"),
                // remember the location of this Node
                new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
                // remember the angle of this Node
                new go.Binding("angle", "angle").makeTwoWay(),
                // move a selected part into the Foreground layer, so it isn't obscured by any non-selected parts
                new go.Binding("layerName", "isSelected", function(s) {
                    return s ? "Foreground" : "";
                }).ofObject(),
                $(go.Shape,
                    {
                        name: "SHAPE",
                        // the following are default values;
                        // actual values may come from the node data object via data binding
                        geometryString: "F1 M0 0 L20 0 20 20 0 20 z",
                        fill: "rgba(128, 128, 128, 0.5)"
                    },
                    // this determines the actual shape of the Shape
                    new go.Binding("geometryString", "geo"),
                    // selection causes the stroke to be blue instead of black
                    new go.Binding("stroke", "isSelected", (s) => {
                        return s ? "dodgerblue" : "black";
                    }).ofObject())
            ),
            $(go.TextBlock, { margin: 5 }, new go.Binding("text", "text"))
        );

这可以正确呈现文本,但由于端口切换了两侧,它完全破坏了布局,我不知道为什么。最重要的是,在管道之间看到的 space 现在我无法通过尝试更改管道上的 loc 字符串来协调,实际上我对 loc 属性没有做任何事情现在什么都做。见下图:

如何在保持相同布局和功能的同时向这些形状添加文本块?

因此管道模板当前的结构如下:

Node (that is a Spot Panel)
 - 1st child: Shape
 - 2nd-nth child: Item array of x's

Spot 面板有一个主要元素(通常是第一个子元素,除非您指定它),然后是基于它定位的其他 N 个元素。所以至少你需要这样的结构:

Node (that is a Spot Panel)
 - 1st child: Panel (another Spot panel)
    - Shape
    - TextBlock
 - 2nd-nth child: Item array of x's

所以您要将形状换成包含该形状的面板(一个装有很多东西的容器)。只要该 Panel 的大小与其要替换的形状完全相同,这就会起作用。如果它更大,例如,如果文本比形状大,那么你就有麻烦了。

如何解决该问题实际上取决于您希望结果是什么样子。最简单的方法是将 TextBlock 强制设置为 stretch: go.GraphObject.Fill,这样它的大小始终与形状相同,这样面板 (Shape+TextBlock) 的大小始终与其替换的形状相同。

另外,您可能希望 TextBlock 垂直居中,这将假定灰色形状的整个区域,因此您需要添加 verticalAlignment: go.Spot.Center

像这样:

      myDiagram.nodeTemplate =
        $(go.Node, "Spot",
          {
            locationObjectName: "SHAPE",
            locationSpot: go.Spot.Center,
            selectionAdorned: false,  // use a Binding on the Shape.stroke to show selection
            itemTemplate:
              // each port is an "X" shape whose alignment spot and port ID are given by the item data
              $(go.Panel,
                new go.Binding("portId", "id"),
                new go.Binding("alignment", "spot", go.Spot.parse),
                $(go.Shape, "XLine",
                  { width: 6, height: 6, background: "transparent", fill: null, stroke: "gray" },
                  new go.Binding("figure", "id", portFigure),  // portFigure converter is defined below
                  new go.Binding("angle", "angle"))
              ),
            // hide a port when it is connected
            linkConnected: function(node, link, port) {
              if (link.category === "") port.visible = false;
            },
            linkDisconnected: function(node, link, port) {
              if (link.category === "") port.visible = true;
            }
          },
          // this creates the variable number of ports for this Spot Panel, based on the data
          new go.Binding("itemArray", "ports"),
          // remember the location of this Node
          new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
          // remember the angle of this Node
          new go.Binding("angle", "angle").makeTwoWay(),
          // move a selected part into the Foreground layer, so it isn't obscured by any non-selected parts
          new go.Binding("layerName", "isSelected", function(s) { return s ? "Foreground" : ""; }).ofObject(),
          // Everything except the ports: (the pipe body, and pipe text)
          $(go.Panel, "Spot",
            $(go.Shape,
              {
                name: "SHAPE",
                // the following are default values;
                // actual values may come from the node data object via data binding
                geometryString: "F1 M0 0 L20 0 20 20 0 20 z",
                fill: "rgba(128, 128, 128, 0.5)"
              },
              // this determines the actual shape of the Shape
              new go.Binding("geometryString", "geo"),
              // selection causes the stroke to be blue instead of black
              new go.Binding("stroke", "isSelected", function(s) { return s ? "dodgerblue" : "black"; }).ofObject()),
            $(go.TextBlock, "Some text")
          )
        );

这是实时修改:https://codepen.io/simonsarris/pen/RwrKqrq?editors=1010