0

我正在使用 yFiles 开发动态图形编辑器。这意味着用户可以从菜单中选择新节点并将它们拖到图形区域中。但是,我希望我的图表在 x 轴上的大小有限。也就是说,图形应该是可扩展的,垂直方向没有限制,但要保持最大宽度。我完全不知道这样做的方式,所以定义图形的最大宽度。

我想在这个演示中有一个像橙色矩形一样的最终效果。在那里,PositionHandler使用了a,但我不知道如何集成它。

不知道它是否有任何帮助,但这是我定义图形交互部分的片段。

'createEditorMode': function() {
    var /** yfiles.input.GraphSnapContext */ snapContext = new yfiles.input.GraphSnapContext();
    snapContext.enabled = false;
    snapContext.nodeGridConstraintProvider = new yfiles.input.SimpleGridConstraintProvider /** .<yfiles.graph.INode> */.FromGridInfo(this.gridInfo);
    snapContext.bendGridConstraintProvider = new yfiles.input.SimpleGridConstraintProvider /** .<yfiles.graph.IBend> */.FromGridInfo(this.gridInfo);
    snapContext.portGridConstraintProvider = new yfiles.input.SimpleGridConstraintProvider /** .<yfiles.graph.IPort> */.FromGridInfo(this.gridInfo);

    var graph = this.graphControl.graph;

    var /** yfiles.input.GraphEditorInputMode */ mode = new yfiles.input.GraphEditorInputMode();
    mode.snapContext = snapContext;
    mode.edgeCreationAllowed = false; //only one edge create
    mode.marqueeSelectionInputMode.enabled = true; //block selection
    mode.nodeCreator = null;

    var /** yfiles.input.OrthogonalEdgeEditingContext */ newOrthogonalEdgeEditingContext = new yfiles.input.OrthogonalEdgeEditingContext();
    newOrthogonalEdgeEditingContext.orthogonalEdgeEditing = true;

    mode.createEdgeInputMode.orthogonalEdgeCreation = true; //Enable edges' creation in orthogonal mode
    mode.orthogonalEdgeEditingContext = newOrthogonalEdgeEditingContext;
    mode.createBendModePriority = mode.moveModePriority - 1;// add a context// menu
    mode.clickSelectableItems = yfiles.graph.GraphItemTypes.NODE | yfiles.graph.GraphItemTypes.EDGE;
    mode.labelAddingAllowed = false;
    mode.labelEditingAllowed = false;
    mode.clipboardOperationsAllowed  = false;
    mode.undoOperationsAllowed = true;
    //mode.undoOperationsAllowed = false;
    mode.addItemClickedListener(yfiles.lang.delegate(this.onItemClicked, this));
    mode.addItemDoubleClickedListener(yfiles.lang.delegate(this.onItemDoubleClicked, this));

    this.contextMenu = new demo.ContextMenu();
    mode.contextMenuInputMode.menu = this.contextMenu;
    this.contextMenu.install(this.graphControl.div);
    this.contextMenu.addOpenedListener(function( /** Object */
        sender, /** yfiles.system.EventArgs */
        args) {
            var /** yfiles.system.CancelEventArgs */ cancelEventArgs = new yfiles.system.CancelEventArgs();
            mode.contextMenuInputMode.menuOpening(cancelEventArgs);
            if (cancelEventArgs.cancel) {
                (( /** @type {demo.ContextMenu} */ (sender))).visible = false;
            }
        }
    );
    this.contextMenu.addClosedListener(function( /** Object */ sender, /** yfiles.system.EventArgs */ args) {
        mode.contextMenuInputMode.menuClosed();
    });
    mode.contextMenuInputMode.addCloseMenuListener((function( /** Object */ o, /** yfiles.system.EventArgs */ args) {
        this.contextMenu.visible = false;
    }).bind(this));
    mode.contextMenuInputMode.addPopulateContextMenuListener(yfiles.lang.delegate(this.onPopulateContextMenu, this));
    return mode;
},
4

1 回答 1

2

(旁注:如果您的 yFiles 许可证有有效的支持订阅,您可以询问我们的支持团队。虽然我们有时会在 Stack Overflow 上闲逛,但这并不是获得支持的最佳方式。)


实际上,这其中涉及到一些事情。首先,默认情况下,yFiles 对图形的延伸范围没有任何限制,尽管我相当确定坐标在 210 万左右时会变得很奇怪。因此,要确保图形的最大宽度需要您更改许多不同的方面:

  1. 防止用户将节点放置在错误的位置

    您可能在某处有一个NodeDropInputMode,即使我在您的配置中没有看到它。NodeDropInputMode 有一个validDropHitTestable属性,它定义了可以删除节点的位置。您可以简单地禁止在 x 坐标处放置超出您想要允许的范围。

    稍微复杂一点的过程会在拖动手势期间将 x 坐标钳制为有效值。您可以通过继承 NodeDropInputMode 并相应地覆盖setDragLocation方法来实现。这也将确保预览“坚持”到最大 x 位置,即使鼠标指针超出该位置,而不是仅仅禁止放置。

  2. 防止用户将节点移动到边界之外

    可以使用自定义IPositionHandler自定义节点移动。您可以在输入演示中找到如何执行此操作的示例(实际上是一个非常相似的示例)

  3. 防止用户调整节点大小以使其超出范围

    调整大小的限制类似于节点移动,尽管在通过IReshapeHandleProvider创建句柄的位置。还有一个演示也显示了这一点。

  4. 确保自动布局仅限于特定区域

    并非所有布局算法都能够做到这一点。事实上,只有我们的有机布局才能设置合适的输出限制,将布局强制为矩形。

  5. 一堆其他的小东西

    必须通过合适的手柄来防止用户将弯道移动到边界之外,并装饰有弯道

    可以通过适当的标签布局模型来限制标签​​移动。

    通过将GEIM上的 pasteDelta 设置为 (0, 0)可以最简单地确保复制/粘贴或复制不会将创建的项目放置在边界之外(它们通常以轻微的偏移量创建)。

    ViewportLimiter可用于防止用户将视口移离图形太远。

    可能还有其他我错过的地方可能会将物品或其中的一部分放在你的范围之外。

于 2017-04-19T07:17:16.113 回答