Web前端最新mxGraph,web优化的内容及策略

文末

技术是没有终点的,也是学不完的,最重要的是活着、不秃。

零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。

最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。

自学最怕的就是缺乏自驱力,一定要自律,杜绝“三天打鱼两天晒网”,到最后白忙活一场。

高度自律的同时,要保持耐心,不抛弃不放弃,切勿自怨自艾,每天给自己一点点鼓励,学习的劲头就会很足,不容易犯困。

技术学到手后,找工作的时候一定要好好准备一份简历,不要无头苍蝇一样去海投简历,容易“竹篮打水一场空”。好好的准备一下简历,毕竟是找工作的敲门砖。

拿到面试邀请后,在面试的过程中一定要大大方方,尽力把自己学到的知识舒适地表达出来,不要因为是自学就不够自信,给面试官一个好的印象,面试成功的几率就会大很多,加油吧,骚年!

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

mxClient.defaultBundles.push(mxClient.basePath + '/resources/graph');

}


在创建mxGraph实例时,如果传入了container则会调用init方法进行初始化并创建相应的数据结构:



/**

  • container - DOM结点用于包含graph
    */
    mxGraph.prototype.init = function (container) {
    this.container = container;

    // 初始化就地编辑器
    this.cellEditor = this.createCellEditor();

    // 使用视图初始化容器
    this.view.init();

    // 更新当前图形的容器大小
    this.sizeDidChange();

    // 如果鼠标离开容器,则隐藏工具提示并重置工具提示计时器
    mxEvent.addListener(container, ‘mouseleave’, mxUtils.bind(this, function () {
    if (this.tooltipHandler != null) {
    this.tooltipHandler.hide();
    }
    }));

    // 自动释放内存
    if (mxClient.IS_IE) {
    mxEvent.addListener(window, ‘unload’, mxUtils.bind(this, function () {
    this.destroy();
    }));

     // 禁用文本的shift-click
     mxEvent.addListener(container, 'selectstart',
         mxUtils.bind(this, function (evt) {
             return this.isEditing() || (!this.isMouseDown && !mxEvent.isShiftDown(evt));
         })
     );
    

    }

    // 如果没有显示初始图形或没有定义形状标签,则在IE8标准模式下缺少最后一个形状和连接预览的解决方法
    if (document.documentMode == 8) {
    container.insertAdjacentHTML(‘beforeend’, ‘<’ + mxClient.VML_PREFIX + ‘:group’ +
    ’ style=“DISPLAY: none;”></’ + mxClient.VML_PREFIX + ‘:group>’);
    }
    };


### 3. 功能性


由于mxGraph定义了很多原型属性,这里不能一一列举,需要的时候可以查看源码。主要关注mxGraph功能性方面有哪些,以及结构如何。


#### 3.1 句柄


mxGraph会在init方法调用之前创建几个句柄用于处理对应的事件,有如下几个句柄:tooltip、panning、connection、graph,不过目前都是关闭的:



mxGraph.prototype.createHandlers = function () {
this.tooltipHandler = this.createTooltipHandler();
this.tooltipHandler.setEnabled(false);

this.selectionCellsHandler = this.createSelectionCellsHandler();

this.connectionHandler = this.createConnectionHandler();
this.connectionHandler.setEnabled(false);

this.graphHandler = this.createGraphHandler();

this.panningHandler = this.createPanningHandler();
this.panningHandler.panningEnabled = false;

this.popupMenuHandler = this.createPopupMenuHandler();

};


#### 3.2 cell重叠


当cell重叠时,mxGraph需要额外进行一些操作记录重叠的cell并更新graph的显示,这样才能实现cell重叠层次的改变:



/**

  • cell - 被叠加的mxCell

  • overlay - 添加到cell上的mxCellOverlay
    */
    mxGraph.prototype.addCellOverlay = function (cell, overlay) {
    // overlays是实例变量
    if (cell.overlays == null) {
    cell.overlays = [];
    }

    cell.overlays.push(overlay);

    var state = this.view.getState(cell);

    // 如果state存在,立即更新cell的重叠显示
    // state保存的是cell在graph中的所有状态
    if (state != null) {
    this.cellRenderer.redraw(state);
    }

    this.fireEvent(new mxEventObject(mxEvent.ADD_OVERLAY,
    ‘cell’, cell, ‘overlay’, overlay));

    return overlay;
    };


