如何在移动顶点时重新调整 mxgraph 边缘以使其看起来不奇怪?

How to readjust mxgraph edges while moving vertices to not look weird?

我需要允许用户重新排列图形,并且需要在移动顶点时重新调整边。现在我还做不好

我目前的情况是这样的:

边缘调整奇怪的图表:

但我希望他们是这样的:

边缘调整得很好的图表:

第二张图的XML代码是:

    <mxGraphModel dx="774" dy="824" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100">
      <root>
        <mxCell id="0"/>
        <mxCell id="1" parent="0"/>
        <mxCell id="4" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;targetPerimeterSpacing=8;sourcePerimeterSpacing=8;strokeColor=#aaaaaa;strokeWidth=2;curved=1;" edge="1" parent="1" source="2" target="3">
          <mxGeometry relative="1" as="geometry"/>
        </mxCell>
        <mxCell id="2" value="Product" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8b241;gradientColor=#e97704;gradientDirection=south;fontStyle=1;fontColor=#FFFFFF;strokeColor=#ea7703;" vertex="1" parent="1">
          <mxGeometry x="80" y="33" width="116" height="26" as="geometry"/>
        </mxCell>
        <mxCell id="6" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;targetPerimeterSpacing=8;sourcePerimeterSpacing=8;strokeColor=#aaaaaa;strokeWidth=2;curved=1;" edge="1" parent="1" source="3" target="5">
          <mxGeometry relative="1" as="geometry"/>
        </mxCell>
        <mxCell id="10" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;targetPerimeterSpacing=8;sourcePerimeterSpacing=8;strokeColor=#aaaaaa;strokeWidth=2;curved=1;" edge="1" parent="1" source="3" target="9">
          <mxGeometry relative="1" as="geometry"/>
        </mxCell>
        <mxCell id="3" value="Order_line" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8b241;gradientColor=#e97704;gradientDirection=south;fontStyle=1;fontColor=#FFFFFF;strokeColor=#ea7703;" vertex="1" parent="1">
          <mxGeometry x="280" y="216" width="116" height="26" as="geometry"/>
        </mxCell>
        <mxCell id="12" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;targetPerimeterSpacing=8;sourcePerimeterSpacing=8;strokeColor=#aaaaaa;strokeWidth=2;curved=1;" edge="1" parent="1" source="9" target="11">
          <mxGeometry relative="1" as="geometry"/>
        </mxCell>
        <mxCell id="9" value="New_1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8b241;gradientColor=#e97704;gradientDirection=south;fontStyle=1;fontColor=#FFFFFF;strokeColor=#ea7703;" vertex="1" parent="1">
          <mxGeometry x="460" y="190" width="116" height="26" as="geometry"/>
        </mxCell>
        <mxCell id="14" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;targetPerimeterSpacing=8;sourcePerimeterSpacing=8;strokeColor=#aaaaaa;strokeWidth=2;curved=1;" edge="1" parent="1" source="11" target="13">
          <mxGeometry relative="1" as="geometry"/>
        </mxCell>
        <mxCell id="11" value="New_2" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8b241;gradientColor=#e97704;gradientDirection=south;fontStyle=1;fontColor=#FFFFFF;strokeColor=#ea7703;" vertex="1" parent="1">
          <mxGeometry x="530" y="20" width="116" height="26" as="geometry"/>
        </mxCell>
        <mxCell id="13" value="New_3" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8b241;gradientColor=#e97704;gradientDirection=south;fontStyle=1;fontColor=#FFFFFF;strokeColor=#ea7703;" vertex="1" parent="1">
          <mxGeometry x="680" y="126" width="116" height="26" as="geometry"/>
        </mxCell>
        <mxCell id="8" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;targetPerimeterSpacing=8;sourcePerimeterSpacing=8;strokeColor=#aaaaaa;strokeWidth=2;curved=1;" edge="1" parent="1" source="5" target="7">
          <mxGeometry relative="1" as="geometry"/>
        </mxCell>
        <mxCell id="5" value="Order" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8b241;gradientColor=#e97704;gradientDirection=south;fontStyle=1;fontColor=#FFFFFF;strokeColor=#ea7703;" vertex="1" parent="1">
          <mxGeometry x="80" y="100" width="116" height="26" as="geometry"/>
        </mxCell>
        <mxCell id="7" value="Customer" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8b241;gradientColor=#e97704;gradientDirection=south;fontStyle=1;fontColor=#FFFFFF;strokeColor=#ea7703;" vertex="1" parent="1">
          <mxGeometry x="10" y="260" width="116" height="26" as="geometry"/>
        </mxCell>
      </root>
    </mxGraphModel>

