From dd6de9b2006cfe5bc7be28d70addc321691d2746 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Mon, 7 May 2012 10:19:08 +0200 Subject: [IMP] replacing by flotr2, initial commit bzr revid: fp@tinyerp.com-20120507081908-j0sfm5f84f0t32yg --- .../static/lib/dhtmlxGraph/sources/dhtmlxchart.js | 3498 -------------------- 1 file changed, 3498 deletions(-) delete mode 100644 addons/web_graph/static/lib/dhtmlxGraph/sources/dhtmlxchart.js (limited to 'addons/web_graph/static/lib/dhtmlxGraph/sources/dhtmlxchart.js') diff --git a/addons/web_graph/static/lib/dhtmlxGraph/sources/dhtmlxchart.js b/addons/web_graph/static/lib/dhtmlxGraph/sources/dhtmlxchart.js deleted file mode 100644 index cbb0f8346bd..00000000000 --- a/addons/web_graph/static/lib/dhtmlxGraph/sources/dhtmlxchart.js +++ /dev/null @@ -1,3498 +0,0 @@ -/* -2010 July 02 -*/ - - - -/* DHX DEPEND FROM FILE 'assert.js'*/ - - -if (!window.dhtmlx) - dhtmlx={}; - -//check some rule, show message as error if rule is not correct -dhtmlx.assert = function(test, message){ - if (!test) dhtmlx.error(message); -}; -dhtmlx.assert_enabled=function(){ return false; }; - -//register names of event, which can be triggered by the object -dhtmlx.assert_event = function(obj, evs){ - if (!obj._event_check){ - obj._event_check = {}; - obj._event_check_size = {}; - } - - for (var a in evs){ - obj._event_check[a.toLowerCase()]=evs[a]; - var count=-1; for (var t in evs[a]) count++; - obj._event_check_size[a.toLowerCase()]=count; - } -}; -dhtmlx.assert_method_info=function(obj, name, descr, rules){ - var args = []; - for (var i=0; i < rules.length; i++) { - args.push(rules[i][0]+" : "+rules[i][1]+"\n "+rules[i][2].describe()+(rules[i][3]?"; optional":"")); - } - return obj.name+"."+name+"\n"+descr+"\n Arguments:\n - "+args.join("\n - "); -}; -dhtmlx.assert_method = function(obj, config){ - for (var key in config) - dhtmlx.assert_method_process(obj, key, config[key].descr, config[key].args, (config[key].min||99), config[key].skip); -}; -dhtmlx.assert_method_process = function (obj, name, descr, rules, min, skip){ - var old = obj[name]; - if (!skip) - obj[name] = function(){ - if (arguments.length != rules.length && arguments.length < min) - dhtmlx.log("warn","Incorrect count of parameters\n"+obj[name].describe()+"\n\nExpecting "+rules.length+" but have only "+arguments.length); - else - for (var i=0; i= 0) return true; - return false; - }; - dhtmlx.assert_rule_dimension.describe=function(){ - return "{Integer} value must be a positive number"; - }; - - dhtmlx.assert_rule_number=function(check){ - if (typeof check == "number") return true; - return false; - }; - dhtmlx.assert_rule_number.describe=function(){ - return "{Integer} value must be a number"; - }; - - dhtmlx.assert_rule_function=function(check){ - if (typeof check == "function") return true; - return false; - }; - dhtmlx.assert_rule_function.describe=function(){ - return "{Function} value must be a custom function"; - }; - - dhtmlx.assert_rule_any=function(check){ - return true; - }; - dhtmlx.assert_rule_any.describe=function(){ - return "Any value"; - }; - - dhtmlx.assert_rule_mix=function(a,b){ - var t = function(check){ - if (a(check)||b(check)) return true; - return false; - }; - t.describe = function(){ - return a.describe(); - }; - return t; - }; - -} - - -/* DHX DEPEND FROM FILE 'dhtmlx.js'*/ - - -/*DHX:Depend assert.js*/ - -/* - Common helpers -*/ -dhtmlx.version="3.0"; -dhtmlx.codebase="./"; - -//coding helpers - -//copies methods and properties from source to the target -dhtmlx.extend = function(target, source){ - for (var method in source) - target[method] = source[method]; - - //applying asserts - if (dhtmlx.assert_enabled() && source._assert){ - target._assert(); - target._assert=null; - } - - //if source object has init code - call init against target - if (source._init) - target._init(); - - return target; -}; -//creates function with specified "this" pointer -dhtmlx.bind=function(functor, object){ - return function(){ return functor.apply(object,arguments); }; -}; - -//loads module from external js file -dhtmlx.require=function(module){ - if (!dhtmlx._modules[module]){ - dhtmlx.assert(dhtmlx.ajax,"load module is required"); - - //load and exec the required module - dhtmlx.exec( dhtmlx.ajax().sync().get(dhtmlx.codebase+module).responseText ); - dhtmlx._modules[module]=true; - } -}; -dhtmlx._modules = {}; //hash of already loaded modules - -//evaluate javascript code in the global scoope -dhtmlx.exec=function(code){ - if (window.execScript) //special handling for IE - window.execScript(code); - else window.eval(code); -}; - -/* - creates method in the target object which will transfer call to the source object - if event parameter was provided , each call of method will generate onBefore and onAfter events -*/ -dhtmlx.methodPush=function(object,method,event){ - return function(){ - var res = false; - //if (!event || this.callEvent("onBefore"+event,arguments)){ //not used anymore, probably can be removed - res=object[method].apply(object,arguments); - // if (event) this.callEvent("onAfter"+event,arguments); - //} - return res; //result of wrapped method - }; -}; -//check === undefined -dhtmlx.isNotDefined=function(a){ - return typeof a == "undefined"; -}; -//delay call to after-render time -dhtmlx.delay=function(method, obj, params){ - setTimeout(function(){ - var ret = method.apply(obj,params); - method = obj = params = null; - return ret; - },1); -}; - -//common helpers - -//generates unique ID (unique per window, nog GUID) -dhtmlx.uid = function(){ - if (!this._seed) this._seed=(new Date).valueOf(); //init seed with timestemp - this._seed++; - return this._seed; -}; -//resolve ID as html object -dhtmlx.toNode = function(node){ - if (typeof node == "string") return document.getElementById(node); - return node; -}; -//adds extra methods for the array -dhtmlx.toArray = function(array){ - return dhtmlx.extend((array||[]),dhtmlx.PowerArray); -}; -//resolve function name -dhtmlx.toFunctor=function(str){ - return (typeof(str)=="string") ? eval(str) : str; -}; - -//dom helpers - -//hash of attached events -dhtmlx._events = {}; -//attach event to the DOM element -dhtmlx.event=function(node,event,handler,master){ - node = dhtmlx.toNode(node); - - var id = dhtmlx.uid(); - dhtmlx._events[id]=[node,event,handler]; //store event info, for detaching - - if (master) - handler=dhtmlx.bind(handler,master); - - //use IE's of FF's way of event's attaching - if (node.addEventListener) - node.addEventListener(event, handler, false); - else if (node.attachEvent) - node.attachEvent("on"+event, handler); - - return id; //return id of newly created event, can be used in eventRemove -}; - -//remove previously attached event -dhtmlx.eventRemove=function(id){ - - if (!id) return; - dhtmlx.assert(this._events[id],"Removing non-existing event"); - - var ev = dhtmlx._events[id]; - //browser specific event removing - if (ev[0].removeEventListener) - ev[0].removeEventListener(ev[1],ev[2],false); - else if (ev[0].detachEvent) - ev[0].detachEvent("on"+ev[1],ev[2]); - - delete this._events[id]; //delete all traces -}; - - -//debugger helpers -//anything starting from error or log will be removed during code compression - -//add message in the log -dhtmlx.log = function(type,message,details){ - if (window.console && console.log){ - type=type.toLowerCase(); - if (window.console[type]) - window.console[type](message); - else - window.console.log(type +": "+message); - if (details) - window.console.log(details); - } -}; -//register rendering time from call point -dhtmlx.log_full_time = function(name){ - dhtmlx._start_time_log = new Date(); - dhtmlx.log("Info","Timing start ["+name+"]"); - window.setTimeout(function(){ - var time = new Date(); - dhtmlx.log("Info","Timing end ["+name+"]:"+(time.valueOf()-dhtmlx._start_time_log.valueOf())/1000+"s"); - },1); -}; -//register execution time from call point -dhtmlx.log_time = function(name){ - var fname = "_start_time_log"+name; - if (!dhtmlx[fname]){ - dhtmlx[fname] = new Date(); - dhtmlx.log("Info","Timing start ["+name+"]"); - } else { - var time = new Date(); - dhtmlx.log("Info","Timing end ["+name+"]:"+(time.valueOf()-dhtmlx[fname].valueOf())/1000+"s"); - dhtmlx[fname] = null; - } -}; -//log message with type=error -dhtmlx.error = function(message,details){ - dhtmlx.log("Error",message,details); -}; -//event system -dhtmlx.EventSystem={ - _init:function(){ - this._events = {}; //hash of event handlers, name => handler - this._handlers = {}; //hash of event handlers, ID => handler - this._map = {}; - }, - //temporary block event triggering - block : function(){ - this._events._block = true; - }, - //re-enable event triggering - unblock : function(){ - this._events._block = false; - }, - mapEvent:function(map){ - dhtmlx.extend(this._map, map); - }, - //trigger event - callEvent:function(type,params){ - if (this._events._block) return true; - - type = type.toLowerCase(); - dhtmlx.assert_event_call(this, type, params); - - var event_stack =this._events[type.toLowerCase()]; //all events for provided name - var return_value = true; - - if (dhtmlx.debug) //can slowdown a lot - dhtmlx.log("info","["+this.name+"] event:"+type,params); - - if (event_stack) - for(var i=0; i=0) this.splice(pos,(len||1)); - }, - //find element in collection and remove it - remove:function(value){ - this.removeAt(this.find(value)); - }, - //add element to collection at specific position - insertAt:function(data,pos){ - if (!pos && pos!==0) //add to the end by default - this.push(data); - else { - var b = this.splice(pos,(this.length-pos)); - this[pos] = data; - this.push.apply(this,b); //reconstruct array without loosing this pointer - } - }, - //return index of element, -1 if it doesn't exists - find:function(data){ - for (i=0; i0){ - str=this._toHex[number%16]+str; - number=Math.floor(number/16); - } - while (str.length "); - }, - addSector:function(id,alpha0,alpha1,x,y,R,ky){ - var points = []; - points.push(x); - points.push(Math.floor(y*ky)); - for(var i = alpha0; i < alpha1; i+=Math.PI/18){ - points.push(Math.floor(x+R*Math.cos(i))); - points.push(Math.floor((y+R*Math.sin(i))*ky)); - } - points.push(Math.floor(x+R*Math.cos(alpha1))); - points.push(Math.floor((y+R*Math.sin(alpha1))*ky)); - points.push(x); - points.push(Math.floor(y*ky)); - - return this.addPoly(id,points); - }, - render:function(obj){ - var d = dhtmlx.html.create("DIV"); - d.style.cssText="position:absolute; width:100%; height:100%; top:0px; left:0px;"; - obj.appendChild(d); - var src = dhtmlx._isIE?"":"src='data:image/gif;base64,R0lGODlhEgASAIAAAP///////yH5BAUUAAEALAAAAAASABIAAAIPjI+py+0Po5y02ouz3pwXADs='"; - d.innerHTML=""+this._map.join("\n")+""; - - obj._htmlmap = d; //for clearing routine - - this._map = []; - } -}; - - -/* DHX DEPEND FROM FILE 'chart_graph.js'*/ - - -/*DHX:Depend map.js*/ - -if (!dhtmlx.chart) dhtmlx.chart = {}; - -dhtmlx.chart.line = { - - /** - * renders a graphic - * @param: ctx - canvas object - * @param: data - object those need to be displayed - * @param: width - the width of the container - * @param: height - the height of the container - */ - pvt_render_line:function(ctx, data, width, height){ - var maxValue,minValue; - /*necessary if maxValue - minValue < 0*/ - var valueFactor; - /*maxValue - minValue*/ - var relValue; - - - /*necessary to add events and tooltips*/ - var map = new dhtmlx.ui.Map(this._id); - - /*scales*/ - var yax = !!this._settings.yAxis; - var xax = !!this._settings.xAxis; - - if(yax&&(typeof this._settings.yAxis.end!="undefied")&&(typeof this._settings.yAxis.start!="undefied")&&this._settings.yAxis.step){ - maxValue = parseFloat(this._settings.yAxis.end); - minValue = parseFloat(this._settings.yAxis.start); - } - else{ - maxValue = this.max(this._settings.value); - minValue = this.min(this._settings.value); - } - - /*a vertical scale*/ - this._drawYAxis(ctx,data,width,height,minValue,maxValue); - - /*necessary for automatic scale*/ - if(yax){ - maxValue = parseFloat(this._settings.yAxis.end); - minValue = parseFloat(this._settings.yAxis.start); - } - - var topPadding = parseInt(this._settings.padding.top,10); - var leftPadding = parseInt(this._settings.padding.left,10); - var bottomPadding = parseInt(this._settings.padding.bottom,10); - var rightPadding = parseInt(this._settings.padding.right,10); - - /*available height*/ - var total_height = height-topPadding-bottomPadding; - - - /*unit calculation (y_position = value*unit)*/ - var relativeValues = this._getRelativeValue(minValue,maxValue); - relValue = relativeValues[0]; - valueFactor = relativeValues[1]; - var unit = total_height/relValue; - - if(!yax){ - /*defines start value for better representation of small values*/ - var startValue = (unit>10?unit:10); - unit = (total_height-startValue)/relValue; - } - - /*a space available for a single item*/ - var cellWidth = Math.round((width - leftPadding - rightPadding)/data.length); - - /*the value that defines the map area position*/ - var areaPos = Math.floor(cellWidth/2); - - /*drawing all items*/ - if (data.length) { - /*gets the vertical coordinate of an item*/ - var _graph_point = function(data){ - /*the real value of an object*/ - var value = this._settings.value(data); - /*a relative value*/ - var v = (parseFloat(value) - minValue)*valueFactor; - if(!yax) - v += startValue/unit; - /*a vertical coordinate*/ - var y = height - Math.floor(unit*v) - bottomPadding; - /*the limit of the minimum value is the minimum visible value*/ - if(v<0) - y = height - topPadding; - /*the limit of the maximum value*/ - if(value > maxValue) - y = topPadding; - /*the limit of the minimum value*/ - if(value < minValue) - y = height - bottomPadding; - return y; - }; - /*the vertical position of the first item*/ - var y1 = _graph_point.call(this,data[0]); - /*drawing the previous item and the line between to items*/ - for(var i=1; i <= data.length;i ++){ - - - /*horizontal positions of the previous and current items (0.5 - the fix for line width)*/ - var x1 = Math.floor(cellWidth*(i-0.5)) - 0.5 + leftPadding; - var x2 = Math.floor(cellWidth*(i+0.5)) - 0.5 + leftPadding; - - /*sets label on the horizontal scale*/ - this._drawXAxisLabel(x1,data[i-1]); - /*draws a vertical line for the horizontal scale*/ - this._drawXAxisLine(ctx,x1,height-bottomPadding,topPadding); - - /*a line between items*/ - if (data.length!=i){ - var y2 = _graph_point.call(this,data[i]); - this._drawLine(ctx,x1,y1,x2,y2,this._settings.line.color(data[i-1]),this._settings.line.width); - } - - /*draws prevous item*/ - this._drawGraphicItem(ctx,x1,y1,data[i-1]); - - /*creates map area*/ - map.addRect(data[i-1].id,[x1-areaPos,y1-areaPos,x1+areaPos,y1+areaPos]); - - y1=y2; - } - _graph_point = null; - } - /*horizontal scale*/ - this._drawXAxis(ctx,data,width,height); - map.render(this._obj); - }, - /** - * draws an item and its label - * @param: ctx - canvas object - * @param: x0 - the x position of a circle - * @param: y0 - the y position of a circle - * @param: obj - data object - */ - _drawGraphicItem:function(ctx,x0,y0,obj){ - var R = parseInt(this._settings.item.radius,10); - ctx.lineWidth = parseInt(this._settings.item.borderWidth,10); - ctx.fillStyle = this._settings.item.color(obj); - ctx.strokeStyle = this._settings.item.borderColor(obj); - ctx.beginPath(); - ctx.arc(x0,y0,R,0,Math.PI*2,true); - ctx.fill(); - ctx.stroke(); - /*item label*/ - this.renderTextAt(false, true, x0,y0-R-this._settings.labelOffset,this._settings.label(obj)); - } -}; - - -/* DHX DEPEND FROM FILE 'chart_bar.js'*/ - - -/*DHX:Depend map.js*/ - -if (!dhtmlx.chart) dhtmlx.chart = {}; - -dhtmlx.chart.bar = { - /** - * renders a bar chart - * @param: ctx - canvas object - * @param: data - object those need to be displayed - * @param: x - the width of the container - * @param: y - the height of the container - */ - pvt_render_bar:function(ctx, data, x, y){ - var maxValue,minValue; - /*necessary if maxValue - minValue < 0*/ - var valueFactor; - /*maxValue - minValue*/ - var relValue; - - var map = new dhtmlx.ui.Map(this._id); - - var yax = !!this._settings.yAxis; - var xax = !!this._settings.xAxis; - - if(yax&&(typeof this._settings.yAxis.end!="undefied")&&(typeof this._settings.yAxis.start!="undefied")&&this._settings.yAxis.step){ - maxValue = parseFloat(this._settings.yAxis.end); - minValue = parseFloat(this._settings.yAxis.start); - } - else{ - maxValue = this.max(this._settings.value); - minValue = this.min(this._settings.value); - } - - /*a vertical scale*/ - this._drawYAxis(ctx,data,x,y,minValue,maxValue); - - /*necessary for automatic scale*/ - if(yax){ - maxValue = parseFloat(this._settings.yAxis.end); - minValue = parseFloat(this._settings.yAxis.start); - } - - var yPadding = parseInt(this._settings.padding.top,10); - var xPadding = parseInt(this._settings.padding.left,10); - var bottomPadding = parseInt(this._settings.padding.bottom,10); - var total_height = y-yPadding-bottomPadding; - - /*unit calculation (bar_height = value*unit)*/ - var relativeValues = this._getRelativeValue(minValue,maxValue); - relValue = relativeValues[0]; - valueFactor = relativeValues[1]; - - var unit = total_height/relValue; - if(!yax){ - /*defines start value for better representation of small values*/ - var startValue = (unit>10?unit:10); - unit = (total_height-startValue)/relValue; - } - - /*an available width for one bar*/ - var cellWidth = Math.floor((x-xPadding-parseInt(this._settings.padding.right,10))/data.length); - /*a real bar width */ - var barWidth = parseInt(this._settings.width,10); - if(barWidth>cellWidth) barWidth = cellWidth-2; - /*the half of distance between bars*/ - var barOffset = Math.floor((cellWidth - barWidth)/2); - /*the radius of rounding in the top part of each bar*/ - var radius = Math.round(barWidth/5); - - var inner_gradient = false; - var gradient = this._settings.gradient; - - if (gradient === true){ - inner_gradient = true; - gradient = false; - } else if (gradient){ - gradient = ctx.createLinearGradient(0,bottomPadding,0,y-yPadding); - this._settings.gradient(gradient); - } - var scaleY = 0; - /*draws a black line if the horizontal scale isn't defined*/ - if(bottomPadding&&!xax){ - scaleY = y-bottomPadding; - this._drawLine(ctx,0,scaleY+0.5,x,scaleY+0.5,"#000000",1); //hardcoded color! - } - - for(var i=0; i < data.length;i ++){ - - - var value = parseFloat(this._settings.value(data[i])); - if(value>maxValue) value = maxValue; - value -= minValue; - value *= valueFactor; - - /*start point (bottom left)*/ - var x0 = xPadding + barOffset + i*cellWidth; - var y0 = y-bottomPadding; - - - /*sets a label in the horizontal scale*/ - this._drawXAxisLabel(x0+Math.floor(barWidth/2),data[i]); - - if(value<0||(this._settings.yAxis&&value===0)){ - this.renderTextAt(true, true, x0+Math.floor(barWidth/2),y0,this._settings.label(data[i])); - continue; - } - - /*takes start value into consideration*/ - if(!yax) value += startValue/unit; - var color = gradient||this._settings.color.call(this,data[i]); - - /*drawing the gradient border of a bar*/ - if(this._settings.border){ - ctx.beginPath(); - ctx.fillStyle = color; - this._setBarPoints(ctx,x0-1,y0,barWidth+2,radius,unit,value,0); - ctx.lineTo(x0,0); - ctx.fill(); - - ctx.fillStyle = "#000000"; - ctx.globalAlpha = 0.37; - ctx.beginPath(); - this._setBarPoints(ctx,x0-1,y0,barWidth+2,radius,unit,value,0); - ctx.fill(); - } - - /*drawing bar body*/ - ctx.globalAlpha = this._settings.alpha.call(this,data[i]); - ctx.fillStyle = (gradient||this._settings.color.call(this,data[i])); - ctx.beginPath(); - var points = this._setBarPoints(ctx,x0,y0,barWidth,radius,unit,value,(this._settings.border?1:0)); - if (gradient) ctx.lineTo(x0,0); //fix gradient sphreading - ctx.fill(); - ctx.globalAlpha = 1; - - if (inner_gradient){ - var i_gradient = ctx.createLinearGradient(0,y0-unit*value+2,0,y0); - i_gradient.addColorStop(0,color); - i_gradient.addColorStop(0.1,color); - i_gradient.addColorStop(1,"#FFFFFF"); - ctx.fillStyle = i_gradient; - ctx.beginPath(); - var points = this._setBarPoints(ctx,x0+2,y0,barWidth-4,radius,unit,value,1); - ctx.fill(); - } - - - /*sets a bar label*/ - this.renderTextAt(true, true, x0+Math.floor(barWidth/2),points[1],this._settings.label(data[i])); - /*defines a map area for a bar*/ - map.addRect(data[i].id,[x0,points[1],points[0],y0]); - } - - this._drawXAxis(ctx,data,x,y); - map.render(this._obj); - }, - /** - * sets points for bar and returns the position of the bottom right point - * @param: ctx - canvas object - * @param: x0 - the x position of start point - * @param: y0 - the y position of start point - * @param: barWidth - bar width - * @param: radius - the rounding radius of the top - * @param: unit - the value defines the correspondence between item value and bar height - * @param: value - item value - * @param: offset - the offset from expected bar edge (necessary for drawing border) - */ - _setBarPoints:function(ctx,x0,y0,barWidth,radius,unit,value,offset){ - /*correction for displaing small values (when rounding radius is bigger than bar height)*/ - var angle_corr = 0; - if(radius>unit*value){ - var cosA = (radius-unit*value)/radius; - angle_corr = -Math.acos(cosA)+Math.PI/2; - } - /*start*/ - ctx.moveTo(x0,y0); - /*start of left rounding*/ - var y1 = y0 - Math.floor(unit*value) + radius; - if(radiusdetails.total_height)) - y0 += y-details.total_height-ctx.lineWidth/2; - /*considers item index*/ - y0 += i*details.height; - - ctx.moveTo(x0,y0); - var x1 = x0+details.marker.width-details.marker.height +1; - ctx.lineTo(x1,y0); - ctx.stroke(); - - /*item text*/ - this.renderText(x1+details.marker.width/2+5,y0-details.marker.height/2,details.template(obj)); - }, - /** - * returns calculated pie parameters: center position and radius - * @param: x - the width of a container - * @param: y - the height of a container - */ - _getPieParameters:function(x,y){ - var offset = 0; - if(this._settings.legend) - offset = this._settings.legend.width*(this._settings.legend.align=="right"?-1:1); - x = (x + offset)/2; - y = y/2; - var radius = Math.min(x,y)-this._settings.padding.top; - return {"x":x,"y":y,"radius":radius}; - }, - /** - * creates lower part of sector in 3Dpie - * @param: ctx - canvas object - * @param: x0 - the horizontal position of the pie center - * @param: y0 - the vertical position of the pie center - * @param: a0 - the angle that defines the first edge of a sector - * @param: a1 - the angle that defines the second edge of a sector - * @param: R - pie radius - * @param: line (boolean) - if the sector needs a border - */ - _createLowerSector:function(ctx,x0,y0,a1,a2,R,line){ - ctx.lineWidth = 1; - /*checks if the lower sector needs being displayed*/ - if(!((a1<=0 && a2>=0)||(a1>=0 && a2<=Math.PI)||(a1<=Math.PI && a2>=Math.PI))) return; - - if(a1<=0 && a2>=0){ - a1 = 0; - line = false; - this._drawSectorLine(ctx,x0,y0,R,a1,a2); - } - if(a1<=Math.PI && a2>=Math.PI){ - a2 = Math.PI; - line = false; - this._drawSectorLine(ctx,x0,y0,R,a1,a2); - } - /*the height of 3D pie*/ - var offset = (this._settings.height||Math.floor(R/4))/this._settings.cant; - ctx.beginPath(); - ctx.arc(x0,y0,R,a1,a2,false); - ctx.lineTo(x0+R*Math.cos(a2),y0+R*Math.sin(a2)+offset); - ctx.arc(x0,y0+offset,R,a2,a1,true); - ctx.lineTo(x0+R*Math.cos(a1),y0+R*Math.sin(a1)); - ctx.fill(); - if(line) - ctx.stroke(); - }, - /** - * draws a serctor arc - */ - _drawSectorLine:function(ctx,x0,y0,R,a1,a2){ - ctx.beginPath(); - ctx.arc(x0,y0,R,a1,a2,false); - ctx.stroke(); - }, - /** - * adds a shadow to pie - * @param: ctx - canvas object - * @param: x - the horizontal position of the pie center - * @param: y - the vertical position of the pie center - * @param: R - pie radius - */ - _addShadow:function(ctx,x,y,R){ - var shadows = ["#676767","#7b7b7b","#a0a0a0","#bcbcbc","#d1d1d1","#d6d6d6"]; - for(var i = shadows.length-1;i>-1;i--){ - ctx.beginPath(); - ctx.fillStyle = shadows[i]; - ctx.arc(x+2,y+2,R+i,0,Math.PI*2,true); - ctx.fill(); - } - }, - /** - * returns a gray gradient - * @param: gradient - gradient object - */ - _getGrayGradient:function(gradient){ - gradient.addColorStop(0.0,"#ffffff"); - gradient.addColorStop(0.7,"#7a7a7a"); - gradient.addColorStop(1.0,"#000000"); - return gradient; - }, - /** - * adds gray radial gradient - * @param: ctx - canvas object - * @param: x - the horizontal position of the pie center - * @param: y - the vertical position of the pie center - * @param: radius - pie radius - * @param: x0 - the horizontal position of a gradient center - * @param: y0 - the vertical position of a gradient center - */ - _showRadialGradient:function(ctx,x,y,radius,x0,y0){ - ctx.globalAlpha = 0.3; - ctx.beginPath(); - var gradient; - if(typeof this._settings.gradient!= "function"){ - gradient = ctx.createRadialGradient(x0,y0,radius/4,x,y,radius); - gradient = this._getGrayGradient(gradient); - } - else gradient = this._settings.gradient(gradient); - ctx.fillStyle = gradient; - ctx.arc(x,y,radius,0,Math.PI*2,true); - ctx.fill(); - ctx.globalAlpha = 1; - }, - /** - * returns the calculates pie parameters: center position and radius - * @param: ctx - canvas object - * @param: x0 - the horizontal position of the pie center - * @param: y0 - the vertical position of the pie center - * @param: R - pie radius - * @param: alpha1 - the angle that defines the 1st edge of a sector - * @param: alpha2 - the angle that defines the 2nd edge of a sector - * @param: ky - the value that defines an angle of inclination - * @param: text - label text - * @param: in_width (boolean) - if label needs being displayed inside a pie - */ - _drawSectorLabel:function(x0,y0,R,alpha1,alpha2,ky,text,in_width){ - var t = this.renderText(0,0,text,0,1); - if (!t) return; - - //get existing width of text - var labelWidth = t.scrollWidth; - t.style.width = labelWidth+"px"; //adjust text label to fit all text - if (labelWidth>x0) labelWidth = x0; //the text can't be greater than half of view - - //calculate expected correction based on default font metrics - var width = 8; - if (in_width) width = labelWidth/1.8; - var alpha = alpha1+(alpha2-alpha1)/2; - - //calcualteion position and correction - R = R-(width-8)/2; - var corr_x = - width; - var corr_y = -8; - var align = "left"; - - //for items in right upper sector - if(alpha>=Math.PI/2 && alpha=Math.PI){ - corr_x = -labelWidth-corr_x+1; - align = "right"; - } - - //calculate position of text - //basically get point at center of pie sector - var y = (y0+Math.floor(R*Math.sin(alpha)))*ky+corr_y; - var x = x0+Math.floor((R+width/2)*Math.cos(alpha))+corr_x; - - //if pie sector starts in left of right part pie, related text - //must be placed to the left of to the right of pie as well - var left_end = (alpha2 < Math.PI/2+0.01) - var left_start = (alpha < Math.PI/2); - if (left_start && left_end) - x = Math.max(x,x0+3); //right part of pie - else if (!left_start && !left_end) - x = Math.min(x,x0-labelWidth); //left part of pie - - - /*correction for the lower sector of the 3D pie*/ - if (!in_width && ky<1 && y > y0*ky){ - y+= (this._settings.height||Math.floor(R/4)); - } - - //we need to set position of text manually, based on above calculations - t.style.top = y+"px"; - t.style.left = x+"px"; - t.style.width = labelWidth+"px"; - t.style.textAlign = align; - t.style.whiteSpace = "nowrap"; - } -}; - - -/* DHX DEPEND FROM FILE 'template.js'*/ - - -/* - Template - handles html templates -*/ - -/*DHX:Depend dhtmlx.js*/ - -dhtmlx.Template={ - _cache:{ - }, - empty:function(){ - return ""; - }, - setter:function(name, value){ - return dhtmlx.Template.fromHTML(value); - }, - obj_setter:function(name,value){ - var f = dhtmlx.Template.setter(name,value); - var obj = this; - return function(){ - return f.apply(obj, arguments); - }; - }, - fromHTML:function(str){ - if (typeof str == "function") return str; - if (this._cache[str]) - return this._cache[str]; - - //supported idioms - // {obj} => value - // {obj.attr} => named attribute or value of sub-tag in case of xml - // {obj.attr?some:other} conditional output - // {-obj => sub-template - str=(str||"").toString(); - str=str.replace(/[\r\n]+/g,"\\n"); - str=str.replace(/\{obj\.([^}?]+)\?([^:]*):([^}]*)\}/g,"\"+(obj.$1?\"$2\":\"$3\")+\""); - str=str.replace(/\{common\.([^}\(]*)\}/g,"\"+common.$1+\""); - str=str.replace(/\{common\.([^\}\(]*)\(\)\}/g,"\"+(common.$1?common.$1(obj):\"\")+\""); - str=str.replace(/\{obj\.([^}]*)\}/g,"\"+obj.$1+\""); - str=str.replace(/#([a-z0-9_]+)#/gi,"\"+obj.$1+\""); - str=str.replace(/\{obj\}/g,"\"+obj+\""); - str=str.replace(/\{-obj/g,"{obj"); - str=str.replace(/\{-common/g,"{common"); - str="return \""+str+"\";"; - return this._cache[str]= Function("obj","common",str); - } -}; - -dhtmlx.Type={ - /* - adds new template-type - obj - object to which template will be added - data - properties of template - */ - add:function(obj, data){ - //auto switch to prototype, if name of class was provided - if (!obj.types && obj.prototype.types) - obj = obj.prototype; - //if (typeof data == "string") - // data = { template:data }; - - if (dhtmlx.assert_enabled()) - this.assert_event(data); - - var name = data.name||"default"; - - //predefined templates - autoprocessing - this._template(data); - this._template(data,"edit"); - this._template(data,"loading"); - - obj.types[name]=dhtmlx.extend(dhtmlx.extend({},(obj.types[name]||this._default)),data); - return name; - }, - //default template value - basically empty box with 5px margin - _default:{ - css:"default", - template:function(){ return ""; }, - template_edit:function(){ return ""; }, - template_loading:function(){ return "..."; }, - width:150, - height:80, - margin:5, - padding:0 - }, - //template creation helper - _template:function(obj,name){ - name = "template"+(name?("_"+name):""); - var data = obj[name]; - //if template is a string - check is it plain string or reference to external content - if (data && (typeof data == "string")){ - if (data.indexOf("->")!=-1){ - data = data.split("->"); - switch(data[0]){ - case "html": //load from some container on the page - data = dhtmlx.html.getValue(data[1]).replace(/\"/g,"\\\""); - break; - case "http": //load from external file - data = new dhtmlx.ajax().sync().get(data[1],{uid:(new Date()).valueOf()}).responseText; - break; - default: - //do nothing, will use template as is - break; - } - } - obj[name] = dhtmlx.Template.fromHTML(data); - } - } -}; - - - -/* DHX DEPEND FROM FILE 'single_render.js'*/ - - -/* - REnders single item. - Can be used for elements without datastore, or with complex custom rendering logic - - @export - render -*/ - -/*DHX:Depend template.js*/ - -dhtmlx.SingleRender={ - _init:function(){ - }, - //convert item to the HTML text - _toHTML:function(obj){ - /* - this one doesn't support per-item-$template - it has not sense, because we have only single item per object - */ - return this.type._item_start(obj,this.type)+this.type.template(obj,this.type)+this.type._item_end; - }, - //render self, by templating data object - render:function(){ - if (!this.callEvent || this.callEvent("onBeforeRender",[this.data])){ - if (this.data) - this._dataobj.innerHTML = this._toHTML(this.data); - if (this.callEvent) this.callEvent("onAfterRender",[]); - } - } -}; - - -/* DHX DEPEND FROM FILE 'tooltip.js'*/ - - -/* - UI: Tooltip - - @export - show - hide -*/ - -/*DHX:Depend tooltip.css*/ -/*DHX:Depend template.js*/ -/*DHX:Depend single_render.js*/ - -dhtmlx.ui.Tooltip=function(container){ - this.name = "Tooltip"; - this.version = "3.0"; - - if (dhtmlx.assert_enabled()) this._assert(); - - if (typeof container == "string"){ - container = { template:container }; - } - - dhtmlx.extend(this, dhtmlx.Settings); - dhtmlx.extend(this, dhtmlx.SingleRender); - this._parseSettings(container,{ - type:"default", - dy:0, - dx:20 - }); - - //create container for future tooltip - this._dataobj = this._obj = document.createElement("DIV"); - this._obj.className="dhx_tooltip"; - dhtmlx.html.insertBefore(this._obj,document.body.firstChild); -}; -dhtmlx.ui.Tooltip.prototype = { - //show tooptip - //pos - object, pos.x - left, pox.y - top - show:function(data,pos){ - //render sefl only if new data was provided - if (this.data!=data){ - this.data=data; - this.render(data); - } - //show at specified position - this._obj.style.top = pos.y+this._settings.dy+"px"; - this._obj.style.left = pos.x+this._settings.dx+"px"; - this._obj.style.display="block"; - }, - //hide tooltip - hide:function(){ - this.data=null; //nulify, to be sure that on next show it will be fresh-rendered - this._obj.style.display="none"; - }, - types:{ - "default":dhtmlx.Template.fromHTML("{obj.id}") - }, - template_item_start:dhtmlx.Template.empty, - template_item_end:dhtmlx.Template.empty -}; - - - -/* DHX DEPEND FROM FILE 'autotooltip.js'*/ - - -/* - Behavior: AutoTooltip - links tooltip to data driven item -*/ - -/*DHX:Depend tooltip.js*/ - -dhtmlx.AutoTooltip = { - tooltip_setter:function(mode,value){ - var t = new dhtmlx.ui.Tooltip(value); - this.attachEvent("onMouseMove",function(id,e){ //show tooltip on mousemove - t.show(this.get(id),dhtmlx.html.pos(e)); - }); - this.attachEvent("onMouseOut",function(id,e){ //hide tooltip on mouseout - t.hide(); - }); - this.attachEvent("onMouseMoving",function(id,e){ //hide tooltip just after moving start - t.hide(); - }); - return t; - } -}; - - -/* DHX DEPEND FROM FILE 'datastore.js'*/ - - -/*DHX:Depend dhtmlx.js*/ - -/* - DataStore is not a behavior, it standalone object, which represents collection of data. - Call provideAPI to map data API - - @export - exists - idByIndex - indexById - get - set - refresh - dataCount - sort - filter - next - previous - clearAll - first - last -*/ -dhtmlx.DataStore = function(){ - this.name = "DataStore"; - - dhtmlx.extend(this, dhtmlx.EventSystem); - - this.setDriver("xml"); //default data source is an XML - this.pull = {}; //hash of IDs - this.order = dhtmlx.toArray(); //order of IDs -}; - -dhtmlx.DataStore.prototype={ - //defines type of used data driver - //data driver is an abstraction other different data formats - xml, json, csv, etc. - setDriver:function(type){ - dhtmlx.assert(dhtmlx.DataDriver[type],"incorrect DataDriver"); - this.driver = dhtmlx.DataDriver[type]; - }, - //process incoming raw data - _parse:function(data){ - //get size and position of data - var info = this.driver.getInfo(data); - //get array of records - var recs = this.driver.getRecords(data); - - var from = (info._from||0)*1; - var j=0; - for (var i=0; ito){ //can be in case of backward shift-selection - var a=to; to=from; from=a; - } - } - return this.getIndexRange(from,to); - }, - //converts range of indexes to array of all IDs between them - getIndexRange:function(from,to){ - to=Math.min(to,this.dataCount()-1); - - var ret=dhtmlx.toArray(); //result of method is rich-array - for (var i=from; i <= to; i++) - ret.push(this.get(this.order[i])); - return ret; - }, - //returns total count of elements - dataCount:function(){ - return this.order.length; - }, - //returns truy if item with such ID exists - exists:function(id){ - return !!(this.pull[id]); - }, - //nextmethod is not visible on component level, check DataMove.move - //moves item from source index to the target index - move:function(sindex,tindex){ - if (sindex<0 || tindex<0 || tindex >= this.order.length){ - dhtmlx.error("DataStore::move","Incorrect indexes"); - return; - } - - - var id = this.idByIndex(sindex); - var obj = this.get(id); - - this.order.removeAt(sindex); //remove at old position - //if (sindex>tindex) tindex--; //correct shift, caused by element removing - this.order.insertAt(id,tindex); //insert at new position - - //repaint signal - this.callEvent("onStoreUpdated",[id,obj,"move"]); - }, - //adds item to the store - add:function(obj,index){ - //generate id for the item - var id = this.id(obj); - - //by default item is added to the end of the list - var data_size = this.dataCount(); - if (dhtmlx.isNotDefined(index)) - index = data_size; - //check to prevent too big indexes - if (index > data_size){ - dhtmlx.log("Warning","DataStore:add","Index of out of bounds"); - index = Math.min(this.order.length,index); - } - - if (!this.callEvent("onbeforeAdd",[id,index])) return; - - if (this.exists(id)) return dhtmlx.error("Not unique ID"); - - this.pull[id]=obj; - this.order.insertAt(id,index); - if (this._filter_order){ //adding during filtering - //we can't know the location of new item in full dataset, making suggestion - //put at end by default - var original_index = this._filter_order.length; - //put at start only if adding to the start and some data exists - if (!index && this.order.length) - original_index = 0; - - this._filter_order.insertAt(id,original_index); - } - - this.callEvent("onafterAdd",[id,index]); - //repaint signal - this.callEvent("onStoreUpdated",[id,obj,"add"]); - return id; - }, - - //removes element from datastore - remove:function(id){ - //id can be an array of IDs - result of getSelect, for example - if (id instanceof Array){ - for (var i=0; i < id.length; i++) - this.remove(id[i]); - return; - } - if (!this.callEvent("onbeforedelete",[id])) return; - if (!this.exists(id)) return dhtmlx.error("Not existing ID",id); - var obj = this.get(id); //save for later event - //clear from collections - this.order.remove(id); - if (this._filter_order) - this._filter_order.remove(id); - - delete this.pull[id]; - this.callEvent("onafterdelete",[id]); - //repaint signal - this.callEvent("onStoreUpdated",[id,obj,"delete"]); - }, - //deletes all records in datastore - clearAll:function(){ - //instead of deleting one by one - just reset inner collections - this.pull = {}; - this.order = dhtmlx.toArray(); - this._filter_order = null; - this.callEvent("onClearAll",[]); - this.refresh(); - }, - //converts id to index - idByIndex:function(index){ - if (index>=this.order.length || index<0) - dhtmlx.log("Warning","DataStore::idByIndex Incorrect index"); - - return this.order[index]; - }, - //converts index to id - indexById:function(id){ - var res = this.order.find(id); //slower than idByIndex - - if (!res && res!==0) - dhtmlx.log("Warning","DataStore::indexById Non-existing ID: "+ id); - - return res; - }, - //returns ID of next element - next:function(id,step){ - return this.order[this.indexById(id)+(step||1)]; - }, - //returns ID of first element - first:function(){ - return this.order[0]; - }, - //returns ID of last element - last:function(){ - return this.order[this.order.length-1]; - }, - //returns ID of previous element - previous:function(id,step){ - return this.order[this.indexById(id)-(step||1)]; - }, - /* - sort data in collection - by - settings of sorting - - or - - by - sorting function - dir - "asc" or "desc" - - or - - by - property - dir - "asc" or "desc" - as - type of sortings - - Sorting function will accept 2 parameters and must return 1,0,-1, based on desired order - */ - sort:function(by, dir, as){ - - var sort = by; - if (typeof by == "function") - sort = {as:by, dir:dir}; - else if (typeof by == "string") - sort = {by:by, dir:dir, as:as}; - - - var parameters = [sort.by, sort.dir, sort.as]; - if (!this.callEvent("onbeforesort",parameters)) return; - - var sorter = dhtmlx.sort.create(sort); - //get array of IDs - var neworder = this.getRange(); - neworder.sort(sorter); - this.order = neworder.map(function(obj){ return this.id(obj); },this); - - //repaint self - this.refresh(); - - this.callEvent("onaftersort",parameters); - }, - /* - Filter datasource - - text - property, by which filter - value - filter mask - - or - - text - filter method - - Filter method will receive data object and must return true or false - */ - filter:function(text,value){ - //remove previous filtering , if any - if (this._filter_order){ - this.order = this._filter_order; - delete this._filter_order; - } - //if text not define -just unfilter previous state and exit - if (text){ - var filter = text; - if (typeof text == "string"){ - text = dhtmlx.Template.setter(0,text); - filter = function(obj,value){ //default filter - string start from, case in-sensitive - return text(obj).toLowerCase().indexOf(value)!=-1; - }; - } - - value = (value||"").toString().toLowerCase(); - var neworder = dhtmlx.toArray(); - this.order.each(function(id){ - if (filter(this.get(id),value)) - neworder.push(id); - },this); - //set new order of items, store original - this._filter_order = this.order; - this.order = neworder; - } - //repaint self - this.refresh(); - }, - /* - Iterate through collection - */ - each:function(method,master){ - for (var i=0; ib?1:(ab?1:(ab?1:(a max) max = property(obj)*1; - }); - return max; - }, - _split_data_by:function(stats){ - var any=function(property, data){ - property = dhtmlx.Template.setter(0,property); - return property(data[0]); - }; - var key = dhtmlx.Template.setter(0,stats.by); - if (!stats.map[key]) - stats.map[key] = [key, any]; - - var groups = {}; - var labels = []; - this.data.each(function(data){ - var current = key(data); - if (!groups[current]){ - labels.push({id:current}); - groups[current] = dhtmlx.toArray(); - } - groups[current].push(data); - }); - for (var prop in stats.map){ - var functor = (stats.map[prop][1]||any); - if (typeof functor != "function") - functor = this[functor]; - - for (var i=0; i < labels.length; i++) { - labels[i][prop]=functor.call(this, stats.map[prop][0], groups[labels[i].id]); - } - } -// if (this._settings.sort) -// labels.sortBy(stats.sort); - - this._not_grouped_data = this.data; - this.data = new dhtmlx.DataStore(); - this.data.provideApi(this,true); - this._init_group_data_event(this.data, this); - this.parse(labels,"json"); - }, - group:function(config,mode){ - this.ungroup(false); - this._split_data_by(config); - if (mode!==false) - this.render(); - }, - ungroup:function(mode){ - if (this._not_grouped_data){ - this.data = this._not_grouped_data; - this.data.provideApi(this, true); - } - if (mode!==false) - this.render(); - }, - group_setter:function(name, config){ - dhtmlx.assert(typeof config == "object", "Incorrect group value"); - dhtmlx.assert(config.by,"group.by is mandatory"); - dhtmlx.assert(config.map,"group.map is mandatory"); - return config; - }, - //need to be moved to more appropriate object - sort_setter:function(name, config){ - if (typeof config != "object") - config = { by:config }; - - this._mergeSettings(config,{ - as:"string", - dir:"asc" - }); - return config; - } -}; - - -/* DHX DEPEND FROM FILE 'key.js'*/ - - -/* - Behavior:KeyEvents - hears keyboard -*/ -dhtmlx.KeyEvents = { - _init:function(){ - //attach handler to the main container - dhtmlx.event(this._obj,"keypress",this._onKeyPress,this); - }, - //called on each key press , when focus is inside of related component - _onKeyPress:function(e){ - e=e||event; - var code = e.keyCode; //FIXME better solution is required - this.callEvent((this._edit_id?"onEditKeyPress":"onKeyPress"),[code,e.ctrlKey,e.shiftKey,e]); - } -}; - - -/* DHX DEPEND FROM FILE 'mouse.js'*/ - - -/* - Behavior:MouseEvents - provides inner evnets for mouse actions -*/ -dhtmlx.MouseEvents={ - _init: function(){ - //attach dom events if related collection is defined - if (this._click){ - dhtmlx.event(this._obj,"click",this._onClick,this); - dhtmlx.event(this._obj,"contextmenu",this._onContext,this); - } - if (this._dblclick) - dhtmlx.event(this._obj,"dblclick",this._onDblClick,this); - if (this._mouse_move){ - dhtmlx.event(this._obj,"mousemove",this._onMouse,this); - dhtmlx.event(this._obj,(dhtmlx._isIE?"mouseleave":"mouseout"),this._onMouse,this); - } - - }, - //inner onclick object handler - _onClick: function(e) { - return this._mouseEvent(e,this._click,"ItemClick"); - }, - //inner ondblclick object handler - _onDblClick: function(e) { - return this._mouseEvent(e,this._dblclick,"ItemDblClick"); - }, - //process oncontextmenu events - _onContext: function(e) { - var id = dhtmlx.html.locate(e, this._id); - if (id && !this.callEvent("onBeforeContextMenu", [id,e])) - return dhtmlx.html.preventEvent(e); - }, - /* - event throttler - ignore events which occurs too fast - during mouse moving there are a lot of event firing - we need no so much - also, mouseout can fire when moving inside the same html container - we need to ignore such fake calls - */ - _onMouse:function(e){ - if (dhtmlx._isIE) //make a copy of event, will be used in timed call - e = document.createEventObject(event); - - if (this._mouse_move_timer) //clear old event timer - window.clearTimeout(this._mouse_move_timer); - - //this event just inform about moving operation, we don't care about details - this.callEvent("onMouseMoving",[e]); - //set new event timer - this._mouse_move_timer = window.setTimeout(dhtmlx.bind(function(){ - //called only when we have at least 100ms after previous event - if (e.type == "mousemove") - this._onMouseMove(e); - else - this._onMouseOut(e); - },this),500); - }, - //inner mousemove object handler - _onMouseMove: function(e) { - if (!this._mouseEvent(e,this._mouse_move,"MouseMove")) - this.callEvent("onMouseOut",[e||event]); - }, - //inner mouseout object handler - _onMouseOut: function(e) { - this.callEvent("onMouseOut",[e||event]); - }, - //common logic for click and dbl-click processing - _mouseEvent:function(e,hash,name){ - e=e||event; - var trg=e.target||e.srcElement; - var css = ""; - var id = null; - var found = false; - //loop through all parents - while (trg && trg.parentNode){ - if (!found){ //if element with ID mark is not detected yet - id = trg.getAttribute(this._id); //check id of current one - if (id){ - if (!this.callEvent("on"+name,[id,e,trg])) return; //it will be triggered only for first detected ID, in case of nested elements - found = true; //set found flag - } - } - css=trg.className; - if (css){ //check if pre-defined reaction for element's css name exists - css = css.split(" "); - css = css[0]||css[1]; //FIXME:bad solution, workaround css classes which are starting from whitespace - if (hash[css]) - return hash[css].call(this,e,id,trg); - } - trg=trg.parentNode; - } - return found; //returns true if item was located and event was triggered - } -}; - - -/* DHX DEPEND FROM FILE 'config.js'*/ - - -/* - Behavior:Settings - - @export - customize - config -*/ - -/*DHX:Depend template.js*/ -/*DHX:Depend dhtmlx.js*/ - -dhtmlx.Settings={ - _init:function(){ - /* - property can be accessed as this.config.some - in same time for inner call it have sense to use _settings - because it will be minified in final version - */ - this._settings = this.config=[]; - this._settings.sort = null; //mask default method - }, - define:function(property, value){ - if (typeof property == "object") - return this._parseSeetingColl(property); - return this._define(property, value); - }, - _define:function(property,value){ - dhtmlx.assert_settings.call(this,property,value); - - //method with name {prop}_setter will be used as property setter - //setter is optional - var setter = this[property+"_setter"]; - return this._settings[property]=setter?setter.call(this,property,value):value; - }, - //process configuration object - _parseSeetingColl:function(coll){ - if (coll){ - for (var a in coll) //for each setting - this._define(a,coll[a]); //set value through config - } - }, - //helper for object initialization - _parseSettings:function(obj,initial){ - //initial - set of default values - var settings = dhtmlx.extend({},initial); - //code below will copy all properties over default one - if (typeof obj == "object" && !obj.tagName) - dhtmlx.extend(settings,obj); - //call config for each setting - this._parseSeetingColl(settings); - }, - _mergeSettings:function(config, defaults){ - for (var key in defaults) - switch(typeof config[key]){ - case "object": - config[key] = this._mergeSettings((config[key]||{}), defaults[key]); - break; - case "undefined": - config[key] = defaults[key]; - break; - default: //do nothing - break; - } - return config; - }, - //helper for html container init - _parseContainer:function(obj,name,fallback){ - /* - parameter can be a config object, in such case real container will be obj.container - or it can be html object or ID of html object - */ - if (typeof obj == "object" && !obj.tagName) - obj=obj.container; - this._obj = dhtmlx.toNode(obj); - if (!this._obj && fallback) - this._obj = fallback(obj); - - dhtmlx.assert(this._obj, "Incorrect html container"); - - this._obj.className+=" "+name; - this._obj.onselectstart=function(){return false;}; //block selection by default - this._dataobj = this._obj;//separate reference for rendering modules - }, - //apply template-type - _set_type:function(name){ - //parameter can be a hash of settings - if (typeof name == "object") - return this.type_setter("type",name); - - dhtmlx.assert(this.types, "RenderStack :: Types are not defined"); - dhtmlx.assert(this.types[name],"RenderStack :: Inccorect type name",name); - //or parameter can be a name of existing template-type - this.type=dhtmlx.extend({},this.types[name]); - this.customize(); //init configs - }, - customize:function(obj){ - //apply new properties - if (obj) dhtmlx.extend(this.type,obj); - - //init tempaltes for item start and item end - this.type._item_start = dhtmlx.Template.fromHTML(this.template_item_start(this.type)); - this.type._item_end = this.template_item_end(this.type); - - //repaint self - this.render(); - }, - //config.type - creates new template-type, based on configuration object - type_setter:function(mode,value){ - this._set_type(typeof value == "object"?dhtmlx.Type.add(this,value):value); - return value; - }, - //config.template - creates new template-type with defined template string - template_setter:function(mode,value){ - return this.type_setter("type",{template:value}); - }, - //config.css - css name for top level container - css_setter:function(mode,value){ - this._obj.className += " "+value; - return value; - } -}; - - -/* DHX DEPEND FROM FILE 'compatibility.js'*/ - - -/* - Collection of compatibility hacks -*/ - -/*DHX:Depend dhtmlx.js*/ - -dhtmlx.compat=function(name, obj){ - //check if name hach present, and applies it when necessary - if (dhtmlx.compat[name]) - dhtmlx.compat[name](obj); -}; - - -(function(){ - if (!window.dhtmlxError){ - //dhtmlxcommon is not included - - //create fake error tracker for connectors - var dummy = function(){}; - window.dhtmlxError={ catchError:dummy, throwError:dummy }; - //helpers instead of ones from dhtmlxcommon - window.convertStringToBoolean=function(value){ - return !!value; - }; - window.dhtmlxEventable = function(node){ - dhtmlx.extend(node,dhtmlx.EventSystem); - }; - //imitate ajax layer of dhtmlxcommon - var loader = { - getXMLTopNode:function(name){ - - }, - doXPath:function(path){ - return dhtmlx.DataDriver.xml.xpath(this.xml,path); - }, - xmlDoc:{ - responseXML:true - } - }; - //wrap ajax methods of dataprocessor - dhtmlx.compat.dataProcessor=function(obj){ - //FIXME - //this is pretty ugly solution - we replace whole method , so changes in dataprocessor need to be reflected here - - var sendData = "_sendData"; - var in_progress = "_in_progress"; - var tMode = "_tMode"; - var waitMode = "_waitMode"; - - obj[sendData]=function(a1,rowId){ - if (!a1) return; //nothing to send - if (rowId) - this[in_progress][rowId]=(new Date()).valueOf(); - - if (!this.callEvent("onBeforeDataSending",rowId?[rowId,this.getState(rowId)]:[])) return false; - - var a2 = this; - var a3=this.serverProcessor; - if (this[tMode]!="POST") - //use dhtmlx.ajax instead of old ajax layer - dhtmlx.ajax().get(a3+((a3.indexOf("?")!=-1)?"&":"?")+a1,"",function(t,x,xml){ - loader.xml = dhtmlx.DataDriver.xml.checkResponse(t,x); - a2.afterUpdate(a2, null, null, null, loader); - }); - else - dhtmlx.ajax().post(a3,a1,function(t,x,xml){ - loader.xml = dhtmlx.DataDriver.xml.checkResponse(t,x); - a2.afterUpdate(a2, null, null, null, loader); - }); - - this[waitMode]++; - }; - }; - } - -})(); - - -/* DHX DEPEND FROM FILE 'compatibility_layout.js'*/ - - -/*DHX:Depend dhtmlx.js*/ -/*DHX:Depend compatibility.js*/ - -if (!dhtmlx.attaches) - dhtmlx.attaches = {}; - -dhtmlx.attaches.attachAbstract=function(name, conf){ - var obj = document.createElement("DIV"); - obj.id = "CustomObject_"+dhtmlx.uid(); - obj.style.width = "100%"; - obj.style.height = "100%"; - obj.cmp = "grid"; - document.body.appendChild(obj); - this.attachObject(obj.id); - - conf.container = obj.id; - this.grid = new window[name](conf); - - this.gridId = obj.id; - this.gridObj = obj; - return this.grid; -}; -dhtmlx.attaches.attachDataView = function(conf){ - return this.attachAbstract("dhtmlXDataView",conf); -}; -dhtmlx.attaches.attachChart = function(conf){ - return this.attachAbstract("dhtmlXChart",conf); -}; - -dhtmlx.compat.layout = function(){ -if (window.dhtmlXChart) - dhtmlXChart.prototype.setSizes = function(){ - this.resize(); - }; -if (window.dhtmlXDataView) - dhtmlXDataView.prototype.setSizes = function(){ - this.render(); - }; -}; - - -/* DHX DEPEND FROM FILE 'load.js'*/ - - -/* - ajax operations - - can be used for direct loading as - dhtmlx.ajax(ulr, callback) - or - dhtmlx.ajax().get(url) - dhtmlx.ajax().post(url) - -*/ - -/*DHX:Depend datastore.js*/ -/*DHX:Depend dhtmlx.js*/ - -dhtmlx.ajax = function(url,call,master){ - //if parameters was provided - made fast call - if (arguments.length!==0){ - var http_request = new dhtmlx.ajax(); - if (master) http_request.master=master; - http_request.get(url,null,call); - } - if (!this.getXHR) return new dhtmlx.ajax(); //allow to create new instance without direct new declaration - - return this; -}; -dhtmlx.ajax.prototype={ - //creates xmlHTTP object - getXHR:function(){ - if (dhtmlx._isIE) - return new ActiveXObject("Microsoft.xmlHTTP"); - else - return new XMLHttpRequest(); - }, - /* - send data to the server - params - hash of properties which will be added to the url - call - callback, can be an array of functions - */ - send:function(url,params,call){ - var x=this.getXHR(); - if (typeof call == "function") - call = [call]; - //add extra params to the url - if (typeof params == "object"){ - var t=[]; - for (var a in params) - t.push(a+"="+encodeURIComponent(params[a]));// utf-8 escaping - params=t.join("&"); - } - if (params && !this.post){ - url=url+(url.indexOf("?")!=-1 ? "&" : "?")+params; - params=null; - } - - x.open(this.post?"POST":"GET",url,!this._sync); - if (this.post) - x.setRequestHeader('Content-type','application/x-www-form-urlencoded'); - - //async mode, define loading callback - if (!this._sync){ - var self=this; - x.onreadystatechange= function(){ - if (!x.readyState || x.readyState == 4){ - dhtmlx.log_full_time("data_loading"); //log rendering time - if (call && self) - for (var i=0; i < call.length; i++) //there can be multiple callbacks - if (call[i]) - call[i].call((self.master||self),x.responseText,x.responseXML,x); - self.master=null; - call=x=self=null; //anti-leak - } - }; - } - - x.send(params||null); - return x; //return XHR, which can be used in case of sync. mode - }, - //GET request - get:function(url,params,call){ - this.post=false; - return this.send(url,params,call); - }, - //POST request - post:function(url,params,call){ - this.post=true; - return this.send(url,params,call); - }, - sync:function(){ - this._sync = true; - return this; - } -}; - - -/* - Behavior:DataLoader - load data in the component - - @export - load - parse -*/ -dhtmlx.DataLoader={ - _init:function(){ - //prepare data store - this.data = new dhtmlx.DataStore(); - }, - //loads data from external URL - load:function(url,call){ - this.callEvent("onXLS",[]); - if (typeof call == "string"){ //second parameter can be a loading type or callback - this.data.setDriver(call); - call = arguments[2]; - } - //prepare data feed for dyn. loading - if (!this.data.feed) - this.data.feed = function(from,count){ - //allow only single request at same time - if (this._load_count) - return this._load_count=[from,count]; //save last ignored request - else - this._load_count=true; - - this.load(url+((url.indexOf("?")==-1)?"?":"&")+"posStart="+from+"&count="+count,function(){ - //after loading check if we have some ignored requests - var temp = this._load_count; - this._load_count = false; - if (typeof temp =="object") - this.data.feed.apply(this, temp); //load last ignored request - }); - }; - //load data by async ajax call - dhtmlx.ajax(url,[this._onLoad,call],this); - }, - //loads data from object - parse:function(data,type){ - this.callEvent("onXLS",[]); - if (type) - this.data.setDriver(type); - this._onLoad(data,null); - }, - //default after loading callback - _onLoad:function(text,xml,loader){ - this.data._parse(this.data.driver.toObject(text,xml)); - this.callEvent("onXLE",[]); - } -}; - -/* - Abstraction layer for different data types -*/ - -dhtmlx.DataDriver={}; -dhtmlx.DataDriver.json={ - //convert json string to json object if necessary - toObject:function(data){ - if (typeof data == "string"){ - eval ("dhtmlx.temp="+data); - return dhtmlx.temp; - } - return data; - }, - //get array of records - getRecords:function(data){ - if (data && !(data instanceof Array)) - return [data]; - return data; - }, - //get hash of properties for single record - getDetails:function(data){ - return data; - }, - //get count of data and position at which new data need to be inserted - getInfo:function(data){ - return { - _size:(data.total_count||0), - _from:(data.pos||0) - }; - } -}; - -dhtmlx.DataDriver.html={ - /* - incoming data can be - - collection of nodes - - ID of parent container - - HTML text - */ - toObject:function(data){ - if (typeof data == "string"){ - var t=null; - if (data.indexOf("<")==-1) //if no tags inside - probably its an ID - t = dhtmlx.toNode(data); - if (!t){ - t=document.createElement("DIV"); - t.innerHTML = data; - } - - return t.getElementsByTagName(this.tag); - } - return data; - }, - //get array of records - getRecords:function(data){ - if (data.tagName) - return data.childNodes; - return data; - }, - //get hash of properties for single record - getDetails:function(data){ - return dhtmlx.DataDriver.xml.tagToObject(data); - }, - //dyn loading is not supported by HTML data source - getInfo:function(data){ - return { - _size:0, - _from:0 - }; - }, - tag: "LI" -}; - -dhtmlx.DataDriver.jsarray={ - //eval jsarray string to jsarray object if necessary - toObject:function(data){ - if (typeof data == "string"){ - eval ("dhtmlx.temp="+data); - return dhtmlx.temp; - } - return data; - }, - //get array of records - getRecords:function(data){ - return data; - }, - //get hash of properties for single record, in case of array they will have names as "data{index}" - getDetails:function(data){ - var result = {}; - for (var i=0; i < data.length; i++) - result["data"+i]=data[i]; - - return result; - }, - //dyn loading is not supported by js-array data source - getInfo:function(data){ - return { - _size:0, - _from:0 - }; - } -}; - -dhtmlx.DataDriver.csv={ - //incoming data always a string - toObject:function(data){ - return data; - }, - //get array of records - getRecords:function(data){ - return data.split(this.row); - }, - //get hash of properties for single record, data named as "data{index}" - getDetails:function(data){ - data = this.stringToArray(data); - var result = {}; - for (var i=0; i < data.length; i++) - result["data"+i]=data[i]; - - return result; - }, - //dyn loading is not supported by csv data source - getInfo:function(data){ - return { - _size:0, - _from:0 - }; - }, - //split string in array, takes string surrounding quotes in account - stringToArray:function(data){ - data = data.split(this.cell); - for (var i=0; i < data.length; i++) - data[i] = data[i].replace(/^[ \t\n\r]*(\"|)/g,"").replace(/(\"|)[ \t\n\r]*$/g,""); - return data; - }, - row:"\n", //default row separator - cell:"," //default cell separator -}; - -dhtmlx.DataDriver.xml={ - //convert xml string to xml object if necessary - toObject:function(text,xml){ - if (xml && (xml=this.checkResponse(text,xml))) //checkResponse - fix incorrect content type and extra whitespaces errors - return xml; - if (typeof text == "string"){ - return this.fromString(text); - } - return text; - }, - //get array of records - getRecords:function(data){ - return this.xpath(data,this.records); - }, - records:"/*/item", - userdata:"/*/userdata", - //get hash of properties for single record - getDetails:function(data){ - return this.tagToObject(data,{}); - }, - getUserData:function(data,col){ - col = col || {}; - var ud = this.xpath(data,this.userdata); - for (var i=0; i < ud.length; i++) { - var udx = this.tagToObject(ud[i]); - col[udx.name] = udx.value; - } - return col; - }, - //get count of data and position at which new data_loading need to be inserted - getInfo:function(data){ - return { - _size:(data.documentElement.getAttribute("total_count")||0), - _from:(data.documentElement.getAttribute("pos")||0) - }; - }, - //xpath helper - xpath:function(xml,path){ - if (window.XPathResult){ //FF, KHTML, Opera - var node=xml; - if(xml.nodeName.indexOf("document")==-1) - xml=xml.ownerDocument; - var res = []; - var col = xml.evaluate(path, node, null, XPathResult.ANY_TYPE, null); - var temp = col.iterateNext(); - while (temp){ - res.push(temp); - temp = col.iterateNext(); - } - return res; - } //IE - return xml.selectNodes(path); - }, - //convert xml tag to js object, all subtags and attributes are mapped to the properties of result object - tagToObject:function(tag,z){ - z=z||{}; - //map attributes - var a=tag.attributes; - for (var i=0; i5?10:5); - step = parseInt(stepVal,10)*calculStep; - - if(step>Math.abs(nmin)) start = (nmin<0?-step:0); - else{ - - var absNmin = Math.abs(nmin); - var powerStart = Math.floor(this.log10(absNmin)); - var nminVal = absNmin/Math.pow(10,powerStart); - start = Math.ceil(nminVal*10)/10*Math.pow(10,powerStart)-step; - if(nmin<0) start =-start-2*step; - } - var end = start; - while(end<=nmax){ - end += step; - end = parseFloat((new Number(end)).toFixed(Math.abs(power))); - } - return {start:start,end:end,step:step,fixNum:Math.abs(power)}; - }, - log10:function(n){ - return Math.floor((Math.log(n)/Math.LN10)); - }, - _drawXAxisLabel:function(x,obj){ - if (!this._settings.xAxis) return; - var elem = this.renderTextAt(false, true, x, - this._obj.offsetHeight-parseInt(this._settings.padding.bottom,10), - this._settings.xAxis.template(obj)); - }, - _drawXAxisLine:function(ctx,x,y1,y2){ - if (!this._settings.xAxis||!this._settings.xAxis.lines) return; - this._drawLine(ctx,x,y1,x,y2,this._settings.xAxis.color,0.2); - }, - _drawLine:function(ctx,x1,y1,x2,y2,color,width){ - ctx.strokeStyle = color; - ctx.lineWidth = width; - ctx.beginPath(); - ctx.moveTo(x1,y1); - ctx.lineTo(x2,y2); - ctx.stroke(); - }, - _getRelativeValue:function(minValue,maxValue){ - var relValue; - var valueFactor = 1; - if(maxValue != minValue){ - relValue = maxValue - minValue; - if(Math.abs(relValue) < 1){ - while(Math.abs(relValue)<1){ - valueFactor *= 10; - relValue *= valueFactor; - } - } - } - else relValue = minValue; - return [relValue,valueFactor]; - }, - _rainbow : [ - function(pos){ return "#FF"+dhtmlx.math.toHex(pos/2,2)+"00";}, - function(pos){ return "#FF"+dhtmlx.math.toHex(pos/2+128,2)+"00";}, - function(pos){ return "#"+dhtmlx.math.toHex(255-pos,2)+"FF00";}, - function(pos){ return "#00FF"+dhtmlx.math.toHex(pos,2);}, - function(pos){ return "#00"+dhtmlx.math.toHex(255-pos,2)+"FF";}, - function(pos){ return "#"+dhtmlx.math.toHex(pos,2)+"00FF";} - ] -}; - -dhtmlx.compat("layout"); \ No newline at end of file -- cgit v1.2.3