如何在移动顶点时重新调整 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;');
我需要允许用户重新排列图形,并且需要在移动顶点时重新调整边。现在我还做不好
我目前的情况是这样的:
边缘调整奇怪的图表:
但我希望他们是这样的:
边缘调整得很好的图表:
第二张图的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;');