GoJS Пример трубы Добавить текстовый блок - PullRequest
1 голос
/ 19 июня 2020

Мне не очевидно, как отредактировать здесь GoJS Pipes , чтобы я мог отображать текст внутри «каналов», не нарушая макета. Я пытаюсь применить ответ на тот же вопрос, данный здесь , но он настолько старый, что может быть устаревшим, или, может быть, он просто недостаточно ясен, чтобы я мог правильно его понять с моими ограниченными знаниями этой библиотеки.

Я запустил жестко запрограммированный конвейер, который выглядит так:

enter image description 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 из исходного кода Pipe:

    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())
        );

Теперь, когда я пытаюсь применить решение , указанное в указанном потоке , я получаю 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"))
        );

Это отображает текст правильно, но полностью нарушает макет, поскольку порты поменялись сторонами, я не знаю почему. Вдобавок ко всему, пространство, видимое между трубами, теперь я вообще не могу согласовать, пытаясь изменить строки loc в конвейере, фактически, ничего, что я делаю со свойствами loc, сейчас вообще ничего не делает. См. Изображение ниже:

enter image description here

Как я могу просто добавить текстовые блоки к этим фигурам, сохранив тот же макет и функциональность?

1 Ответ

1 голос
/ 19 июня 2020

Итак, шаблон трубы в настоящее время имеет такую ​​структуру:

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

Точечные панели имеют один основной элемент (обычно первый дочерний элемент, если вы не укажете его), а затем N других элементов, которые позиционируются на его основе . Итак, как минимум вам нужна такая структура:

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

Итак, вы заменяете Shape на 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

...