概述
mxGraph是一个JS绘图组件适用于需要在网页中设计/编辑Workflow/BPM流程图、图表、网络图和普通图形的Web应用程序。mxgraph下载包中包括用javascript写的前端程序。
学习路径
API:http://jgraph.github.io/mxgraph/docs/js-api/files/index-txt.html
demo:http://jgraph.github.io/mxgraph/javascript/index.html
例子
安装
npm install mxgraph
引入
首先要声名一个全局变量 mxBasePath 指向一个路径,然后引入 mxGraph。mxBasePath 指向的路径作为 mxGraph 的静态资源路径。
import mx from 'mxgraph';
const mxgraph = mx({
mxImageBasePath: './src/images',
mxBasePath: './src'
});
export default mxgraph;
在使用的组件页面引入mxgraph
import mxgraph from '@/util/mxgraph'
使用解构的方式按照需求引入需要的模块
const { mxGraph, mxUtils, mxEvent } = mxgraph
检查浏览器
代码的第一部分是检查浏览器是否支持mxgraph,如果浏览器不支持就能在此显示错误信息。
对于主函数function main(){}没有什么特殊的规定。function引用头部加载的文件,并且可以有任何名称包含任何参数。在这个例子中参数是body中的dom节点
<script type="text/javascript";>
function main(container)
{
// Checks if the browser is supported
//检查浏览器是否支持
if (!mxClient.isBrowserSupported())
{
// Displays an error message if the browser is not supported.
//如果浏览器不支持,则显示错误信息
mxUtils.error('Browser is not supported!', 200, false);
}
Container 容器
页面用一个dom节点将graph与javascript结合。它可以使用document.getElementById在body中取得或者直接动态创建(如createElement)。如果你想让容器中有滚动条,那么将容器样式的属性 overflow 设为auto。
let container = document.createElement("div");
container.style.position = "absolute";
container.style.overflow = "hidden";
container.style.left = "0px";
container.style.top = "0px";
container.style.right = "0px";
container.style.bottom = "0px";
Graph 图
代码创建了一个空的graph图模型并通过容器和空的模型来构建具体的图
var model = new mxGraphModel();
var graph = new mxGraph(container, model);
如果你希望graph图只读,可用 graph.setEnabed(false)
常用属性:
graph.setCellsEditable(true);//单元格是否可编辑
graph.setCellsResizable(false);//是否可调整大小
graph.setConnectable(false);//是否可以连接
graph.setCellsMovable(true);//是否可以移动
graph.setAutoSizeCells(true);//是否可以自动调节大小
graph.setPanning(true);//移动镜头
graph.connectionHandler.setCreateTarget(true);//是否创建目标
graph.setAllowLoops(true);// 允许连线的目标和源是同一元素
graph.setVertexLabelsMovable(true);// 允许移动 Vertex 的 Label
mxGraphHandler.prototype.guidesEnabled = true;//显示细胞位置标尺
/*禁用节点双击,防止改变数据 */
graph.dblClick = function (evt, cell)
{
var model = graph.getModel();
if (model.isVertex(cell))
{
return false;
} };
//重写方法不允许那条线(edge)可以编辑
graph.isCellEditable = function(cell)
{
return !this.getModel().isEdge(cell)&&!this.getModel().isVertex(cell);
};
Vertices (节点)and Edges(连线)
程序需要在beginUpdate和endUpdate中来插入节点和连线(更新图形)。endUpdate应放在finally-block中以确保endUpdate一直执行。但beginUpdate不能在try-block中,这样如果beginUpdate失败那么endupdate永远不会执行。 块内的部分为图形创建节点和连线。默认的父节点是在用graph时无需参数自动创建在图中根节点的第一个子节点
//为插入节点获得默认的父节点。
//这通常是根节点的第一个子节点
var parent = graph.getDefaultParent();
// Adds cells to the model in a single step
//在单独的一步中添加cell
model.beginUpdate();
try
{
var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
var e1 = graph.insertEdge(parent, null, '', v1, v2);
}
finally
{
// Updates the display
//更新显示
model.endUpdate();
}
Stylesheet 样式表
cell的样式由样式表(mxStylesheet的实例)来决定。样式表规定了样式名称到样式之间的映射关系。一个样式是一个键的数组。那些键对应所用cell的值。值在mxConstants中定义,可以是字符串和数字、javascript对象、函数等 。 修改节点和连线的默认样式
var vertexStyle = graph.getStylesheet().getDefaultVertexStyle();
vertexStyle[mxConstants.ROUNDED] = true;
var edgeStyle = graph.getStylesheet().getDefaultEdgeStyle();
edgeStyle[mxConstants.STYLE_EDGE] = mxEdgeStyle.TopToBottom;
Styles 样式
cell的样式在属性style中(cell.style)。样式是cell状态的一部分,它可以通mxGraphModel.setStyle来改变。style是form[stylename;|key=value;]中的一段字符串。默认样式可覆盖此cell的制定键值。例如:你用 rounded 样式,它可以覆盖 stroke和fillColor
单个样式
1.字体相关
fontColor # 颜色
fontSize # 字体大小
fontFamily # 字体库
fontStyle # 字体样式
textDirection # 文本书写方向
align # 水平对齐
verticalAlign # 垂直对齐
2.标签相关
labelWidth # 宽
labelPosition # 水平位置
verticalLabelPosition # 垂直位置
noLabel # 不显示标签
labelBackgroundColor # 背景颜色
labelBorderColor # 边框颜色
labelPadding # 标签文字和边框之间的距离
spacing # 标签与顶点的间距
spacingLet # 标签与顶点的左间距
spacingBottom # 标签与顶点的下间距
spacingRight # 标签与顶点的右间距
spacingTop # 标签与顶点的上间距
3.顶点相关
fillColor # 填充颜色
strokeColor # 描边颜色
strokeWidth # 描边线宽
dashed # 虚线边
dashPattern # 虚线点大小和间距
rounded # 圆角
arcSize # 圆角大小
glass # 玻璃按钮
4.边相关
perimeterSpacing # 周边间距的关键点
sourcePerimeterSpacing # 边与源关键点周边间距
targetPerimeterSpacing # 边与目标关键点周边间距
例:
var v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30, 'rounded;strokeColor=red;fillColor=green');
全局设置
1.设置vertex的style
var style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_MIDDLE;
style[mxConstants.STYLE_GRADIENTCOLOR] = '#41B9F5';
style[mxConstants.STYLE_FILLCOLOR] = '#8CCDF5';
style[mxConstants.STYLE_STROKECOLOR] = '#1B78C8';
style[mxConstants.STYLE_FONTCOLOR] = '#000000';
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_OPACITY] = '80';
style[mxConstants.STYLE_FONTSIZE] = '12';
style[mxConstants.STYLE_FONTSTYLE] = 0;
style[mxConstants.STYLE_IMAGE_WIDTH] = '48';
style[mxConstants.STYLE_IMAGE_HEIGHT] = '48';
graph.getStylesheet().putDefaultVertexStyle(style);
2.设置edge的style
style = graph.getStylesheet().getDefaultEdgeStyle();
style[mxConstants.STYLE_LABEL_BACKGROUNDCOLOR] = '#FFFFFF';
style[mxConstants.STYLE_STROKEWIDTH] = '2';
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_EDGE] = mxEdgeStyle.SegmentConnector;
3.设置cell的 style
style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_SWIMLANE;
style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
style[mxConstants.STYLE_ALIGN] = mxConstants.ALIGN_CENTER;
style[mxConstants.STYLE_VERTICAL_ALIGN] = mxConstants.ALIGN_TOP;
style[mxConstants.STYLE_FILLCOLOR] = '#FF9103';
style[mxConstants.STYLE_GRADIENTCOLOR] = '#F8C48B';
style[mxConstants.STYLE_STROKECOLOR] = '#E86A00';
style[mxConstants.STYLE_FONTCOLOR] = '#000000';
style[mxConstants.STYLE_ROUNDED] = true;
style[mxConstants.STYLE_OPACITY] = '80';
style[mxConstants.STYLE_STARTSIZE] = '30';
style[mxConstants.STYLE_FONTSIZE] = '16';
style[mxConstants.STYLE_FONTSTYLE] = 1;
graph.getStylesheet().putCellStyle('group', style);
属性选项值
- mxgraph 提供的图形
SHAPE_RECTANGLE: 'rectangle'
SHAPE_ELLIPSE: 'ellipse'
SHAPE_DOUBLE_ELLIPSE: 'doubleEllipse'
SHAPE_RHOMBUS: 'rhombus'
SHAPE_LINE: 'line'
SHAPE_IMAGE: 'image'
SHAPE_ARROW: 'arrow'
SHAPE_ARROW_CONNECTOR: 'arrowConnector'
SHAPE_LABEL: 'label'
SHAPE_CYLINDER: 'cylinder'
SHAPE_SWIMLINE: 'swimlane'
SHAPE_CONNECTOR: 'connector'
SHAPE_ACTOR: 'actor'
SHAPE_CLOUD: 'cloud'
SHAPE_TRIANGLE: 'triangle'
SHAPE_HEXAGON: 'hexagon'
- 线连接样式
EDGESTYLE_ELBOW: 'elbowEdgeStyle'
EDGESTYLE_ENTITY_RELATION: 'entityRelationEdgeStyle'
EDGESTYLE_LOOP: 'loopEdgeStyle'
EDGESTYLE_SIDETOSIDE: 'sideToSideEdgeStyle'
EDGESTYLE_TOPTOBOTTOM: 'topToBottomEdgeStyle'
EDGESTYLE_ORTHOGONAL: 'orthogonalEdgeStyle'
EDGESTYLE_SEGMENT: 'segmentEdgeStyle'
// elbowEdgeStyle 方向属性
STYLE_ELBOW: 'elbow'
ELBOW_VERTICAL: 'vertical'
ELBOW_HORIZONTAL: 'horizontal'
- 边箭头样式
ARROW_CLASSIC: 'classic'
ARROW_CLASSIC_THIN: 'classicThin'
ARROW_BLOCK: 'block'
ARROW_BLOCK_THIN: 'blockThin'
ARROW_OPEN: 'open'
ARROW_OPEN_THIN: 'openThin'
ARROW_OVAL: 'oval'
ARROW_DIMAND: 'diamond'
ARROW_DIMAND_THIN: 'diamondThin'
- 文字样式
涉及 STYLE_FONTSTYLE
FONT_BOLD: 1
FONT_ITALIC: 2
FONT_UNDERLINE: 4
- 文本对齐
涉及 STYLE_ALIGN、STYLE_VERTICAL_ALIGN、STYLE_LABEL_ALIGN、STYLE_VERTICAL_LABEL_ALIGN
ALIGN_LET: 'left'
ALITGN_CENTER: 'center'
ALIGN_RIGHT: 'right'
ALIGN_TOP: 'top'
ALIGN_MIDDLE: 'middle'
ALIGN_BOTTOM: 'bottom'
- 文本书写方向
涉及 STYLE_TEXT_DIRECTION
TEXT_DIRECTION_AUTO: 'auto'
TEXT_DIRECTION_LTR: 'ltr'
TEXT_DIRECTION_RTL: 'rtl'
- 图形的方向
涉及 STYLE_DIRECTION
DIRECTION_NORTH : 'north'
DIRECTION_SOUTH: 'south'
DIRECTION_EAST: 'east'
DIRECTION_WEST: 'west'
- 周长相关
涉及 STYLE_PERIMETER
PERIMETER_ELLIPSE: 'ellipsePerimeter'
PERIMETER_RECTANGLE: 'rectangelPerimeter'
PERIMETER_RHOMBUS: 'rhombusPerimeter'
PERIMETER_HEXAGON: 'hexagonPerimeter'
PERIMETER_TRIANGLE: 'trianglePerimater'
拓展
还可以自定图形,替换原有的图形或者形状
let style = this.getPrefix(type) + "labelPosition=right";
const v = graph.insertVertex(
parent,
null,
current,
1,
0,
60,
60,
style
);
getPrefix(type) {
let prefix;
if (type === "xxx") {
prefix = "shape=image;image=/img/icons/firewall.svg;";
}
return prefix;
}