|
这两天,又扩展了一下基于excanvas和jquery的拓扑功能。下来,准备增加画图工具了。

/** * @author leishu <leishu@sina.com> */var jvConstants = {ELEMENT_ID_PREFIX : 'jvElement_',ELEMENT_ID_COUNT : 0,DEFAULT_VALID_COLOR:'#00FF00',DEFAULT_INVALID_COLOR:'#FF0000',HIGHLIGHT_STROKEWIDTH:3,CURSOR_MOVABLE_ELEMENT:'move',CURSOR_MOVABLE_EDGE:'move',CURSOR_CONNECT:'pointer',VALID_COLOR:'#00FF00',INVALID_COLOR:'#FF0000',STYLE_STROKECOLOR:'strokeColor',STYLE_STROKEWIDTH:'strokeWidth',SHAPE_RECTANGLE:'rectangle',SHAPE_ELLIPSE:'ellipse',SHAPE_TEXT:'text',ELEMENT_GROUP:'group',ELEMENT_TYPE_EDGE:'edge',BACKGROUND_COLOR:'background-color',ACTION_MOUSEDOWN:'mousedown',ACTION_MOUSEUP:'mouseup',ACTION_MOVE : 'mousemove',STYLE_ALIGN:'align',STYLE_SPACING:'spacing',STYLE_SPACING_TOP:'spacingTop',STYLE_SPACING_LEFT:'spacingLeft',STYLE_SPACING_BOTTOM:'spacingBottom',STYLE_SPACING_RIGHT:'spacingRight',STYLE_HORIZONTAL:'horizontal',STYLE_FONTCOLOR:'color',STYLE_FONTFAMILY:'font-family',STYLE_FONTSIZE:'font-size',STYLE_OVERFLOW:'overflow',ALIGN_CENTER:'center',DEFAULT_FONTFAMILY:'Arial,Helvetica',DEFAULT_FONTSIZE:10,SELECT_START : 'start',SELECT_END : 'end',LABEL_LOCATION_MIDDLE : 'middle',LABEL_LOCATION_BOTTOM : 'bottom',LABEL_INTERVAL : 3,END_POINT_LEFTTOP : 'lt',END_POINT_LEFTMIDDLE : 'lm',END_POINT_LEFTBOTTOM : 'lb',END_POINT_MIDDLETOP : 'mt',END_POINT_MIDDLEBOTTOM : 'mb',END_POINT_RIGHTTOP : 'rt',END_POINT_RIGHTMIDDLE : 'rm',END_POINT_RIGHTBOTTOM : 'rb'};function getMouseButton(eventObject) { var buttons = { 'left':false, 'middle':false, 'right':false }; if(eventObject.toString && eventObject.toString().indexOf('MouseEvent') != -1) { switch(eventObject.button) { case 0: buttons.left = true; break; case 1: buttons.middle = true; break; case 2: buttons.right = true; break; default: break; } } else if(eventObject.button) { switch(eventObject.button) { case 1: buttons.left = true; break; case 2: buttons.right = true; break; case 3: buttons.left = true; buttons.right = true; break; case 4: buttons.middle = true; break; case 5: buttons.left = true; buttons.middle = true; break; case 6: buttons.middle = true; buttons.right = true; break; case 7: buttons.left = true; buttons.middle = true; buttons.right = true; break; default: break; } } else { return false; } return buttons;};function jvMap(){this.data = new Array();};jvMap.prototype.clear=function(){this.data = [];};jvMap.prototype.get=function(key){$(this.data).each( function(i) {if (this.key === k){return this.value;}});return null;};jvMap.prototype.put=function(k, v){$(this.data).each( function(i) {if (this.key === k){this.value = v;return; }});this.data.push({key:k, value:v});};jvMap.prototype.remove=function(k){var d = [];$(this.data).each( function(i) {if (this.key != k){d.push({key:this.key,value:this.value});}});this.data = d;};jvMap.prototype.isEmpty = function() {if (this.data.length == 0){return true;}else{return false;}};jvMap.prototype.size = function() {return this.data.length;};jvMap.prototype.containsKey=function(k){$(this.data).each( function(i) {if (this.key === k){return true;}});return false;};jvMap.prototype.getValues=function(){var result=[];$(this.data).each( function(i) {result.push(this.value);});return result;};function jvPoint(x,y){this.x = (x!=null)?x:0;this.y = (y!=null)?y:0;};jvPoint.prototype.x=null;jvPoint.prototype.y=null;jvPoint.prototype.equals=function(obj){return obj.x==this.x&&obj.y==this.y;};function jvEndPoint(x, y, type, cursor){jvPoint.call(this, x, y);this.type = type;this.cursor = cursor;};jvEndPoint.prototype=new jvPoint();jvEndPoint.prototype.constructor=jvEndPoint;function jvRectangle(x, y, width, height){jvPoint.call(this, x, y);this.width = (width != null) ? width : 0;this.height = (height != null) ? height : 0;};jvRectangle.prototype=new jvPoint();jvRectangle.prototype.constructor=jvRectangle;jvRectangle.prototype.width=null;jvRectangle.prototype.height=null;jvRectangle.prototype.getCenterX=function(){return this.x+this.width/2;};jvRectangle.prototype.getCenterY=function(){return this.y+this.height/2;};jvRectangle.prototype.getPoint=function(){return new jvPoint(this.x,this.y);};jvRectangle.prototype.equals=function(obj){return obj.x==this.x&&obj.y==this.y&&obj.width==this.width&&obj.height==this.height;};jvRectangle.prototype.grow=function(amount){this.x-=amount;this.y-=amount;this.width+=2*amount;this.height+=2*amount;};function jvStylesheet(){this.styles = [];this.putDefaultElementStyle(this.createDefaultElementStyle());this.putDefaultEdgeStyle(this.createDefaultEdgeStyle());this.putDefaultTextStyle(this.createDefaultTextStyle());return this;};jvStylesheet.prototype.createDefaultElementStyle = function(){var style=new Object();style[jvConstants.STYLE_SHAPE]=jvConstants.SHAPE_RECTANGLE;style[jvConstants.STYLE_FILLCOLOR]='#C3D9FF';style[jvConstants.STYLE_STROKECOLOR]='#6482B9';style[jvConstants.STYLE_FONTCOLOR]='#774400';style[jvConstants.STYLE_STROKEWIDTH] = 2;return style;};jvStylesheet.prototype.createDefaultEdgeStyle = function(){var style=new Object();style[jvConstants.STYLE_SHAPE]=jvConstants.SHAPE_CONNECTOR;style[jvConstants.STYLE_STROKECOLOR]='#6482B9';style[jvConstants.STYLE_FONTCOLOR]='#446299';style[jvConstants.STYLE_STROKEWIDTH] = 2;return style;};jvStylesheet.prototype.createDefaultTextStyle = function(){var style=new Object();style[jvConstants.STYLE_ALIGN] = jvConstants.ALIGN_CENTER;style[jvConstants.STYLE_FONTCOLOR] = 'gray';style[jvConstants.STYLE_FONTFAMILY] = jvConstants.DEFAULT_FONTFAMILY;style[jvConstants.STYLE_FONTSIZE] = jvConstants.DEFAULT_FONTSIZE;style[jvConstants.STYLE_SPACING] = 0;style[jvConstants.STYLE_SPACING_TOP] = 0;style[jvConstants.STYLE_SPACING_RIGHT] = 0;style[jvConstants.STYLE_SPACING_BOTTOM] = 0;style[jvConstants.STYLE_SPACING_LEFT] = 0;style[jvConstants.STYLE_OVERFLOW] = 'visible';style['z-index'] = 2;return style;};jvStylesheet.prototype.putDefaultElementStyle=function(style){this.putCellStyle('defaultElement',style);};jvStylesheet.prototype.putDefaultEdgeStyle=function(style){this.putCellStyle('defaultEdge',style);};jvStylesheet.prototype.putDefaultTextStyle=function(style){this.putCellStyle('defaultText',style);};jvStylesheet.prototype.getDefaultElementStyle=function(){return this.styles['defaultElement'];};jvStylesheet.prototype.getDefaultEdgeStyle=function(){return this.styles['defaultEdge'];};jvStylesheet.prototype.getDefaultTextStyle=function(){return this.styles['defaultText'];};jvStylesheet.prototype.putCellStyle=function(name,style){this.styles[name] = style;};function jvState(x, y, width, height, action){jvRectangle.call(this, x, y, width, height);this.action = action;}jvState.prototype =new jvRectangle();jvState.prototype.constructor = jvState;jvState.prototype.startX = null;jvState.prototype.startY = null;jvState.prototype.elementID = null;jvState.prototype.changed = false;jvState.prototype.resized = false;jvState.prototype.position=function(x, y, width, height){jvRectangle.call(this, x, y, width, height);};function jvElement(canvas, type, x, y, width, height, label){jvRectangle.call(this, x, y, width, height);this.canvas = canvas;this.type = type;this.label = label;};jvElement.prototype =new jvRectangle();jvElement.prototype.constructor = jvElement;jvElement.prototype.id = null;jvElement.prototype.shape = null;jvElement.prototype.frame = null;jvElement.prototype.endPoints = null;jvElement.prototype.source = null;jvElement.prototype.target = null;jvElement.prototype.edges = null;jvElement.prototype.edge=false;jvElement.prototype.state=null;jvElement.prototype.edge=false;jvElement.prototype.areaCoords = [];jvElement.prototype.area = null;jvElement.prototype.text = null;jvElement.prototype.isEdge=function(){return this.edge;};jvElement.prototype.setStyle = function(style){jQuery.extend(this.style, style);this.reDraw();this.unselect();};jvElement.prototype.setLabelLocation = function(location){if (this.text){this.text.location = location;this.text.setY();$(this.text.table).css({top:this.text.y});}};jvElement.prototype.create = function(){this.id = $.jvChart.getElementID();this.container = this.canvas.parentElement;if (this.type == jvConstants.ELEMENT_TYPE_EDGE){this.style = $.jvChart.getStylesheet().getDefaultEdgeStyle();this.edge = true;}else{this.edges = [];this.style = $.jvChart.getStylesheet().getDefaultElementStyle();this.style[jvConstants.BACKGROUND_COLOR] = $(this.container).css(jvConstants.BACKGROUND_COLOR);}if (this.label){this.text = new jvTextElement(this.canvas, this.label, this);}this.draw();this.createArea();this.bindMouseEvents();};jvElement.prototype.move = function(e){if (this.height < 0){var t = this.y + this.height;this.y += this.height;this.height = Math.abs(this.height);this.state.y = this.y;this.state.height = this.height;this.state.startY = e.clientY;if (this.state.action == jvConstants.END_POINT_MIDDLEBOTTOM){this.state.action = jvConstants.END_POINT_MIDDLETOP;}else if (this.state.action == jvConstants.END_POINT_MIDDLETOP){this.state.action = jvConstants.END_POINT_MIDDLEBOTTOM;}}this.state.changed = true;this.updateFrame();};jvElement.prototype.updateFrame = function(){$(this.frame).css('left', this.x).css('top', this.y).css('width', this.width).css('height', this.height);};jvElement.prototype.updateEndPoints = function(){var c = this.container;if (this.endPoints){$(this.endPoints).remove();this.endPoints = null;}if (this.isEdge()){}else{var xr = this.x + this.width,xm = Math.round(this.x + this.width /2),yr = this.y + this.height,ym = Math.round(this.y + this.height /2);var e = [];e.push(new jvEndPoint(this.x, this.y, jvConstants.END_POINT_LEFTTOP, 'nw-resize'));e.push(new jvEndPoint(xm, this.y, jvConstants.END_POINT_MIDDLETOP, 'row-resize'));e.push(new jvEndPoint(xr, this.y, jvConstants.END_POINT_RIGHTTOP, 'ne-resize'));e.push(new jvEndPoint(this.x, ym, jvConstants.END_POINT_LEFTMIDDLE, 'col-resize'));e.push(new jvEndPoint(xr, ym, jvConstants.END_POINT_RIGHTMIDDLE, 'col-resize'));e.push(new jvEndPoint(this.x, yr, jvConstants.END_POINT_LEFTBOTTOM, 'sw-resize'));e.push(new jvEndPoint(xm, yr, jvConstants.END_POINT_MIDDLEBOTTOM, 'row-resize'));e.push(new jvEndPoint(xr, yr, jvConstants.END_POINT_RIGHTBOTTOM, 'se-resize'));var ep = this.endPoints = [];$(e).each(function(i){var l = this.x - 3;var t = this.y - 3;ep.push($.jvChart.createElement('div', {action:this.type}, {position: 'absolute', 'z-index':1, 'background-color':'lime',left:l, top:t, width: '7px', height: '7px', overflow:'hidden', cursor:this.cursor}, c));});var $e = this;$(ep).each(function(i){$(this).mousedown(function (e) {$e.refreshState(e, $(this).attr('action'));return false;}).mouseup(function (e) {return $e.mouseup($(this).attr('action'));});});}};jvElement.prototype.reDraw = function(x, y){if (this.shape){$(this.shape).remove();}this.x += x || 0;this.y += y || 0;this.draw();this.updateFrame();this.updateEndPoints();this.bindMouseEvents();if (this.text && this.state){var xc = x || this.x - this.state.x;var yc = y || this.y - this.state.y;this.text.refreshPosition(xc, yc);}if (!this.isEdge && !this.selected){this.clearState();}else if (this.state){this.state.changed = false;}if (!this.isEdge()){$(this.edges).each(function(i){this.reDraw();});}};jvElement.prototype.createArea = function(){};jvElement.prototype.createFrame = function(){if (this.frame != null){return;}var c = this.container;var color = 'lime';if (this.type == jvConstants.ELEMENT_GROUP){color = 'slategray';}this.frame = $.jvChart.createElement('div', {id: c.id + '-frame'}, {position: 'absolute', 'z-index':-1, border:'dotted 2 ' + color,left:this.x, top:this.y, width: this.width, height: this.height}, c);$(this.frame).mouseup(function (e) {return true;});if (this.type != jvConstants.ELEMENT_GROUP){this.updateEndPoints();}};jvElement.prototype.removeFrame = function(){$(this.frame).remove();this.frame = null;$(this.endPoints).remove();this.endPoints = null;this.clearState();};jvElement.prototype.buildArea = function(){var str = "<area shape=poly style='cursor:move; ' coords=";var length = $(this.areaCoords).length;$(this.areaCoords).each(function(i){str += this.x + ',' + this.y;if (i != length - 1){str += ',';}});str +='>';var area = document.createElement(str);this.container.imagemap.appendChild(area);this.area = area;};jvElement.prototype.setShape = function(n){this.shape = [];if ($.browser.msie) {var shapes = this.canvas.getElementsByTagName("shape");for (var i = n; i > 0; i--){this.shape.push(shapes[shapes.length - i]);}}};jvElement.prototype.selected = false;jvElement.prototype.toggle = function(e, action){if (this.selected){this.unselect();}else{this.select(e, action);}};jvElement.prototype.select = function(e, action){if (e.ctrlKey){}else{var $e = this;var data = this.container.selected.getValues();$(data).each(function(i){if($e.id != this.id){this.unselect();}});}if (!this.selected){this.createFrame();this.selected = true;this.container.selected.addElement(this);}this.refreshState(e, action);document.onselectstart=new Function ("return false");return false;};jvElement.prototype.refreshState = function(e, action){if (this.state){this.state.position(this.x, this.y, this.width, this.height);this.state.action = action;}else{this.state = new jvState(this.x, this.y, this.width, this.height, action);this.state.elementID = this.id;}this.state.startX = e.clientX;this.state.startY = e.clientY;};jvElement.prototype.unselect = function(){this.container.selected.deleteElement(this);this.selected = false;this.removeFrame();this.clearState();return false;};jvElement.prototype.clearState = function(){this.state = null;};jvElement.prototype.mouseup = function(action){if (this.state && !this.state.changed){this.state.action = action;return false;}return true;};jvElement.prototype.bindMouseEvents = function(){if (this.idEdge){return;}var $e = this;$(this.shape).css({cursor:'move'}).mousedown(function (e) {if (e.ctrlKey){if (!$e.selected){$e.select(e, jvConstants.ACTION_MOVE);$e.selected = jvConstants.SELECT_START;}}else{if (!$e.selected){$e.select(e, jvConstants.ACTION_MOVE);}else {$e.refreshState(e, jvConstants.ACTION_MOVE);}}var group = $e.container.selected;if (group.size() > 1){group.refreshState(e, jvConstants.ACTION_MOVE);}return false;}).mouseup(function (e) {if (e.ctrlKey){if ($e.selected == jvConstants.SELECT_END){$e.unselect();}else{$e.selected = jvConstants.SELECT_END;}}else{var group = $e.container.selected;if (group.size() > 1){return group.mouseup(jvConstants.ACTION_MOVE);}if ($e.state){return $e.mouseup(jvConstants.ACTION_MOVE);}}return false;});};function jvGroup(canvas){jvElement.call(this, canvas, jvConstants.ELEMENT_GROUP);this.id = $.jvChart.getElementID();this.container = this.canvas.parentElement;return this;};jvGroup.prototype = new jvElement();jvGroup.prototype.constructor = jvGroup;jvGroup.prototype.action = null;jvGroup.prototype.elements = new jvMap();jvGroup.prototype.addElement = function(element){this.elements.put(element.id, element);this.refreshFrame();};jvGroup.prototype.deleteElement = function(element){this.elements.remove(element.id);this.refreshFrame();};jvGroup.prototype.getValues = function(){return this.elements.getValues();};jvGroup.prototype.size = function(){return this.elements.size();};jvGroup.prototype.containsKey=function(k){return this.elements.containsKey(k);};jvGroup.prototype.refreshFrame = function(){var $g = this;var elements = this.getValues();if (this.size() < 2){this.removeFrame();return;}$g.x = elements[0].x;$g.y = elements[0].y;$g.width = elements[0].width;$g.height = elements[0].height;$(elements).each(function(i){$g.x = Math.min($g.x, this.x);$g.y = Math.min($g.y, this.y);});$(elements).each(function(i){$g.width = Math.max($g.width, this.x + this.width - $g.x);$g.height = Math.max($g.height, this.y + this.height - $g.y);});this.createFrame();};jvGroup.prototype.reDraw = function(){var x = this.x - this.state.x;var y = this.y - this.state.y;$(this.getValues()).each(function(i){this.reDraw(x, y);});};function jvEllipseElement(canvas, x, y, width, height, label){jvElement.call(this, canvas, jvConstants.SHAPE_ELLIPSE, x, y, width, height, label);this.create();return this;};jvEllipseElement.prototype = new jvElement();jvEllipseElement.prototype.constructor = jvEllipseElement;jvEllipseElement.prototype.draw = function(){var ctx = this.canvas.getContext('2d');ctx.beginPath(); var hB = (this.width / 2) * .5522848, vB = (this.height / 2) * .5522848, eX = this.x + this.width, eY = this.y + this.height, mX = this.x + this.width / 2, mY = this.y + this.height / 2; ctx.moveTo(this.x, mY); ctx.bezierCurveTo(this.x, mY - vB, mX - hB, this.y, mX, this.y); ctx.bezierCurveTo(mX + hB, this.y, eX, mY - vB, eX, mY); ctx.bezierCurveTo(eX, mY + vB, mX + hB, eY, mX, eY); ctx.bezierCurveTo(mX - hB, eY, this.x, mY + vB, this.x, mY); ctx.closePath(); ctx.strokeStyle = this.style[jvConstants.STYLE_STROKECOLOR];ctx.lineWidth = this.style[jvConstants.STYLE_STROKEWIDTH];ctx.fillStyle = this.style[jvConstants.BACKGROUND_COLOR];ctx.fill();ctx.stroke();this.setShape(2);};jvEllipseElement.prototype.createArea = function(){if (!this.imagemap){return;}if (this.area){$(this.area).remove();this.areaCoords = [];}var a = 0.5 * Math.sqrt(this.height * this.height + this.width * this.width),b = 0.5 * this.height,e = Math.sqrt(1.0 - b * b / a / a),ox = 0.5 * (this.x + this.width),oy = 0.5 * (this.y + this.height),phi = 0,sinphi = Math.sin(phi),cosphi = Math.cos(phi);for (var i=0;i< 360; i+=15){var sita = Math.PI / 180.0 * i ,cn = Math.cos(sita),sn = Math.sin(sita),r = b / Math.sqrt( 1.0 - e * e * cn * cn), tx = r * cn ,ty = r * sn,xx = tx * cosphi - ty * sinphi,yy = ty * cosphi + tx * sinphi;this.areaCoords.push(new jvPoint(Math.round(xx + ox), Math.round(yy + oy)));}this.buildArea();};function jvRectangleElement(canvas, x, y, width, height, radius, label){jvElement.call(this, canvas, jvConstants.SHAPE_RECTANGLE, x, y, width, height, label);this.radius = radius;this.create();return this;};jvRectangleElement.prototype = new jvElement();jvRectangleElement.prototype.constructor = jvRectangleElement;jvRectangleElement.prototype.draw = function(){var ctx = this.canvas.getContext('2d');ctx.beginPath();if (!this.radius) {ctx.rect(this.x, this.y, this.width, this.height);} else {ctx.moveTo(this.x, this.y + this.radius);ctx.lineTo(this.x, this.y + this.height - this.radius);ctx.quadraticCurveTo(this.x, this.y + this.height, this.x + this.radius, this.y + this.height); ctx.lineTo(this.x + this.width - this.radius, this.y + this.height);ctx.quadraticCurveTo(this.x + this.width, this.y + this.height, this.x + this.width, this.y + this.height - this.radius);ctx.lineTo(this.x + this.width, this.y + this.radius);ctx.quadraticCurveTo(this.x + this.width, this.y , this.x + this.width - this.radius, this.y);ctx.lineTo(this.x + this.radius, this.y);ctx.quadraticCurveTo(this.x , this.y, this.x, this.y + this.radius);}ctx.closePath();ctx.strokeStyle = this.style[jvConstants.STYLE_STROKECOLOR];ctx.lineWidth = this.style[jvConstants.STYLE_STROKEWIDTH];ctx.fillStyle = this.style[jvConstants.BACKGROUND_COLOR];ctx.fill();ctx.stroke();this.setShape(2);};function jvEdgeElement(canvas, source, target){jvElement.call(this, canvas, jvConstants.ELEMENT_TYPE_EDGE);this.source = source;this.target = target;this.edge = true;this.create();return this;};jvEdgeElement.prototype = new jvElement();jvEdgeElement.prototype.constructor = jvEdgeElement;jvEdgeElement.prototype.draw = function(){var ctx = this.canvas.getContext('2d');var p = [{x: this.source.x + this.source.width / 2, y: this.source.y - 1}, {x: this.source.x + this.source.width / 2, y: this.source.y + this.source.height + 1}, {x: this.source.x - 1, y: this.source.y + this.source.height / 2}, {x: this.source.x + this.source.width + 1, y: this.source.y + this.source.height / 2}, {x: this.target.x + this.target.width / 2, y: this.target.y - 1}, {x: this.target.x + this.target.width / 2, y: this.target.y + this.target.height + 1}, {x: this.target.x - 1, y: this.target.y + this.target.height / 2}, {x: this.target.x + this.target.width + 1, y: this.target.y + this.target.height / 2}];var d = {}, dis = [];for (var i = 0; i < 4; i++) { for (var j = 4; j < 8; j++) { var dx = Math.abs(p.x - p[j].x), dy = Math.abs(p.y - p[j].y); if ((i == j - 4) || (((i != 3 && j != 6) || p.x < p[j].x) && ((i != 2 && j != 7) || p.x > p[j].x) && ((i != 0 && j != 5) || p.y > p[j].y) && ((i != 1 && j != 4) || p.y < p[j].y))) { dis.push(dx + dy); d[dis[dis.length - 1]] = [i, j]; } }}if (dis.length == 0) { var res = [0, 4];} else { var res = d[Math.min.apply(Math, dis)];}var x1 = p[res[0]].x, y1 = p[res[0]].y, x4 = p[res[1]].x, y4 = p[res[1]].y/*, dx = Math.max(Math.abs(x1 - x4) / 2, 10), dy = Math.max(Math.abs(y1 - y4) / 2, 10), x2 = [x1, x1, x1 - dx, x1 + dx][res[0]].toFixed(3), y2 = [y1 - dy, y1 + dy, y1, y1][res[0]].toFixed(3), x3 = [0, 0, 0, 0, x4, x4, x4 - dx, x4 + dx][res[1]].toFixed(3), y3 = [0, 0, 0, 0, y1 + dy, y1 - dy, y4, y4][res[1]].toFixed(3)*/;this.x = x1;this.y = y1;this.width = x4;this.height = y4;ctx.beginPath();ctx.strokeStyle = this.style[jvConstants.STYLE_STROKECOLOR];ctx.lineWidth = this.style[jvConstants.STYLE_STROKEWIDTH];ctx.moveTo(x1, y1);ctx.lineTo(x4, y4);ctx.closePath(); ctx.stroke(); this.setShape(1);};function jvTextElement(canvas, value, parent){jvElement.call(this, canvas, jvConstants.SHAPE_TEXT);this.value = value;this.location = jvConstants.LABEL_LOCATION_BOTTOM;if (parent){this.parent = parent;this.create();}return this;};jvTextElement.prototype = new jvElement();jvTextElement.prototype.constructor = jvTextElement;jvTextElement.prototype.parent = null;jvTextElement.prototype.value = null;jvTextElement.prototype.table = null;jvTextElement.prototype.location = null;jvTextElement.prototype.position = function(){this.height = this.table.offsetHeight;this.setY();this.width = this.table.offsetWidth;this.setX();$(this.table).css({left:this.x, top:this.y, width:this.width, height:this.height});};jvTextElement.prototype.setX = function(){this.x = this.parent.x + (this.parent.width - this.width) / 2;};jvTextElement.prototype.setY = function(){if (this.location == jvConstants.LABEL_LOCATION_MIDDLE){this.y = this.parent.y + (this.parent.height - this.height) / 2;}else{this.y = this.parent.y + this.parent.height + jvConstants.LABEL_INTERVAL;}};jvTextElement.prototype.refreshX = function(x){if (this.parent.state.resized){this.setX();}else{this.x += x || 0;}};jvTextElement.prototype.refreshY = function(y){if (this.parent.state.resized){this.setY();}else{this.y += y || 0;}};jvTextElement.prototype.refreshPosition = function(x, y){this.refreshX(x);this.refreshY(y);$(this.table).css({left:this.x, top:this.y});};jvTextElement.prototype.create = function(){this.createHtmlTable();this.canvas.appendChild(this.table);this.position();};jvTextElement.prototype.createHtmlTable=function(){this.table=document.createElement('table');$(this.table).css({position:'absolute', 'border-collapse':'collapse'});var style = $.jvChart.getStylesheet().getDefaultTextStyle();$(this.table).css(style);var tbody=document.createElement('tbody');var tr=document.createElement('tr');var td=document.createElement('td');tr.appendChild(td);if (this.value){$(td).html(this.value);}tbody.appendChild(tr);this.table.appendChild(tbody);};$.jvChart = $.jvChart || {};$.extend($.jvChart,{createElement : function(tag, attribs, styles, parent, nopad) {var el = document.createElement(tag);if (attribs) $(el).attr(attribs);if (nopad) $(el).css({padding: 0, border: 'none', margin: 0});if (styles) $(el).css(styles);if (parent) $(parent).append(el);return el;},createCanvas : function(div){var cvs = $.jvChart.createElement('canvas', {id: div.id + '-canvas',width: $(div).width(),height: $(div).height()}, {position: 'absolute'}, div);if ($.browser.msie) {G_vmlCanvasManager.initElement(cvs);cvs = document.getElementById(cvs.id);}return cvs;},createSelect : function(div){var sd = $.jvChart.createElement('div', {id: div.id + '-select',left : 0,top : 0,width: 1,height: 1}, {position: 'absolute'}, div);return sd;},getElementID : function(){return jvConstants.ELEMENT_ID_PREFIX + jvConstants.ELEMENT_ID_COUNT ++;},dragMove: function(div, e) {var element = div.selected;if (div.selected.size() == 1){var element = div.selected.getValues()[0];}var x = e.clientX - element.state.startX;var y = e.clientY - element.state.startY;element.x = element.state.x + x;element.y = element.state.y + y;element.move(e);},bottomResize : function(div, e) {$(div.selected.getValues()).each( function(i) {var y = e.clientY - this.state.startY;this.height = this.state.height + y;this.state.changed = true;this.state.resized = true;this.move(e);});},topResize : function(div, e) {$(div.selected.getValues()).each( function(i) {var y = e.clientY - this.state.startY;this.y = this.state.y + y;this.height = this.state.height - y;this.state.changed = true;this.state.resized = true;this.move(e);});},reDrawConnections : function (paper){paper.edgePaper.ctx.clearRect(0, 0, paper.width, paper.height);$(paper.edgePaper.edges).each(function(i){$.jvChart.drawConnection(paper.edgePaper, document.getElementById(paper.edgePaper.edges[0]), document.getElementById(paper.edgePaper.edges[1]), 'rgb(0,0,0)', 2);});},reDrawElements : function (paper){$('.ui-draggable', $(paper.canvas)).remove();$(paper.elements).each(function(i){var e = paper.elements;if (e.type == 'ellipse'){$.jvChart.drawEllipse(paper, e.id, e.x, e.y, e.rx, e.ry, e.color, e.width);}else if(e.type == 'rectangle'){$.jvChart.drawRect(paper, e.id, e.x, e.y, e.w, e.h, e.r, e.color, e.width);}});}});(function($) {$.fn.jvChart = function() {$.extend($.jvChart,{getCvsId : function(){ return getCvsId();}});$.extend($.jvChart,{getStylesheet : function(){ return new jvStylesheet();}});return this.each( function() {this.elements = [];this.canvas = $.jvChart.createCanvas(this);this.selected = new jvGroup(this.canvas);//createImageMap(this);$(this).css({overflow:'hidden', position:'relative'});var $d = this;$(this).mousemove(function (e) {if (!getMouseButton(e).left){return;}if (this.selected.size() > 1){$.jvChart.dragMove($d, e);return false;}$(this.selected.getValues()).each( function(i) {if(this && this.state ){var action = this.state.action;if (action == jvConstants.ACTION_MOVE){$.jvChart.dragMove($d, e);}else if (action == jvConstants.END_POINT_MIDDLEBOTTOM){$.jvChart.bottomResize($d, e);}else if (action == jvConstants.END_POINT_MIDDLETOP){$.jvChart.topResize($d, e);}}});return false;}).mouseup(function (e) {if (this.selected.size() > 1){if (this.selected.state && this.selected.state.changed){this.selected.reDraw();}return false;}$(this.selected.getValues()).each( function(i) {if (this.state && this.state.changed){this.reDraw();}else{this.unselect();$d.selected.deleteElement(this);document.onselectstart=new Function ("return true");}});return false;}).mousedown(function (e) {$(this.selected.getValues()).each( function(i) {this.unselect();$d.selected.deleteElement(this);});});});};$.fn.extend({circle : function (x, y, r, color, width, fill, shadow, image) {return $.jvChart.drawCircle($(this).attr('paper'), x || 0, y || 0, r || 0, color, width, fill, shadow, image);},insertEllipse : function (x, y, rx, ry, label) {var element = new jvEllipseElement($(this).attr('canvas'), x, y, rx, ry, label);$(this).attr('elements').push(element);return element;},insertRectangle : function (x, y, w, h, r, label) {var element = new jvRectangleElement($(this).attr('canvas'), x, y, w, h, r, label);$(this).attr('elements').push(element);return element; }, insertEdge : function(source, target){ var element = new jvEdgeElement($(this).attr('canvas'), source, target); source.edges.push(element); target.edges.push(element); //$(this).attr('elements').push(element); return element; }, reDrawCanvas : function(){ var elements = $(this).attr('elements'); $(elements).each( function(i) { this.reDraw(); this.unselect(); }); }});})(jQuery);
调用js
$(document).ready(function(){$("#container").jvChart(300, 200);var v1 = $("#container").insertEllipse(10, 120, 80, 40, '椭圆');var s = {};s[jvConstants.STYLE_STROKECOLOR] = '#A0C88F';v1.setStyle(s);var v2 = $("#container").insertRectangle(100, 20, 80, 40, 10, '矩形');v2.setLabelLocation(jvConstants.LABEL_LOCATION_MIDDLE);var v4 = $("#container").insertEllipse(200, 100, 50, 50);var v3 = $("#container").insertRectangle(150, 180, 60, 40, 2); $("#container").insertEdge(v1, v2);$("#container").insertEdge(v2, v3);$("#container").insertEdge(v2, v4);/**/}); container是一个div:
<div id="container" style="width:640px; height:400px; background-color:rgb(255,255,255); background-image:url('images/graph/grid.gif')"></div> |
|