还有其他相关方法:getCellOverlays、removeCellOverlay、removeCellOverlays、clearCellOverlays,这里就不详述具体实现了。


#### 3.3 就地编辑


就地编辑通过在graph中双击触发,可以在双击的地方创建一个文本输入框,具体实现如下:



/**

  • cell - 开始就地编辑的cell

  • evt - 可选的触发编辑的鼠标事件
    */
    mxGraph.prototype.startEditingAtCell = function (cell, evt) {
    if (evt == null || !mxEvent.isMultiTouchEvent(evt)) {
    if (cell == null) {
    cell = this.getSelectionCell();

         // 选中的cell是否可以编辑
         if (cell != null && !this.isCellEditable(cell)) {
             cell = null;
         }
     }
    
     if (cell != null) {
         // 触发START_EDITING事件
         this.fireEvent(new mxEventObject(mxEvent.START_EDITING,
             'cell', cell, 'event', evt));
         // 开始编辑
         this.cellEditor.startEditing(cell, evt);
         // 触发EDITING_STARTED事件
         this.fireEvent(new mxEventObject(mxEvent.EDITING_STARTED,
             'cell', cell, 'event', evt));
     }
    

    }
    };


还有其他相关方法:getEditingValue、stopEditing、labelChanged、cellLabelChanged、escape,这里就不详述具体实现了。


#### 3.4 事件处理


事件处理方法的具体实现各异,不能一一详述,只需要知道如何触发,以及有什么效果即可,列举几个事件处理函数:




| 方法 | 描述 |
| --- | --- |
| escape | 处理ESC键事件 |
| click | 处理cell上的单击事件 |
| dblClick | 处理cell上的双击事件 |
| tapAndHold | 处理按住cell的事件 |


#### 3.5 Cell样式


cell的样式处理有许多方法,列举几个graph处理cell的方法,这里不详述了:




| 方法 | 描述 |
| --- | --- |
| getCellStyle | 返回表示给定cell样式的键值对的数组 |
| setCellStyle | 设置指定cell的样式。 如果没有给出cell,则改变选中的cell |
| toggleCellStyle | 以给定cell的样式切换给定键的布尔值,并将新值返回为0或1。如果未指定cell,则使用选中的cell |
| setCellStyleFlags | 在指定cell的样式中设置或切换给定键的给定位 |


#### 3.6 Cell的排列和方向


这里涉及处理cell的排列和方向的许多方法,列举一些就不详述了:




| 方法 | 描述 |
| --- | --- |
| alignCells | 使用可选参数作为坐标,根据给定的对齐方式垂直或水平对齐给定cell |
| flipEdge | 在null(或空)和alternateEdgeStyle之间切换给定边的样式。事务正在进行时,此方法将触发mxEvent.FLIP\_EDGE。返回被翻转的边 |
| addImageBundle | 添加指定的mxImageBundle |
| orderCells | 将给定的cell移动到前面或后面。使用cellsOrdered执行更改。事务正在进行时,此方法将触发mxEvent.ORDER\_CELLS |


#### 3.7 分组


graph的分组是一个非常强大的功能,列举一些方法:




| 方法 | 描述 |
| --- | --- |
| groupCells | 将cell添加到给定组中。使用cellsAdded,cellsMoved和cellsResized执行更改。事务正在进行时,此方法将触发mxEvent.GROUP\_CELLS。返回新组。仅当给定cell数组中至少有一个条目时,才会创建组 |
| getBoundsForGroup | 返回用于给定组和子项的边界 |
| createGroupCell | 如果没有为group函数提供组cell,则钩子用于创建组cell以保存给定的mxCells数组 |


#### 3.8 Cell克隆、插入和删除


graph的cell可以克隆、插入,也可以删除,列举一些常用的方法:




