Как исправить привязку свойства «местоположение» элементов-членов в группе в палитре?

#javascript #gojs

#javascript #gojs

Вопрос:

Я настраивал проект планировщика этажей из GoJS и хочу создать свой собственный настраиваемый элемент (сгруппированные элементы) в области палитры. Я смог сгенерировать элемент, но элементы внутри группы не реагируют на карту шаблона узла, которую я настроил, как показано на скриншоте ниже: введите описание изображения здесь

Чего я ожидал, так это иметь сгруппированный элемент, подобный этому:

введите описание изображения здесь

Вот как я настраиваю свои карты шаблонов:

Для синих линий

 function makeBlueLine() {
    var $ = go.GraphObject.make;
    return $(go.Node, "Auto",
    {
        contextMenu: makeContextMenu(),
        selectionObjectName: "SHAPE",
        selectionAdorned: false,
        resizeAdornmentTemplate: makeWallPartResizeAdornment(),
        locationSpot: go.Spot.Left,
        toolTip: makeNodeToolTip(),
        resizable: true,
        resizeObjectName: "SHAPE",
        rotatable: true,
        doubleClick: function (e) { if (e.diagram.floorplanUI) e.diagram.floorplanUI.hideShow("selectionInfoWindow"); },
    },
    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
    new go.Binding("visible", "showOnPlan"),
    new go.Binding("angle", "angle"),
    $(go.Shape,
    { name: "SHAPE", fill: "blue", stroke: "#000", strokeWidth: 1, height: 1, figure: "Rectangle" },
    new go.Binding("width", "length").makeTwoWay(),
    new go.Binding("stroke", "isSelected", function (s, obj) {
                return s ? "green" : "blue";
            }).ofObject(),
    ),
  );
}
  

Для группы

 function makeLineContainer() {
    var $ = go.GraphObject.make;
    return $(go.Group, "Vertical",
        {
            //isSubGraphExpanded: false,
            contextMenu: makeContextMenu(),
            doubleClick: function (e) {
                if (e.diagram.floorplanUI) e.diagram.floorplanUI.hideShow("selectionInfoWindow");
            },
            toolTip: makeGroupToolTip()
        },
        new go.Binding("location", "loc"),
          $(go.Panel, "Auto",
            $(go.Shape, "RoundedRectangle", { fill: "rgba(0,0,0,0)", stroke: null, name: 'SHAPE', strokeCap: 'square' },
              new go.Binding("fill", "isSelected", function (s, obj) {
                  return s ? "rgba(128, 128, 128, 0.10)" : "rgba(0,0,0,0)";
              }).ofObject()
              ),
            $(go.Placeholder, { padding: 5 })
          )
        )
}
  

Это моя настройка массива модели:

 BLUE_LINE_DATA_ARRAY = [
    {
        category: "LineParent",
        key: "Type1",
        isGroup: true,
    },
    {
        category: "BlueLine",
        group: "Type1",
        loc: '0 0',
        angle: 90,
        length: 50,
        key: "G1",
    },
    {
        category: "BlueLine",
        group: "Type1",
        loc: '10 10',
        angle: 0,
        length: 50,
        key: "G2",
    },  
];
  

Для инициализации палитры я не внес никаких изменений, кроме добавления карты шаблона группы. Вот сопоставление шаблона, которое я сделал:

 this.nodeTemplateMap.add("BlueLine", makeBlueLine());
this.groupTemplateMap.add("LineParent", makeLineContainer());
  

Я не смог найти то, чего мне не хватает. Я также проверил на macros.html пример, и все выглядит аналогично.

Ответ №1:

