Ext扩展组件介绍之一--Ext.Drawing.Surface绘图组件(vml/svg)
Kimm King
2009年2月27日0:53:15
作为一个Ext JS的fans,我一直为Ext JS的UI为傲。
但是Ext JS的类库中并未提供关于Graphics的部分,不得不说的是一种遗憾。
可能是目前各个浏览器上并没有统一的相关实现,目前比较好的解决方法有两个:
一个是使用其他的、二进制的RIA工具来做绘图的容器比如(flash,silverlight)。另一个就是使用vml(IE only)、svg(general)。
今天在extjs官方论坛的扩展和自定义组件板块搜了下“graphic”,找到了一个组件Ext.Drawing.Surface。
作者是:nouveauc ,来自西非最富裕的国家——科特迪瓦。
组件比较简单,继承一个Box,根据浏览器判断使用vml还是svg,
定义了绘制和填充(矩形、圆、椭圆)等常见组件
~~~~~~~~~~~几个效果图的代码在附件中。~~~~~~~~~~~~~~
(详见:http://extjs.com/forum/showthread.php?t=50609)
在线例子:http://www.jadacosta.es/extjs/examples/drawing&charting/linechart.html
组件代码:
Ext.namespace("Ext.Drawing"); Ext.Drawing.version='version 0.0.1'; Ext.Drawing.vmlGraphic=function(s){ this.surface=s; var i=Ext.id(); this.svgid=i+'vml'; } Ext.Drawing.vmlGraphic.prototype.createRect=function(config){ var r =document.createElement("v:rect"); r.style.top=config.y; r.style.left=config.x; r.style.width=config.width; r.style.height=config.height; if(!Ext.isEmpty(config.fill)) { var d=this.createfill(config.fill); r.fill=d; } return new Ext.Element(r); } Ext.Drawing.vmlGraphic.prototype.createEllipse=function(config){ var r=document.createElement("v:oval"); r.style.top=config.cy-config.ry/2; r.style.left=config.cx-config.rx/2; r.style.width=config.rx; r.style.height=config.ry; if(!Ext.isEmpty(config.fill)) { r.fill=this.createfill(config.fill); } return new Ext.Element(r); } Ext.Drawing.vmlGraphic.prototype.createCircle=function(config){ var r=document.createElement("v:oval"); r.style.top=config.cy-config.r/2; r.style.left=config.cx-config.r/2; r.style.width=config.r; r.style.height=config.r; if(!Ext.isEmpty(config.fill)) { r.fill=this.createfill(config.fill); } return new Ext.Element(r); } Ext.Drawing.vmlGraphic.prototype.createfill=function(config) { var f = document.createElement("v:fill"); f.on=true; if(typeof config == "string"){ f.color=config; f.type="solid"; } else { if(!Ext.isEmpty(config.url)) return "url(#"+config.url+")"; else { if(config.type == "color" || !Ext.isEmpty(config.color)){ f.color=config.color; f.type="solid"; } else if(config.type == "linear"){ var stops=""; Ext.each(config.stops,function(it,ind,ar){ stops+=it.offset*100+"% "+it.color+"," }); f.colors=stops; f.type="gradient"; } else if(config.type == "radial"){ var stops=""; Ext.each(config.stops,function(it,ind,ar){ stops+=it.offset*100+"% "+it.color+"," }); f.colors=stops; f.type="gradientradial"; } } } return f; } Ext.Drawing.vmlGraphic.prototype.createRender=function(e) { if (!document.namespaces['vml']){ document.namespaces.add('vml', 'urn:schemas-microsoft-com:vml'); //var styleSheet = (document.styleSheets.length > 0) ? document.styleSheets[0] : document.createStyleSheet(); var styleSheet =document.createStyleSheet(); styleSheet.addRule('v\:* {behavior:url(#default#VML);}'); } return e; } Ext.Drawing.svgGraphic=function(s){ this.surface=s; var i=Ext.id(); this.svgid=i+'svg'; } Ext.Drawing.svgGraphic.prototype.createRect=function(config){ var r =document.createElementNS("http://www.w3.org/2000/svg","rect"); r.setAttribute("x",config.x); r.setAttribute("y",config.y); r.setAttribute("width",config.width); r.setAttribute("height",config.height); if(!Ext.isEmpty(config.fill)) { r.setAttribute("fill",this.createfill(config.fill)); } return new Ext.Element(r); } Ext.Drawing.svgGraphic.prototype.createEllipse=function(config){ var r=document.createElementNS("http://www.w3.org/2000/svg","ellipse"); r.setAttribute("cx",config.cx); r.setAttribute("cy",config.cy); r.setAttribute("rx",config.rx); r.setAttribute("ry",config.ry); if(!Ext.isEmpty(config.fill)) { r.setAttribute("fill",this.createfill(config.fill)); } return new Ext.Element(r); } Ext.Drawing.svgGraphic.prototype.createCircle=function(config){ var r=document.createElementNS("http://www.w3.org/2000/svg","circle"); r.setAttribute("cx",config.cx); r.setAttribute("cy",config.cy); r.setAttribute("r",config.r); if(!Ext.isEmpty(config.fill)) { r.setAttribute("fill",this.createfill(config.fill)); } return new Ext.Element(r); } Ext.Drawing.svgGraphic.prototype.createfill=function(config) { if(typeof config == "string") return config; else { if(!Ext.isEmpty(config.url)) return "url(#"+config.url+")"; else { if(config.type == "color" || !Ext.isEmpty(config.color)) return config.color; else if(config.type == "linear"){ var grad=document.createElementNS("http://www.w3.org/2000/svg","linearGradient"); if(Ext.isEmpty()) grad.id=Ext.id(); else grad.id=config.id; if(!Ext.isEmpty(config.x1)) grad.setAttribute("x1",config.x1); if(!Ext.isEmpty(config.x1)) grad.setAttribute("y1",config.y1); if(!Ext.isEmpty(config.x1)) grad.setAttribute("x2",config.x2); if(!Ext.isEmpty(config.x1)) grad.setAttribute("y2",config.y2); Ext.each(config.stops,function(it,ind,ar){ var st=document.createElementNS("http://www.w3.org/2000/svg","stop"); st.setAttribute("offset",it.offset); st.setAttribute("style","stop-color:"+it.color); grad.appendChild(st); }); this.surface.defs.appendChild(grad); return "url(#"+grad.id+")"; } else if(config.type == "radial"){ var grad=document.createElementNS("http://www.w3.org/2000/svg","radialGradient"); if(Ext.isEmpty()) grad.id=Ext.id(); else grad.id=config.id; grad.setAttribute("cx",config.cx); grad.setAttribute("cy",config.cy); grad.setAttribute("fx",config.fx); grad.setAttribute("fy",config.fy); grad.setAttribute("r",config.r); Ext.each(config.stops,function(it,ind,ar){ var st=document.createElementNS("http://www.w3.org/2000/svg","stop"); st.setAttribute("offset",it.offset); st.setAttribute("style","stop-color:"+it.color); grad.appendChild(st); }); this.surface.defs.appendChild(grad); return "url(#"+grad.id+")"; } } } } Ext.Drawing.svgGraphic.prototype.createRender=function(e) { var el=document.createElementNS("http://www.w3.org/2000/svg","svg"); el.setAttribute("width",this.surface.width+"px"); el.setAttribute("height",this.surface.height+"px"); e.insertFirst(el); var def=document.createElementNS("http://www.w3.org/2000/svg","defs"); el.appendChild(def); this.surface.defs=def; return el; } Ext.Drawing.Surface=Ext.extend(Ext.BoxComponent,{ initComponent : function(){ Ext.Drawing.Surface.superclass.initComponent.call(this); if(Ext.isIE) this.graphic=new Ext.Drawing.vmlGraphic(this); else this.graphic=new Ext.Drawing.svgGraphic(this); }, onRender : function(ct, position){ Ext.Drawing.Surface.superclass.onRender.call(this, ct, position); this.el=Ext.get(this.renderTo); this.render=this.graphic.createRender(this.el); if(!this.width){ var sz = this.el.getSize(); this.setSize(sz.width, this.height || sz.height); } }, // private onDestroy : function(){ } }); Ext.reg('surface', Ext.Drawing.Surface);
test:
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>XTech SVG Demo</title> <link href="../sivom/ext/resources/css/ext-all.css" rel="stylesheet" type="text/css" /> <script language="javascript" src="../sivom/ext/adapter/ext/ext-base.js"></script> <script language="javascript" src="../sivom/ext/ext-all.js"></script> <script language="javascript" src="../drawing/Graphic.js"></script> <script language="javascript"> Ext.onReady(function(){ var sur=new Ext.Drawing.Surface( { width:600, height:600, renderTo:'essdiv' } ); var m= sur.graphic.createRect({ x:20, y:30, width:200, height:300, fill:{ type:"linear", stops:[{offset:"0",color:"#FFFF00"},{offset:"0.75",color:"#0000FF"},{offset:"1",color:"#F0F0FF"}] } }); var r=sur.graphic.createCircle({ cx:100, cy:50, r:100, fill:"red" }); sur.render.appendChild(m.dom); sur.render.appendChild(r.dom); }); </script> </head> <body id="body" style="border: 1px solid black; position: absolute; z-index: 0; left: 5%; top: 5%; width: 90%; height: 90%;"> <div id="essdiv"></div> </body> </html>