goJS dropdown remove items

旧城冷巷雨未停 提交于 2019-12-13 16:24:31

问题


I have simple python flask goJS graph application which looks like this:

Sources for node and link texts are loaded from backend side of app and I set them in model.modelData part like this:

var graphDataString = JSON.parse('{{ diagramData | tojson | safe}}');
myDiagram.model = go.Model.fromJson(graphDataString);
myDiagram.model.set(myDiagram.model.modelData, "linkchoices", JSON.parse('{{ link_choices | tojson | safe}}'));
myDiagram.model.set(myDiagram.model.modelData, "nodechoices", JSON.parse('{{ node_choices | tojson | safe}}'));
console.log("whole model");
console.log(myDiagram.model.modelData);

it all loads fine into modelData and I can write it to console without problems:

My problem is that it doesn't show on my nodes and link dropdowns, and I don't know why.

This is my node template:

myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        // define the node's outer shape, which will surround the TextBlock
        $(go.Shape, "RoundedRectangle",
          {
            parameter1: 20,  // the corner has a large radius
            fill: $(go.Brush, "Linear", { 0: "rgb(254, 201, 0)", 1: "rgb(254, 162, 0)" }),
            stroke: null,
            portId: "",  // this Shape is the Node's port, not the whole Node
            fromLinkable: true, fromLinkableDuplicates: true,
            toLinkable: true, toLinkableDuplicates: true,
            cursor: "pointer"
          }),
        $(go.TextBlock,
          {
            font: "bold 11pt helvetica, bold arial, sans-serif",
            editable: true,  // editing the text automatically updates the model data
            //textEditor: window.TextEditorRadioButtons, // defined in textEditorRadioButtons.js
              // this specific TextBlock has its own choices:
              textEditor: window.TextEditorSelectBox, // defined in extensions/textEditorSelectBox.js
              textEdited: function(tb, oldstr, newstr) {
                var currentNodeChoices = tb.diagram.model.modelData.nodechoices;
                console.log("currentNodeChoices");
                console.log(currentNodeChoices);
                console.log("newstr");
                console.log(newstr);
                console.log("oldstr");
                console.log(oldstr);
                var idx = currentNodeChoices.indexOf(newstr);
                if (idx >= 0 && oldstr !== newstr) {
                  console.log("removing choice " + idx + ": " + newstr);
                  var newNodeChoices = Array.prototype.slice.call(currentNodeChoices);
                  newNodeChoices.splice(idx, 1);
                  tb.diagram.model.set(tb.diagram.model.modelData, "nodechoices", newNodeChoices);
                }
              }
          },
        new go.Binding("text").makeTwoWay(),
        new go.Binding("nodechoices").ofModel())
    ); 

This is my link template:

myDiagram.linkTemplate =
      $(go.Link,  // the whole link panel
        {
          curve: go.Link.Bezier, 
          adjusting: go.Link.Stretch,
          reshapable: true, 
          relinkableFrom: true, 
          relinkableTo: true,
          toShortLength: 3
        },
        new go.Binding("points").makeTwoWay(),
        new go.Binding("curviness"),
        $(go.Shape,  // the link shape
          { strokeWidth: 1.5 }),
        $(go.Shape,  // the arrowhead
          { toArrow: "standard", stroke: null }),
        $(go.Panel, "Auto",
          $(go.Shape,  // the label background, which becomes transparent around the edges
          {
              fill: $(go.Brush, "Radial", { 0: "rgb(240, 240, 240)", 0.3: "rgb(240, 240, 240)", 1: "rgba(240, 240, 240, 0)" }),
                stroke: null
            }),
            $(go.TextBlock,
            {
              background: "white",
              editable: true,
              textEditor: window.TextEditorSelectBox, // defined in extensions/textEditorSelectBox.js
              textEdited: function(tb, oldstr, newstr) {
                var currentLinkChoices = tb.diagram.model.modelData.linkchoices;
                console.log("currentLinkChoices");
                console.log(currentLinkChoices);
                console.log("newstr");
                console.log(newstr);
                console.log("oldstr");
                console.log(oldstr);
                var idx = currentLinkChoices.indexOf(newstr);
                if (idx >= 0 && oldstr !== newstr) {
                  console.log("removing choice " + idx + ": " + newstr);
                  var newLinkChoices = Array.prototype.slice.call(currentLinkChoices);
                  newLinkChoices.splice(idx, 1);
                  tb.diagram.model.set(tb.diagram.model.modelData, "linkchoices", newLinkChoices);
                }
              }
            },
            new go.Binding("text").makeTwoWay(),
            new go.Binding("linkchoices").ofModel())
        )
    );