| 方法 | 描述 |
| --- | --- |
| cloneCells | 返回给定cell的克隆。克隆是使用mxGraphModel.cloneCells递归创建的。如果Edge的终端不在给定阵列中,则为相应的端分配终端点并移除终端 |
| insertVertex | 使用value作为用户对象并将给定坐标作为新vertex的mxGeometry,将新vertex添加到给定父mxCell中。id和style用于返回的新mxCell的各个属性 |
| removeCells | 如果includeEdges为true,则从graph中移除给定的cell,包括所有连接的edge。使用cellsRemoved执行更改。事务正在进行时,此方法将触发mxEvent.REMOVE\_CELLS。删除的单元格作为数组返回 |


#### 3.9 Cell的可见性


cell能设置它的可见性,用如下两个方法设置:




| 方法 | 描述 |
| --- | --- |
| toggleCells | 如果includeEdges为true,则设置指定cell和所有连接edge的可见状态。使用cellsToggled执行更改。事务正在进行时,此方法将触发mxEvent.TOGGLE\_CELLS。返回可见状态已更改的cell |
| cellsToggled | 设置指定cell的可见状态 |


#### 3.10 折叠


graph的分组以及有些cell是可以折叠的,用如下方法实现:




| 方法 | 描述 |
| --- | --- |
| foldCells | 如果recurse为true,则设置指定cell和所有后代的折叠状态。使用cellsFolded执行更改。事务正在进行时,此方法将触发mxEvent.FOLD\_CELLS。返回折叠状态已更改的cell |
| swapBounds | 在执行交换之前,交换调用updateAlternateBounds的给定cell的几何中的替代边界和实际边界 |


#### 3.11 Cell大小


列举一些改变cell大小的方法:




| 方法 | 描述 |
| --- | --- |
| updateCellSize | 使用cellSizeUpdated更新模型中给定cell的大小。事务正在进行时,此方法将触发mxEvent.UPDATE\_CELL\_SIZE。返回其大小已更新的单元格 |
| getPreferredSizeForCell | 返回给定mxCell的首选宽度和高度,作为mxRectangle。要实现最小宽度,要添加新样式 |
| resizeCell | 使用resizeCells设置给定cell的边界。返回传递给函数的cell |
| resizeChildCells | 相对于cell的当前几何图形,针对给定的新几何图形调整给定cell的子cell的大小 |


#### 3.12 Cell移动


列举一些移动cell的方法:




| 方法 | 描述 |
| --- | --- |
| importCells | 使用move方法克隆并将给定cell插入到图形中,并返回插入的cell。如果通过datatransfer插入cell,则使用此快捷方式 |
| moveCells | 移动或克隆指定的cell,并按给定的数量移动cell或克隆,将它们添加到可选的目标cell中。当鼠标被释放时,evt是鼠标事件。 使用cellsMoved执行更改。事务正在进行时,此方法将触发mxEvent.MOVE\_CELLS。返回已移动的cell |
| translateCell | 转换给定cell的几何图形,并将新的,已转换的几何图形作为原子更改存储在模型中 |


#### 3.13 Cell连接及其约束


列举一些cell连接,和连接约束的方法:




| 方法 | 描述 |
| --- | --- |
| getOutlineConstraint | 返回用于连接到给定状态轮廓的约束 |
| getAllConnectionConstraints | 返回给定终端的所有mxConnectionConstraints的数组。 如果给定终端的形状是mxStencilShape,则返回相应mxStencil的约束 |
| getConnectionPoint | 返回绝对点列表中最近的点或相对终端的中心 |
| connectCell | 在事务正在进行时,使用cellConnected将给定边的指定端连接到给定终端并触发mxEvent.CONNECT\_CELL。返回更新的边缘 |


#### 3.14 追溯


列举一些追溯cell关系的方法:




| 方法 | 描述 |
| --- | --- |
| getCurrentRoot | 返回显示的单元格层次结构的当前根。这是view中mxGraphView.currentRoot的快捷方式 |
| getTerminalForPort | 返回用于给定端口的终端。此实现始终返回父单元格 |
| enterGroup | 使用给定的单元格作为显示的单元格层次结构的根。如果未指定单元格,则使用选择单元格。仅当isValidRoot返回true时才使用该单元格 |
| home | 使用模型的根作为显示的单元层次结构的根,并选择以前的根 |


#### 3.15 graph显示


列举一些graph显示相关的方法:




| 方法 | 描述 |
| --- | --- |
| getGraphBounds | 返回可见图的边界。mxGraphView.getGraphBounds的快捷方式 |
| getCellBounds | 返回给定单元格的缩放,平移边界 |
| refresh | 清除从给定单元格开始的层次结构的所有单元格状态或状态,并验证图形。 这会触发刷新事件作为最后一步 |
| snap | 如果gridEnabled为true,则将给定的数值捕捉到网格 |
| panGraph | 按给定的量移动图表显示。这用于预览平移操作,使用mxGraphView.setTranslate设置视图的持久转换。触发mxEvent.PAN |
| zoomIn | 通过zoomFactor放大图形 |
| zoomOut | 通过zoomFactor缩小图表 |
| center | 将图表置于容器中心 |


#### 3.16 验证


列举一些验证性的方法:




| 方法 | 描述 |
| --- | --- |
| validationAlert | 在对话框中显示给定的验证错误。此实现使用mxUtils.alert |
| isEdgeValid | 检查给定参数的getEdgeValidationError的返回值是否为null |
| validateGraph | 通过验证给定单元格的每个后代或模型的根来验证图形。Context是一个包含完整验证运行的验证状态的对象。使用setCellWarning将验证错误附加到其单元格。在成功验证的情况下返回null,或者在验证失败的情况下返回字符串数组(警告) |
| getCellValidationError | 检查在修改图形时不能强制执行的所有multiplicities,即所有需要至少1个边缘的多重性 |


#### 3.17 graph外观


列举一些graph外观相关的方法:




| 方法 | 描述 |
| --- | --- |
| setBackgroundImage | 设置新的backgroundImage |
| getFoldingImage | 返回用于显示指定单元状态的折叠状态的mxImage。这将为所有边返回null |
| getLabel | 返回表示给定单元格标签的字符串或DOM节点。如果labelsVisible为true,则此实现使用convertValueToString。否则返回一个空字符串 |


#### 3.18 graph行为


列举一些graph行为相关的方法:




| 方法 | 描述 |
| --- | --- |
| isResizeContainer | 设置resizeContainer |
| isCellLocked | 如果无法移动,调整大小,弯曲,断开连接,编辑或选择给定单元格,则返回true。如果locked为false,则对于具有相对几何的所有顶点,此实现返回true |
| getCloneableCells | 返回可在给定单元格数组中导出的单元格 |


#### 3.19 获取Cell


列举一些graph行为相关的方法:




| 方法 | 描述 |
| --- | --- |
| getDefaultParent | 如果两者都为null,则返回defaultParent或mxGraphView.currentRoot或mxGraphModel.root的第一个子子项。此函数返回的值应该用作新单元格(也就是默认图层)的父级 |
| getSwimlane | 返回给定单元格的最近祖先,如果泳道本身是泳道,则返回泳道或给定单元格 |
| getCellAt | 返回与给定父级开始的单元层次结构中给定点(x,y)相交的最底部单元格。 如果给定位置与泳道的内容区域相交,这也将返回泳道。 如果不希望这样,那么如果返回的单元格是泳道,则可以使用hitsSwimlaneContent来确定该位置是在内容区域内还是在泳道的实际标题上 |


#### 3.20 选中


列举一些跟选中相关的方法:




| 方法 | 描述 |
| --- | --- |
| isCellSelected | 如果选择了给定单元格,则返回true |
| isSelectionEmpty | 如果选择为空,则返回true |
| getSelectionCells | 返回所选mxCells的数组 |


#### 3.21 选中状态


列举一些跟选中状态相关的方法:




| 方法 | 描述 |
| --- | --- |
| createHandler | 为给定的单元格状态创建一个新的处理程序。 此实现返回相应单元格的新mxEdgeHandler是边缘,否则返回mxVertexHandler |
| createVertexHandler | 挂钩为给定的mxCellState创建新的mxVertexHandler |
| createEdgeHandler | 挂钩为给定的mxCellState创建新的mxEdgeHandler |


#### 3.22 graph事件


列举一些graph事件相关的方法:




| 方法 | 描述 |
| --- | --- |
| addMouseListener | 向图形事件调度循环添加侦听器。监听器必须实现mouseDown,mouseMove和mouseUp方法,如mxMouseEvent类所示 |
| updateMouseEvent | 如果需要,设置给定wxMouseEvent的图形和graphY属性,并返回事件 |
| getStateForTouchEvent | 返回给定触摸事件的状态 |


 