但我无法用 TS 代码翻译它:-(

因为我将它与 Angular 和 TS 一起使用,所以在 Plunker 中创建一些东西来提供帮助有点棘手,但我拥有的是一个像这样初始化图形的组件:

    declare var require: any;

    const mx = require('mxgraph')({
      mxImageBasePath: 'assets/mxgraph/images',
      mxBasePath: 'assets/mxgraph',
    });


    const container = document.getElementById('graphContainer');
    this.graph = new mx.mxGraph(container);

So I start editing it, as you can see here:

    try {
      const parent = this.graph.getDefaultParent();
      this.graph.getModel().beginUpdate();

      const defaultVertexStyle = this.graph.stylesheet.getDefaultVertexStyle();
      defaultVertexStyle[mx.mxConstants.STYLE_SHAPE] = mx.mxConstants.SHAPE_LABEL;
      defaultVertexStyle[mx.mxConstants.STYLE_PERIMETER] = mx.mxConstants.PERIMETER_RECTANGLE;
      defaultVertexStyle[mx.mxConstants.STYLE_FONTSIZE] = 12;
      defaultVertexStyle[mx.mxConstants.STYLE_FONTFAMILY] = 'Helvetica';
      defaultVertexStyle[mx.mxConstants.STYLE_ALIGN] = mx.mxConstants.ALIGN_CENTER;
      defaultVertexStyle[mx.mxConstants.STYLE_VERTICAL_ALIGN] = mx.mxConstants.ALIGN_MIDDLE;
      defaultVertexStyle[mx.mxConstants.STYLE_FILLCOLOR] = '#f8b241';
      defaultVertexStyle[mx.mxConstants.STYLE_GRADIENTCOLOR] = '#e97704';
      defaultVertexStyle[mx.mxConstants.STYLE_STROKECOLOR] = '#ea7703';
      defaultVertexStyle[mx.mxConstants.STYLE_FONTCOLOR] = '#ffffff';
      defaultVertexStyle[mx.mxConstants.STYLE_FONTSIZE] = 14;
      defaultVertexStyle[mx.mxConstants.STYLE_ROUNDED] = true;

      const defaultEdgeStyle = this.graph.stylesheet.getDefaultEdgeStyle();
      defaultEdgeStyle[mx.mxConstants.STYLE_SHAPE] = mx.mxConstants.SHAPE_CONNECTOR;
      defaultEdgeStyle[mx.mxConstants.STYLE_FONTSIZE] = 12;
      defaultEdgeStyle[mx.mxConstants.STYLE_FONTFAMILY] = 'Helvetica';
      defaultEdgeStyle[mx.mxConstants.STYLE_ALIGN] = mx.mxConstants.ALIGN_CENTER;
      defaultEdgeStyle[mx.mxConstants.STYLE_VERTICAL_ALIGN] = mx.mxConstants.ALIGN_MIDDLE;
      defaultEdgeStyle[mx.mxConstants.STYLE_ROUNDED] = 1;
      defaultEdgeStyle[mx.mxConstants.STYLE_STARTARROW] = mx.mxConstants.ARROW_CLASSIC;
      defaultEdgeStyle[mx.mxConstants.STYLE_STARTSIZE] = 8;
      defaultEdgeStyle[mx.mxConstants.STYLE_ENDARROW] = mx.mxConstants.ARROW_CLASSIC;
      defaultEdgeStyle[mx.mxConstants.STYLE_ENDSIZE] = 8;
      defaultEdgeStyle[mx.mxConstants.STYLE_STROKECOLOR] = '#aaaaaa';

      let product = graph.insertVertex(parent,'Product','Product',0,0,120,20);
      let orderLine = graph.insertVertex(parent,'Order_Line','Order_Line',0,0,120,20);
      let order = graph.insertVertex(parent,'Order','Order',0,0,120,20);
      let customer = graph.insertVertex(parent,'Customer','Customer',0,0,120,20);
      let new1 = graph.insertVertex(parent,'new1','new1',0,0,120,20);

      graph.insertEdge(parent, '1', '', product, orderLine);
      graph.insertEdge(parent, '2', '', orderLine, order);
      graph.insertEdge(parent, '3', '', order, customer);
      graph.insertEdge(parent, '4', '', orderLine, new1);

      const layout = new mx.mxHierarchicalLayout(this.graph, mx.mxConstants.DIRECTION_NORTH);
      layout.execute(graph.getDefaultParent());
    } finally {
      this.graph.getModel().endUpdate();
    }

结果就是你在上面第一张图片中看到的。 (Graph with edges weirdly adjusted)

你能帮我实现我们在第二张图片 (Graph with edges nicely adjusted) 中看到的效果吗?

编辑 1: 不幸的是,即使我使用与 XML 文件中相同的样式,它也不会像 demo/showcase 中那样重新排列边缘,我已经尝试过了:

graph.insertEdge(
                parent,
                `${getId()}`,
                '',
                source,
                target, 
 'edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;targetPerimeterSpacing=8;sourcePerimeterSpacing=8;strokeColor=#aaaaaa;strokeWidth=2;curved=1;'
              );

结果:

编辑 2:

虽然它没有在我的代码上工作,但在这个 CodePen 上它正在工作:https://codepen.io/palerique/pen/povEEVY

所以现在我认为我调用的这个布局 class 可能会改变样式并导致这种不良行为。

有没有不改变边缘样式的布局class?

you should realize custom edges paintEdgeShape定义了边缘的渲染,你使用canvas API to define that drawing. Look example.

为了解决长路径问题,我建议创建函数来计算点之间的最近路径并绘制。

                NewShape.prototype.paintEdgeShape = function(c, pts)
                {
                    // calculate nearest path and draw
                };

@PauloRodrigues 有趣,但你的决定已经受到质疑!

只需 insertEdge 使用此样式参数 edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;targetPerimeterSpacing=8;sourcePerimeterSpacing=8;strokeColor=#aaaaaa;strokeWidth=2;curved=1;

致电insertEdge(parent,id,value,source,target, yourStyle)

它会像: graph.insertEdge(parent, null, '', mxCell, mxCell,'edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;targetPerimeterSpacing=8;sourcePerimeterSpacing=8;strokeColor=#aaaaaa;strokeWidth=2;curved=1;');