label - 顶点约束和连接到 mxgraph 中的约束的边
问题描述
我正在使用 mxgraph(javascript 版本)来绘制图表。我正在使用正交EdgeStyle 和radialTreeLayout。我有两个问题:
- 几条边从同一个源连接点开始。此外,多个边进入同一个目标连接点。我需要的是每条边都在唯一的连接点开始和结束。我使用顶点的连接点(约束),您可以通过将鼠标悬停在顶点上来查看约束。但是,我不知道如何让radialTreeLayout 自动将边缘连接到唯一约束。我知道我可以在 insertEdge 方法的样式部分使用 entryX、entryY、exitX、exitY。但是,这无济于事,因为我需要布局自动将边缘连接到适当的约束(连接点)。如果可以在不使用约束的情况下实现这一点,我也很好。如果这是不可能的,任何人都可以告诉我如何找到顶点和约束点之间的距离,
- 我对边缘使用“curved=1”,这是我需要的。但是,副作用是边缘标签偏离边缘线。当曲线尺寸较大时,这一点尤其明显。有什么方法可以让标签贴在边缘线上,同时保持“curved=1”
您可以在以下笔中看到我的代码
笔的相同代码如下:
<html>
<head>
<title>Port References Example</title>
<!-- JQuery -->
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script type="text/javascript">
mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
</script>
<!-- Loads and initializes the library -->
<script type="text/javascript" src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js">
</script>
<!-- Example code -->
<script type="text/javascript">
function main(container)
{
// Replaces the port image
//mxConstraintHandler.prototype.pointImage = new mxImage('images/dot.gif', 10, 10);
var graph = new mxGraph(container);
graph.setConnectable(true);
// Disables automatic handling of ports. This disables the reset of the
// respective style in mxGraph.cellConnected. Note that this feature may
// be useful if floating and fixed connections are combined.
graph.setPortsEnabled(false);
// Enables rubberband selection
new mxRubberband(graph);
// Gets the default parent for inserting new cells. This
// is normally the first child of the root (ie. layer 0).
var parent = graph.getDefaultParent();
// Ports are equal for all shapes...
var ports = new Array();
// NOTE: Constraint is used later for orthogonal edge routing (currently ignored)
ports['w'] = {x: 0, y: 0.5, perimeter: true, constraint: 'west'};
ports['e'] = {x: 1, y: 0.5, perimeter: true, constraint: 'east'};
ports['n'] = {x: 0.5, y: 0, perimeter: true, constraint: 'north'};
ports['s'] = {x: 0.5, y: 1, perimeter: true, constraint: 'south'};
ports['nw'] = {x: 0, y: 0, perimeter: true, constraint: 'north west'};
ports['ne'] = {x: 1, y: 0, perimeter: true, constraint: 'north east'};
ports['sw'] = {x: 0, y: 1, perimeter: true, constraint: 'south west'};
ports['se'] = {x: 1, y: 1, perimeter: true, constraint: 'south east'};
// ... except for triangles
var ports2 = new Array();
// NOTE: Constraint is used later for orthogonal edge routing (currently ignored)
ports2['in1'] = {x: 0, y: 0, perimeter: true, constraint: 'west'};
ports2['in2'] = {x: 0, y: 0.25, perimeter: true, constraint: 'west'};
ports2['in3'] = {x: 0, y: 0.5, perimeter: true, constraint: 'west'};
ports2['in4'] = {x: 0, y: 0.75, perimeter: true, constraint: 'west'};
ports2['in5'] = {x: 0, y: 1, perimeter: true, constraint: 'west'};
ports2['out1'] = {x: 0.5, y: 0, perimeter: true, constraint: 'north east'};
ports2['out2'] = {x: 1, y: 0.5, perimeter: true, constraint: 'east'};
ports2['out3'] = {x: 0.5, y: 1, perimeter: true, constraint: 'south east'};
// Extends shapes classes to return their ports
mxShape.prototype.getPorts = function()
{
return ports;
};
mxTriangle.prototype.getPorts = function()
{
return ports2;
};
// Disables floating connections (only connections via ports allowed)
graph.connectionHandler.isConnectableCell = function(cell)
{
return false;
};
mxEdgeHandler.prototype.isConnectableCell = function(cell)
{
return graph.connectionHandler.isConnectableCell(cell);
};
// Disables existing port functionality
graph.view.getTerminalPort = function(state, terminal, source)
{
return terminal;
};
// Returns all possible ports for a given terminal
graph.getAllConnectionConstraints = function(terminal, source)
{
if (terminal != null && terminal.shape != null &&
terminal.shape.stencil != null)
{
// for stencils with existing constraints...
if (terminal.shape.stencil != null)
{
return terminal.shape.stencil.constraints;
}
}
else if (terminal != null && this.model.isVertex(terminal.cell))
{
if (terminal.shape != null)
{
var ports = terminal.shape.getPorts();
var cstrs = new Array();
for (var id in ports)
{
var port = ports[id];
var cstr = new mxConnectionConstraint(new mxPoint(port.x, port.y), port.perimeter);
cstr.id = id;
cstrs.push(cstr);
}
return cstrs;
}
}
return null;
};
// Sets the port for the given connection
graph.setConnectionConstraint = function(edge, terminal, source, constraint)
{
if (constraint != null)
{
var key = (source) ? mxConstants.STYLE_SOURCE_PORT : mxConstants.STYLE_TARGET_PORT;
if (constraint == null || constraint.id == null)
{
this.setCellStyles(key, null, [edge]);
}
else if (constraint.id != null)
{
this.setCellStyles(key, constraint.id, [edge]);
}
}
};
// Returns the port for the given connection
graph.getConnectionConstraint = function(edge, terminal, source)
{
var key = (source) ? mxConstants.STYLE_SOURCE_PORT : mxConstants.STYLE_TARGET_PORT;
var id = edge.style[key];
if (id != null)
{
var c = new mxConnectionConstraint(null, null);
c.id = id;
return c;
}
return null;
};
// Returns the actual point for a port by redirecting the constraint to the port
graphGetConnectionPoint = graph.getConnectionPoint;
graph.getConnectionPoint = function(vertex, constraint)
{
if (constraint.id != null && vertex != null && vertex.shape != null)
{
var port = vertex.shape.getPorts()[constraint.id];
if (port != null)
{
constraint = new mxConnectionConstraint(new mxPoint(port.x, port.y), port.perimeter);
}
}
return graphGetConnectionPoint.apply(this, arguments);
};
// Adds cells to the model in a single step
graph.getModel().beginUpdate();
try
{
var v1 = graph.insertVertex(parent, null, 'A', 0, 0, 80, 80);
var v2 = graph.insertVertex(parent, null, 'B', 0, 0, 80, 80,'shape=ellipse;perimeter=ellipsePerimeter');
var v3 = graph.insertVertex(parent, null, 'C', 0, 0, 80, 80,'shape=triangle;perimeter=trianglePerimeter;');
var v4 = graph.insertVertex(parent, null, 'C', 0, 0, 80, 80,'shape=triangle;perimeter=trianglePerimeter;');
var v5 = graph.insertVertex(parent, null, 'C', 0, 0, 80, 80,'shape=triangle;perimeter=trianglePerimeter;');
var e1 = graph.insertEdge(parent, null, 'AAA', v1, v2, 'startArrow=none;strokeWidth=1;labelBackgroundColor=white;fontStyle=1;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startFill=1;curved=1;');
var e2 = graph.insertEdge(parent, null, 'BBB', v1, v3, 'startArrow=none;strokeWidth=1;labelBackgroundColor=white;fontStyle=1;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startFill=1;curved=1;');
var e3 = graph.insertEdge(parent, null, 'CCC', v1, v4, 'startArrow=none;strokeWidth=1;labelBackgroundColor=white;fontStyle=1;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startFill=1;curved=1;');
var e4 = graph.insertEdge(parent, null, 'DDD', v1, v5, 'startArrow=none;strokeWidth=1;labelBackgroundColor=white;fontStyle=1;edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;startFill=1;curved=1;');
radialLayout = new mxRadialTreeLayout(graph);
radialLayout.nodeDistance=200;
radialLayout.levelDistance=150;
radialLayout.execute(parent);
}
finally
{
// Updates the display
graph.getModel().endUpdate();
}
// Coming soon... Integration with orthogonal edge style
// Sets default edge style to use port constraints (needs to be moved up when uncommented)
//graph.getStylesheet().getDefaultEdgeStyle()['edgeStyle'] = 'orthogonalEdgeStyle';
/*var mxUtilsGetPortConstraints = mxUtils.getPortConstraints;
mxUtils.getPortConstraints = function(terminal, edge, source, defaultValue)
{
var key = (source) ? mxConstants.STYLE_SOURCE_PORT : mxConstants.STYLE_TARGET_PORT;
var id = edge.style[key];
var port = terminal.shape.getPorts()[id];
// TODO: Add support for rotation, direction
if (port != null)
{
return port.constraint;
}
return mxUtilsGetPortConstraints.apply(this, arguments);
};
// Connect preview
graph.connectionHandler.createEdgeState = function(me)
{
var edge = graph.createEdge(null, null, null, null, null);
return new mxCellState(this.graph.view, edge, this.graph.getCellStyle(edge));
};
*/
};
</script>
</head>
<body onload="main(document.getElementById('graphContainer'))">
<div id="graphContainer"
style="overflow:auto;position:relative;width:100%;height:541px;background:url('editors/images/grid.gif');cursor:default;">
</div>
</body>
</html>
解决方案
推荐阅读
- r - R. Excel 读取更改列类型
- ansible - 如何在jinja ansible的列表中附加项目索引
- google-sheets - 如何仅对几个单元格(不是范围)中的正数求和?
- django - 如何在模型验证器 django 中访问 self
- c# - 如何在使用 Puppeteer Sharp 加载 javascript 后获取页面源?
- mysql - 具有 3 个表、左连接和计数的 MySQL
- c# - 特征列“ImagePath”的 ML.Net 架构不匹配:预期 VarVector
,得到字符串 - javascript - 'this' node 和 v8 chrome 中的不同行为
- bioconductor - 为什么函数plotSex在编织时出错?
- c# - 在 C# 中创建导出函数并使用 csc.exe 进行编译