## 【mxGraph】源码学习:mxCell


### 1. 概览


mxCell是graph model的元素。它们表示graph中的group、vertex和edge的状态。


对于自定义属性,建议使用XML节点作为cell的值。以下代码可用于创建具有XML节点的cell作为值:



var doc = mxUtils.createXmlDocument();
var node = doc.createElement(‘MyNode’)
node.setAttribute(‘label’, ‘MyLabel’);
node.setAttribute(‘attribute1’, ‘value1’);
graph.insertVertex(graph.getDefaultParent(), null, node, 40, 40, 80, 30);


要使标签起作用,应重写mxGraph.convertValueToString和mxGraph.cellLabelChanged,如下所示:



graph.convertValueToString = function(cell) {
if (mxUtils.isNode(cell.value)) {
return cell.getAttribute(‘label’, ‘’)
}
};

var cellLabelChanged = graph.cellLabelChanged;
graph.cellLabelChanged = function(cell, newValue, autoSize) {
if (mxUtils.isNode(cell.value)) {
// clone正确撤消/重做的值
var elt = cell.value.cloneNode(true);
elt.setAttribute(‘label’, newValue);
newValue = elt;
}

cellLabelChanged.apply(this, arguments);
};


### 2. 构造


mxCell的构造函数如下:



/**

  • value - 表示cell值的可选对象。

  • geometry - 可选的mxGeometry,用于指定几何体。

  • style - 可选的格式化字符串,用于定义样式
    */
    function mxCell(value, geometry, style) {
    this.value = value;
    this.setGeometry(geometry);
    this.setStyle(style);

    if (this.onInit != null) {
    this.onInit();
    }
    }


### 3. 原型属性


列举一些mxCell的原型属性:



// cell的id。默认为null
mxCell.prototype.id = null;

// 用户对象。默认为null
mxCell.prototype.value = null;

// mxGeometry表示cell的几何状态。默认为null
mxCell.prototype.geometry = null;

// 将样式保存为[(stylename|key = value);]形式的字符串。默认值为null
mxCell.prototype.style = null;

// 指定cell是否为vertex。默认值为false
mxCell.prototype.vertex = false;

// 指定cell是否为edge。默认值为false
mxCell.prototype.edge = false;

// 指向父cell
mxCell.prototype.parent = null;

// 指向子cell
mxCell.prototype.children = null;

// 不应在clone中克隆的成员列表。此字段将传递给mxUtils.clone,并且不会在mxCellCodec中保持持久性。
// 这不是所有类的约定,它仅在此类中用于标记瞬态字段,因为js不支持瞬态修饰符。
mxCell.prototype.mxTransient = [‘id’, ‘value’, ‘parent’, ‘source’,
‘target’, ‘children’, ‘edges’];


### 4. 原型方法


除了原型属性的getter和setter外,列举几个方法的实现:



/**

  • 将指定的edge插入edge数组并返回edge。将更新edge的相应终端参考

  • edge - 要插入edge数组的mxCell

  • isOutgoing - Boolean,指定边是否外支
    */
    mxCell.prototype.insertEdge = function (edge, isOutgoing) {
    if (edge != null) {
    edge.removeFromTerminal(isOutgoing);
    edge.setTerminal(this, isOutgoing);

     if (this.edges == null ||
         edge.getTerminal(!isOutgoing) != this ||
         mxUtils.indexOf(this.edges, edge) < 0) {
         if (this.edges == null) {
             this.edges = [];
         }
    
         this.edges.push(edge);
     }
    

    }

    return edge;
    };

/**

  • 返回cell的克隆。使用cloneValue克隆用户对象。克隆过程中将忽略mxTransient中的所有字段
    */
    mxCell.prototype.clone = function () {
    var clone = mxUtils.clone(this, this.mxTransient);
    clone.setValue(this.cloneValue());

    return clone;
    };

/**

  • 返回cell用户对象的克隆。
    */
    mxCell.prototype.cloneValue = function () {
    var value = this.getValue();

    if (value != null) {

总结

面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。

还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

前端面试题汇总

JavaScript

前端资料汇总

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值