Я только что попытался реализовать такой образец, но не смог столкнуться с какими-либо проблемами с группами в палитре. Вот мой код:

 <!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
  <script src="go.js"></script>

  <script>
    function init() {
      var $ = go.GraphObject.make;

      // initialize main Diagram
      myDiagram =
        $(go.Diagram, "myDiagramDiv",
          { "undoManager.isEnabled": true });

      myDiagram.nodeTemplate =
        $(go.Node, "Auto",
          new go.Binding("location", "location", go.Point.parse).makeTwoWay(go.Point.stringify),
          $(go.Shape,
            { fill: "white", stroke: "gray", strokeWidth: 2 },
            new go.Binding("stroke", "color")),
          $(go.TextBlock,
            { margin: 4 },
            new go.Binding("text").makeTwoWay())
        );

      // initialize Palette
      myPalette =
        $(go.Palette, "myPaletteDiv",
          { nodeTemplateMap: myDiagram.nodeTemplateMap });

      myPalette.model.nodeDataArray = [
        { key: 1, group: 3, text: "blue node", color: "blue", location: "30 0" },
        { key: 2, group: 3, text: "orange node", color: "orange", location: "0 40" },
        { key: 3, isGroup: true, text: "GROUP" }
      ];

      // initialize Overview
      myOverview =
        $(go.Overview, "myOverviewDiv",
          { observed: myDiagram, contentAlignment: go.Spot.Center });

      load();
    }

    // save a model to and load a model from Json text, displayed below the Diagram
    function save() {
      var str = myDiagram.model.toJson();
      document.getElementById("mySavedModel").value = str;
    }
    function load() {
      var str = document.getElementById("mySavedModel").value;
      myDiagram.model = go.Model.fromJson(str);
    }
  </script>
</head>
<body onload="init()">
  <div style="width: 100%; display: flex; justify-content: space-between">
    <div style="display: flex; flex-direction: column; margin: 0 2px 0 0">
      <div id="myPaletteDiv" style="flex-grow: 1; width: 120px; background-color: whitesmoke; border: solid 1px black"></div>
      <div id="myOverviewDiv" style="margin: 2px 0 0 0; width: 120px; height: 100px; background-color: lightgray; border: solid 1px black"></div>
    </div>
    <div id="myDiagramDiv" style="flex-grow: 1; height: 400px; border: solid 1px black"></div>
  </div>
  <div id="buttons">
    <button id="loadModel" onclick="load()">Load</button>
    <button id="saveModel" onclick="save()">Save</button>
  </div>
  <textarea id="mySavedModel" style="width:100%;height:200px">
{ "class": "go.GraphLinksModel",
  "nodeDataArray": [
{"key":1, "text":"hello", "color":"green", "location":"0 0"},
{"key":2, "text":"world", "color":"red", "location":"70 0"}
  ],
  "linkDataArray": [
{"from":1, "to":2}
  ]}
  </textarea>
</body>
</html>
  

Обратите внимание, как группа отображается в палитре, и когда копия удаляется на главной диаграмме. Каждый из двух узлов-членов расположен в соответствии с привязкой, и они остаются в этом относительном местоположении, пока пользователь не переместит узел-член на главной диаграмме.

Комментарии:

1. Спасибо за ваш ответ, Уолтер. Да, я также пытался изменить Macros.html образец, который поставляется с загружаемым GoJS, и он отлично работает, как и предполагалось. Просто в примере планировщика этажей он действует по-другому. Я пытался отключить прослушиватели и вызовы пользовательских методов, но все еще безуспешно. Могло ли это быть связано с тем, как палитра объявлена в планировщике этажа? Это единственное, что я могу найти, которое было реализовано по-разному в примере, который вы предоставили, и с Macros.html пример.

Ответ №2:

Попытался изучить это еще немного, но, к сожалению, я все еще не нашел окончательной причины проблемы. Тем не менее, я нашел обходной путь, но это будет стоить мне возможности иметь несколько палитр для планировщика этажей. Итак, в основном, я изменил конструктор палитры пакета floor planner, чтобы следовать шаблону образцов для палитры, найденных на веб-сайте GoJS.

Как это было объявлено первым:

 function FloorplanPalette(div, floorplan, nodeDataArray) {
    go.Palette.call(this, div);

    var $ = go.GraphObject.make;
    this.model = $(go.GraphLinksModel, { nodeDataArray: nodeDataArray });
    this.contentAlignment = go.Spot.Center;
    this.nodeTemplateMap = floorplan.nodeTemplateMap;
    this.groupTemplateMap = floorplan.groupTemplateMap;
    this.toolManager.contextMenuTool.isEnabled = false;

    // add this new FloorplanPalette to the "palettes" field of its associated Floorplan
    floorplan.palettes.push(this);
} go.Diagram.inherit(FloorplanPalette, go.Palette);
  

Мое изменение:

 function FloorplanPalette(div, floorplan, nodeDataArray) {
    var $ = go.GraphObject.make;
    myPalette =
    $(go.Palette, div,  // must name or refer to the DIV HTML element
        {
        nodeTemplateMap: floorplan.nodeTemplateMap,
        groupTemplateMap: floorplan.groupTemplateMap,
        contentAlignment: go.Spot.Center,
        });

    myPalette.model = new go.GraphLinksModel(nodeDataArray);
}