/** * Copyright (c) 2006-2015, JGraph Ltd * Copyright (c) 2006-2015, Gaudenz Alder */ /** * Class: mxCellOverlay * * Extends to implement a graph overlay, represented by an icon * and a tooltip. Overlays can handle and fire events and are added to * the graph using , and removed using * , or to remove all overlays. * The function returns the array of overlays for a given * cell in a graph. If multiple overlays exist for the same cell, then * should be overridden in at least one of the overlays. * * Overlays appear on top of all cells in a special layer. If this is not * desirable, then the image must be rendered as part of the shape or label of * the cell instead. * * Example: * * The following adds a new overlays for a given vertex and selects the cell * if the overlay is clicked. * * (code) * var overlay = new mxCellOverlay(img, html); * graph.addCellOverlay(vertex, overlay); * overlay.addListener(mxEvent.CLICK, function(sender, evt) * { * var cell = evt.getProperty('cell'); * graph.setSelectionCell(cell); * }); * (end) * * For cell overlays to be printed use . * * Event: mxEvent.CLICK * * Fires when the user clicks on the overlay. The event property * contains the corresponding mouse event and the cell property * contains the cell. For touch devices this is fired if the element receives * a touchend event. * * Constructor: mxCellOverlay * * Constructs a new overlay using the given image and tooltip. * * Parameters: * * image - that represents the icon to be displayed. * tooltip - Optional string that specifies the tooltip. * align - Optional horizontal alignment for the overlay. Possible * values are , and * (default). * verticalAlign - Vertical alignment for the overlay. Possible * values are , and * (default). */ function mxCellOverlay(image, tooltip, align, verticalAlign, offset, cursor) { this.image = image; this.tooltip = tooltip; this.align = (align != null) ? align : this.align; this.verticalAlign = (verticalAlign != null) ? verticalAlign : this.verticalAlign; this.offset = (offset != null) ? offset : new mxPoint(); this.cursor = (cursor != null) ? cursor : 'help'; }; /** * Extends mxEventSource. */ mxCellOverlay.prototype = new mxEventSource(); mxCellOverlay.prototype.constructor = mxCellOverlay; /** * Variable: image * * Holds the to be used as the icon. */ mxCellOverlay.prototype.image = null; /** * Variable: tooltip * * Holds the optional string to be used as the tooltip. */ mxCellOverlay.prototype.tooltip = null; /** * Variable: align * * Holds the horizontal alignment for the overlay. Default is * . For edges, the overlay always appears in the * center of the edge. */ mxCellOverlay.prototype.align = mxConstants.ALIGN_RIGHT; /** * Variable: verticalAlign * * Holds the vertical alignment for the overlay. Default is * . For edges, the overlay always appears in the * center of the edge. */ mxCellOverlay.prototype.verticalAlign = mxConstants.ALIGN_BOTTOM; /** * Variable: offset * * Holds the offset as an . The offset will be scaled according to the * current scale. */ mxCellOverlay.prototype.offset = null; /** * Variable: cursor * * Holds the cursor for the overlay. Default is 'help'. */ mxCellOverlay.prototype.cursor = null; /** * Variable: defaultOverlap * * Defines the overlapping for the overlay, that is, the proportional distance * from the origin to the point defined by the alignment. Default is 0.5. */ mxCellOverlay.prototype.defaultOverlap = 0.5; /** * Function: getBounds * * Returns the bounds of the overlay for the given as an * . This should be overridden when using multiple overlays * per cell so that the overlays do not overlap. * * The following example will place the overlay along an edge (where * x=[-1..1] from the start to the end of the edge and y is the * orthogonal offset in px). * * (code) * overlay.getBounds = function(state) * { * var bounds = mxCellOverlay.prototype.getBounds.apply(this, arguments); * * if (state.view.graph.getModel().isEdge(state.cell)) * { * var pt = state.view.getPoint(state, {x: 0, y: 0, relative: true}); * * bounds.x = pt.x - bounds.width / 2; * bounds.y = pt.y - bounds.height / 2; * } * * return bounds; * }; * (end) * * Parameters: * * state - that represents the current state of the * associated cell. */ mxCellOverlay.prototype.getBounds = function(state) { var isEdge = state.view.graph.getModel().isEdge(state.cell); var s = state.view.scale; var pt = null; var w = this.image.width; var h = this.image.height; if (isEdge) { var pts = state.absolutePoints; if (pts.length % 2 == 1) { pt = pts[Math.floor(pts.length / 2)]; } else { var idx = pts.length / 2; var p0 = pts[idx-1]; var p1 = pts[idx]; pt = new mxPoint(p0.x + (p1.x - p0.x) / 2, p0.y + (p1.y - p0.y) / 2); } } else { pt = new mxPoint(); if (this.align == mxConstants.ALIGN_LEFT) { pt.x = state.x; } else if (this.align == mxConstants.ALIGN_CENTER) { pt.x = state.x + state.width / 2; } else { pt.x = state.x + state.width; } if (this.verticalAlign == mxConstants.ALIGN_TOP) { pt.y = state.y; } else if (this.verticalAlign == mxConstants.ALIGN_MIDDLE) { pt.y = state.y + state.height / 2; } else { pt.y = state.y + state.height; } } return new mxRectangle(Math.round(pt.x - (w * this.defaultOverlap - this.offset.x) * s), Math.round(pt.y - (h * this.defaultOverlap - this.offset.y) * s), w * s, h * s); }; /** * Function: toString * * Returns the textual representation of the overlay to be used as the * tooltip. This implementation returns . */ mxCellOverlay.prototype.toString = function() { return this.tooltip; };