1. 程式人生 > >【mxGraph】原始碼學習:(7)mxCell

【mxGraph】原始碼學習:(7)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) {
        if (typeof(value.clone) == 'function') {
            value = value.clone();
        }
        else if (!isNaN(value.nodeType)) {
            value = value.cloneNode(true);
        }
    }

    return value;
};