diff --git a/js/x11/win/plot.js b/js/x11/win/plot.js new file mode 100644 index 0000000..c6a6f52 --- /dev/null +++ b/js/x11/win/plot.js @@ -0,0 +1,363 @@ +/** + ** ============================== + ** O O O OOOO + ** O O O O O O + ** O O O O O O + ** OOOO OOOO O OOO OOOO + ** O O O O O O O + ** O O O O O O O + ** OOOO OOOO O O OOOO + ** ============================== + ** Dr. Stefan Bosse http://www.bsslab.de + ** + ** COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED + ** BY THE AUTHOR(S). + ** THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED, + ** MODIFIED, OR OTHERWISE USED IN A CONTEXT + ** OUTSIDE OF THE SOFTWARE SYSTEM. + ** + ** $AUTHORS: Stefan Bosse + ** $INITIAL: (C) 2006-2017 bLAB + ** $CREATED: 1-10-17 by sbosse. + ** $VERSION: 1.3.1 + ** + ** $INFO: + ** + ** X11/Widget library - High-level plot/data visualization widgets extending the window class + ** + ** + ** plot({ + ** type:'vector', + ** x,y,min?,max?, + ** width,height + ** margin?, + ** columns?, + ** label?:{x0:string,x1:string,y0:string,y1:string}, + ** bar?: { + ** fill:{ + ** color:string + ** } + ** }, + ** init?:function (i) { return 0.0 } // Creates vector:number [] attribute! + ** }) + ** + ** $ENDOFINFO +*/ + +var Comp = Require('com/compat'); + + +function window(options) { + this.plots={}; +} + +function update(dst,src) { + for(var a in src) { + if (typeof dst[a] == 'object' && typeof src[a] == 'object') + update(dst[a],src[a]); + else + dst[a]=src[a]; + } +} +function modifies(attr,shape) { + for(var a in attr) { + if (typeof attr[a] == 'object' && typeof shape[a] == 'object') + return modifies(attr[a],shape[a]); + else if (attr[a] != shape[a]) return true; + } + return false; +} + +function makeLabel(options,modify) { + if (options.label.y0) { + if (modify) this.remove(options.id+':Ly0'); + this.add({ + id:options.id+':Ly0', + shape:'text', + align:'left', + x:options.x-15, + y:options.y+options.height, + text:options.label.y0 + }); + } + if (options.label.y1) { + if (modify) this.remove(options.id+':Ly1'); + this.add({ + id:options.id+':Ly1', + shape:'text', + align:'left', + x:options.x-15, + y:options.y, + text:options.label.y1 + }); + } + if (options.label.x0) { + if (modify) this.remove(options.id+':Lx0'); + this.add({ + id:options.id+':Lx0', + shape:'text', + align:'left', + x:options.x, + y:options.y+options.height+15, + text:options.label.x0 + }); + } + if (options.label.x1) { + if (modify) this.remove(options.id+':Lx1'); + this.add({ + id:options.id+':Lx1', + shape:'text', + align:'left', + x:options.x+options.width, + y:options.y+options.height, + text:options.label.x1 + }); + } +} +/** Plot a metric matrix (image) or a grid (2d plot) of nodes +** +** typeof options = { +** type='matrix', +** x,y, +** rows?,columns?,margin?, +** align?={'center'|'left'}, +** node: { +** shape, +** width,height, +** fill:{color:string}, +** line:{color:string,width?} +** }, +** init?: function (^i,^j) -> ^attr | [][], +** map?: function (^i,^j,^v) -> ^attr:object, +** matrix?: *[][] +** } +*/ +function plotMatrix (options) { + for(var j=0; j=0 || options.max <= 0) { + h=Math.max(1,h); + y=options.y+options.height-h; + } else { + off=int(options.height/(options.max-options.min)*(-options.min)); + if (options.vector[i]<0) + y=options.y+options.height-off, h=Math.max(1,off-h); + else + h=Math.max(1,h-off),y=options.y+options.height-off-h; + } + + this.add({ + id:options.id+':B'+i, + shape:'rect', + align:'left', + x:x, + y:y, + width:w, + height:h, + fill:{ + color:(options.bar.fill && options.bar.fill.color)||'black' + }, + }); +} + +function plotBars (options) { + for(var i=0; i number | [] +** } +*/ + +function plotVector (options) { + var v,x,y,x0,y0,x1,y1,min,max; + options.vector=options.vector||[]; + for(var i=0; i=0 && i0 && i=0 && i0 && i=0 && i