I want to accomplish this behaviour: User can add new nodes and links but user can only choose available options from dropdown for links and nodes. Adding new nodes and links works fine and I don't have any problems with it. I want to make so that when user uses one option for node, that option is not available again until he deletes that node or change it for some other option.

For example he uses "node_choice_1" he can not use it anymore on any other node until he changes that option on that node or deletes node. Same goes for links. So I added this code to my diagram definition:

myDiagram =
    $(go.Diagram, "myDiagramDiv",  // must name or refer to the DIV HTML element
    {
      // start everything in the middle of the viewport
      initialContentAlignment: go.Spot.Center,
      // have mouse wheel events zoom in and out instead of scroll up and down
      "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,
      // support double-click in background creating a new node
      "clickCreatingTool.archetypeNodeData": { text: "new node" },
      // enable undo & redo
      "textEditingTool.defaultTextEditor": window.TextEditorSelectBox,
      "undoManager.isEnabled": true,
      "layout": new go.ForceDirectedLayout(),
      "ModelChanged": function(e) {
        console.log("Diagram model changed!");
              if (e.change === go.ChangedEvent.Remove && e.modelChange === "linkDataArray") {
                console.log("eee");
                console.log(e);
                var linkdata = e.oldValue;
                console.log("linkdata");
                console.log(linkdata);
                var oldstr = linkdata.text;
                console.log("oldstr");
                console.log(oldstr);

                if (!oldstr) return;
                var currentLinkChoices = e.model.modelData.linkchoices;
                console.log("currentLinkChoices");
                console.log(currentLinkChoices);
                var idx = currentLinkChoices.indexOf(oldstr);
                if (idx < 0) {
                  console.log("adding choice: " + oldstr);
                  var newLinkChoices = Array.prototype.slice.call(currentLinkChoices);
                  newLinkChoices.push(oldstr);
                  e.model.set(e.model.modelData, "linkchoices", newLinkChoices);
                }
              }
              else if(e.change === go.ChangedEvent.Remove && e.modelChange === "nodeDataArray"){
                console.log("eee");
                console.log(e);
                var nodedata = e.oldValue;
                console.log("nodedata");
                console.log(nodedata);
                var oldstr = nodedata.text;
                console.log("oldstr");
                console.log(oldstr);

                if (!oldstr) return;
                var currentNodeChoices = e.model.modelData.nodechoices;
                console.log("currentNodeChoices");
                console.log(currentNodeChoices);
                var idx = currentNodeChoices.indexOf(oldstr);
                if (idx < 0) {
                  console.log("adding choice: " + oldstr);
                  var newNodeChoices = Array.prototype.slice.call(currentNodeChoices);
                  newNodeChoices.push(oldstr);
                  e.model.set(e.model.modelData, "nodechoices", newNodeChoices);
                }

              }
            }
    });

Also, when there are no more available node options for nodes user can not add any more nodes. Same goes for links.

I am getting really desperate because I am trying to make this simple thing to work and I am stuck in place for days. I tried to read documentation, but haven't found anything useful, there are so many documented cases, but no examples for what I need. Any help will be greatly appreciated.


回答1:


I seem to have answered this question before for links, so I took the same code and duplicated it all for nodes. I did improve the textEdited event handler to handle undo/redo, although it's obviously more verbose with all the calls to console.log.

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

  myDiagram =
    $(go.Diagram, "myDiagramDiv",
      {
        initialContentAlignment: go.Spot.Center,
        "undoManager.isEnabled": true,
        "ModelChanged": function(e) {     // just for demonstration purposes,
          if (e.isTransactionFinished) {  // show the model data in the page's TextArea
            document.getElementById("mySavedModel").textContent = e.model.toJson();
          }
          if (e.change === go.ChangedEvent.Remove) {
            if (e.modelChange === "linkDataArray") {
              var linkdata = e.oldValue;
              var oldstr = linkdata.text;
              if (!oldstr) return;
              var linkchoices = e.model.modelData.linkchoices;
              var idx = linkchoices.indexOf(oldstr);
              if (idx < 0) {
                console.log("deletion adding link choice: " + oldstr);
                var newlinkchoices = Array.prototype.slice.call(linkchoices);
                newlinkchoices.push(oldstr);
                e.model.set(e.model.modelData, "linkchoices", newlinkchoices);
              }
            } else if (e.modelChange === "nodeDataArray") {
              var nodedata = e.oldValue;
              var oldstr = nodedata.text;
              if (!oldstr) return;
              var nodechoices = e.model.modelData.nodechoices;
              var idx = nodechoices.indexOf(oldstr);
              if (idx < 0) {
                console.log("deletion adding node choice: " + oldstr);
                var newnodechoices = Array.prototype.slice.call(nodechoices);
                newnodechoices.push(oldstr);
                e.model.set(e.model.modelData, "nodechoices", newnodechoices);
              }
            }
          }
        }
      });

  myDiagram.nodeTemplate =
    $(go.Node, "Auto",
      $(go.Shape,
        { fill: "white", portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer" },
        new go.Binding("fill", "color")),
      $(go.TextBlock,
        {
          margin: 8,
          editable: true,
          textEditor: window.TextEditorSelectBox, // defined in extensions/textEditorSelectBox.js
          textEdited: function(tb, oldstr, newstr) {
            if (oldstr !== newstr) {
              console.log("changing from " + oldstr + " to " + newstr);
              var model = tb.diagram.model;
              var nodechoices = model.modelData.nodechoices;
              if (!nodechoices) {
                nodechoices = [];
                model.set(model.modelData, "nodechoices", nodechoices);
              }
              var idx = nodechoices.indexOf(newstr);
              if (idx >= 0) {
                console.log("removing node choice " + idx + ": " + newstr);
                model.removeArrayItem(nodechoices, idx);
              }
              if (oldstr) {
                console.log("  adding node choice " + oldstr);
                model.addArrayItem(nodechoices, oldstr);
              }
            }
          }
        },
        new go.Binding("text").makeTwoWay(),
        new go.Binding("choices", "nodechoices").ofModel())
    );

  myDiagram.linkTemplate =
    $(go.Link,
      $(go.Shape),
      $(go.Shape, { toArrow: "OpenTriangle" }),
      $(go.TextBlock,
        {
          background: "white",
          editable: true,
          textEditor: window.TextEditorSelectBox, // defined in extensions/textEditorSelectBox.js
          textEdited: function(tb, oldstr, newstr) {
            if (oldstr !== newstr) {
              console.log("changing from " + oldstr + " to " + newstr);
              var model = tb.diagram.model;
              var linkchoices = model.modelData.linkchoices;
              if (!linkchoices) {
                linkchoices = [];
                model.set(model.modelData, "linkchoices", linkchoices);
              }
              var idx = linkchoices.indexOf(newstr);
              if (idx >= 0) {
                console.log("removing link choice " + idx + ": " + newstr);
                model.removeArrayItem(linkchoices, idx);
              }
              if (oldstr) {
                console.log("  adding link choice " + oldstr);
                model.addArrayItem(linkchoices, oldstr);
              }
            }
          }
        },
        new go.Binding("text").makeTwoWay(),
        new go.Binding("choices", "linkchoices").ofModel())
    );

  myDiagram.model = new go.GraphLinksModel(
  [
    { key: 1, text: "Alpha", color: "lightblue" },
    { key: 2, text: "Beta", color: "orange" },
    { key: 3, text: "Gamma", color: "lightgreen" },
    { key: 4, text: "Delta", color: "pink" }
  ],
  [
    { from: 1, to: 2, text: "one" },
    { from: 1, to: 3, text: "two" },
    { from: 3, to: 4, text: "three" }
  ]);
  myDiagram.model.set(myDiagram.model.modelData, "nodechoices", ["Epsilon"]);
  myDiagram.model.set(myDiagram.model.modelData, "linkchoices", ["four"]);
}


来源:https://stackoverflow.com/questions/48891610/gojs-dropdown-remove-items

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!