1. 程式人生 > >解決mxGraph放大/縮小在非IE瀏覽器下overlay圖示位置不變化的問題

解決mxGraph放大/縮小在非IE瀏覽器下overlay圖示位置不變化的問題

首先要建立一個工具欄,併為工具欄中的放大、縮小按鈕定義事件。

<div id="toolbar" style="float:left;margin-top:5px;margin-left: 5px;line-height: 35px;">
     <img src="src/images/zoomin.gif" action="zoomIn" title="放大" width="16" height="16" />
     <img src="src/images/zoomout.gif" action="zoomOut" title="縮小" width="16" height="16" />
</div>

var canvas=ylEditor.ylCanvas;//ylEditor.ylCanvas是我定義的一個mxGraph例項的全域性物件。
var toolbar= $('#toolbar');
toolbar.find('img').css( {
    'margin-right' : '5px',
    'cursor' : 'pointer'
}).click(function() {
    switch ($(this).attr('action')) {
        case 'zoomIn':
            canvas.zoomIn();
            break;
        case 'zoomOut':
            canvas.zoomOut();
            break;
    }
});

下面是一個建立overlay的方法,這個方法中為圖形建立了3個overlay圖示,在圖形的左上角一個,右上角兩個。
ylCommon.createOverlay = function (cell) {
    var canvas=ylEditor.ylCanvas;
    var img, point, align = 'left', title;
    var iconSize = 16;
    
    img = '../../images/icon-unlock.png';
    title = '已解鎖-點選鎖定';
    point = new mxPoint(cell.geometry.width - 15, 10);
    var overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');

    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
    
    img = '../../images/icon-diagram.png';
    title = '輻射圖';
    point = new mxPoint(cell.geometry.width - 35, 10);
    overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');
    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
    
    img = 'src/images/properties.gif';
    title = '屬性';
    point = new mxPoint(27, 10);
    overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');
    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
}
執行以上程式碼,在IE下正常,在火狐和谷歌瀏覽器下顯示不正常,overlay圖示位置沒有發生改變。主要原因是因為呼叫zoomIn()和zoomOut()方法之後畫布顯示比例發生了變化,而overlay的座標是固定的。那麼只要對overlay座標也根據這個比例來建立是不是就解決問題了呢?好,下面就來改造建立overlay的這個方法。
ylCommon.createOverlay = function (cell) {
    var canvas=ylEditor.ylCanvas;
    var img, point, align = 'left', title;
    var iconSize = 16;
    var scale=canvas.getView().getScale();//獲取當前畫布的顯示比例,把座標的x,y都乘以這個比例
    img = '../../images/icon-unlock.png';
    title = '已解鎖-點選鎖定';
    point = new mxPoint((cell.geometry.width - 15)*scale, 10*scale);
    var overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');

    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
    
    img = '../../images/icon-diagram.png';
    title = '輻射圖';
    point = new mxPoint((cell.geometry.width - 35)*scale, 10*scale);
    overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');
    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
    
    img = 'src/images/properties.gif';
    title = '屬性';
    point = new mxPoint(27*scale, 10*scale);
    overlay = new mxCellOverlay(new mxImage(img, iconSize, iconSize), title, align, 'top', point, 'pointer');
    overlay.addListener(mxEvent.CLICK, function (sender, evt2) {
        //do something
    });
    canvas.addCellOverlay(cell, overlay);
}
改造完成,問題是否解決了呢?經過驗證,並沒有解決,這是為什麼呢?可能是因為這個方法只是針對建立overlay的時候生效,在執行放大縮小的時候,並不會再重新建立overlay。我想當然的認為mxGraph會根據這個比例來重新渲染overlay。好吧,那我就在執行放大縮小之後,再重新建立一下overlay的好了。

定義一個重新建立overlay的方法。

ylCommon.resetOverlay=function(){
    var scale=ylEditor.ylCanvas.getView().getScale();
    var oldSelectCells=ylEditor.ylCanvas.getSelectionCells();//獲取當前選中的圖形
    if(!mxClient.IS_IE){
        ylEditor.ylCanvas.selectAll();
        var cells=ylEditor.ylCanvas.getSelectionCells();
        ylEditor.ylCanvas.clearSelection();
        ylEditor.ylCanvas.setSelectionCells(oldSelectCells);//重新選中
        ylEditor.ylModel.beginUpdate();
        for(var i=0;i<cells.length;i++){
            ylEditor.ylCanvas.clearCellOverlays(cells[i]);//移除overlay
            ylCommon.createOverlay(cells[i]);//重新建立overlay
        }
        ylEditor.ylModel.endUpdate();
    }
}

然後在點選放大和縮小的時候呼叫一下這個方法。
toolbar.find('img').css( {
    'margin-right' : '5px',
    'cursor' : 'pointer'
}).click(function() {
    switch ($(this).attr('action')) {
        case 'zoomIn':
            canvas.zoomIn();
            ylCommon.resetOverlay();
            break;
        case 'zoomOut':
            canvas.zoomOut();
            ylCommon.resetOverlay();
            break;
    }
});
好了,問題終於解決了。