3 MochiKit.MochiKit 1.4 : PACKED VERSION
5 THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
6 diff against the source tree, not this file.
8 See <http://mochikit.com/> for documentation, downloads, license, etc.
10 (c) 2005 Bob Ippolito. All rights Reserved.
14 if(typeof (dojo
)!="undefined"){
15 dojo
.provide("MochiKit.Base");
17 if(typeof (MochiKit
)=="undefined"){
20 if(typeof (MochiKit
.Base
)=="undefined"){
23 if(typeof (MochiKit
.__export__
)=="undefined"){
24 MochiKit
.__export__
=(MochiKit
.__compat__
||(typeof (JSAN
)=="undefined"&&typeof (dojo
)=="undefined"));
26 MochiKit
.Base
.VERSION
="1.4";
27 MochiKit
.Base
.NAME
="MochiKit.Base";
28 MochiKit
.Base
.update
=function(_1
,_2
){
32 for(var i
=1;i
<arguments
.length
;i
++){
34 if(typeof (o
)!="undefined"&&o
!==null){
42 MochiKit
.Base
.update(MochiKit
.Base
,{__repr__
:function(){
43 return "["+this.NAME
+" "+this.VERSION
+"]";
44 },toString
:function(){
45 return this.__repr__();
46 },camelize
:function(_6
){
49 for(var i
=1;i
<_7
.length
;i
++){
50 cc
+=_7
[i
].charAt(0).toUpperCase()+_7
[i
].substring(1);
53 },counter
:function(n
){
54 if(arguments
.length
===0){
61 var me
=arguments
.callee
;
62 if(arguments
.length
==1){
66 },_flattenArray
:function(_d
,_e
){
67 for(var i
=0;i
<_e
.length
;i
++){
69 if(o
instanceof Array
){
70 arguments
.callee(_d
,o
);
76 },flattenArray
:function(lst
){
77 return MochiKit
.Base
._flattenArray([],lst
);
78 },flattenArguments
:function(lst
){
81 var _15
=m
.extend(null,arguments
);
84 if(o
&&typeof (o
)=="object"&&typeof (o
.length
)=="number"){
85 for(var i
=o
.length
-1;i
>=0;i
--){
93 },extend
:function(_18
,obj
,_1a
){
99 if(typeof (l
)!="number"){
100 if(typeof (MochiKit
.Iter
)!="undefined"){
101 obj
=MochiKit
.Iter
.list(obj
);
104 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
110 for(var i
=_1a
;i
<l
;i
++){
115 },updatetree
:function(_1d
,obj
){
119 for(var i
=1;i
<arguments
.length
;i
++){
121 if(typeof (o
)!="undefined"&&o
!==null){
124 if(typeof (_1d
[k
])=="object"&&typeof (v
)=="object"){
125 arguments
.callee(_1d
[k
],v
);
133 },setdefault
:function(_23
,obj
){
137 for(var i
=1;i
<arguments
.length
;i
++){
146 },keys
:function(obj
){
152 },values
:function(obj
){
158 },items
:function(obj
){
172 },_newNamedError
:function(_33
,_34
,_35
){
173 _35
.prototype=new MochiKit
.Base
.NamedError(_33
.NAME
+"."+_34
);
175 },operator
:{truth
:function(a
){
177 },lognot
:function(a
){
179 },identity
:function(a
){
201 },lshift
:function(a
,b
){
203 },rshift
:function(a
,b
){
205 },zrshift
:function(a
,b
){
224 return MochiKit
.Base
.compare(a
,b
)===0;
226 return MochiKit
.Base
.compare(a
,b
)!==0;
228 return MochiKit
.Base
.compare(a
,b
)==1;
230 return MochiKit
.Base
.compare(a
,b
)!=-1;
232 return MochiKit
.Base
.compare(a
,b
)==-1;
234 return MochiKit
.Base
.compare(a
,b
)!=1;
235 },logand
:function(a
,b
){
237 },logor
:function(a
,b
){
239 },contains
:function(a
,b
){
241 }},forwardCall
:function(_73
){
243 return this[_73
].apply(this,arguments
);
245 },itemgetter
:function(_74
){
246 return function(arg
){
249 },typeMatcher
:function(){
251 for(var i
=0;i
<arguments
.length
;i
++){
252 var typ
=arguments
[i
];
256 for(var i
=0;i
<arguments
.length
;i
++){
257 if(!(typeof (arguments
[i
]) in _76
)){
264 for(var i
=0;i
<arguments
.length
;i
++){
265 if(arguments
[i
]!==null){
270 },isUndefinedOrNull
:function(){
271 for(var i
=0;i
<arguments
.length
;i
++){
273 if(!(typeof (o
)=="undefined"||o
===null)){
278 },isEmpty
:function(obj
){
279 return !MochiKit
.Base
.isNotEmpty
.apply(this,arguments
);
280 },isNotEmpty
:function(obj
){
281 for(var i
=0;i
<arguments
.length
;i
++){
288 },isArrayLike
:function(){
289 for(var i
=0;i
<arguments
.length
;i
++){
292 if((typ
!="object"&&!(typ
=="function"&&typeof (o
.item
)=="function"))||o
===null||typeof (o
.length
)!="number"||o
.nodeType
===3){
297 },isDateLike
:function(){
298 for(var i
=0;i
<arguments
.length
;i
++){
300 if(typeof (o
)!="object"||o
===null||typeof (o
.getTime
)!="function"){
307 return MochiKit
.Base
.extend(null,arguments
,1);
310 for(var i
=1;i
<arguments
.length
;i
++){
311 _87
.push(fn(arguments
[i
]));
314 },map
:function(fn
,lst
){
316 var itr
=MochiKit
.Iter
;
317 var _8d
=m
.isArrayLike
;
318 if(arguments
.length
<=2){
326 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
330 return m
.extend(null,lst
);
333 for(var i
=0;i
<lst
.length
;i
++){
334 _8e
.push(fn(lst
[i
]));
342 for(i
=1;i
<arguments
.length
;i
++){
343 if(!_8d(arguments
[i
])){
345 return itr
.list(itr
.imap
.apply(null,arguments
));
347 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
350 var l
=arguments
[i
].length
;
351 if(_90
===null||_90
>l
){
358 for(var j
=1;j
<arguments
.length
;j
++){
359 _92
.push(arguments
[j
][i
]);
361 _8e
.push(fn
.apply(this,_92
));
365 },xfilter
:function(fn
){
368 fn
=MochiKit
.Base
.operator
.truth
;
370 for(var i
=1;i
<arguments
.length
;i
++){
377 },filter
:function(fn
,lst
,_9a
){
380 if(!m
.isArrayLike(lst
)){
382 lst
=MochiKit
.Iter
.list(lst
);
384 throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
390 if(typeof (Array
.prototype.filter
)=="function"){
391 return Array
.prototype.filter
.call(lst
,fn
,_9a
);
393 if(typeof (_9a
)=="undefined"||_9a
===null){
394 for(var i
=0;i
<lst
.length
;i
++){
401 for(i
=0;i
<lst
.length
;i
++){
410 },_wrapDumbFunction
:function(_9f
){
412 switch(arguments
.length
){
416 return _9f(arguments
[0]);
418 return _9f(arguments
[0],arguments
[1]);
420 return _9f(arguments
[0],arguments
[1],arguments
[2]);
423 for(var i
=0;i
<arguments
.length
;i
++){
424 _a0
.push("arguments["+i
+"]");
426 return eval("(func("+_a0
.join(",")+"))");
428 },methodcaller
:function(_a2
){
429 var _a3
=MochiKit
.Base
.extend(null,arguments
,1);
430 if(typeof (_a2
)=="function"){
431 return function(obj
){
432 return _a2
.apply(obj
,_a3
);
435 return function(obj
){
436 return obj
[_a2
].apply(obj
,_a3
);
439 },method
:function(_a6
,_a7
){
441 return m
.bind
.apply(this,m
.extend([_a7
,_a6
],arguments
,2));
442 },compose
:function(f1
,f2
){
445 if(arguments
.length
===0){
446 throw new TypeError("compose() requires at least one argument");
448 for(var i
=0;i
<arguments
.length
;i
++){
450 if(typeof (fn
)!="function"){
451 throw new TypeError(m
.repr(fn
)+" is not a function");
457 for(var i
=_ab
.length
-1;i
>=0;i
--){
458 _af
=[_ab
[i
].apply(this,_af
)];
462 },bind
:function(_b1
,_b2
){
463 if(typeof (_b1
)=="string"){
467 var _b4
=_b1
.im_preargs
;
470 if(typeof (_b1
)=="function"&&typeof (_b1
.apply
)=="undefined"){
471 _b1
=m
._wrapDumbFunction(_b1
);
473 if(typeof (_b3
)!="function"){
476 if(typeof (_b2
)!="undefined"){
479 if(typeof (_b4
)=="undefined"){
484 m
.extend(_b4
,arguments
,2);
487 var me
=arguments
.callee
;
488 if(me
.im_preargs
.length
>0){
489 _b8
=m
.concat(me
.im_preargs
,_b8
);
495 return me
.im_func
.apply(_ba
,_b8
);
501 },bindMethods
:function(_bb
){
502 var _bc
=MochiKit
.Base
.bind
;
505 if(typeof (_be
)=="function"){
509 },registerComparator
:function(_bf
,_c0
,_c1
,_c2
){
510 MochiKit
.Base
.comparatorRegistry
.register(_bf
,_c0
,_c1
,_c2
);
511 },_primitives
:{"boolean":true,"string":true,"number":true},compare
:function(a
,b
){
515 var _c5
=(typeof (a
)=="undefined"||a
===null);
516 var _c6
=(typeof (b
)=="undefined"||b
===null);
529 var _c8
=m
._primitives
;
530 if(!(typeof (a
) in _c8
&&typeof (b
) in _c8
)){
532 return m
.comparatorRegistry
.match(a
,b
);
548 throw new TypeError(_c9(a
)+" and "+_c9(b
)+" can not be compared");
549 },compareDateLike
:function(a
,b
){
550 return MochiKit
.Base
.compare(a
.getTime(),b
.getTime());
551 },compareArrayLike
:function(a
,b
){
552 var _ce
=MochiKit
.Base
.compare
;
563 for(var i
=0;i
<_cf
;i
++){
564 var cmp
=_ce(a
[i
],b
[i
]);
570 },registerRepr
:function(_d3
,_d4
,_d5
,_d6
){
571 MochiKit
.Base
.reprRegistry
.register(_d3
,_d4
,_d5
,_d6
);
573 if(typeof (o
)=="undefined"){
581 if(typeof (o
.__repr__
)=="function"){
584 if(typeof (o
.repr
)=="function"&&o
.repr
!=arguments
.callee
){
588 return MochiKit
.Base
.reprRegistry
.match(o
);
591 if(typeof (o
.NAME
)=="string"&&(o
.toString
==Function
.prototype.toString
||o
.toString
==Object
.prototype.toString
)){
599 return "["+typeof (o
)+"]";
601 if(typeof (o
)=="function"){
602 o
=_d8
.replace(/^\s+/,"");
603 var idx
=o
.indexOf("{");
605 o
=o
.substr(0,idx
)+"{...}";
609 },reprArrayLike
:function(o
){
611 return "["+m
.map(m
.repr
,o
).join(", ")+"]";
612 },reprString
:function(o
){
613 return ("\""+o
.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");
614 },reprNumber
:function(o
){
616 },registerJSON
:function(_de
,_df
,_e0
,_e1
){
617 MochiKit
.Base
.jsonRegistry
.register(_de
,_df
,_e0
,_e1
);
618 },evalJSON
:function(){
619 return eval("("+arguments
[0]+")");
620 },serializeJSON
:function(o
){
622 if(_e3
=="number"||_e3
=="boolean"){
630 var _e5
=m
.reprString
;
634 var me
=arguments
.callee
;
636 if(typeof (o
.__json__
)=="function"){
642 if(typeof (o
.json
)=="function"){
648 if(_e3
!="function"&&typeof (o
.length
)=="number"){
650 for(var i
=0;i
<o
.length
;i
++){
652 if(typeof (val
)!="string"){
657 return "["+res
.join(", ")+"]";
660 _e7
=m
.jsonRegistry
.match(o
);
670 if(_e3
=="undefined"){
671 throw new TypeError("undefined can not be serialized as JSON");
679 if(typeof (k
)=="number"){
682 if(typeof (k
)=="string"){
689 if(typeof (val
)!="string"){
692 res
.push(_ec
+":"+val
);
694 return "{"+res
.join(", ")+"}";
695 },objEqual
:function(a
,b
){
696 return (MochiKit
.Base
.compare(a
,b
)===0);
697 },arrayEqual
:function(_ef
,arr
){
698 if(_ef
.length
!=arr
.length
){
701 return (MochiKit
.Base
.compare(_ef
,arr
)===0);
704 var _f2
=MochiKit
.Base
.extend
;
705 for(var i
=0;i
<arguments
.length
;i
++){
706 _f2(_f1
,arguments
[i
]);
709 },keyComparator
:function(key
){
712 if(arguments
.length
==1){
713 return function(a
,b
){
714 return _f6(a
[key
],b
[key
]);
717 var _f9
=m
.extend(null,arguments
);
718 return function(a
,b
){
720 for(var i
=0;(_fc
===0)&&(i
<_f9
.length
);i
++){
722 _fc
=_f6(a
[key
],b
[key
]);
726 },reverseKeyComparator
:function(key
){
727 var _100
=MochiKit
.Base
.keyComparator
.apply(this,arguments
);
728 return function(a
,b
){
731 },partial
:function(func
){
733 return m
.bind
.apply(this,m
.extend([func
,undefined
],arguments
,1));
734 },listMinMax
:function(_105
,lst
){
739 var _108
=MochiKit
.Base
.compare
;
740 for(var i
=1;i
<lst
.length
;i
++){
742 if(_108(o
,cur
)==_105
){
748 return MochiKit
.Base
.listMinMax(1,arguments
);
750 return MochiKit
.Base
.listMinMax(-1,arguments
);
751 },findIdentical
:function(lst
,_10c
,_10d
,end
){
752 if(typeof (end
)=="undefined"||end
===null){
755 if(typeof (_10d
)=="undefined"||_10d
===null){
758 for(var i
=_10d
;i
<end
;i
++){
767 var args
=m
.extend(null,arguments
);
768 var _113
=args
.length
;
771 if(o
&&typeof (o
)=="object"&&typeof (o
.length
)=="number"){
773 for(var i
=o
.length
-1;i
>=0;i
--){
781 throw new TypeError("mean() requires at least one argument");
785 var data
=MochiKit
.Base
.flattenArguments(arguments
);
787 throw new TypeError("median() requires at least one argument");
790 if(data
.length
%2==0){
791 var _117
=data
.length
/2;
792 return (data
[_117
]+data
[_117
-1])/2;
794 return data
[(data
.length
-1)/2];
796 },findValue
:function(lst
,_119
,_11a
,end
){
797 if(typeof (end
)=="undefined"||end
===null){
800 if(typeof (_11a
)=="undefined"||_11a
===null){
803 var cmp
=MochiKit
.Base
.compare
;
804 for(var i
=_11a
;i
<end
;i
++){
805 if(cmp(lst
[i
],_119
)===0){
810 },nodeWalk
:function(node
,_11f
){
812 var _121
=MochiKit
.Base
.extend
;
814 var res
=_11f(_120
.shift());
819 },nameFunctions
:function(_123
){
821 if(typeof (base
)=="undefined"){
826 for(var name
in _123
){
828 if(typeof (o
)=="function"&&typeof (o
.NAME
)=="undefined"){
836 },queryString
:function(_127
,_128
){
837 if(typeof (MochiKit
.DOM
)!="undefined"&&arguments
.length
==1&&(typeof (_127
)=="string"||(typeof (_127
.nodeType
)!="undefined"&&_127
.nodeType
>0))){
838 var kv
=MochiKit
.DOM
.formContents(_127
);
842 if(arguments
.length
==1){
843 if(typeof (_127
.length
)=="number"&&_127
.length
==2){
844 return arguments
.callee(_127
[0],_127
[1]);
851 if(typeof (v
)=="function"){
854 if(typeof (v
)!="string"&&typeof (v
.length
)=="number"){
855 for(var i
=0;i
<v
.length
;i
++){
868 var len
=Math
.min(_127
.length
,_128
.length
);
869 var _130
=MochiKit
.Base
.urlEncode
;
870 for(var i
=0;i
<len
;i
++){
872 if(typeof (v
)!="undefined"&&v
!==null){
873 rval
.push(_130(_127
[i
])+"="+_130(v
));
876 return rval
.join("&");
877 },parseQueryString
:function(_131
,_132
){
878 var qstr
=(_131
.charAt(0)=="?")?_131
.substring(1):_131
;
879 var _134
=qstr
.replace(/\+/g,"%20").split(/(\&\;|\&\#38\;|\&|\&)/);
882 if(typeof (decodeURIComponent
)!="undefined"){
883 _136
=decodeURIComponent
;
888 for(var i
=0;i
<_134
.length
;i
++){
889 var pair
=_134
[i
].split("=");
890 var name
=_136(pair
.shift());
895 if(!(arr
instanceof Array
)){
899 arr
.push(_136(pair
.join("=")));
902 for(i
=0;i
<_134
.length
;i
++){
903 pair
=_134
[i
].split("=");
904 var name
=pair
.shift();
908 o
[_136(name
)]=_136(pair
.join("="));
913 MochiKit
.Base
.AdapterRegistry
=function(){
916 MochiKit
.Base
.AdapterRegistry
.prototype={register
:function(name
,_13c
,wrap
,_13e
){
918 this.pairs
.unshift([name
,_13c
,wrap
]);
920 this.pairs
.push([name
,_13c
,wrap
]);
923 for(var i
=0;i
<this.pairs
.length
;i
++){
924 var pair
=this.pairs
[i
];
925 if(pair
[1].apply(this,arguments
)){
926 return pair
[2].apply(this,arguments
);
929 throw MochiKit
.Base
.NotFound
;
930 },unregister
:function(name
){
931 for(var i
=0;i
<this.pairs
.length
;i
++){
932 var pair
=this.pairs
[i
];
934 this.pairs
.splice(i
,1);
940 MochiKit
.Base
.EXPORT
=["flattenArray","noop","camelize","counter","clone","extend","update","updatetree","setdefault","keys","values","items","NamedError","operator","forwardCall","itemgetter","typeMatcher","isCallable","isUndefined","isUndefinedOrNull","isNull","isEmpty","isNotEmpty","isArrayLike","isDateLike","xmap","map","xfilter","filter","methodcaller","compose","bind","bindMethods","NotFound","AdapterRegistry","registerComparator","compare","registerRepr","repr","objEqual","arrayEqual","concat","keyComparator","reverseKeyComparator","partial","merge","listMinMax","listMax","listMin","objMax","objMin","nodeWalk","zip","urlEncode","queryString","serializeJSON","registerJSON","evalJSON","parseQueryString","findValue","findIdentical","flattenArguments","method","average","mean","median"];
941 MochiKit
.Base
.EXPORT_OK
=["nameFunctions","comparatorRegistry","reprRegistry","jsonRegistry","compareDateLike","compareArrayLike","reprArrayLike","reprString","reprNumber"];
942 MochiKit
.Base
._exportSymbols
=function(_144
,_145
){
943 if(!MochiKit
.__export__
){
946 var all
=_145
.EXPORT_TAGS
[":all"];
947 for(var i
=0;i
<all
.length
;i
++){
948 _144
[all
[i
]]=_145
[all
[i
]];
951 MochiKit
.Base
.__new__
=function(){
953 m
.noop
=m
.operator
.identity
;
954 m
.forward
=m
.forwardCall
;
956 if(typeof (encodeURIComponent
)!="undefined"){
957 m
.urlEncode
=function(_149
){
958 return encodeURIComponent(_149
).replace(/\'/g,"%27");
961 m
.urlEncode
=function(_14a
){
962 return escape(_14a
).replace(/\+/g,"%2B").replace(/\"/g,"%22").rval
.replace(/\'/g,"%27");
965 m
.NamedError
=function(name
){
969 m
.NamedError
.prototype=new Error();
970 m
.update(m
.NamedError
.prototype,{repr
:function(){
971 if(this.message
&&this.message
!=this.name
){
972 return this.name
+"("+m
.repr(this.message
)+")";
974 return this.name
+"()";
976 },toString
:m
.forwardCall("repr")});
977 m
.NotFound
=new m
.NamedError("MochiKit.Base.NotFound");
978 m
.listMax
=m
.partial(m
.listMinMax
,1);
979 m
.listMin
=m
.partial(m
.listMinMax
,-1);
980 m
.isCallable
=m
.typeMatcher("function");
981 m
.isUndefined
=m
.typeMatcher("undefined");
982 m
.merge
=m
.partial(m
.update
,null);
983 m
.zip
=m
.partial(m
.map
,null);
985 m
.comparatorRegistry
=new m
.AdapterRegistry();
986 m
.registerComparator("dateLike",m
.isDateLike
,m
.compareDateLike
);
987 m
.registerComparator("arrayLike",m
.isArrayLike
,m
.compareArrayLike
);
988 m
.reprRegistry
=new m
.AdapterRegistry();
989 m
.registerRepr("arrayLike",m
.isArrayLike
,m
.reprArrayLike
);
990 m
.registerRepr("string",m
.typeMatcher("string"),m
.reprString
);
991 m
.registerRepr("numbers",m
.typeMatcher("number","boolean"),m
.reprNumber
);
992 m
.jsonRegistry
=new m
.AdapterRegistry();
993 var all
=m
.concat(m
.EXPORT
,m
.EXPORT_OK
);
994 m
.EXPORT_TAGS
={":common":m
.concat(m
.EXPORT_OK
),":all":all
};
995 m
.nameFunctions(this);
997 MochiKit
.Base
.__new__();
998 if(MochiKit
.__export__
){
999 compare
=MochiKit
.Base
.compare
;
1000 compose
=MochiKit
.Base
.compose
;
1001 serializeJSON
=MochiKit
.Base
.serializeJSON
;
1003 MochiKit
.Base
._exportSymbols(this,MochiKit
.Base
);
1004 if(typeof (dojo
)!="undefined"){
1005 dojo
.provide("MochiKit.Format");
1007 if(typeof (MochiKit
)=="undefined"){
1010 if(typeof (MochiKit
.Format
)=="undefined"){
1013 MochiKit
.Format
.NAME
="MochiKit.Format";
1014 MochiKit
.Format
.VERSION
="1.4";
1015 MochiKit
.Format
.__repr__
=function(){
1016 return "["+this.NAME
+" "+this.VERSION
+"]";
1018 MochiKit
.Format
.toString
=function(){
1019 return this.__repr__();
1021 MochiKit
.Format
._numberFormatter
=function(_14d
,_14e
,_14f
,_150
,_151
,_152
,_153
,_154
,_155
){
1022 return function(num
){
1023 num
=parseFloat(num
);
1024 if(typeof (num
)=="undefined"||num
===null||isNaN(num
)){
1032 _157
=_157
.replace(/-/,"");
1034 var me
=arguments
.callee
;
1035 var fmt
=MochiKit
.Format
.formatLocale(_150
);
1038 _158
=fmt
.percent
+_158
;
1040 num
=MochiKit
.Format
.roundToFixed(num
,_152
);
1041 var _15b
=num
.split(/\./);
1043 var frac
=(_15b
.length
==1)?"":_15b
[1];
1045 while(_15c
.length
<_153
){
1049 while(_15c
.length
>_154
){
1050 var i
=_15c
.length
-_154
;
1051 res
=fmt
.separator
+_15c
.substring(i
,_15c
.length
)+res
;
1052 _15c
=_15c
.substring(0,i
);
1057 while(frac
.length
<_155
){
1060 res
=res
+fmt
.decimal+frac
;
1062 return _157
+res
+_158
;
1065 MochiKit
.Format
.numberFormatter
=function(_160
,_161
,_162
){
1066 if(typeof (_161
)=="undefined"){
1069 var _163
=_160
.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/);
1071 throw TypeError("Invalid pattern");
1073 var _164
=_160
.substr(0,_163
.index
);
1074 var _165
=_160
.substr(_163
.index
+_163
[0].length
);
1075 if(_164
.search(/-/)==-1){
1079 var frac
=(typeof (_163
[2])=="string"&&_163
[2]!="")?_163
[2]:"";
1080 var _168
=(typeof (_163
[3])=="string"&&_163
[3]!="");
1081 var tmp
=_166
.split(/,/);
1083 if(typeof (_162
)=="undefined"){
1091 var _16b
=_166
.length
-_166
.replace(/0/g,"").length
;
1092 var _16c
=frac
.length
-frac
.replace(/0/g,"").length
;
1093 var _16d
=frac
.length
;
1094 var rval
=MochiKit
.Format
._numberFormatter(_161
,_164
,_165
,_162
,_168
,_16d
,_16b
,_16a
,_16c
);
1095 var m
=MochiKit
.Base
;
1097 var fn
=arguments
.callee
;
1098 var args
=m
.concat(arguments
);
1099 rval
.repr
=function(){
1100 return [self
.NAME
,"(",map(m
.repr
,args
).join(", "),")"].join("");
1105 MochiKit
.Format
.formatLocale
=function(_172
){
1106 if(typeof (_172
)=="undefined"||_172
===null){
1109 if(typeof (_172
)=="string"){
1110 var rval
=MochiKit
.Format
.LOCALE
[_172
];
1111 if(typeof (rval
)=="string"){
1112 rval
=arguments
.callee(rval
);
1113 MochiKit
.Format
.LOCALE
[_172
]=rval
;
1120 MochiKit
.Format
.twoDigitAverage
=function(_174
,_175
){
1124 return MochiKit
.Format
.twoDigitFloat(_174
/_175
);
1129 MochiKit
.Format
.twoDigitFloat
=function(_177
){
1130 var sign
=(_177
<0?"-":"");
1131 var s
=Math
.floor(Math
.abs(_177
)*100).toString();
1136 while(s
.charAt(s
.length
-1)=="0"){
1137 s
=s
.substring(0,s
.length
-1);
1141 var head
=sign
+s
.substring(0,s
.length
-2);
1142 var tail
=s
.substring(s
.length
-2,s
.length
);
1146 if(tail
.charAt(1)=="0"){
1147 return head
+"."+tail
.charAt(0);
1149 return head
+"."+tail
;
1153 MochiKit
.Format
.lstrip
=function(str
,_17d
){
1155 if(typeof (str
)!="string"){
1159 return str
.replace(/^\s+/,"");
1161 return str
.replace(new RegExp("^["+_17d
+"]+"),"");
1164 MochiKit
.Format
.rstrip
=function(str
,_17f
){
1166 if(typeof (str
)!="string"){
1170 return str
.replace(/\s+$/,"");
1172 return str
.replace(new RegExp("["+_17f
+"]+$"),"");
1175 MochiKit
.Format
.strip
=function(str
,_181
){
1176 var self
=MochiKit
.Format
;
1177 return self
.rstrip(self
.lstrip(str
,_181
),_181
);
1179 MochiKit
.Format
.truncToFixed
=function(_183
,_184
){
1180 _183
=Math
.floor(_183
*Math
.pow(10,_184
));
1181 var res
=(_183
*Math
.pow(10,-_184
)).toFixed(_184
);
1182 if(res
.charAt(0)=="."){
1187 MochiKit
.Format
.roundToFixed
=function(_186
,_187
){
1188 return MochiKit
.Format
.truncToFixed(_186
+0.5*Math
.pow(10,-_187
),_187
);
1190 MochiKit
.Format
.percentFormat
=function(_188
){
1191 return MochiKit
.Format
.twoDigitFloat(100*_188
)+"%";
1193 MochiKit
.Format
.EXPORT
=["truncToFixed","roundToFixed","numberFormatter","formatLocale","twoDigitAverage","twoDigitFloat","percentFormat","lstrip","rstrip","strip"];
1194 MochiKit
.Format
.LOCALE
={en_US
:{separator
:",",decimal:".",percent
:"%"},de_DE
:{separator
:".",decimal:",",percent
:"%"},fr_FR
:{separator
:" ",decimal:",",percent
:"%"},"default":"en_US"};
1195 MochiKit
.Format
.EXPORT_OK
=[];
1196 MochiKit
.Format
.EXPORT_TAGS
={":all":MochiKit
.Format
.EXPORT
,":common":MochiKit
.Format
.EXPORT
};
1197 MochiKit
.Format
.__new__
=function(){
1198 var base
=this.NAME
+".";
1200 for(k
in this.LOCALE
){
1202 if(typeof (o
)=="object"){
1206 o
.NAME
=base
+"LOCALE."+k
;
1211 if(typeof (o
)=="function"&&typeof (o
.NAME
)=="undefined"){
1220 MochiKit
.Format
.__new__();
1221 if(typeof (MochiKit
.Base
)!="undefined"){
1222 MochiKit
.Base
._exportSymbols(this,MochiKit
.Format
);
1224 (function(_18d
,_18e
){
1225 if((typeof (JSAN
)=="undefined"&&typeof (dojo
)=="undefined")||(MochiKit
.__export__
===false)){
1226 var all
=_18e
.EXPORT_TAGS
[":all"];
1227 for(var i
=0;i
<all
.length
;i
++){
1228 _18d
[all
[i
]]=_18e
[all
[i
]];
1231 })(this,MochiKit
.Format
);
1233 if(typeof (dojo
)!="undefined"){
1234 dojo
.provide("MochiKit.DOM");
1235 dojo
.require("MochiKit.Base");
1237 if(typeof (JSAN
)!="undefined"){
1238 JSAN
.use("MochiKit.Base",[]);
1241 if(typeof (MochiKit
.Base
)=="undefined"){
1246 throw "MochiKit.DOM depends on MochiKit.Base!";
1248 if(typeof (MochiKit
.DOM
)=="undefined"){
1251 MochiKit
.DOM
.NAME
="MochiKit.DOM";
1252 MochiKit
.DOM
.VERSION
="1.4";
1253 MochiKit
.DOM
.__repr__
=function(){
1254 return "["+this.NAME
+" "+this.VERSION
+"]";
1256 MochiKit
.DOM
.toString
=function(){
1257 return this.__repr__();
1259 MochiKit
.DOM
.EXPORT
=["removeEmptyTextNodes","formContents","currentWindow","currentDocument","withWindow","withDocument","registerDOMConverter","coerceToDOM","createDOM","createDOMFunc","isChildNode","getNodeAttribute","removeNodeAttribute","setNodeAttribute","updateNodeAttributes","appendChildNodes","insertSiblingNodesAfter","insertSiblingNodesBefore","replaceChildNodes","removeElement","swapDOM","BUTTON","TT","PRE","H1","H2","H3","BR","CANVAS","HR","LABEL","TEXTAREA","FORM","STRONG","SELECT","OPTION","OPTGROUP","LEGEND","FIELDSET","P","UL","OL","LI","TD","TR","THEAD","TBODY","TFOOT","TABLE","TH","INPUT","SPAN","A","DIV","IMG","getElement","$","getElementsByTagAndClassName","addToCallStack","addLoadEvent","focusOnLoad","setElementClass","toggleElementClass","addElementClass","removeElementClass","swapElementClass","hasElementClass","escapeHTML","toHTML","emitHTML","scrapeText","isParent","getFirstParentByTagAndClassName","makeClipping","undoClipping","makePositioned","undoPositioned","getFirstElementByTagAndClassName"];
1260 MochiKit
.DOM
.EXPORT_OK
=["domConverters"];
1261 MochiKit
.DOM
.DEPRECATED
=[["computedStyle","MochiKit.Style.getStyle","1.4"],["elementDimensions","MochiKit.Style.getElementDimensions","1.4"],["elementPosition","MochiKit.Style.getElementPosition","1.4"],["hideElement","MochiKit.Style.hideElement","1.4"],["setElementDimensions","MochiKit.Style.setElementDimensions","1.4"],["setElementPosition","MochiKit.Style.setElementPosition","1.4"],["setDisplayForElement","MochiKit.Style.setDisplayForElement","1.4"],["setOpacity","MochiKit.Style.setOpacity","1.4"],["showElement","MochiKit.Style.showElement","1.4"],["Coordinates","MochiKit.Style.Coordinates","1.4"],["Dimensions","MochiKit.Style.Dimensions","1.4"]];
1262 MochiKit
.DOM
.getViewportDimensions
=new Function(""+"if (!MochiKit[\"Style\"]) {"+" throw new Error(\"This function has been deprecated and depends on MochiKit.Style.\");"+"}"+"return MochiKit.Style.getViewportDimensions.apply(this, arguments);");
1263 MochiKit
.Base
.update(MochiKit
.DOM
,{currentWindow
:function(){
1264 return MochiKit
.DOM
._window
;
1265 },currentDocument
:function(){
1266 return MochiKit
.DOM
._document
;
1267 },withWindow
:function(win
,func
){
1268 var self
=MochiKit
.DOM
;
1269 var _194
=self
._document
;
1270 var _195
=self
._window
;
1274 self
._document
=win
.document
;
1279 self
._document
=_194
;
1283 self
._document
=_194
;
1285 },formContents
:function(elem
){
1288 var m
=MochiKit
.Base
;
1289 var self
=MochiKit
.DOM
;
1290 if(typeof (elem
)=="undefined"||elem
===null){
1291 elem
=self
._document
.body
;
1293 elem
=self
.getElement(elem
);
1295 m
.nodeWalk(elem
,function(elem
){
1297 if(m
.isNotEmpty(name
)){
1298 var _19e
=elem
.tagName
.toUpperCase();
1299 if(_19e
==="INPUT"&&(elem
.type
=="radio"||elem
.type
=="checkbox")&&!elem
.checked
){
1302 if(_19e
==="SELECT"){
1303 if(elem
.type
=="select-one"){
1304 if(elem
.selectedIndex
>=0){
1305 var opt
=elem
.options
[elem
.selectedIndex
];
1308 var h
=opt
.outerHTML
;
1309 if(h
&&!h
.match(/^[^>]+\svalue\s*=/i)){
1321 var opts
=elem
.options
;
1327 for(var i
=0;i
<opts
.length
;i
++){
1334 var h
=opt
.outerHTML
;
1335 if(h
&&!h
.match(/^[^>]+\svalue\s*=/i)){
1345 if(_19e
==="FORM"||_19e
==="P"||_19e
==="SPAN"||_19e
==="DIV"){
1346 return elem
.childNodes
;
1349 _199
.push(elem
.value
||"");
1352 return elem
.childNodes
;
1355 },withDocument
:function(doc
,func
){
1356 var self
=MochiKit
.DOM
;
1357 var _1a7
=self
._document
;
1364 self
._document
=_1a7
;
1367 self
._document
=_1a7
;
1369 },registerDOMConverter
:function(name
,_1aa
,wrap
,_1ac
){
1370 MochiKit
.DOM
.domConverters
.register(name
,_1aa
,wrap
,_1ac
);
1371 },coerceToDOM
:function(node
,ctx
){
1372 var m
=MochiKit
.Base
;
1373 var im
=MochiKit
.Iter
;
1374 var self
=MochiKit
.DOM
;
1380 var _1b5
=self
.domConverters
;
1381 var _1b6
=arguments
.callee
;
1382 var _1b7
=m
.NotFound
;
1384 if(typeof (node
)=="undefined"||node
===null){
1387 if(typeof (node
)=="function"&&typeof (node
.length
)=="number"&&!(node
instanceof Function
)){
1390 if(typeof (node
.nodeType
)!="undefined"&&node
.nodeType
>0){
1393 if(typeof (node
)=="number"||typeof (node
)=="boolean"){
1394 node
=node
.toString();
1396 if(typeof (node
)=="string"){
1397 return self
._document
.createTextNode(node
);
1399 if(typeof (node
.__dom__
)=="function"){
1400 node
=node
.__dom__(ctx
);
1403 if(typeof (node
.dom
)=="function"){
1407 if(typeof (node
)=="function"){
1408 node
=node
.apply(ctx
,[ctx
]);
1419 return map(_1b6
,_1b8
,_1b3(ctx
));
1423 node
=_1b5
.match(node
,ctx
);
1431 return self
._document
.createTextNode(node
.toString());
1434 },isChildNode
:function(node
,_1ba
){
1435 var self
=MochiKit
.DOM
;
1436 if(typeof (node
)=="string"){
1437 node
=self
.getElement(node
);
1439 if(typeof (_1ba
)=="string"){
1440 _1ba
=self
.getElement(_1ba
);
1445 while(node
&&node
.tagName
.toUpperCase()!="BODY"){
1446 node
=node
.parentNode
;
1452 },setNodeAttribute
:function(node
,attr
,_1be
){
1456 return MochiKit
.DOM
.updateNodeAttributes(node
,o
);
1461 },getNodeAttribute
:function(node
,attr
){
1462 var self
=MochiKit
.DOM
;
1463 var _1c3
=self
.attributeArray
.renames
[attr
];
1464 node
=self
.getElement(node
);
1469 return node
.getAttribute(attr
);
1474 },removeNodeAttribute
:function(node
,attr
){
1475 var self
=MochiKit
.DOM
;
1476 var _1c7
=self
.attributeArray
.renames
[attr
];
1477 node
=self
.getElement(node
);
1482 return node
.removeAttribute(attr
);
1487 },updateNodeAttributes
:function(node
,_1c9
){
1489 var self
=MochiKit
.DOM
;
1490 if(typeof (node
)=="string"){
1491 elem
=self
.getElement(node
);
1494 var _1cc
=MochiKit
.Base
.updatetree
;
1495 if(self
.attributeArray
.compliant
){
1498 if(typeof (v
)=="object"&&typeof (elem
[k
])=="object"){
1499 if(k
=="style"&&MochiKit
.Style
){
1500 MochiKit
.Style
.setStyle(elem
,v
);
1505 if(k
.substring(0,2)=="on"){
1506 if(typeof (v
)=="string"){
1511 elem
.setAttribute(k
,v
);
1516 var _1cf
=self
.attributeArray
.renames
;
1520 if(k
=="style"&&typeof (v
)=="string"){
1521 elem
.style
.cssText
=v
;
1523 if(typeof (_1d0
)=="string"){
1526 if(typeof (elem
[k
])=="object"&&typeof (v
)=="object"){
1527 if(k
=="style"&&MochiKit
.Style
){
1528 MochiKit
.Style
.setStyle(elem
,v
);
1533 if(k
.substring(0,2)=="on"){
1534 if(typeof (v
)=="string"){
1539 elem
.setAttribute(k
,v
);
1548 },appendChildNodes
:function(node
){
1550 var self
=MochiKit
.DOM
;
1551 if(typeof (node
)=="string"){
1552 elem
=self
.getElement(node
);
1554 var _1d4
=[self
.coerceToDOM(MochiKit
.Base
.extend(null,arguments
,1),elem
)];
1555 var _1d5
=MochiKit
.Base
.concat
;
1558 if(typeof (n
)=="undefined"||n
===null){
1560 if(typeof (n
.nodeType
)=="number"){
1561 elem
.appendChild(n
);
1568 },insertSiblingNodesBefore
:function(node
){
1570 var self
=MochiKit
.DOM
;
1571 if(typeof (node
)=="string"){
1572 elem
=self
.getElement(node
);
1574 var _1da
=[self
.coerceToDOM(MochiKit
.Base
.extend(null,arguments
,1),elem
)];
1575 var _1db
=elem
.parentNode
;
1576 var _1dc
=MochiKit
.Base
.concat
;
1579 if(typeof (n
)=="undefined"||n
===null){
1581 if(typeof (n
.nodeType
)=="number"){
1582 _1db
.insertBefore(n
,elem
);
1589 },insertSiblingNodesAfter
:function(node
){
1591 var self
=MochiKit
.DOM
;
1592 if(typeof (node
)=="string"){
1593 elem
=self
.getElement(node
);
1595 var _1e1
=[self
.coerceToDOM(MochiKit
.Base
.extend(null,arguments
,1),elem
)];
1596 if(elem
.nextSibling
){
1597 return self
.insertSiblingNodesBefore(elem
.nextSibling
,_1e1
);
1599 return self
.appendChildNodes(elem
.parentNode
,_1e1
);
1601 },replaceChildNodes
:function(node
){
1603 var self
=MochiKit
.DOM
;
1604 if(typeof (node
)=="string"){
1605 elem
=self
.getElement(node
);
1609 while((_1e5
=elem
.firstChild
)){
1610 elem
.removeChild(_1e5
);
1612 if(arguments
.length
<2){
1615 return self
.appendChildNodes
.apply(this,arguments
);
1617 },createDOM
:function(name
,_1e7
){
1619 var self
=MochiKit
.DOM
;
1620 var m
=MochiKit
.Base
;
1621 if(typeof (_1e7
)=="string"||typeof (_1e7
)=="number"){
1622 var args
=m
.extend([name
,null],arguments
,1);
1623 return arguments
.callee
.apply(this,args
);
1625 if(typeof (name
)=="string"){
1626 var _1ec
=self
._xhtml
;
1627 if(_1e7
&&!self
.attributeArray
.compliant
){
1630 _1ed
+=" name=\""+self
.escapeHTML(_1e7
.name
)+"\"";
1632 if(name
=="input"&&"type" in _1e7
){
1633 _1ed
+=" type=\""+self
.escapeHTML(_1e7
.type
)+"\"";
1636 name
="<"+name
+_1ed
+">";
1640 var d
=self
._document
;
1641 if(_1ec
&&d
===document
){
1642 elem
=d
.createElementNS("http://www.w3.org/1999/xhtml",name
);
1644 elem
=d
.createElement(name
);
1650 self
.updateNodeAttributes(elem
,_1e7
);
1652 if(arguments
.length
<=2){
1655 var args
=m
.extend([elem
],arguments
,2);
1656 return self
.appendChildNodes
.apply(this,args
);
1658 },createDOMFunc
:function(){
1659 var m
=MochiKit
.Base
;
1660 return m
.partial
.apply(this,m
.extend([MochiKit
.DOM
.createDOM
],arguments
));
1661 },removeElement
:function(elem
){
1662 var e
=MochiKit
.DOM
.getElement(elem
);
1663 e
.parentNode
.removeChild(e
);
1665 },swapDOM
:function(dest
,src
){
1666 var self
=MochiKit
.DOM
;
1667 dest
=self
.getElement(dest
);
1668 var _1f5
=dest
.parentNode
;
1670 src
=self
.getElement(src
);
1671 _1f5
.replaceChild(src
,dest
);
1673 _1f5
.removeChild(dest
);
1676 },getElement
:function(id
){
1677 var self
=MochiKit
.DOM
;
1678 if(arguments
.length
==1){
1679 return ((typeof (id
)=="string")?self
._document
.getElementById(id
):id
);
1681 return MochiKit
.Base
.map(self
.getElement
,arguments
);
1683 },getElementsByTagAndClassName
:function(_1f8
,_1f9
,_1fa
){
1684 var self
=MochiKit
.DOM
;
1685 if(typeof (_1f8
)=="undefined"||_1f8
===null){
1688 if(typeof (_1fa
)=="undefined"||_1fa
===null){
1689 _1fa
=self
._document
;
1691 _1fa
=self
.getElement(_1fa
);
1692 var _1fc
=(_1fa
.getElementsByTagName(_1f8
)||self
._document
.all
);
1693 if(typeof (_1f9
)=="undefined"||_1f9
===null){
1694 return MochiKit
.Base
.extend(null,_1fc
);
1697 for(var i
=0;i
<_1fc
.length
;i
++){
1699 var cls
=_1ff
.className
;
1703 var _201
=cls
.split(" ");
1704 for(var j
=0;j
<_201
.length
;j
++){
1712 },_newCallStack
:function(path
,once
){
1713 var rval
=function(){
1714 var _206
=arguments
.callee
.callStack
;
1715 for(var i
=0;i
<_206
.length
;i
++){
1716 if(_206
[i
].apply(this,arguments
)===false){
1730 },addToCallStack
:function(_208
,path
,func
,once
){
1731 var self
=MochiKit
.DOM
;
1732 var _20d
=_208
[path
];
1734 if(!(typeof (_20d
)=="function"&&typeof (_20d
.callStack
)=="object"&&_20d
.callStack
!==null)){
1735 _20e
=self
._newCallStack(path
,once
);
1736 if(typeof (_20d
)=="function"){
1737 _20e
.callStack
.push(_20d
);
1741 _20e
.callStack
.push(func
);
1742 },addLoadEvent
:function(func
){
1743 var self
=MochiKit
.DOM
;
1744 self
.addToCallStack(self
._window
,"onload",func
,true);
1745 },focusOnLoad
:function(_211
){
1746 var self
=MochiKit
.DOM
;
1747 self
.addLoadEvent(function(){
1748 _211
=self
.getElement(_211
);
1753 },setElementClass
:function(_213
,_214
){
1754 var self
=MochiKit
.DOM
;
1755 var obj
=self
.getElement(_213
);
1756 if(self
.attributeArray
.compliant
){
1757 obj
.setAttribute("class",_214
);
1759 obj
.setAttribute("className",_214
);
1761 },toggleElementClass
:function(_217
){
1762 var self
=MochiKit
.DOM
;
1763 for(var i
=1;i
<arguments
.length
;i
++){
1764 var obj
=self
.getElement(arguments
[i
]);
1765 if(!self
.addElementClass(obj
,_217
)){
1766 self
.removeElementClass(obj
,_217
);
1769 },addElementClass
:function(_21b
,_21c
){
1770 var self
=MochiKit
.DOM
;
1771 var obj
=self
.getElement(_21b
);
1772 var cls
=obj
.className
;
1773 if(cls
==undefined
||cls
.length
===0){
1774 self
.setElementClass(obj
,_21c
);
1780 var _220
=cls
.split(" ");
1781 for(var i
=0;i
<_220
.length
;i
++){
1786 self
.setElementClass(obj
,cls
+" "+_21c
);
1788 },removeElementClass
:function(_222
,_223
){
1789 var self
=MochiKit
.DOM
;
1790 var obj
=self
.getElement(_222
);
1791 var cls
=obj
.className
;
1792 if(cls
==undefined
||cls
.length
===0){
1796 self
.setElementClass(obj
,"");
1799 var _227
=cls
.split(" ");
1800 for(var i
=0;i
<_227
.length
;i
++){
1803 self
.setElementClass(obj
,_227
.join(" "));
1808 },swapElementClass
:function(_229
,_22a
,_22b
){
1809 var obj
=MochiKit
.DOM
.getElement(_229
);
1810 var res
=MochiKit
.DOM
.removeElementClass(obj
,_22a
);
1812 MochiKit
.DOM
.addElementClass(obj
,_22b
);
1815 },hasElementClass
:function(_22e
,_22f
){
1816 var obj
=MochiKit
.DOM
.getElement(_22e
);
1817 var cls
=obj
.className
;
1821 var _232
=cls
.split(" ");
1822 for(var i
=1;i
<arguments
.length
;i
++){
1824 for(var j
=0;j
<_232
.length
;j
++){
1825 if(_232
[j
]==arguments
[i
]){
1835 },escapeHTML
:function(s
){
1836 return s
.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">");
1837 },toHTML
:function(dom
){
1838 return MochiKit
.DOM
.emitHTML(dom
).join("");
1839 },emitHTML
:function(dom
,lst
){
1840 if(typeof (lst
)=="undefined"||lst
===null){
1844 var self
=MochiKit
.DOM
;
1845 var _23c
=self
.escapeHTML
;
1846 var _23d
=self
.attributeArray
;
1849 if(typeof (dom
)=="string"){
1852 if(dom
.nodeType
==1){
1853 lst
.push("<"+dom
.tagName
.toLowerCase());
1856 for(var i
=0;i
<_23f
.length
;i
++){
1858 _23e
.push([" ",a
.name
,"=\"",_23c(a
.value
),"\""]);
1861 for(i
=0;i
<_23e
.length
;i
++){
1863 for(var j
=0;j
<_242
.length
;j
++){
1867 if(dom
.hasChildNodes()){
1869 _23a
.push("</"+dom
.tagName
.toLowerCase()+">");
1870 var _244
=dom
.childNodes
;
1871 for(i
=_244
.length
-1;i
>=0;i
--){
1878 if(dom
.nodeType
==3){
1879 lst
.push(_23c(dom
.nodeValue
));
1885 },scrapeText
:function(node
,_246
){
1888 var cn
=node
.childNodes
;
1890 for(var i
=0;i
<cn
.length
;i
++){
1891 arguments
.callee
.call(this,cn
[i
]);
1894 var _24b
=node
.nodeValue
;
1895 if(typeof (_24b
)=="string"){
1898 })(MochiKit
.DOM
.getElement(node
));
1902 return rval
.join("");
1904 },removeEmptyTextNodes
:function(_24c
){
1905 _24c
=MochiKit
.DOM
.getElement(_24c
);
1906 for(var i
=0;i
<_24c
.childNodes
.length
;i
++){
1907 var node
=_24c
.childNodes
[i
];
1908 if(node
.nodeType
==3&&!/\S/.test(node
.nodeValue
)){
1909 node
.parentNode
.removeChild(node
);
1912 },makeClipping
:function(_24f
){
1913 _24f
=MochiKit
.DOM
.getElement(_24f
);
1914 var _250
=_24f
.style
.overflow
;
1915 if((MochiKit
.Style
.getStyle(_24f
,"overflow")||"visible")!="hidden"){
1916 _24f
.style
.overflow
="hidden";
1919 },undoClipping
:function(_251
,_252
){
1920 _251
=MochiKit
.DOM
.getElement(_251
);
1924 _251
.style
.overflow
=_252
;
1925 },makePositioned
:function(_253
){
1926 _253
=MochiKit
.DOM
.getElement(_253
);
1927 var pos
=MochiKit
.Style
.getStyle(_253
,"position");
1928 if(pos
=="static"||!pos
){
1929 _253
.style
.position
="relative";
1930 if(/Opera/.test(navigator
.userAgent
)){
1935 },undoPositioned
:function(_255
){
1936 _255
=MochiKit
.DOM
.getElement(_255
);
1937 if(_255
.style
.position
=="relative"){
1938 _255
.style
.position
=_255
.style
.top
=_255
.style
.left
=_255
.style
.bottom
=_255
.style
.right
="";
1940 },getFirstElementByTagAndClassName
:function(_256
,_257
,_258
){
1941 var self
=MochiKit
.DOM
;
1942 if(typeof (_256
)=="undefined"||_256
===null){
1945 if(typeof (_258
)=="undefined"||_258
===null){
1946 _258
=self
._document
;
1948 _258
=self
.getElement(_258
);
1949 var _25a
=(_258
.getElementsByTagName(_256
)||self
._document
.all
);
1950 if(typeof (_257
)=="undefined"||_257
===null){
1953 for(var i
=0;i
<_25a
.length
;i
++){
1955 var _25d
=_25c
.className
.split(" ");
1956 for(var j
=0;j
<_25d
.length
;j
++){
1962 },getFirstParentByTagAndClassName
:function(elem
,_260
,_261
){
1963 var self
=MochiKit
.DOM
;
1964 elem
=self
.getElement(elem
);
1965 if(typeof (_260
)=="undefined"||_260
===null){
1968 _260
=_260
.toUpperCase();
1970 if(typeof (_261
)=="undefined"||_261
===null){
1975 while(elem
&&elem
.tagName
){
1976 elem
=elem
.parentNode
;
1977 if(_260
=="*"&&_261
===null){
1980 _263
=elem
.className
.split(" ");
1981 _264
=elem
.tagName
.toUpperCase();
1982 if(_261
===null&&_260
==_264
){
1986 for(var i
=0;i
<_263
.length
;i
++){
1987 if(_260
=="*"&&_263
[i
]==_261
){
1990 if(_260
==_264
&&_263
[i
]==_261
){
1999 },isParent
:function(_266
,_267
){
2000 if(!_266
.parentNode
||_266
==_267
){
2003 if(_266
.parentNode
==_267
){
2006 return MochiKit
.DOM
.isParent(_266
.parentNode
,_267
);
2007 },__new__
:function(win
){
2008 var m
=MochiKit
.Base
;
2009 if(typeof (document
)!="undefined"){
2010 this._document
=document
;
2011 var _26a
="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
2012 this._xhtml
=(document
.documentElement
&&document
.createElementNS
&&document
.documentElement
.namespaceURI
===_26a
);
2014 if(MochiKit
.MockDOM
){
2015 this._document
=MochiKit
.MockDOM
.document
;
2019 this.domConverters
=new m
.AdapterRegistry();
2020 var _26b
=this._document
.createElement("span");
2022 if(_26b
&&_26b
.attributes
&&_26b
.attributes
.length
>0){
2024 _26c
=function(node
){
2025 return _26d(_26c
.ignoreAttrFilter
,node
.attributes
);
2028 var _26f
=_26b
.attributes
;
2029 var _270
=_26c
.ignoreAttr
;
2030 for(var i
=0;i
<_26f
.length
;i
++){
2032 _270
[a
.name
]=a
.value
;
2034 _26c
.ignoreAttrFilter
=function(a
){
2035 return (_26c
.ignoreAttr
[a
.name
]!=a
.value
);
2037 _26c
.compliant
=false;
2038 _26c
.renames
={"class":"className","checked":"defaultChecked","usemap":"useMap","for":"htmlFor","readonly":"readOnly","colspan":"colSpan","bgcolor":"bgColor","cellspacing":"cellSpacing","cellpadding":"cellPadding"};
2040 _26c
=function(node
){
2041 return node
.attributes
;
2043 _26c
.compliant
=true;
2046 this.attributeArray
=_26c
;
2047 var _275
=function(_276
,arr
){
2048 var _278
=arr
[1].split(".");
2051 str
+="if (!MochiKit."+_278
[1]+") { throw new Error(\"";
2052 str
+="This function has been deprecated and depends on MochiKit.";
2053 str
+=_278
[1]+".\");}";
2054 str
+="return MochiKit."+_278
[1]+"."+arr
[0];
2055 str
+=".apply(this, arguments);";
2056 obj
[_278
[2]]=new Function(str
);
2057 MochiKit
.Base
.update(MochiKit
[_276
],obj
);
2059 for(var i
;i
<MochiKit
.DOM
.DEPRECATED
.length
;i
++){
2060 _275("DOM",MochiKit
.DOM
.DEPRECATED
[i
]);
2062 var _27b
=this.createDOMFunc
;
2068 this.TBODY
=_27b("tbody");
2069 this.THEAD
=_27b("thead");
2070 this.TFOOT
=_27b("tfoot");
2071 this.TABLE
=_27b("table");
2073 this.INPUT
=_27b("input");
2074 this.SPAN
=_27b("span");
2076 this.DIV
=_27b("div");
2077 this.IMG
=_27b("img");
2078 this.BUTTON
=_27b("button");
2080 this.PRE
=_27b("pre");
2086 this.LABEL
=_27b("label");
2087 this.TEXTAREA
=_27b("textarea");
2088 this.FORM
=_27b("form");
2090 this.SELECT
=_27b("select");
2091 this.OPTION
=_27b("option");
2092 this.OPTGROUP
=_27b("optgroup");
2093 this.LEGEND
=_27b("legend");
2094 this.FIELDSET
=_27b("fieldset");
2095 this.STRONG
=_27b("strong");
2096 this.CANVAS
=_27b("canvas");
2097 this.$=this.getElement
;
2098 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
2099 m
.nameFunctions(this);
2101 MochiKit
.DOM
.__new__(((typeof (window
)=="undefined")?this:window
));
2102 if(MochiKit
.__export__
){
2103 withWindow
=MochiKit
.DOM
.withWindow
;
2104 withDocument
=MochiKit
.DOM
.withDocument
;
2106 MochiKit
.Base
._exportSymbols(this,MochiKit
.DOM
);
2107 if(typeof (dojo
)!="undefined"){
2108 dojo
.provide("MochiKit.Style");
2109 dojo
.require("MochiKit.Base");
2110 dojo
.require("MochiKit.DOM");
2112 if(typeof (JSAN
)!="undefined"){
2113 JSAN
.use("MochiKit.Base",[]);
2114 JSAN
.use("MochiKit.DOM",[]);
2117 if(typeof (MochiKit
.Base
)=="undefined"){
2122 throw "MochiKit.Style depends on MochiKit.Base!";
2125 if(typeof (MochiKit
.DOM
)=="undefined"){
2130 throw "MochiKit.Style depends on MochiKit.DOM!";
2132 if(typeof (MochiKit
.Style
)=="undefined"){
2135 MochiKit
.Style
.NAME
="MochiKit.Style";
2136 MochiKit
.Style
.VERSION
="1.4";
2137 MochiKit
.Style
.__repr__
=function(){
2138 return "["+this.NAME
+" "+this.VERSION
+"]";
2140 MochiKit
.Style
.toString
=function(){
2141 return this.__repr__();
2143 MochiKit
.Style
.EXPORT_OK
=[];
2144 MochiKit
.Style
.EXPORT
=["setStyle","setOpacity","getStyle","getElementDimensions","elementDimensions","setElementDimensions","getElementPosition","elementPosition","setElementPosition","setDisplayForElement","hideElement","showElement","getViewportDimensions","getViewportPosition","Dimensions","Coordinates"];
2145 MochiKit
.Style
.Dimensions
=function(w
,h
){
2149 MochiKit
.Style
.Dimensions
.prototype.__repr__
=function(){
2150 var repr
=MochiKit
.Base
.repr
;
2151 return "{w: "+repr(this.w
)+", h: "+repr(this.h
)+"}";
2153 MochiKit
.Style
.Dimensions
.prototype.toString
=function(){
2154 return this.__repr__();
2156 MochiKit
.Style
.Coordinates
=function(x
,y
){
2160 MochiKit
.Style
.Coordinates
.prototype.__repr__
=function(){
2161 var repr
=MochiKit
.Base
.repr
;
2162 return "{x: "+repr(this.x
)+", y: "+repr(this.y
)+"}";
2164 MochiKit
.Style
.Coordinates
.prototype.toString
=function(){
2165 return this.__repr__();
2167 MochiKit
.Base
.update(MochiKit
.Style
,{getStyle
:function(elem
,_283
){
2168 var dom
=MochiKit
.DOM
;
2169 var d
=dom
._document
;
2170 elem
=dom
.getElement(elem
);
2171 _283
=MochiKit
.Base
.camelize(_283
);
2175 if(_283
=="opacity"&&elem
.filters
){
2176 var _286
=(MochiKit
.Style
.getStyle(elem
,"filter")||"").match(/alpha\(opacity=(.*)\)/);
2178 return parseFloat(_286
[1])/100;
2182 var _287
=elem
.style
?elem
.style
[_283
]:null;
2184 if(d
.defaultView
&&d
.defaultView
.getComputedStyle
){
2185 var css
=d
.defaultView
.getComputedStyle(elem
,null);
2186 _283
=_283
.replace(/([A-Z])/g,"-$1").toLowerCase();
2187 _287
=css
?css
.getPropertyValue(_283
):null;
2189 if(elem
.currentStyle
){
2190 _287
=elem
.currentStyle
[_283
];
2194 if(_283
=="opacity"){
2195 _287
=parseFloat(_287
);
2197 if(/Opera/.test(navigator
.userAgent
)&&(MochiKit
.Base
.find(["left","top","right","bottom"],_283
)!=-1)){
2198 if(MochiKit
.Style
.getStyle(elem
,"position")=="static"){
2202 return _287
=="auto"?null:_287
;
2203 },setStyle
:function(elem
,_28a
){
2204 elem
=MochiKit
.DOM
.getElement(elem
);
2205 for(var name
in _28a
){
2206 if(name
=="opacity"){
2207 MochiKit
.Style
.setOpacity(elem
,_28a
[name
]);
2209 elem
.style
[MochiKit
.Base
.camelize(name
)]=_28a
[name
];
2212 },setOpacity
:function(elem
,o
){
2213 elem
=MochiKit
.DOM
.getElement(elem
);
2214 var self
=MochiKit
.Style
;
2216 var _28f
=/Gecko/.test(navigator
.userAgent
)&&!(/Konqueror|AppleWebKit|KHTML/.test(navigator
.userAgent
));
2217 elem
.style
["opacity"]=_28f
?0.999999:1;
2218 if(/MSIE/.test(navigator
.userAgent
)){
2219 elem
.style
["filter"]=self
.getStyle(elem
,"filter").replace(/alpha\([^\)]*\)/gi,"");
2225 elem
.style
["opacity"]=o
;
2226 if(/MSIE/.test(navigator
.userAgent
)){
2227 elem
.style
["filter"]=self
.getStyle(elem
,"filter").replace(/alpha\([^\)]*\)/gi,"")+"alpha(opacity="+o
*100+")";
2230 },getElementPosition
:function(elem
,_291
){
2231 var self
=MochiKit
.Style
;
2232 var dom
=MochiKit
.DOM
;
2233 elem
=dom
.getElement(elem
);
2234 if(!elem
||(!(elem
.x
&&elem
.y
)&&(!elem
.parentNode
===null||self
.getStyle(elem
,"display")=="none"))){
2237 var c
=new self
.Coordinates(0,0);
2240 var d
=MochiKit
.DOM
._document
;
2241 var de
=d
.documentElement
;
2243 if(!elem
.parentNode
&&elem
.x
&&elem
.y
){
2247 if(elem
.getBoundingClientRect
){
2248 box
=elem
.getBoundingClientRect();
2249 c
.x
+=box
.left
+(de
.scrollLeft
||b
.scrollLeft
)-(de
.clientLeft
||0);
2250 c
.y
+=box
.top
+(de
.scrollTop
||b
.scrollTop
)-(de
.clientTop
||0);
2252 if(elem
.offsetParent
){
2253 c
.x
+=elem
.offsetLeft
;
2254 c
.y
+=elem
.offsetTop
;
2255 _296
=elem
.offsetParent
;
2258 c
.x
+=_296
.offsetLeft
;
2259 c
.y
+=_296
.offsetTop
;
2260 _296
=_296
.offsetParent
;
2263 var ua
=navigator
.userAgent
.toLowerCase();
2264 if((typeof (opera
)!="undefined"&&parseFloat(opera
.version())<9)||(ua
.indexOf("AppleWebKit")!=-1&&self
.getStyle(elem
,"position")=="absolute")){
2271 if(typeof (_291
)!="undefined"){
2272 _291
=arguments
.callee(_291
);
2278 if(elem
.parentNode
){
2279 _296
=elem
.parentNode
;
2284 var _29b
=_296
.tagName
.toUpperCase();
2285 if(_29b
==="BODY"||_29b
==="HTML"){
2288 var disp
=self
.getStyle(_296
,"display");
2289 if(disp
!="inline"&&disp
!="table-row"){
2290 c
.x
-=_296
.scrollLeft
;
2291 c
.y
-=_296
.scrollTop
;
2293 if(_296
.parentNode
){
2294 _296
=_296
.parentNode
;
2300 },setElementPosition
:function(elem
,_29e
,_29f
){
2301 elem
=MochiKit
.DOM
.getElement(elem
);
2302 if(typeof (_29f
)=="undefined"){
2306 var _2a1
=MochiKit
.Base
.isUndefinedOrNull
;
2308 _2a0
["left"]=_29e
.x
+_29f
;
2311 _2a0
["top"]=_29e
.y
+_29f
;
2313 MochiKit
.DOM
.updateNodeAttributes(elem
,{"style":_2a0
});
2314 },getElementDimensions
:function(elem
){
2315 var self
=MochiKit
.Style
;
2316 var dom
=MochiKit
.DOM
;
2317 if(typeof (elem
.w
)=="number"||typeof (elem
.h
)=="number"){
2318 return new self
.Dimensions(elem
.w
||0,elem
.h
||0);
2320 elem
=dom
.getElement(elem
);
2324 var disp
=self
.getStyle(elem
,"display");
2325 if(disp
!="none"&&disp
!==""&&typeof (disp
)!="undefined"){
2326 return new self
.Dimensions(elem
.offsetWidth
||0,elem
.offsetHeight
||0);
2329 var _2a7
=s
.visibility
;
2330 var _2a8
=s
.position
;
2331 s
.visibility
="hidden";
2332 s
.position
="absolute";
2334 var _2a9
=elem
.offsetWidth
;
2335 var _2aa
=elem
.offsetHeight
;
2339 return new self
.Dimensions(_2a9
,_2aa
);
2340 },setElementDimensions
:function(elem
,_2ac
,_2ad
){
2341 elem
=MochiKit
.DOM
.getElement(elem
);
2342 if(typeof (_2ad
)=="undefined"){
2346 var _2af
=MochiKit
.Base
.isUndefinedOrNull
;
2348 _2ae
["width"]=_2ac
.w
+_2ad
;
2351 _2ae
["height"]=_2ac
.h
+_2ad
;
2353 MochiKit
.DOM
.updateNodeAttributes(elem
,{"style":_2ae
});
2354 },setDisplayForElement
:function(_2b0
,_2b1
){
2355 var _2b2
=MochiKit
.Base
.extend(null,arguments
,1);
2356 var _2b3
=MochiKit
.DOM
.getElement
;
2357 for(var i
=0;i
<_2b2
.length
;i
++){
2360 _2b1
.style
.display
=_2b0
;
2363 },getViewportDimensions
:function(){
2364 var d
=new MochiKit
.Style
.Dimensions();
2365 var w
=MochiKit
.DOM
._window
;
2366 var b
=MochiKit
.DOM
._document
.body
;
2371 if(b
.parentElement
.clientWidth
){
2372 d
.w
=b
.parentElement
.clientWidth
;
2373 d
.h
=b
.parentElement
.clientHeight
;
2375 if(b
&&b
.clientWidth
){
2382 },getViewportPosition
:function(){
2383 var c
=new MochiKit
.Style
.Coordinates(0,0);
2384 var d
=MochiKit
.DOM
._document
;
2385 var de
=d
.documentElement
;
2387 if(de
&&(de
.scrollTop
||de
.scrollLeft
)){
2397 },__new__
:function(){
2398 var m
=MochiKit
.Base
;
2399 this.elementPosition
=this.getElementPosition
;
2400 this.elementDimensions
=this.getElementDimensions
;
2401 this.hideElement
=m
.partial(this.setDisplayForElement
,"none");
2402 this.showElement
=m
.partial(this.setDisplayForElement
,"block");
2403 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
2404 m
.nameFunctions(this);
2406 MochiKit
.Style
.__new__();
2407 MochiKit
.Base
._exportSymbols(this,MochiKit
.Style
);
2408 if(typeof (dojo
)!="undefined"){
2409 dojo
.provide("MochiKit.Color");
2410 dojo
.require("MochiKit.Base");
2411 dojo
.require("MochiKit.DOM");
2412 dojo
.require("MochiKit.Style");
2414 if(typeof (JSAN
)!="undefined"){
2415 JSAN
.use("MochiKit.Base",[]);
2416 JSAN
.use("MochiKit.DOM",[]);
2417 JSAN
.use("MochiKit.Style",[]);
2420 if(typeof (MochiKit
.Base
)=="undefined"){
2425 throw "MochiKit.Color depends on MochiKit.Base";
2428 if(typeof (MochiKit
.DOM
)=="undefined"){
2433 throw "MochiKit.Color depends on MochiKit.DOM";
2436 if(typeof (MochiKit
.Style
)=="undefined"){
2441 throw "MochiKit.Color depends on MochiKit.Style";
2443 if(typeof (MochiKit
.Color
)=="undefined"){
2446 MochiKit
.Color
.NAME
="MochiKit.Color";
2447 MochiKit
.Color
.VERSION
="1.4";
2448 MochiKit
.Color
.__repr__
=function(){
2449 return "["+this.NAME
+" "+this.VERSION
+"]";
2451 MochiKit
.Color
.toString
=function(){
2452 return this.__repr__();
2454 MochiKit
.Color
.Color
=function(red
,_2be
,blue
,_2c0
){
2455 if(typeof (_2c0
)=="undefined"||_2c0
===null){
2458 this.rgb
={r
:red
,g
:_2be
,b
:blue
,a
:_2c0
};
2460 MochiKit
.Color
.Color
.prototype={__class__
:MochiKit
.Color
.Color
,colorWithAlpha
:function(_2c1
){
2462 var m
=MochiKit
.Color
;
2463 return m
.Color
.fromRGB(rgb
.r
,rgb
.g
,rgb
.b
,_2c1
);
2464 },colorWithHue
:function(hue
){
2465 var hsl
=this.asHSL();
2467 var m
=MochiKit
.Color
;
2468 return m
.Color
.fromHSL(hsl
);
2469 },colorWithSaturation
:function(_2c7
){
2470 var hsl
=this.asHSL();
2472 var m
=MochiKit
.Color
;
2473 return m
.Color
.fromHSL(hsl
);
2474 },colorWithLightness
:function(_2ca
){
2475 var hsl
=this.asHSL();
2477 var m
=MochiKit
.Color
;
2478 return m
.Color
.fromHSL(hsl
);
2479 },darkerColorWithLevel
:function(_2cd
){
2480 var hsl
=this.asHSL();
2481 hsl
.l
=Math
.max(hsl
.l
-_2cd
,0);
2482 var m
=MochiKit
.Color
;
2483 return m
.Color
.fromHSL(hsl
);
2484 },lighterColorWithLevel
:function(_2d0
){
2485 var hsl
=this.asHSL();
2486 hsl
.l
=Math
.min(hsl
.l
+_2d0
,1);
2487 var m
=MochiKit
.Color
;
2488 return m
.Color
.fromHSL(hsl
);
2489 },blendedColor
:function(_2d3
,_2d4
){
2490 if(typeof (_2d4
)=="undefined"||_2d4
===null){
2497 return MochiKit
.Color
.Color
.fromRGB((s
.r
*sf
)+(d
.r
*df
),(s
.g
*sf
)+(d
.g
*df
),(s
.b
*sf
)+(d
.b
*df
),(s
.a
*sf
)+(d
.a
*df
));
2498 },compareRGB
:function(_2d9
){
2501 return MochiKit
.Base
.compare([a
.r
,a
.g
,a
.b
,a
.a
],[b
.r
,b
.g
,b
.b
,b
.a
]);
2502 },isLight
:function(){
2503 return this.asHSL().b
>0.5;
2504 },isDark
:function(){
2505 return (!this.isLight());
2506 },toHSLString
:function(){
2508 var ccc
=MochiKit
.Color
.clampColorComponent
;
2509 var rval
=this._hslString
;
2511 var mid
=(ccc(c
.h
,360).toFixed(0)+","+ccc(c
.s
,100).toPrecision(4)+"%"+","+ccc(c
.l
,100).toPrecision(4)+"%");
2515 rval
="hsl("+mid
+")";
2520 rval
="hsla("+mid
+","+a
+")";
2522 this._hslString
=rval
;
2525 },toRGBString
:function(){
2527 var ccc
=MochiKit
.Color
.clampColorComponent
;
2528 var rval
=this._rgbString
;
2530 var mid
=(ccc(c
.r
,255).toFixed(0)+","+ccc(c
.g
,255).toFixed(0)+","+ccc(c
.b
,255).toFixed(0));
2532 rval
="rgba("+mid
+","+c
.a
+")";
2534 rval
="rgb("+mid
+")";
2536 this._rgbString
=rval
;
2540 return MochiKit
.Base
.clone(this.rgb
);
2541 },toHexString
:function(){
2542 var m
=MochiKit
.Color
;
2544 var ccc
=MochiKit
.Color
.clampColorComponent
;
2545 var rval
=this._hexString
;
2547 rval
=("#"+m
.toColorPart(ccc(c
.r
,255))+m
.toColorPart(ccc(c
.g
,255))+m
.toColorPart(ccc(c
.b
,255)));
2548 this._hexString
=rval
;
2554 if(typeof (hsv
)=="undefined"||hsv
===null){
2555 hsv
=MochiKit
.Color
.rgbToHSV(this.rgb
);
2558 return MochiKit
.Base
.clone(hsv
);
2562 if(typeof (hsl
)=="undefined"||hsl
===null){
2563 hsl
=MochiKit
.Color
.rgbToHSL(this.rgb
);
2566 return MochiKit
.Base
.clone(hsl
);
2567 },toString
:function(){
2568 return this.toRGBString();
2571 var col
=[c
.r
,c
.g
,c
.b
,c
.a
];
2572 return this.__class__
.NAME
+"("+col
.join(", ")+")";
2574 MochiKit
.Base
.update(MochiKit
.Color
.Color
,{fromRGB
:function(red
,_2f0
,blue
,_2f2
){
2575 var _2f3
=MochiKit
.Color
.Color
;
2576 if(arguments
.length
==1){
2581 if(typeof (rgb
.a
)=="undefined"){
2587 return new _2f3(red
,_2f0
,blue
,_2f2
);
2588 },fromHSL
:function(hue
,_2f6
,_2f7
,_2f8
){
2589 var m
=MochiKit
.Color
;
2590 return m
.Color
.fromRGB(m
.hslToRGB
.apply(m
,arguments
));
2591 },fromHSV
:function(hue
,_2fb
,_2fc
,_2fd
){
2592 var m
=MochiKit
.Color
;
2593 return m
.Color
.fromRGB(m
.hsvToRGB
.apply(m
,arguments
));
2594 },fromName
:function(name
){
2595 var _300
=MochiKit
.Color
.Color
;
2596 if(name
.charAt(0)=="\""){
2597 name
=name
.substr(1,name
.length
-2);
2599 var _301
=_300
._namedColors
[name
.toLowerCase()];
2600 if(typeof (_301
)=="string"){
2601 return _300
.fromHexString(_301
);
2603 if(name
=="transparent"){
2604 return _300
.transparentColor();
2608 },fromString
:function(_302
){
2609 var self
=MochiKit
.Color
.Color
;
2610 var _304
=_302
.substr(0,3);
2612 return self
.fromRGBString(_302
);
2615 return self
.fromHSLString(_302
);
2617 if(_302
.charAt(0)=="#"){
2618 return self
.fromHexString(_302
);
2622 return self
.fromName(_302
);
2623 },fromHexString
:function(_305
){
2624 if(_305
.charAt(0)=="#"){
2625 _305
=_305
.substring(1);
2631 hex
=_305
.substr(i
,1);
2632 _306
.push(parseInt(hex
+hex
,16)/255);
2636 hex
=_305
.substr(i
,2);
2637 _306
.push(parseInt(hex
,16)/255);
2640 var _309
=MochiKit
.Color
.Color
;
2641 return _309
.fromRGB
.apply(_309
,_306
);
2642 },_fromColorString
:function(pre
,_30b
,_30c
,_30d
){
2643 if(_30d
.indexOf(pre
)===0){
2644 _30d
=_30d
.substring(_30d
.indexOf("(",3)+1,_30d
.length
-1);
2646 var _30e
=_30d
.split(/\s*,\s*/);
2648 for(var i
=0;i
<_30e
.length
;i
++){
2651 var _313
=c
.substring(c
.length
-3);
2652 if(c
.charAt(c
.length
-1)=="%"){
2653 val
=0.01*parseFloat(c
.substring(0,c
.length
-1));
2656 val
=parseFloat(c
)/360;
2659 val
=parseFloat(c
)/(Math
.PI
*2);
2661 val
=_30c
[i
]*parseFloat(c
);
2667 return this[_30b
].apply(this,_30f
);
2668 },fromComputedStyle
:function(elem
,_315
){
2670 var cls
=MochiKit
.Color
.Color
;
2671 for(elem
=d
.getElement(elem
);elem
;elem
=elem
.parentNode
){
2672 var _318
=MochiKit
.Style
.getStyle
.apply(d
,arguments
);
2676 var _319
=cls
.fromString(_318
);
2680 if(_319
.asRGB().a
>0){
2685 },fromBackground
:function(elem
){
2686 var cls
=MochiKit
.Color
.Color
;
2687 return cls
.fromComputedStyle(elem
,"backgroundColor","background-color")||cls
.whiteColor();
2688 },fromText
:function(elem
){
2689 var cls
=MochiKit
.Color
.Color
;
2690 return cls
.fromComputedStyle(elem
,"color","color")||cls
.blackColor();
2691 },namedColors
:function(){
2692 return MochiKit
.Base
.clone(MochiKit
.Color
.Color
._namedColors
);
2694 MochiKit
.Base
.update(MochiKit
.Color
,{clampColorComponent
:function(v
,_31f
){
2705 },_hslValue
:function(n1
,n2
,hue
){
2721 val
=n1
+(n2
-n1
)*(4-hue
);
2728 },hsvToRGB
:function(hue
,_325
,_326
,_327
){
2729 if(arguments
.length
==1){
2744 var i
=Math
.floor(hue
*6);
2746 var p
=_326
*(1-_325
);
2747 var q
=_326
*(1-(_325
*f
));
2748 var t
=_326
*(1-(_325
*(1-f
)));
2783 return {r
:red
,g
:_32a
,b
:blue
,a
:_327
};
2784 },hslToRGB
:function(hue
,_332
,_333
,_334
){
2785 if(arguments
.length
==1){
2804 m2
=_333
+_332
-(_333
*_332
);
2807 var f
=MochiKit
.Color
._hslValue
;
2813 return {r
:red
,g
:_337
,b
:blue
,a
:_334
};
2814 },rgbToHSV
:function(red
,_33e
,blue
,_340
){
2815 if(arguments
.length
==1){
2822 var max
=Math
.max(Math
.max(red
,_33e
),blue
);
2823 var min
=Math
.min(Math
.min(red
,_33e
),blue
);
2834 hue
=(_33e
-blue
)/_347
;
2837 hue
=2+((blue
-red
)/_347
);
2839 hue
=4+((red
-_33e
)/_347
);
2850 return {h
:hue
,s
:_345
,v
:_346
,a
:_340
};
2851 },rgbToHSL
:function(red
,_349
,blue
,_34b
){
2852 if(arguments
.length
==1){
2859 var max
=Math
.max(red
,Math
.max(_349
,blue
));
2860 var min
=Math
.min(red
,Math
.min(_349
,blue
));
2863 var _351
=(max
+min
)/2;
2870 _350
=_352
/(max
+min
);
2872 _350
=_352
/(2-max
-min
);
2875 hue
=(_349
-blue
)/_352
;
2878 hue
=2+((blue
-red
)/_352
);
2880 hue
=4+((red
-_349
)/_352
);
2891 return {h
:hue
,s
:_350
,l
:_351
,a
:_34b
};
2892 },toColorPart
:function(num
){
2893 num
=Math
.round(num
);
2894 var _354
=num
.toString(16);
2899 },__new__
:function(){
2900 var m
=MochiKit
.Base
;
2901 this.Color
.fromRGBString
=m
.bind(this.Color
._fromColorString
,this.Color
,"rgb","fromRGB",[1/255,1/255,1/255,1]);
2902 this.Color
.fromHSLString
=m
.bind(this.Color
._fromColorString
,this.Color
,"hsl","fromHSL",[1/360,0.01,0.01,1]);
2904 var _357
={black
:[0,0,0],blue
:[0,0,1],brown
:[0.6,0.4,0.2],cyan
:[0,1,1],darkGray
:[_356
,_356
,_356
],gray
:[0.5,0.5,0.5],green
:[0,1,0],lightGray
:[2*_356
,2*_356
,2*_356
],magenta
:[1,0,1],orange
:[1,0.5,0],purple
:[0.5,0,0.5],red
:[1,0,0],transparent
:[0,0,0,0],white
:[1,1,1],yellow
:[1,1,0]};
2905 var _358
=function(name
,r
,g
,b
,a
){
2906 var rval
=this.fromRGB(r
,g
,b
,a
);
2907 this[name
]=function(){
2914 var _361
=m
.concat([_358
,this.Color
,name
],_357
[k
]);
2915 this.Color
[name
]=m
.bind
.apply(null,_361
);
2917 var _362
=function(){
2918 for(var i
=0;i
<arguments
.length
;i
++){
2919 if(!(arguments
[i
] instanceof Color
)){
2925 var _364
=function(a
,b
){
2926 return a
.compareRGB(b
);
2928 m
.nameFunctions(this);
2929 m
.registerComparator(this.Color
.NAME
,_362
,_364
);
2930 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
2932 MochiKit
.Color
.EXPORT
=["Color"];
2933 MochiKit
.Color
.EXPORT_OK
=["clampColorComponent","rgbToHSL","hslToRGB","rgbToHSV","hsvToRGB","toColorPart"];
2934 MochiKit
.Color
.__new__();
2935 MochiKit
.Base
._exportSymbols(this,MochiKit
.Color
);
2936 MochiKit
.Color
.Color
._namedColors
={aliceblue
:"#f0f8ff",antiquewhite
:"#faebd7",aqua
:"#00ffff",aquamarine
:"#7fffd4",azure
:"#f0ffff",beige
:"#f5f5dc",bisque
:"#ffe4c4",black
:"#000000",blanchedalmond
:"#ffebcd",blue
:"#0000ff",blueviolet
:"#8a2be2",brown
:"#a52a2a",burlywood
:"#deb887",cadetblue
:"#5f9ea0",chartreuse
:"#7fff00",chocolate
:"#d2691e",coral
:"#ff7f50",cornflowerblue
:"#6495ed",cornsilk
:"#fff8dc",crimson
:"#dc143c",cyan
:"#00ffff",darkblue
:"#00008b",darkcyan
:"#008b8b",darkgoldenrod
:"#b8860b",darkgray
:"#a9a9a9",darkgreen
:"#006400",darkgrey
:"#a9a9a9",darkkhaki
:"#bdb76b",darkmagenta
:"#8b008b",darkolivegreen
:"#556b2f",darkorange
:"#ff8c00",darkorchid
:"#9932cc",darkred
:"#8b0000",darksalmon
:"#e9967a",darkseagreen
:"#8fbc8f",darkslateblue
:"#483d8b",darkslategray
:"#2f4f4f",darkslategrey
:"#2f4f4f",darkturquoise
:"#00ced1",darkviolet
:"#9400d3",deeppink
:"#ff1493",deepskyblue
:"#00bfff",dimgray
:"#696969",dimgrey
:"#696969",dodgerblue
:"#1e90ff",firebrick
:"#b22222",floralwhite
:"#fffaf0",forestgreen
:"#228b22",fuchsia
:"#ff00ff",gainsboro
:"#dcdcdc",ghostwhite
:"#f8f8ff",gold
:"#ffd700",goldenrod
:"#daa520",gray
:"#808080",green
:"#008000",greenyellow
:"#adff2f",grey
:"#808080",honeydew
:"#f0fff0",hotpink
:"#ff69b4",indianred
:"#cd5c5c",indigo
:"#4b0082",ivory
:"#fffff0",khaki
:"#f0e68c",lavender
:"#e6e6fa",lavenderblush
:"#fff0f5",lawngreen
:"#7cfc00",lemonchiffon
:"#fffacd",lightblue
:"#add8e6",lightcoral
:"#f08080",lightcyan
:"#e0ffff",lightgoldenrodyellow
:"#fafad2",lightgray
:"#d3d3d3",lightgreen
:"#90ee90",lightgrey
:"#d3d3d3",lightpink
:"#ffb6c1",lightsalmon
:"#ffa07a",lightseagreen
:"#20b2aa",lightskyblue
:"#87cefa",lightslategray
:"#778899",lightslategrey
:"#778899",lightsteelblue
:"#b0c4de",lightyellow
:"#ffffe0",lime
:"#00ff00",limegreen
:"#32cd32",linen
:"#faf0e6",magenta
:"#ff00ff",maroon
:"#800000",mediumaquamarine
:"#66cdaa",mediumblue
:"#0000cd",mediumorchid
:"#ba55d3",mediumpurple
:"#9370db",mediumseagreen
:"#3cb371",mediumslateblue
:"#7b68ee",mediumspringgreen
:"#00fa9a",mediumturquoise
:"#48d1cc",mediumvioletred
:"#c71585",midnightblue
:"#191970",mintcream
:"#f5fffa",mistyrose
:"#ffe4e1",moccasin
:"#ffe4b5",navajowhite
:"#ffdead",navy
:"#000080",oldlace
:"#fdf5e6",olive
:"#808000",olivedrab
:"#6b8e23",orange
:"#ffa500",orangered
:"#ff4500",orchid
:"#da70d6",palegoldenrod
:"#eee8aa",palegreen
:"#98fb98",paleturquoise
:"#afeeee",palevioletred
:"#db7093",papayawhip
:"#ffefd5",peachpuff
:"#ffdab9",peru
:"#cd853f",pink
:"#ffc0cb",plum
:"#dda0dd",powderblue
:"#b0e0e6",purple
:"#800080",red
:"#ff0000",rosybrown
:"#bc8f8f",royalblue
:"#4169e1",saddlebrown
:"#8b4513",salmon
:"#fa8072",sandybrown
:"#f4a460",seagreen
:"#2e8b57",seashell
:"#fff5ee",sienna
:"#a0522d",silver
:"#c0c0c0",skyblue
:"#87ceeb",slateblue
:"#6a5acd",slategray
:"#708090",slategrey
:"#708090",snow
:"#fffafa",springgreen
:"#00ff7f",steelblue
:"#4682b4",tan
:"#d2b48c",teal
:"#008080",thistle
:"#d8bfd8",tomato
:"#ff6347",turquoise
:"#40e0d0",violet
:"#ee82ee",wheat
:"#f5deb3",white
:"#ffffff",whitesmoke
:"#f5f5f5",yellow
:"#ffff00",yellowgreen
:"#9acd32"};
2937 if(typeof (dojo
)!="undefined"){
2938 dojo
.provide("MochiKit.Signal");
2939 dojo
.require("MochiKit.Base");
2940 dojo
.require("MochiKit.DOM");
2941 dojo
.require("MochiKit.Style");
2943 if(typeof (JSAN
)!="undefined"){
2944 JSAN
.use("MochiKit.Base",[]);
2945 JSAN
.use("MochiKit.DOM",[]);
2946 JSAN
.use("MochiKit.Style",[]);
2949 if(typeof (MochiKit
.Base
)=="undefined"){
2954 throw "MochiKit.Signal depends on MochiKit.Base!";
2957 if(typeof (MochiKit
.DOM
)=="undefined"){
2962 throw "MochiKit.Signal depends on MochiKit.DOM!";
2965 if(typeof (MochiKit
.Style
)=="undefined"){
2970 throw "MochiKit.Signal depends on MochiKit.Style!";
2972 if(typeof (MochiKit
.Signal
)=="undefined"){
2975 MochiKit
.Signal
.NAME
="MochiKit.Signal";
2976 MochiKit
.Signal
.VERSION
="1.4";
2977 MochiKit
.Signal
._observers
=[];
2978 MochiKit
.Signal
.Event
=function(src
,e
){
2979 this._event
=e
||window
.event
;
2982 MochiKit
.Base
.update(MochiKit
.Signal
.Event
.prototype,{__repr__
:function(){
2983 var repr
=MochiKit
.Base
.repr
;
2984 var str
="{event(): "+repr(this.event())+", src(): "+repr(this.src())+", type(): "+repr(this.type())+", target(): "+repr(this.target());
2985 if(this.type()&&this.type().indexOf("key")===0||this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu"){
2986 str
+=", modifier(): "+"{alt: "+repr(this.modifier().alt
)+", ctrl: "+repr(this.modifier().ctrl
)+", meta: "+repr(this.modifier().meta
)+", shift: "+repr(this.modifier().shift
)+", any: "+repr(this.modifier().any
)+"}";
2988 if(this.type()&&this.type().indexOf("key")===0){
2989 str
+=", key(): {code: "+repr(this.key().code
)+", string: "+repr(this.key().string
)+"}";
2991 if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
2992 str
+=", mouse(): {page: "+repr(this.mouse().page
)+", client: "+repr(this.mouse().client
);
2993 if(this.type()!="mousemove"){
2994 str
+=", button: {left: "+repr(this.mouse().button
.left
)+", middle: "+repr(this.mouse().button
.middle
)+", right: "+repr(this.mouse().button
.right
)+"}}";
2999 if(this.type()=="mouseover"||this.type()=="mouseout"){
3000 str
+=", relatedTarget(): "+repr(this.relatedTarget());
3004 },toString
:function(){
3005 return this.__repr__();
3011 return this._event
.type
||undefined
;
3012 },target
:function(){
3013 return this._event
.target
||this._event
.srcElement
;
3014 },_relatedTarget
:null,relatedTarget
:function(){
3015 if(this._relatedTarget
!==null){
3016 return this._relatedTarget
;
3019 if(this.type()=="mouseover"){
3020 elem
=(this._event
.relatedTarget
||this._event
.fromElement
);
3022 if(this.type()=="mouseout"){
3023 elem
=(this._event
.relatedTarget
||this._event
.toElement
);
3027 this._relatedTarget
=elem
;
3031 },_modifier
:null,modifier
:function(){
3032 if(this._modifier
!==null){
3033 return this._modifier
;
3036 m
.alt
=this._event
.altKey
;
3037 m
.ctrl
=this._event
.ctrlKey
;
3038 m
.meta
=this._event
.metaKey
||false;
3039 m
.shift
=this._event
.shiftKey
;
3040 m
.any
=m
.alt
||m
.ctrl
||m
.shift
||m
.meta
;
3043 },_key
:null,key
:function(){
3044 if(this._key
!==null){
3048 if(this.type()&&this.type().indexOf("key")===0){
3049 if(this.type()=="keydown"||this.type()=="keyup"){
3050 k
.code
=this._event
.keyCode
;
3051 k
.string
=(MochiKit
.Signal
._specialKeys
[k
.code
]||"KEY_UNKNOWN");
3055 if(this.type()=="keypress"){
3058 if(typeof (this._event
.charCode
)!="undefined"&&this._event
.charCode
!==0&&!MochiKit
.Signal
._specialMacKeys
[this._event
.charCode
]){
3059 k
.code
=this._event
.charCode
;
3060 k
.string
=String
.fromCharCode(k
.code
);
3062 if(this._event
.keyCode
&&typeof (this._event
.charCode
)=="undefined"){
3063 k
.code
=this._event
.keyCode
;
3064 k
.string
=String
.fromCharCode(k
.code
);
3073 },_mouse
:null,mouse
:function(){
3074 if(this._mouse
!==null){
3079 if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
3080 m
.client
=new MochiKit
.Style
.Coordinates(0,0);
3081 if(e
.clientX
||e
.clientY
){
3082 m
.client
.x
=(!e
.clientX
||e
.clientX
<0)?0:e
.clientX
;
3083 m
.client
.y
=(!e
.clientY
||e
.clientY
<0)?0:e
.clientY
;
3085 m
.page
=new MochiKit
.Style
.Coordinates(0,0);
3086 if(e
.pageX
||e
.pageY
){
3087 m
.page
.x
=(!e
.pageX
||e
.pageX
<0)?0:e
.pageX
;
3088 m
.page
.y
=(!e
.pageY
||e
.pageY
<0)?0:e
.pageY
;
3090 var de
=MochiKit
.DOM
._document
.documentElement
;
3091 var b
=MochiKit
.DOM
._document
.body
;
3092 m
.page
.x
=e
.clientX
+(de
.scrollLeft
||b
.scrollLeft
)-(de
.clientLeft
||0);
3093 m
.page
.y
=e
.clientY
+(de
.scrollTop
||b
.scrollTop
)-(de
.clientTop
||0);
3095 if(this.type()!="mousemove"){
3097 m
.button
.left
=false;
3098 m
.button
.right
=false;
3099 m
.button
.middle
=false;
3101 m
.button
.left
=(e
.which
==1);
3102 m
.button
.middle
=(e
.which
==2);
3103 m
.button
.right
=(e
.which
==3);
3105 m
.button
.left
=!!(e
.button
&1);
3106 m
.button
.right
=!!(e
.button
&2);
3107 m
.button
.middle
=!!(e
.button
&4);
3115 this.stopPropagation();
3116 this.preventDefault();
3117 },stopPropagation
:function(){
3118 if(this._event
.stopPropagation
){
3119 this._event
.stopPropagation();
3121 this._event
.cancelBubble
=true;
3123 },preventDefault
:function(){
3124 if(this._event
.preventDefault
){
3125 this._event
.preventDefault();
3127 if(this._confirmUnload
===null){
3128 this._event
.returnValue
=false;
3131 },_confirmUnload
:null,confirmUnload
:function(msg
){
3132 if(this.type()=="beforeunload"){
3133 this._confirmUnload
=msg
;
3134 this._event
.returnValue
=msg
;
3137 MochiKit
.Signal
._specialMacKeys
={3:"KEY_ENTER",63289:"KEY_NUM_PAD_CLEAR",63276:"KEY_PAGE_UP",63277:"KEY_PAGE_DOWN",63275:"KEY_END",63273:"KEY_HOME",63234:"KEY_ARROW_LEFT",63232:"KEY_ARROW_UP",63235:"KEY_ARROW_RIGHT",63233:"KEY_ARROW_DOWN",63302:"KEY_INSERT",63272:"KEY_DELETE"};
3139 var _373
=MochiKit
.Signal
._specialMacKeys
;
3140 for(i
=63236;i
<=63242;i
++){
3141 _373
[i
]="KEY_F"+(i
-63236+1);
3144 MochiKit
.Signal
._specialKeys
={8:"KEY_BACKSPACE",9:"KEY_TAB",12:"KEY_NUM_PAD_CLEAR",13:"KEY_ENTER",16:"KEY_SHIFT",17:"KEY_CTRL",18:"KEY_ALT",19:"KEY_PAUSE",20:"KEY_CAPS_LOCK",27:"KEY_ESCAPE",32:"KEY_SPACEBAR",33:"KEY_PAGE_UP",34:"KEY_PAGE_DOWN",35:"KEY_END",36:"KEY_HOME",37:"KEY_ARROW_LEFT",38:"KEY_ARROW_UP",39:"KEY_ARROW_RIGHT",40:"KEY_ARROW_DOWN",44:"KEY_PRINT_SCREEN",45:"KEY_INSERT",46:"KEY_DELETE",59:"KEY_SEMICOLON",91:"KEY_WINDOWS_LEFT",92:"KEY_WINDOWS_RIGHT",93:"KEY_SELECT",106:"KEY_NUM_PAD_ASTERISK",107:"KEY_NUM_PAD_PLUS_SIGN",109:"KEY_NUM_PAD_HYPHEN-MINUS",110:"KEY_NUM_PAD_FULL_STOP",111:"KEY_NUM_PAD_SOLIDUS",144:"KEY_NUM_LOCK",145:"KEY_SCROLL_LOCK",186:"KEY_SEMICOLON",187:"KEY_EQUALS_SIGN",188:"KEY_COMMA",189:"KEY_HYPHEN-MINUS",190:"KEY_FULL_STOP",191:"KEY_SOLIDUS",192:"KEY_GRAVE_ACCENT",219:"KEY_LEFT_SQUARE_BRACKET",220:"KEY_REVERSE_SOLIDUS",221:"KEY_RIGHT_SQUARE_BRACKET",222:"KEY_APOSTROPHE"};
3146 var _374
=MochiKit
.Signal
._specialKeys
;
3147 for(var i
=48;i
<=57;i
++){
3148 _374
[i
]="KEY_"+(i
-48);
3150 for(i
=65;i
<=90;i
++){
3151 _374
[i
]="KEY_"+String
.fromCharCode(i
);
3153 for(i
=96;i
<=105;i
++){
3154 _374
[i
]="KEY_NUM_PAD_"+(i
-96);
3156 for(i
=112;i
<=123;i
++){
3157 _374
[i
]="KEY_F"+(i
-112+1);
3160 MochiKit
.Signal
.Ident
=function(_376
){
3161 this.source
=_376
.source
;
3162 this.signal
=_376
.signal
;
3163 this.listener
=_376
.listener
;
3164 this.isDOM
=_376
.isDOM
;
3165 this.objOrFunc
=_376
.objOrFunc
;
3166 this.funcOrStr
=_376
.funcOrStr
;
3167 this.connected
=_376
.connected
;
3169 MochiKit
.Signal
.Ident
.prototype={};
3170 MochiKit
.Base
.update(MochiKit
.Signal
,{__repr__
:function(){
3171 return "["+this.NAME
+" "+this.VERSION
+"]";
3172 },toString
:function(){
3173 return this.__repr__();
3174 },_unloadCache
:function(){
3175 var self
=MochiKit
.Signal
;
3176 var _378
=self
._observers
;
3177 for(var i
=0;i
<_378
.length
;i
++){
3178 if(_378
[i
].signal
!=="onload"&&_378
[i
].signal
!=="onunload"){
3179 self
._disconnect(_378
[i
]);
3182 },_listener
:function(src
,sig
,func
,obj
,_37e
){
3183 var self
=MochiKit
.Signal
;
3186 return MochiKit
.Base
.bind(func
,obj
);
3189 if(typeof (func
)=="string"){
3190 if(sig
==="onload"||sig
==="onunload"){
3191 return function(_381
){
3192 obj
[func
].apply(obj
,[new E(src
,_381
)]);
3193 var _382
=new MochiKit
.Signal
.Ident({source
:src
,signal
:sig
,objOrFunc
:obj
,funcOrStr
:func
});
3194 MochiKit
.Signal
._disconnect(_382
);
3197 return function(_383
){
3198 obj
[func
].apply(obj
,[new E(src
,_383
)]);
3202 if(sig
==="onload"||sig
==="onunload"){
3203 return function(_384
){
3204 func
.apply(obj
,[new E(src
,_384
)]);
3205 MochiKit
.Signal
.disconnect(src
,sig
,func
);
3206 var _385
=new MochiKit
.Signal
.Ident({source
:src
,signal
:sig
,objOrFunc
:func
});
3207 MochiKit
.Signal
._disconnect(_385
);
3210 return function(_386
){
3211 func
.apply(obj
,[new E(src
,_386
)]);
3215 },_browserAlreadyHasMouseEnterAndLeave
:function(){
3216 return /MSIE/.test(navigator
.userAgent
);
3217 },_mouseEnterListener
:function(src
,sig
,func
,obj
){
3218 var E
=MochiKit
.Signal
.Event
;
3219 return function(_38c
){
3220 var e
=new E(src
,_38c
);
3222 e
.relatedTarget().nodeName
;
3228 if(MochiKit
.DOM
.isChildNode(e
.relatedTarget(),src
)){
3234 if(typeof (func
)=="string"){
3235 return obj
[func
].apply(obj
,[e
]);
3237 return func
.apply(obj
,[e
]);
3240 },_getDestPair
:function(_38e
,_38f
){
3243 if(typeof (_38f
)!="undefined"){
3246 if(typeof (_38f
)=="string"){
3247 if(typeof (_38e
[_38f
])!="function"){
3248 throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
3251 if(typeof (_38f
)!="function"){
3252 throw new Error("'funcOrStr' must be a function or string");
3256 if(typeof (_38e
)!="function"){
3257 throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
3263 },connect
:function(src
,sig
,_394
,_395
){
3264 src
=MochiKit
.DOM
.getElement(src
);
3265 var self
=MochiKit
.Signal
;
3266 if(typeof (sig
)!="string"){
3267 throw new Error("'sig' must be a string");
3269 var _397
=self
._getDestPair(_394
,_395
);
3272 if(typeof (obj
)=="undefined"||obj
===null){
3275 var _39a
=!!(src
.addEventListener
||src
.attachEvent
);
3276 if(_39a
&&(sig
==="onmouseenter"||sig
==="onmouseleave")&&!self
._browserAlreadyHasMouseEnterAndLeave()){
3277 var _39b
=self
._mouseEnterListener(src
,sig
.substr(2),func
,obj
);
3278 if(sig
==="onmouseenter"){
3284 var _39b
=self
._listener(src
,sig
,func
,obj
,_39a
);
3286 if(src
.addEventListener
){
3287 src
.addEventListener(sig
.substr(2),_39b
,false);
3289 if(src
.attachEvent
){
3290 src
.attachEvent(sig
,_39b
);
3293 var _39c
=new MochiKit
.Signal
.Ident({source
:src
,signal
:sig
,listener
:_39b
,isDOM
:_39a
,objOrFunc
:_394
,funcOrStr
:_395
,connected
:true});
3294 self
._observers
.push(_39c
);
3295 if(!_39a
&&typeof (src
.__connect__
)=="function"){
3296 var args
=MochiKit
.Base
.extend([_39c
],arguments
,1);
3297 src
.__connect__
.apply(src
,args
);
3300 },_disconnect
:function(_39e
){
3301 if(!_39e
.connected
){
3304 _39e
.connected
=false;
3308 var src
=_39e
.source
;
3309 var sig
=_39e
.signal
;
3310 var _3a1
=_39e
.listener
;
3311 if(src
.removeEventListener
){
3312 src
.removeEventListener(sig
.substr(2),_3a1
,false);
3314 if(src
.detachEvent
){
3315 src
.detachEvent(sig
,_3a1
);
3317 throw new Error("'src' must be a DOM element");
3320 },disconnect
:function(_3a2
){
3321 var self
=MochiKit
.Signal
;
3322 var _3a4
=self
._observers
;
3323 var m
=MochiKit
.Base
;
3324 if(arguments
.length
>1){
3325 var src
=MochiKit
.DOM
.getElement(arguments
[0]);
3326 var sig
=arguments
[1];
3327 var obj
=arguments
[2];
3328 var func
=arguments
[3];
3329 for(var i
=_3a4
.length
-1;i
>=0;i
--){
3331 if(o
.source
===src
&&o
.signal
===sig
&&o
.objOrFunc
===obj
&&o
.funcOrStr
===func
){
3332 self
._disconnect(o
);
3342 var idx
=m
.findIdentical(_3a4
,_3a2
);
3344 self
._disconnect(_3a2
);
3354 },disconnectAllTo
:function(_3ad
,_3ae
){
3355 var self
=MochiKit
.Signal
;
3356 var _3b0
=self
._observers
;
3357 var _3b1
=self
._disconnect
;
3358 var _3b2
=self
._lock
;
3359 var _3b3
=self
._dirty
;
3360 if(typeof (_3ae
)==="undefined"){
3363 for(var i
=_3b0
.length
-1;i
>=0;i
--){
3365 if(_3b5
.objOrFunc
===_3ad
&&(_3ae
===null||_3b5
.funcOrStr
===_3ae
)){
3375 },disconnectAll
:function(src
,sig
){
3376 src
=MochiKit
.DOM
.getElement(src
);
3377 var m
=MochiKit
.Base
;
3378 var _3b9
=m
.flattenArguments(m
.extend(null,arguments
,1));
3379 var self
=MochiKit
.Signal
;
3380 var _3bb
=self
._disconnect
;
3381 var _3bc
=self
._observers
;
3383 var _3bf
=self
._lock
;
3384 var _3c0
=self
._dirty
;
3385 if(_3b9
.length
===0){
3386 for(i
=_3bc
.length
-1;i
>=0;i
--){
3388 if(_3be
.source
===src
){
3399 for(i
=0;i
<_3b9
.length
;i
++){
3402 for(i
=_3bc
.length
-1;i
>=0;i
--){
3404 if(_3be
.source
===src
&&_3be
.signal
in sigs
){
3415 },signal
:function(src
,sig
){
3416 var self
=MochiKit
.Signal
;
3417 var _3c5
=self
._observers
;
3418 src
=MochiKit
.DOM
.getElement(src
);
3419 var args
=MochiKit
.Base
.extend(null,arguments
,2);
3422 for(var i
=0;i
<_3c5
.length
;i
++){
3424 if(_3c9
.source
===src
&&_3c9
.signal
===sig
){
3426 _3c9
.listener
.apply(src
,args
);
3436 for(var i
=_3c5
.length
-1;i
>=0;i
--){
3437 if(!_3c5
[i
].connected
){
3446 var e
=new Error("Multiple errors thrown in handling 'sig', see errors property");
3452 MochiKit
.Signal
.EXPORT_OK
=[];
3453 MochiKit
.Signal
.EXPORT
=["connect","disconnect","signal","disconnectAll","disconnectAllTo"];
3454 MochiKit
.Signal
.__new__
=function(win
){
3455 var m
=MochiKit
.Base
;
3456 this._document
=document
;
3461 this.connect(window
,"onunload",this._unloadCache
);
3465 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
3466 m
.nameFunctions(this);
3468 MochiKit
.Signal
.__new__(this);
3469 if(MochiKit
.__export__
){
3470 connect
=MochiKit
.Signal
.connect
;
3471 disconnect
=MochiKit
.Signal
.disconnect
;
3472 disconnectAll
=MochiKit
.Signal
.disconnectAll
;
3473 signal
=MochiKit
.Signal
.signal
;
3475 MochiKit
.Base
._exportSymbols(this,MochiKit
.Signal
);
3480 PlotKit.PlotKit 0.9.1 : PACKED VERSION
3482 THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
3483 diff against the source tree, not this file.
3485 For more information, <http://www.liquidx.net/plotkit/>.
3487 Copyright (c) 2006. Alastair Tse.
3492 if(typeof (MochiKit
.Base
)=="undefined"||typeof (MochiKit
.DOM
)=="undefined"||typeof (MochiKit
.Color
)=="undefined"||typeof (MochiKit
.Format
)=="undefined"){
3497 throw "PlotKit depends on MochiKit.{Base,Color,DOM,Format}";
3499 MochiKit
.Base
.update(MochiKit
.Color
.Color
.prototype,{asFillColor
:function(){
3500 return this.lighterColorWithLevel(0.3);
3501 },asStrokeColor
:function(){
3502 return this.darkerColorWithLevel(0.1);
3503 },asPointColor
:function(){
3504 return this.lighterColorWithLevel(0.1);
3506 if(typeof (PlotKit
)=="undefined"){
3509 PlotKit
.NAME
="PlotKit";
3510 PlotKit
.VERSION
="0.8";
3511 PlotKit
.__repr__
=function(){
3512 return "["+this.NAME
+" "+this.VERSION
+"]";
3514 PlotKit
.toString
=function(){
3515 return this.__repr__();
3517 if(typeof (PlotKit
.Base
)=="undefined"){
3520 PlotKit
.Base
.NAME
="PlotKit.Base";
3521 PlotKit
.Base
.VERSION
=PlotKit
.VERSION
;
3522 PlotKit
.Base
.__repr__
=function(){
3523 return "["+this.NAME
+" "+this.VERSION
+"]";
3525 PlotKit
.Base
.toString
=function(){
3526 return this.__repr__();
3528 PlotKit
.Base
.usingPrototype
=function(){
3530 return (typeof (Object
.extend
)=="function");
3536 MochiKit
.Base
.update(PlotKit
.Base
,{roundInterval
:function(_1
,_2
,_3
){
3537 var _4
=MochiKit
.Format
.roundToFixed
;
3539 return parseFloat(_4(_5
,_3
));
3540 },collapse
:function(_6
){
3541 var m
=MochiKit
.Base
;
3543 for(var i
=0;i
<_6
.length
;i
++){
3544 _8
=m
.concat(_8
,_6
[i
]);
3546 if(PlotKit
.Base
.usingPrototype()){
3552 },uniq
:function(_10
){
3553 var m
=MochiKit
.Base
;
3554 if(!m
.isArrayLike(_10
)||(_10
.length
<1)){
3557 var _11
=new Array();
3560 for(var i
=1;i
<_10
.length
;i
++){
3561 if(m
.compare(_10
[i
],_12
)!=0){
3567 },colorScheme
:function(){
3568 var mb
=MochiKit
.Base
;
3569 var mc
=MochiKit
.Color
;
3570 var _15
=["red","orange","yellow","green","cyan","blue","purple","magenta"];
3571 var _16
=function(_17
){
3572 return mc
.Color
[_17
+"Color"]();
3574 return mb
.map(_16
,_15
);
3575 },baseDarkPrimaryColors
:function(){
3576 var _18
=MochiKit
.Color
.Color
.fromHexString
;
3577 return [_18("#ad3f40"),_18("#ddac2c"),_18("#dfdd0c"),_18("#5276c4"),_18("#739c5a")];
3578 },basePrimaryColors
:function(){
3579 var _19
=MochiKit
.Color
.Color
.fromHexString
;
3580 return [_19("#d24c4d"),_19("#f2b32f"),_19("#ece90e"),_19("#5d83da"),_19("#78a15d")];
3581 },baseBlueColors
:function(){
3582 var _20
=MochiKit
.Color
.Color
.fromHexString
;
3583 return [_20("#4b6b94"),_20("#5d81b4"),_20("#acbad2")];
3584 },palette
:function(_21
,_22
,_23
,_24
){
3585 var _25
=MochiKit
.Base
.isUndefinedOrNull
;
3586 var _26
=new Array();
3601 var _28
=function(_29
,_30
){
3602 return _29
.lighterColorWithLevel(_30
);
3604 return MochiKit
.Base
.map(partial(_28
,_21
),_26
);
3605 },excanvasSupported
:function(){
3606 if(/MSIE/.test(navigator
.userAgent
)&&!window
.opera
){
3610 },findPosX
:function(obj
){
3612 if(obj
.offsetParent
){
3613 while(obj
.offsetParent
){
3614 _32
+=obj
.offsetLeft
;
3615 obj
=obj
.offsetParent
;
3623 },findPosY
:function(obj
){
3625 if(obj
.offsetParent
){
3626 while(obj
.offsetParent
){
3628 obj
=obj
.offsetParent
;
3636 },isFuncLike
:function(obj
){
3637 return (typeof (obj
)=="function");
3639 PlotKit
.Base
.map
=function(fn
,lst
){
3640 if(PlotKit
.Base
.usingPrototype()){
3643 if(typeof (lst
[x
])=="function"){
3646 _36
.push(fn(lst
[x
]));
3650 return MochiKit
.Base
.map(fn
,lst
);
3653 PlotKit
.Base
.items
=function(lst
){
3654 if(PlotKit
.Base
.usingPrototype()){
3657 if(typeof (lst
[x
])=="function"){
3660 _38
.push([x
,lst
[x
]]);
3664 return MochiKit
.Base
.items(lst
);
3667 PlotKit
.Base
.keys
=function(lst
){
3668 if(PlotKit
.Base
.usingPrototype()){
3671 if(typeof (lst
[x
])=="function"){
3678 return MochiKit
.Base
.keys(lst
);
3681 PlotKit
.Base
.baseColors
=function(){
3682 var _40
=MochiKit
.Color
.Color
.fromHexString
;
3683 return [_40("#476fb2"),_40("#be2c2b"),_40("#85b730"),_40("#734a99"),_40("#26a1c5"),_40("#fb8707"),_40("#000000")];
3685 PlotKit
.Base
.officeBaseStyle
={"axisLineWidth":2,"axisLabelColor":Color
.grayColor(),"axisLineColor":Color
.whiteColor(),"padding":{top
:5,bottom
:10,left
:30,right
:30}};
3686 MochiKit
.Base
.update(PlotKit
.Base
,{officeBlue
:function(){
3687 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[0]),"backgroundColor":PlotKit
.Base
.baseColors()[0].lighterColorWithLevel(0.45)};
3688 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
3690 },officeRed
:function(){
3691 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[1]),"backgroundColor":PlotKit
.Base
.baseColors()[1].lighterColorWithLevel(0.5)};
3692 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
3694 },officeGreen
:function(){
3695 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[2]),"backgroundColor":PlotKit
.Base
.baseColors()[2].lighterColorWithLevel(0.5)};
3696 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
3698 },officePurple
:function(){
3699 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[3]),"backgroundColor":PlotKit
.Base
.baseColors()[3].lighterColorWithLevel(0.5)};
3700 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
3702 },officeCyan
:function(){
3703 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[4]),"backgroundColor":PlotKit
.Base
.baseColors()[4].lighterColorWithLevel(0.5)};
3704 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
3706 },officeOrange
:function(){
3707 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[5]),"backgroundColor":PlotKit
.Base
.baseColors()[5].lighterColorWithLevel(0.4)};
3708 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
3710 },officeBlack
:function(){
3711 var r
={"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[6],0,0.6),"backgroundColor":PlotKit
.Base
.baseColors()[6].lighterColorWithLevel(0.9)};
3712 MochiKit
.Base
.update(r
,PlotKit
.Base
.officeBaseStyle
);
3715 PlotKit
.Base
.EXPORT
=["baseColors","collapse","colorScheme","findPosX","findPosY","officeBaseStyle","officeBlue","officeRed","officeGreen","officePurple","officeCyan","officeOrange","officeBlack","roundInterval","uniq","isFuncLike","excanvasSupported"];
3716 PlotKit
.Base
.EXPORT_OK
=[];
3717 PlotKit
.Base
.__new__
=function(){
3718 var m
=MochiKit
.Base
;
3719 m
.nameFunctions(this);
3720 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
3722 PlotKit
.Base
.__new__();
3723 MochiKit
.Base
._exportSymbols(this,PlotKit
.Base
);
3725 if(typeof (PlotKit
.Base
)=="undefined"){
3730 throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.Base";
3732 if(typeof (PlotKit
.Layout
)=="undefined"){
3735 PlotKit
.Layout
.NAME
="PlotKit.Layout";
3736 PlotKit
.Layout
.VERSION
=PlotKit
.VERSION
;
3737 PlotKit
.Layout
.__repr__
=function(){
3738 return "["+this.NAME
+" "+this.VERSION
+"]";
3740 PlotKit
.Layout
.toString
=function(){
3741 return this.__repr__();
3743 PlotKit
.Layout
.valid_styles
=["bar","line","pie","point"];
3744 PlotKit
.Layout
=function(_42
,_43
){
3745 this.options
={"barWidthFillFraction":0.75,"barOrientation":"vertical","xOriginIsZero":true,"yOriginIsZero":true,"xAxis":null,"yAxis":null,"xTicks":null,"yTicks":null,"xNumberOfTicks":10,"yNumberOfTicks":5,"xTickPrecision":1,"yTickPrecision":1,"pieRadius":0.4};
3747 MochiKit
.Base
.update(this.options
,_43
?_43
:{});
3748 if(!MochiKit
.Base
.isUndefinedOrNull(this.options
.xAxis
)){
3749 this.minxval
=this.options
.xAxis
[0];
3750 this.maxxval
=this.options
.xAxis
[1];
3751 this.xscale
=this.maxxval
-this.minxval
;
3757 if(!MochiKit
.Base
.isUndefinedOrNull(this.options
.yAxis
)){
3758 this.minyval
=this.options
.yAxis
[0];
3759 this.maxyval
=this.options
.yAxis
[1];
3760 this.yscale
=this.maxyval
-this.minyval
;
3766 this.bars
=new Array();
3767 this.points
=new Array();
3768 this.slices
=new Array();
3769 this.xticks
=new Array();
3770 this.yticks
=new Array();
3771 this.datasets
=new Array();
3775 this.hitTestCache
={x2maxy
:null};
3777 PlotKit
.Layout
.prototype.addDataset
=function(_44
,_45
){
3778 this.datasets
[_44
]=_45
;
3780 PlotKit
.Layout
.prototype.removeDataset
=function(_46
,_47
){
3781 delete this.datasets
[_46
];
3783 PlotKit
.Layout
.prototype.addDatasetFromTable
=function(_48
,_49
,_50
,_51
,_52
){
3784 var _53
=MochiKit
.Base
.isUndefinedOrNull
;
3785 var _54
=MochiKit
.DOM
.scrapeText
;
3786 var _55
=MochiKit
.Format
.strip
;
3796 var _56
=_49
.tBodies
[0].rows
;
3797 var _57
=new Array();
3798 var _58
=new Array();
3800 for(var i
=0;i
<_56
.length
;i
++){
3801 _57
.push([parseFloat(_55(_54(_56
[i
].cells
[_50
]))),parseFloat(_55(_54(_56
[i
].cells
[_51
])))]);
3803 _58
.push({v
:parseFloat(_55(_54(_56
[i
].cells
[_50
]))),label
:_55(_54(_56
[i
].cells
[_52
]))});
3806 this.addDataset(_48
,_57
);
3808 this.options
.xTicks
=_58
;
3814 PlotKit
.Layout
.prototype.evaluate
=function(){
3815 this._evaluateLimits();
3816 this._evaluateScales();
3817 if(this.style
=="bar"){
3818 if(this.options
.barOrientation
=="horizontal"){
3819 this._evaluateHorizBarCharts();
3821 this._evaluateBarCharts();
3823 this._evaluateBarTicks();
3825 if(this.style
=="line"){
3826 this._evaluateLineCharts();
3827 this._evaluateLineTicks();
3829 if(this.style
=="pie"){
3830 this._evaluatePieCharts();
3831 this._evaluatePieTicks();
3836 PlotKit
.Layout
.prototype.hitTest
=function(x
,y
){
3837 var f
=MochiKit
.Format
.twoDigitFloat
;
3838 if((this.style
=="bar")&&this.bars
&&(this.bars
.length
>0)){
3839 for(var i
=0;i
<this.bars
.length
;i
++){
3840 var bar
=this.bars
[i
];
3841 if((x
>=bar
.x
)&&(x
<=bar
.x
+bar
.w
)&&(y
>=bar
.y
)&&(y
-bar
.y
<=bar
.h
)){
3846 if(this.style
=="line"){
3847 if(this.hitTestCache
.x2maxy
==null){
3848 this._regenerateHitTestCache();
3850 var _62
=x
/this.xscale
;
3851 var _63
=this.hitTestCache
.xvalues
;
3854 for(var i
=1;i
<_63
.length
;i
++){
3862 var _66
=this.hitTestCache
.x2maxy
[_64
];
3863 var _67
=this.hitTestCache
.x2maxy
[_65
];
3864 var _68
=(1-y
)/this.yscale
;
3865 var _69
=(_67
-_66
)/(_65
-_64
);
3866 var _70
=_66
+_69
*(_62
-_64
);
3868 var obj
={xval
:_62
,yval
:_68
,xafter
:_65
,yafter
:_67
,xbefore
:_64
,ybefore
:_66
,yprojected
:_70
};
3873 if(this.style
=="pie"){
3874 var _71
=Math
.sqrt((y
-0.5)*(y
-0.5)+(x
-0.5)*(x
-0.5));
3875 if(_71
>this.options
.pieRadius
){
3878 var _72
=Math
.atan2(y
-0.5,x
-0.5)-Math
.PI
/2;
3879 for(var i
=0;i
<this.slices
.length
;i
++){
3880 var _73
=this.slices
[i
];
3881 if(_73
.startAngle
<_72
&&_73
.endAngle
>=_72
){
3890 PlotKit
.Layout
.prototype.rectForX
=function(x
){
3893 PlotKit
.Layout
.prototype.angleRangeForX
=function(x
){
3896 PlotKit
.Layout
.prototype._evaluateLimits
=function(){
3897 var map
=PlotKit
.Base
.map
;
3898 var _75
=PlotKit
.Base
.items
;
3899 var _76
=MochiKit
.Base
.itemgetter
;
3900 var _77
=PlotKit
.Base
.collapse
;
3901 var _78
=MochiKit
.Base
.listMin
;
3902 var _79
=MochiKit
.Base
.listMax
;
3903 var _80
=MochiKit
.Base
.isUndefinedOrNull
;
3904 var all
=_77(map(_76(1),_75(this.datasets
)));
3905 if(_80(this.options
.xAxis
)){
3906 if(this.options
.xOriginIsZero
){
3909 this.minxval
=_78(map(parseFloat
,map(_76(0),all
)));
3911 this.maxxval
=_79(map(parseFloat
,map(_76(0),all
)));
3913 this.minxval
=this.options
.xAxis
[0];
3914 this.maxxval
=this.options
.xAxis
[1];
3915 this.xscale
=this.maxval
-this.minxval
;
3917 if(_80(this.options
.yAxis
)){
3918 if(this.options
.yOriginIsZero
){
3921 this.minyval
=_78(map(parseFloat
,map(_76(1),all
)));
3923 this.maxyval
=_79(map(parseFloat
,map(_76(1),all
)));
3925 this.minyval
=this.options
.yAxis
[0];
3926 this.maxyval
=this.options
.yAxis
[1];
3927 this.yscale
=this.maxyval
-this.minyval
;
3930 PlotKit
.Layout
.prototype._evaluateScales
=function(){
3931 var _82
=MochiKit
.Base
.isUndefinedOrNull
;
3932 this.xrange
=this.maxxval
-this.minxval
;
3936 this.xscale
=1/this.xrange
;
3938 this.yrange
=this.maxyval
-this.minyval
;
3942 this.yscale
=1/this.yrange
;
3945 PlotKit
.Layout
.prototype._uniqueXValues
=function(){
3946 var _83
=PlotKit
.Base
.collapse
;
3947 var map
=PlotKit
.Base
.map
;
3948 var _84
=PlotKit
.Base
.uniq
;
3949 var _85
=MochiKit
.Base
.itemgetter
;
3950 var _86
=PlotKit
.Base
.items
;
3951 var _87
=map(parseFloat
,map(_85(0),_83(map(_85(1),_86(this.datasets
)))));
3952 _87
.sort(MochiKit
.Base
.compare
);
3955 PlotKit
.Layout
.prototype._evaluateBarCharts
=function(){
3956 var _88
=PlotKit
.Base
.items
;
3957 var _89
=_88(this.datasets
).length
;
3959 var _91
=this._uniqueXValues();
3960 for(var i
=1;i
<_91
.length
;i
++){
3961 _90
=Math
.min(Math
.abs(_91
[i
]-_91
[i
-1]),_90
);
3969 this.minxval
=_91
[0];
3970 _92
=1*this.options
.barWidthFillFraction
;
3972 _94
=(1-this.options
.barWidthFillFraction
)/2;
3980 this.xscale
=(1-_90
/this.xrange)/this.xrange
;
3983 _92
=_90
*this.xscale
*this.options
.barWidthFillFraction
;
3985 _94
=_90
*this.xscale
*(1-this.options
.barWidthFillFraction
)/2;
3988 this.bars
=new Array();
3990 for(var _95
in this.datasets
){
3991 var _96
=this.datasets
[_95
];
3992 if(PlotKit
.Base
.isFuncLike(_96
)){
3995 for(var j
=0;j
<_96
.length
;j
++){
3997 var _99
={x
:((parseFloat(_98
[0])-this.minxval
)*this.xscale
)+(i
*_93
)+_94
,y
:1-((parseFloat(_98
[1])-this.minyval
)*this.yscale
),w
:_93
,h
:((parseFloat(_98
[1])-this.minyval
)*this.yscale
),xval
:parseFloat(_98
[0]),yval
:parseFloat(_98
[1]),name
:_95
};
3998 if((_99
.x
>=0)&&(_99
.x
<=1)&&(_99
.y
>=0)&&(_99
.y
<=1)){
3999 this.bars
.push(_99
);
4005 PlotKit
.Layout
.prototype._evaluateHorizBarCharts
=function(){
4006 var _100
=PlotKit
.Base
.items
;
4007 var _101
=_100(this.datasets
).length
;
4009 var _103
=this._uniqueXValues();
4010 for(var i
=1;i
<_103
.length
;i
++){
4011 _102
=Math
.min(Math
.abs(_103
[i
]-_103
[i
-1]),_102
);
4019 this.minxval
=_103
[0];
4020 _104
=1*this.options
.barWidthFillFraction
;
4022 _106
=(1-this.options
.barWidthFillFraction
)/2;
4024 this.xscale
=(1-_102
/this.xrange)/this.xrange
;
4025 _104
=_102
*this.xscale
*this.options
.barWidthFillFraction
;
4027 _106
=_102
*this.xscale
*(1-this.options
.barWidthFillFraction
)/2;
4029 this.minxdelta
=_102
;
4030 this.bars
=new Array();
4032 for(var _107
in this.datasets
){
4033 var _108
=this.datasets
[_107
];
4034 if(PlotKit
.Base
.isFuncLike(_108
)){
4037 for(var j
=0;j
<_108
.length
;j
++){
4039 var rect
={y
:((parseFloat(item
[0])-this.minxval
)*this.xscale
)+(i
*_105
)+_106
,x
:0,h
:_105
,w
:((parseFloat(item
[1])-this.minyval
)*this.yscale
),xval
:parseFloat(item
[0]),yval
:parseFloat(item
[1]),name
:_107
};
4046 if((rect
.x
>=0)&&(rect
.x
<=1)){
4047 this.bars
.push(rect
);
4053 PlotKit
.Layout
.prototype._evaluateLineCharts
=function(){
4054 var _111
=PlotKit
.Base
.items
;
4055 var _112
=_111(this.datasets
).length
;
4056 this.points
=new Array();
4058 for(var _113
in this.datasets
){
4059 var _114
=this.datasets
[_113
];
4060 if(PlotKit
.Base
.isFuncLike(_114
)){
4063 _114
.sort(function(a
,b
){
4064 return compare(parseFloat(a
[0]),parseFloat(b
[0]));
4066 for(var j
=0;j
<_114
.length
;j
++){
4068 var _117
={x
:((parseFloat(item
[0])-this.minxval
)*this.xscale
),y
:1-((parseFloat(item
[1])-this.minyval
)*this.yscale
),xval
:parseFloat(item
[0]),yval
:parseFloat(item
[1]),name
:_113
};
4075 if((_117
.x
>=0)&&(_117
.x
<=1)){
4076 this.points
.push(_117
);
4082 PlotKit
.Layout
.prototype._evaluatePieCharts
=function(){
4083 var _118
=PlotKit
.Base
.items
;
4084 var sum
=MochiKit
.Iter
.sum
;
4085 var _120
=MochiKit
.Base
.itemgetter
;
4086 var _121
=_118(this.datasets
).length
;
4087 var _122
=_118(this.datasets
)[0][1];
4088 var _123
=sum(map(_120(1),_122
));
4089 this.slices
=new Array();
4091 for(var i
=0;i
<_122
.length
;i
++){
4092 var _125
=_122
[i
][1]/_123
;
4093 var _126
=_124
*Math
.PI
*2;
4094 var _127
=(_124
+_125
)*Math
.PI
*2;
4095 var _128
={fraction
:_125
,xval
:_122
[i
][0],yval
:_122
[i
][1],startAngle
:_126
,endAngle
:_127
};
4097 this.slices
.push(_128
);
4102 PlotKit
.Layout
.prototype._evaluateLineTicksForXAxis
=function(){
4103 var _129
=MochiKit
.Base
.isUndefinedOrNull
;
4104 if(this.options
.xTicks
){
4105 this.xticks
=new Array();
4106 var _130
=function(tick
){
4107 var _132
=tick
.label
;
4109 _132
=tick
.v
.toString();
4111 var pos
=this.xscale
*(tick
.v
-this.minxval
);
4112 if((pos
>=0)&&(pos
<=1)){
4113 this.xticks
.push([pos
,_132
]);
4116 MochiKit
.Iter
.forEach(this.options
.xTicks
,bind(_130
,this));
4118 if(this.options
.xNumberOfTicks
){
4119 var _134
=this._uniqueXValues();
4120 var _135
=this.xrange
/this.options
.xNumberOfTicks
;
4122 this.xticks
=new Array();
4123 for(var i
=0;i
<=_134
.length
;i
++){
4124 if((_134
[i
]-this.minxval
)>=(_136
*_135
)){
4125 var pos
=this.xscale
*(_134
[i
]-this.minxval
);
4126 if((pos
>1)||(pos
<0)){
4129 this.xticks
.push([pos
,_134
[i
]]);
4132 if(_136
>this.options
.xNumberOfTicks
){
4139 PlotKit
.Layout
.prototype._evaluateLineTicksForYAxis
=function(){
4140 var _137
=MochiKit
.Base
.isUndefinedOrNull
;
4141 if(this.options
.yTicks
){
4142 this.yticks
=new Array();
4143 var _138
=function(tick
){
4144 var _139
=tick
.label
;
4146 _139
=tick
.v
.toString();
4148 var pos
=1-(this.yscale
*(tick
.v
-this.minyval
));
4149 if((pos
>=0)&&(pos
<=1)){
4150 this.yticks
.push([pos
,_139
]);
4153 MochiKit
.Iter
.forEach(this.options
.yTicks
,bind(_138
,this));
4155 if(this.options
.yNumberOfTicks
){
4156 this.yticks
=new Array();
4157 var _140
=PlotKit
.Base
.roundInterval
;
4158 var prec
=this.options
.yTickPrecision
;
4159 var _142
=_140(this.yrange
,this.options
.yNumberOfTicks
,prec
);
4160 for(var i
=0;i
<=this.options
.yNumberOfTicks
;i
++){
4161 var yval
=this.minyval
+(i
*_142
);
4162 var pos
=1-((yval
-this.minyval
)*this.yscale
);
4163 if((pos
>1)||(pos
<0)){
4166 this.yticks
.push([pos
,MochiKit
.Format
.roundToFixed(yval
,prec
)]);
4171 PlotKit
.Layout
.prototype._evaluateLineTicks
=function(){
4172 this._evaluateLineTicksForXAxis();
4173 this._evaluateLineTicksForYAxis();
4175 PlotKit
.Layout
.prototype._evaluateBarTicks
=function(){
4176 this._evaluateLineTicks();
4177 var _144
=function(tick
){
4178 return [tick
[0]+(this.minxdelta
*this.xscale
)/2,tick
[1]];
4180 this.xticks
=MochiKit
.Base
.map(bind(_144
,this),this.xticks
);
4181 if(this.options
.barOrientation
=="horizontal"){
4182 var _145
=this.xticks
;
4183 this.xticks
=this.yticks
;
4185 var _146
=function(tick
){
4186 return [1-tick
[0],tick
[1]];
4188 this.xticks
=MochiKit
.Base
.map(_146
,this.xticks
);
4191 PlotKit
.Layout
.prototype._evaluatePieTicks
=function(){
4192 var _147
=MochiKit
.Base
.isUndefinedOrNull
;
4193 var _148
=MochiKit
.Format
.numberFormatter("#%");
4194 this.xticks
=new Array();
4195 if(this.options
.xTicks
){
4196 var _149
=new Array();
4197 for(var i
=0;i
<this.slices
.length
;i
++){
4198 _149
[this.slices
[i
].xval
]=this.slices
[i
];
4200 for(var i
=0;i
<this.options
.xTicks
.length
;i
++){
4201 var tick
=this.options
.xTicks
[i
];
4202 var _150
=_149
[tick
.v
];
4203 var _151
=tick
.label
;
4206 _151
=tick
.v
.toString();
4208 _151
+=" ("+_148(_150
.fraction
)+")";
4209 this.xticks
.push([tick
.v
,_151
]);
4213 for(var i
=0;i
<this.slices
.length
;i
++){
4214 var _150
=this.slices
[i
];
4215 var _151
=_150
.xval
+" ("+_148(_150
.fraction
)+")";
4216 this.xticks
.push([_150
.xval
,_151
]);
4220 PlotKit
.Layout
.prototype._regenerateHitTestCache
=function(){
4221 this.hitTestCache
.xvalues
=this._uniqueXValues();
4222 this.hitTestCache
.xlookup
=new Array();
4223 this.hitTestCache
.x2maxy
=new Array();
4224 var _152
=MochiKit
.Base
.listMax
;
4225 var _153
=MochiKit
.Base
.itemgetter
;
4226 var map
=MochiKit
.Base
.map
;
4227 var _154
=keys(this.datasets
);
4228 for(var i
=0;i
<_154
.length
;i
++){
4229 var _155
=this.datasets
[_154
[i
]];
4230 for(var j
=0;j
<_155
.length
;j
++){
4231 var xval
=_155
[j
][0];
4232 var yval
=_155
[j
][1];
4233 if(this.hitTestCache
.xlookup
[xval
]){
4234 this.hitTestCache
.xlookup
[xval
].push([yval
,_154
[i
]]);
4236 this.hitTestCache
.xlookup
[xval
]=[[yval
,_154
[i
]]];
4240 for(var x
in this.hitTestCache
.xlookup
){
4241 var _157
=this.hitTestCache
.xlookup
[x
];
4242 this.hitTestCache
.x2maxy
[x
]=_152(map(_153(0),_157
));
4245 PlotKit
.LayoutModule
={};
4246 PlotKit
.LayoutModule
.Layout
=PlotKit
.Layout
;
4247 PlotKit
.LayoutModule
.EXPORT
=["Layout"];
4248 PlotKit
.LayoutModule
.EXPORT_OK
=[];
4249 PlotKit
.LayoutModule
.__new__
=function(){
4250 var m
=MochiKit
.Base
;
4251 m
.nameFunctions(this);
4252 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
4254 PlotKit
.LayoutModule
.__new__();
4255 MochiKit
.Base
._exportSymbols(this,PlotKit
.LayoutModule
);
4257 if((typeof (PlotKit
.Base
)=="undefined")||(typeof (PlotKit
.Layout
)=="undefined")){
4262 throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Base,Layout}";
4264 if(typeof (PlotKit
.CanvasRenderer
)=="undefined"){
4265 PlotKit
.CanvasRenderer
={};
4267 PlotKit
.CanvasRenderer
.NAME
="PlotKit.CanvasRenderer";
4268 PlotKit
.CanvasRenderer
.VERSION
=PlotKit
.VERSION
;
4269 PlotKit
.CanvasRenderer
.__repr__
=function(){
4270 return "["+this.NAME
+" "+this.VERSION
+"]";
4272 PlotKit
.CanvasRenderer
.toString
=function(){
4273 return this.__repr__();
4275 PlotKit
.CanvasRenderer
=function(_158
,_159
,_160
){
4276 if(arguments
.length
>0){
4277 this.__init__(_158
,_159
,_160
);
4280 PlotKit
.CanvasRenderer
.prototype.__init__
=function(_161
,_162
,_163
){
4281 var _164
=MochiKit
.Base
.isUndefinedOrNull
;
4282 var _165
=MochiKit
.Color
.Color
;
4283 this.options
={"drawBackground":true,"backgroundColor":_165
.whiteColor(),"padding":{left
:30,right
:30,top
:5,bottom
:10},"colorScheme":PlotKit
.Base
.palette(PlotKit
.Base
.baseColors()[0]),"strokeColor":_165
.whiteColor(),"strokeColorTransform":"asStrokeColor","strokeWidth":0.5,"shouldFill":true,"shouldStroke":true,"drawXAxis":true,"drawYAxis":true,"axisLineColor":_165
.blackColor(),"axisLineWidth":0.5,"axisTickSize":3,"axisLabelColor":_165
.blackColor(),"axisLabelFont":"Arial","axisLabelFontSize":9,"axisLabelWidth":50,"pieRadius":0.4,"enableEvents":true};
4284 MochiKit
.Base
.update(this.options
,_163
?_163
:{});
4286 this.element
=MochiKit
.DOM
.getElement(_161
);
4287 this.container
=this.element
.parentNode
;
4288 this.isIE
=PlotKit
.Base
.excanvasSupported();
4289 if(this.isIE
&&!_164(G_vmlCanvasManager
)){
4292 this.renderDelay
=null;
4293 this.clearDelay
=null;
4294 this.element
=G_vmlCanvasManager
.initElement(this.element
);
4296 this.height
=this.element
.height
;
4297 this.width
=this.element
.width
;
4298 if(_164(this.element
)){
4299 throw "CanvasRenderer() - passed canvas is not found";
4301 if(!this.isIE
&&!(PlotKit
.CanvasRenderer
.isSupported(this.element
))){
4302 throw "CanvasRenderer() - Canvas is not supported.";
4304 if(_164(this.container
)||(this.container
.nodeName
.toLowerCase()!="div")){
4305 throw "CanvasRenderer() - <canvas> needs to be enclosed in <div>";
4307 this.xlabels
=new Array();
4308 this.ylabels
=new Array();
4309 this.isFirstRender
=true;
4310 this.area
={x
:this.options
.padding
.left
,y
:this.options
.padding
.top
,w
:this.width
-this.options
.padding
.left
-this.options
.padding
.right
,h
:this.height
-this.options
.padding
.top
-this.options
.padding
.bottom
};
4311 MochiKit
.DOM
.updateNodeAttributes(this.container
,{"style":{"position":"relative","width":this.width
+"px"}});
4313 PlotKit
.CanvasRenderer
.prototype.render
=function(){
4316 if(this.renderDelay
){
4317 this.renderDelay
.cancel();
4318 this.renderDelay
=null;
4320 var _166
=this.element
.getContext("2d");
4323 this.isFirstRender
=false;
4324 if(this.maxTries
-->0){
4325 this.renderDelay
=MochiKit
.Async
.wait(this.IEDelay
);
4326 this.renderDelay
.addCallback(bind(this.render
,this));
4331 if(this.options
.drawBackground
){
4332 this._renderBackground();
4334 if(this.layout
.style
=="bar"){
4335 this._renderBarChart();
4336 this._renderBarAxis();
4338 if(this.layout
.style
=="pie"){
4339 this._renderPieChart();
4340 this._renderPieAxis();
4342 if(this.layout
.style
=="line"){
4343 this._renderLineChart();
4344 this._renderLineAxis();
4349 PlotKit
.CanvasRenderer
.prototype._renderBarChartWrap
=function(data
,_168
){
4350 var _169
=this.element
.getContext("2d");
4351 var _170
=this.options
.colorScheme
.length
;
4352 var _171
=this.options
.colorScheme
;
4353 var _172
=MochiKit
.Base
.keys(this.layout
.datasets
);
4354 var _173
=_172
.length
;
4355 for(var i
=0;i
<_173
;i
++){
4357 var _175
=_171
[i
%_170
];
4359 _169
.fillStyle
=_175
.toRGBString();
4360 if(this.options
.strokeColor
){
4361 _169
.strokeStyle
=this.options
.strokeColor
.toRGBString();
4363 if(this.options
.strokeColorTransform
){
4364 _169
.strokeStyle
=_175
[this.options
.strokeColorTransform
]().toRGBString();
4367 _169
.lineWidth
=this.options
.strokeWidth
;
4368 var _176
=function(obj
){
4373 MochiKit
.Iter
.forEach(data
,bind(_176
,this));
4377 PlotKit
.CanvasRenderer
.prototype._renderBarChart
=function(){
4378 var bind
=MochiKit
.Base
.bind
;
4379 var _178
=function(_179
,bar
){
4380 var x
=this.area
.w
*bar
.x
+this.area
.x
;
4381 var y
=this.area
.h
*bar
.y
+this.area
.y
;
4382 var w
=this.area
.w
*bar
.w
;
4383 var h
=this.area
.h
*bar
.h
;
4387 if(this.options
.shouldFill
){
4388 _179
.fillRect(x
,y
,w
,h
);
4390 if(this.options
.shouldStroke
){
4391 _179
.strokeRect(x
,y
,w
,h
);
4394 this._renderBarChartWrap(this.layout
.bars
,bind(_178
,this));
4396 PlotKit
.CanvasRenderer
.prototype._renderLineChart
=function(){
4397 var _182
=this.element
.getContext("2d");
4398 var _183
=this.options
.colorScheme
.length
;
4399 var _184
=this.options
.colorScheme
;
4400 var _185
=MochiKit
.Base
.keys(this.layout
.datasets
);
4401 var _186
=_185
.length
;
4402 var bind
=MochiKit
.Base
.bind
;
4403 var _187
=MochiKit
.Base
.partial
;
4404 for(var i
=0;i
<_186
;i
++){
4406 var _189
=_184
[i
%_183
];
4407 var _190
=this.options
.strokeColorTransform
;
4409 _182
.fillStyle
=_189
.toRGBString();
4410 if(this.options
.strokeColor
){
4411 _182
.strokeStyle
=this.options
.strokeColor
.toRGBString();
4413 if(this.options
.strokeColorTransform
){
4414 _182
.strokeStyle
=_189
[_190
]().toRGBString();
4417 _182
.lineWidth
=this.options
.strokeWidth
;
4418 var _191
=function(ctx
){
4420 ctx
.moveTo(this.area
.x
,this.area
.y
+this.area
.h
);
4421 var _193
=function(ctx_
,_195
){
4422 if(_195
.name
==_188
){
4423 ctx_
.lineTo(this.area
.w
*_195
.x
+this.area
.x
,this.area
.h
*_195
.y
+this.area
.y
);
4426 MochiKit
.Iter
.forEach(this.layout
.points
,_187(_193
,ctx
),this);
4427 ctx
.lineTo(this.area
.w
+this.area
.x
,this.area
.h
+this.area
.y
);
4428 ctx
.lineTo(this.area
.x
,this.area
.y
+this.area
.h
);
4431 if(this.options
.shouldFill
){
4432 bind(_191
,this)(_182
);
4435 if(this.options
.shouldStroke
){
4436 bind(_191
,this)(_182
);
4442 PlotKit
.CanvasRenderer
.prototype._renderPieChart
=function(){
4443 var _196
=this.element
.getContext("2d");
4444 var _197
=this.options
.colorScheme
.length
;
4445 var _198
=this.layout
.slices
;
4446 var _199
=this.area
.x
+this.area
.w
*0.5;
4447 var _200
=this.area
.y
+this.area
.h
*0.5;
4448 var _201
=Math
.min(this.area
.w
*this.options
.pieRadius
,this.area
.h
*this.options
.pieRadius
);
4450 _199
=parseInt(_199
);
4451 _200
=parseInt(_200
);
4452 _201
=parseInt(_201
);
4454 for(var i
=0;i
<_198
.length
;i
++){
4455 var _202
=this.options
.colorScheme
[i
%_197
];
4457 _196
.fillStyle
=_202
.toRGBString();
4458 var _203
=function(){
4460 _196
.moveTo(_199
,_200
);
4461 _196
.arc(_199
,_200
,_201
,_198
[i
].startAngle
-Math
.PI
/2,_198[i].endAngle-Math.PI/2,false);
4462 _196
.lineTo(_199
,_200
);
4465 if(Math
.abs(_198
[i
].startAngle
-_198
[i
].endAngle
)>0.001){
4466 if(this.options
.shouldFill
){
4470 if(this.options
.shouldStroke
){
4472 _196
.lineWidth
=this.options
.strokeWidth
;
4473 if(this.options
.strokeColor
){
4474 _196
.strokeStyle
=this.options
.strokeColor
.toRGBString();
4476 if(this.options
.strokeColorTransform
){
4477 _196
.strokeStyle
=_202
[this.options
.strokeColorTransform
]().toRGBString();
4486 PlotKit
.CanvasRenderer
.prototype._renderBarAxis
=function(){
4489 PlotKit
.CanvasRenderer
.prototype._renderLineAxis
=function(){
4492 PlotKit
.CanvasRenderer
.prototype._renderAxis
=function(){
4493 if(!this.options
.drawXAxis
&&!this.options
.drawYAxis
){
4496 var _204
=this.element
.getContext("2d");
4497 var _205
={"style":{"position":"absolute","fontSize":this.options
.axisLabelFontSize
+"px","zIndex":10,"color":this.options
.axisLabelColor
.toRGBString(),"width":this.options
.axisLabelWidth
+"px","overflow":"hidden"}};
4499 _204
.strokeStyle
=this.options
.axisLineColor
.toRGBString();
4500 _204
.lineWidth
=this.options
.axisLineWidth
;
4501 if(this.options
.drawYAxis
){
4502 if(this.layout
.yticks
){
4503 var _206
=function(tick
){
4504 if(typeof (tick
)=="function"){
4508 var y
=this.area
.y
+tick
[0]*this.area
.h
;
4511 _204
.lineTo(x
-this.options
.axisTickSize
,y
);
4514 var _207
=DIV(_205
,tick
[1]);
4515 _207
.style
.top
=(y
-this.options
.axisLabelFontSize
)+"px";
4516 _207
.style
.left
=(x
-this.options
.padding
.left
-this.options
.axisTickSize
)+"px";
4517 _207
.style
.textAlign
="right";
4518 _207
.style
.width
=(this.options
.padding
.left
-this.options
.axisTickSize
*2)+"px";
4519 MochiKit
.DOM
.appendChildNodes(this.container
,_207
);
4520 this.ylabels
.push(_207
);
4522 MochiKit
.Iter
.forEach(this.layout
.yticks
,bind(_206
,this));
4525 _204
.moveTo(this.area
.x
,this.area
.y
);
4526 _204
.lineTo(this.area
.x
,this.area
.y
+this.area
.h
);
4530 if(this.options
.drawXAxis
){
4531 if(this.layout
.xticks
){
4532 var _206
=function(tick
){
4533 if(typeof (dataset
)=="function"){
4536 var x
=this.area
.x
+tick
[0]*this.area
.w
;
4537 var y
=this.area
.y
+this.area
.h
;
4540 _204
.lineTo(x
,y
+this.options
.axisTickSize
);
4543 var _208
=DIV(_205
,tick
[1]);
4544 _208
.style
.top
=(y
+this.options
.axisTickSize
)+"px";
4545 _208
.style
.left
=(x
-this.options
.axisLabelWidth
/2)+"px";
4546 _208
.style
.textAlign
="center";
4547 _208
.style
.width
=this.options
.axisLabelWidth
+"px";
4548 MochiKit
.DOM
.appendChildNodes(this.container
,_208
);
4549 this.xlabels
.push(_208
);
4551 MochiKit
.Iter
.forEach(this.layout
.xticks
,bind(_206
,this));
4554 _204
.moveTo(this.area
.x
,this.area
.y
+this.area
.h
);
4555 _204
.lineTo(this.area
.x
+this.area
.w
,this.area
.y
+this.area
.h
);
4561 PlotKit
.CanvasRenderer
.prototype._renderPieAxis
=function(){
4562 if(!this.options
.drawXAxis
){
4565 if(this.layout
.xticks
){
4566 var _209
=new Array();
4567 for(var i
=0;i
<this.layout
.slices
.length
;i
++){
4568 _209
[this.layout
.slices
[i
].xval
]=this.layout
.slices
[i
];
4570 var _210
=this.area
.x
+this.area
.w
*0.5;
4571 var _211
=this.area
.y
+this.area
.h
*0.5;
4572 var _212
=Math
.min(this.area
.w
*this.options
.pieRadius
,this.area
.h
*this.options
.pieRadius
);
4573 var _213
=this.options
.axisLabelWidth
;
4574 for(var i
=0;i
<this.layout
.xticks
.length
;i
++){
4575 var _214
=_209
[this.layout
.xticks
[i
][0]];
4576 if(MochiKit
.Base
.isUndefinedOrNull(_214
)){
4579 var _215
=(_214
.startAngle
+_214
.endAngle
)/2;
4582 _216
=_216
-Math
.PI
*2;
4585 _216
=_216
+Math
.PI
*2;
4588 var _217
=_210
+Math
.sin(_216
)*(_212
+10);
4589 var _218
=_211
-Math
.cos(_216
)*(_212
+10);
4590 var _219
={"position":"absolute","zIndex":11,"width":_213
+"px","fontSize":this.options
.axisLabelFontSize
+"px","overflow":"hidden","color":this.options
.axisLabelColor
.toHexString()};
4591 if(_216
<=Math
.PI
*0.5){
4592 _219
["textAlign"]="left";
4593 _219
["verticalAlign"]="top";
4594 _219
["left"]=_217
+"px";
4595 _219
["top"]=(_218
-this.options
.axisLabelFontSize
)+"px";
4597 if((_216
>Math
.PI
*0.5)&&(_216
<=Math
.PI
)){
4598 _219
["textAlign"]="left";
4599 _219
["verticalAlign"]="bottom";
4600 _219
["left"]=_217
+"px";
4601 _219
["top"]=_218
+"px";
4603 if((_216
>Math
.PI
)&&(_216
<=Math
.PI
*1.5)){
4604 _219
["textAlign"]="right";
4605 _219
["verticalAlign"]="bottom";
4606 _219
["left"]=(_217
-_213
)+"px";
4607 _219
["top"]=_218
+"px";
4609 _219
["textAlign"]="right";
4610 _219
["verticalAlign"]="bottom";
4611 _219
["left"]=(_217
-_213
)+"px";
4612 _219
["top"]=(_218
-this.options
.axisLabelFontSize
)+"px";
4616 var _220
=DIV({"style":_219
},this.layout
.xticks
[i
][1]);
4617 this.xlabels
.push(_220
);
4618 MochiKit
.DOM
.appendChildNodes(this.container
,_220
);
4622 PlotKit
.CanvasRenderer
.prototype._renderBackground
=function(){
4623 var _221
=this.element
.getContext("2d");
4625 _221
.fillStyle
=this.options
.backgroundColor
.toRGBString();
4626 _221
.fillRect(0,0,this.width
,this.height
);
4629 PlotKit
.CanvasRenderer
.prototype.clear
=function(){
4632 if(this.clearDelay
){
4633 this.clearDelay
.cancel();
4634 this.clearDelay
=null;
4636 var _222
=this.element
.getContext("2d");
4639 this.isFirstRender
=false;
4640 this.clearDelay
=MochiKit
.Async
.wait(this.IEDelay
);
4641 this.clearDelay
.addCallback(bind(this.clear
,this));
4645 var _222
=this.element
.getContext("2d");
4646 _222
.clearRect(0,0,this.width
,this.height
);
4647 MochiKit
.Iter
.forEach(this.xlabels
,MochiKit
.DOM
.removeElement
);
4648 MochiKit
.Iter
.forEach(this.ylabels
,MochiKit
.DOM
.removeElement
);
4649 this.xlabels
=new Array();
4650 this.ylabels
=new Array();
4652 PlotKit
.CanvasRenderer
.prototype._initialiseEvents
=function(){
4653 var _223
=MochiKit
.Signal
.connect
;
4654 var bind
=MochiKit
.Base
.bind
;
4655 _223(this.element
,"onclick",bind(this.onclick
,this));
4657 PlotKit
.CanvasRenderer
.prototype._resolveObject
=function(e
){
4658 var x
=(e
.mouse().page
.x
-PlotKit
.Base
.findPosX(this.element
)-this.area
.x
)/this.area
.w
;
4659 var y
=(e
.mouse().page
.y
-PlotKit
.Base
.findPosY(this.element
)-this.area
.y
)/this.area
.h
;
4660 var _225
=this.layout
.hitTest(x
,y
);
4666 PlotKit
.CanvasRenderer
.prototype._createEventObject
=function(_226
,e
){
4673 PlotKit
.CanvasRenderer
.prototype.onclick
=function(e
){
4674 var _227
=this._resolveObject(e
);
4675 var _228
=this._createEventObject(_227
,e
);
4677 MochiKit
.Signal
.signal(this,"onclick",_228
);
4680 PlotKit
.CanvasRenderer
.prototype.onmouseover
=function(e
){
4681 var _229
=this._resolveObject(e
);
4682 var _230
=this._createEventObject(_229
,e
);
4684 signal(this,"onmouseover",_230
);
4687 PlotKit
.CanvasRenderer
.prototype.onmouseout
=function(e
){
4688 var _231
=this._resolveObject(e
);
4689 var _232
=this._createEventObject(_231
,e
);
4691 signal(this,"onmouseout",e
);
4693 signal(this,"onmouseout",_232
);
4696 PlotKit
.CanvasRenderer
.prototype.onmousemove
=function(e
){
4697 var _233
=this._resolveObject(e
);
4698 var _234
=this._createEventObject(_233
,e
);
4699 if((_233
==null)&&(this.event_isinside
==null)){
4702 if((_233
!=null)&&(this.event_isinside
==null)){
4703 signal(this,"onmouseover",_234
);
4705 if((_233
==null)&&(this.event_isinside
!=null)){
4706 signal(this,"onmouseout",_234
);
4708 if((_233
!=null)&&(this.event_isinside
!=null)){
4709 signal(this,"onmousemove",_234
);
4711 this.event_isinside
=_233
;
4713 PlotKit
.CanvasRenderer
.isSupported
=function(_235
){
4716 if(MochiKit
.Base
.isUndefinedOrNull(_235
)){
4717 _236
=MochiKit
.DOM
.CANVAS({});
4719 _236
=MochiKit
.DOM
.getElement(_235
);
4721 var _237
=_236
.getContext("2d");
4724 var ie
=navigator
.appVersion
.match(/MSIE (\d\.\d)/);
4725 var _239
=(navigator
.userAgent
.toLowerCase().indexOf("opera")!=-1);
4726 if((!ie
)||(ie
[1]<6)||(_239
)){
4734 PlotKit
.Canvas
.CanvasRenderer
=PlotKit
.CanvasRenderer
;
4735 PlotKit
.Canvas
.EXPORT
=["CanvasRenderer"];
4736 PlotKit
.Canvas
.EXPORT_OK
=["CanvasRenderer"];
4737 PlotKit
.Canvas
.__new__
=function(){
4738 var m
=MochiKit
.Base
;
4739 m
.nameFunctions(this);
4740 this.EXPORT_TAGS
={":common":this.EXPORT
,":all":m
.concat(this.EXPORT
,this.EXPORT_OK
)};
4742 PlotKit
.Canvas
.__new__();
4743 MochiKit
.Base
._exportSymbols(this,PlotKit
.Canvas
);
4746 // Copyright 2006 Dan Vanderkam (danvdk@gmail.com)
4747 // All Rights Reserved.
4750 * @fileoverview Subclasses various parts of PlotKit to meet the additional
4751 * needs of DateGraph: grid overlays and error bars
4754 // Subclass PlotKit.Layout to add:
4755 // 1. Sigma/errorBars properties
4756 // 2. Copy error terms for PlotKit.CanvasRenderer._renderLineChart
4759 * Creates a new DateGraphLayout object. Options are the same as those allowed
4760 * by the PlotKit.Layout constructor.
4761 * @param {Object} options Options for PlotKit.Layout
4762 * @return {Object} The DateGraphLayout object
4764 DateGraphLayout
= function(options
) {
4765 PlotKit
.Layout
.call(this, "line", options
);
4767 DateGraphLayout
.prototype = new PlotKit
.Layout();
4770 * Behaves the same way as PlotKit.Layout, but also copies the errors
4773 DateGraphLayout
.prototype.evaluateWithError
= function() {
4775 if (!this.options
.errorBars
) return;
4777 // Copy over the error terms
4778 var i
= 0; // index in this.points
4779 for (var setName
in this.datasets
) {
4781 var dataset
= this.datasets
[setName
];
4782 if (PlotKit
.Base
.isFuncLike(dataset
)) continue;
4783 for (var j
= 0; j
< dataset
.length
; j
++, i
++) {
4784 var item
= dataset
[j
];
4785 var xv
= parseFloat(item
[0]);
4786 var yv
= parseFloat(item
[1]);
4788 if (xv
== this.points
[i
].xval
&&
4789 yv
== this.points
[i
].yval
) {
4790 this.points
[i
].errorMinus
= parseFloat(item
[2]);
4791 this.points
[i
].errorPlus
= parseFloat(item
[3]);
4798 * Convenience function to remove all the data sets from a graph
4800 DateGraphLayout
.prototype.removeAllDatasets
= function() {
4801 delete this.datasets
;
4802 this.datasets
= new Array();
4806 * Change the values of various layout options
4807 * @param {Object} new_options an associative array of new properties
4809 DateGraphLayout
.prototype.updateOptions
= function(new_options
) {
4810 MochiKit
.Base
.update(this.options
, new_options
? new_options
: {});
4813 // Subclass PlotKit.CanvasRenderer to add:
4814 // 1. X/Y grid overlay
4815 // 2. Ability to draw error bars (if required)
4818 * Sets some PlotKit.CanvasRenderer options
4819 * @param {Object} element The canvas to attach to
4820 * @param {Layout} layout The DateGraphLayout object for this graph.
4821 * @param {Object} options Options to pass on to CanvasRenderer
4823 DateGraphCanvasRenderer
= function(element
, layout
, options
) {
4824 PlotKit
.CanvasRenderer
.call(this, element
, layout
, options
);
4825 this.options
.shouldFill
= false;
4826 this.options
.shouldStroke
= true;
4827 this.options
.drawYGrid
= true;
4828 this.options
.drawXGrid
= true;
4829 this.options
.gridLineColor
= MochiKit
.Color
.Color
.grayColor();
4830 MochiKit
.Base
.update(this.options
, options
);
4832 // TODO(danvk) This shouldn't be necessary: effects should be overlaid
4833 this.options
.drawBackground
= false;
4835 DateGraphCanvasRenderer
.prototype = new PlotKit
.CanvasRenderer();
4838 * Draw an X/Y grid on top of the existing plot
4840 DateGraphCanvasRenderer
.prototype.render
= function() {
4841 // Do the ordinary rendering, as before
4842 // TODO(danvk) Call super.render()
4843 this._renderLineChart();
4844 this._renderLineAxis();
4846 // Draw the new X/Y grid
4847 var ctx
= this.element
.getContext("2d");
4848 if (this.options
.drawYGrid
) {
4849 var ticks
= this.layout
.yticks
;
4851 ctx
.strokeStyle
= this.options
.gridLineColor
.toRGBString();
4852 ctx
.lineWidth
= this.options
.axisLineWidth
;
4853 for (var i
= 0; i
< ticks
.length
; i
++) {
4854 var x
= this.area
.x
;
4855 var y
= this.area
.y
+ ticks
[i
][0] * this.area
.h
;
4858 ctx
.lineTo(x
+ this.area
.w
, y
);
4864 if (this.options
.drawXGrid
) {
4865 var ticks
= this.layout
.xticks
;
4867 ctx
.strokeStyle
= this.options
.gridLineColor
.toRGBString();
4868 ctx
.lineWidth
= this.options
.axisLineWidth
;
4869 for (var i
=0; i
<ticks
.length
; i
++) {
4870 var x
= this.area
.x
+ ticks
[i
][0] * this.area
.w
;
4871 var y
= this.area
.y
+ this.area
.h
;
4874 ctx
.lineTo(x
, this.area
.y
);
4882 * Overrides the CanvasRenderer method to draw error bars
4884 DateGraphCanvasRenderer
.prototype._renderLineChart
= function() {
4885 var context
= this.element
.getContext("2d");
4886 var colorCount
= this.options
.colorScheme
.length
;
4887 var colorScheme
= this.options
.colorScheme
;
4888 var setNames
= MochiKit
.Base
.keys(this.layout
.datasets
);
4889 var errorBars
= this.layout
.options
.errorBars
;
4890 var setCount
= setNames
.length
;
4891 var bind
= MochiKit
.Base
.bind
;
4892 var partial
= MochiKit
.Base
.partial
;
4895 var updatePoint
= function(point
) {
4896 point
.canvasx
= this.area
.w
* point
.x
+ this.area
.x
;
4897 point
.canvasy
= this.area
.h
* point
.y
+ this.area
.y
;
4899 MochiKit
.Iter
.forEach(this.layout
.points
, updatePoint
, this);
4902 var makePath
= function(ctx
) {
4903 for (var i
= 0; i
< setCount
; i
++) {
4904 var setName
= setNames
[i
];
4905 var color
= colorScheme
[i
%colorCount
];
4906 var strokeX
= this.options
.strokeColorTransform
;
4908 // setup graphics context
4910 context
.strokeStyle
= color
.toRGBString();
4911 context
.lineWidth
= this.options
.strokeWidth
;
4913 var point
= this.layout
.points
[0];
4914 var first_point
= true;
4915 var addPoint
= function(ctx_
, point
) {
4916 if (point
.name
== setName
) {
4918 ctx_
.moveTo(point
.canvasx
, point
.canvasy
);
4920 ctx_
.lineTo(point
.canvasx
, point
.canvasy
);
4921 first_point
= false;
4924 MochiKit
.Iter
.forEach(this.layout
.points
, partial(addPoint
, ctx
), this);
4929 var makeErrorBars
= function(ctx
) {
4930 for (var i
= 0; i
< setCount
; i
++) {
4931 var setName
= setNames
[i
];
4932 var color
= colorScheme
[i
% colorCount
];
4933 var strokeX
= this.options
.strokeColorTransform
;
4935 // setup graphics context
4937 context
.strokeStyle
= color
.toRGBString();
4938 context
.lineWidth
= this.options
.strokeWidth
;
4940 var prevYs
= [-1, -1];
4942 var yscale
= this.layout
.yscale
;
4943 var errorTrapezoid
= function(ctx_
,point
) {
4945 if (point
.name
== setName
) {
4946 var newYs
= [ point
.y
- point
.errorPlus
* yscale
,
4947 point
.y
+ point
.errorMinus
* yscale
];
4948 newYs
[0] = this.area
.h
* newYs
[0] + this.area
.y
;
4949 newYs
[1] = this.area
.h
* newYs
[1] + this.area
.y
;
4951 ctx_
.moveTo(prevX
, prevYs
[0]);
4952 ctx_
.lineTo(point
.canvasx
, newYs
[0]);
4953 ctx_
.lineTo(point
.canvasx
, newYs
[1]);
4954 ctx_
.lineTo(prevX
, prevYs
[1]);
4957 prevYs
[0] = newYs
[0];
4958 prevYs
[1] = newYs
[1];
4959 prevX
= point
.canvasx
;
4962 // should be same color as the lines
4963 var err_color
= color
.colorWithAlpha(0.15);
4964 ctx
.fillStyle
= err_color
.toRGBString();
4966 MochiKit
.Iter
.forEach(this.layout
.points
, partial(errorTrapezoid
, ctx
), this);
4972 bind(makeErrorBars
, this)(context
);
4973 bind(makePath
, this)(context
);
4976 // Copyright 2006 Dan Vanderkam (danvdk@gmail.com)
4977 // All Rights Reserved.
4980 * @fileoverview Creates an interactive, zoomable graph based on a CSV file or
4981 * string. DateGraph can handle multiple series with or without error bars. The
4982 * date/value ranges will be automatically set. DateGraph uses the
4983 * <canvas> tag, so it only works in FF1.5+.
4984 * @author danvdk@gmail.com (Dan Vanderkam)
4987 <div id="graphdiv" style="width:800px; height:500px;"></div>
4988 <script type="text/javascript">
4989 new DateGraph(document.getElementById("graphdiv"),
4991 ["Series 1", "Series 2"],
4995 The CSV file is of the form
5000 If null is passed as the third parameter (series names), then the first line
5001 of the CSV file is assumed to contain names for each series.
5003 If the 'errorBars' option is set in the constructor, the input should be of
5006 YYYYMMDD,A1,sigmaA1,B1,sigmaB1,...
5007 YYYYMMDD,A2,sigmaA2,B2,sigmaB2,...
5009 If the 'fractions' option is set, the input should be of the form:
5011 YYYYMMDD,A1/B1,A2/B2,...
5012 YYYYMMDD,A1/B1,A2/B2,...
5014 And error bars will be calculated automatically using a binomial distribution.
5016 For further documentation and examples, see http://www/~danvk/dg/
5021 * An interactive, zoomable graph
5022 * @param {String | Function} file A file containing CSV data or a function that
5023 * returns this data. The expected format for each line is
5024 * YYYYMMDD,val1,val2,... or, if attrs.errorBars is set,
5025 * YYYYMMDD,val1,stddev1,val2,stddev2,...
5026 * @param {Array.<String>} labels Labels for the data series
5027 * @param {Object} attrs Various other attributes, e.g. errorBars determines
5028 * whether the input data contains error ranges.
5030 DateGraph
= function(div
, file
, labels
, attrs
) {
5031 if (arguments
.length
> 0)
5032 this.__init__(div
, file
, labels
, attrs
);
5035 DateGraph
.NAME
= "DateGraph";
5036 DateGraph
.VERSION
= "1.1";
5037 DateGraph
.__repr__
= function() {
5038 return "[" + this.NAME
+ " " + this.VERSION
+ "]";
5040 DateGraph
.toString
= function() {
5041 return this.__repr__();
5044 // Various default values
5045 DateGraph
.DEFAULT_ROLL_PERIOD
= 1;
5046 DateGraph
.DEFAULT_WIDTH
= 480;
5047 DateGraph
.DEFAULT_HEIGHT
= 320;
5048 DateGraph
.DEFAULT_STROKE_WIDTH
= 1.0;
5049 DateGraph
.AXIS_LINE_WIDTH
= 0.3;
5052 * Initializes the DateGraph. This creates a new DIV and constructs the PlotKit
5053 * and interaction <canvas> inside of it. See the constructor for details
5054 * on the parameters.
5055 * @param {String | Function} file Source data
5056 * @param {Array.<String>} labels Names of the data series
5057 * @param {Object} attrs Miscellaneous other options
5060 DateGraph
.prototype.__init__
= function(div
, file
, labels
, attrs
) {
5061 // Copy the important bits into the object
5062 this.maindiv_
= div
;
5063 this.labels_
= labels
;
5065 this.rollPeriod_
= attrs
.rollPeriod
|| DateGraph
.DEFAULT_ROLL_PERIOD
;
5066 this.previousVerticalX_
= -1;
5067 this.width_
= parseInt(div
.style
.width
, 10);
5068 this.height_
= parseInt(div
.style
.height
, 10);
5069 this.errorBars_
= attrs
.errorBars
|| false;
5070 this.fractions_
= attrs
.fractions
|| false;
5071 this.strokeWidth_
= attrs
.strokeWidth
|| DateGraph
.DEFAULT_STROKE_WIDTH
;
5072 this.dateWindow_
= attrs
.dateWindow
|| null;
5073 this.valueRange_
= attrs
.valueRange
|| null;
5074 this.labelsSeparateLines
= attrs
.labelsSeparateLines
|| false;
5075 this.labelsDiv_
= attrs
.labelsDiv
|| null;
5076 this.labelsKMB_
= attrs
.labelsKMB
|| false;
5077 this.minTickSize_
= attrs
.minTickSize
|| 0;
5078 this.xValueParser_
= attrs
.xValueParser
|| DateGraph
.prototype.dateParser
;
5079 this.xValueFormatter_
= attrs
.xValueFormatter
||
5080 DateGraph
.prototype.dateString_
;
5081 this.xTicker_
= attrs
.xTicker
|| DateGraph
.prototype.dateTicker
;
5082 this.sigma_
= attrs
.sigma
|| 2.0;
5083 this.wilsonInterval_
= attrs
.wilsonInterval
|| true;
5084 this.customBars_
= attrs
.customBars
|| false;
5085 this.attrs_
= attrs
;
5087 // Make a note of whether labels will be pulled from the CSV file.
5088 this.labelsFromCSV_
= (this.labels_
== null);
5089 if (this.labels_
== null)
5092 // Prototype of the callback is "void clickCallback(event, date)"
5093 this.clickCallback_
= attrs
.clickCallback
|| null;
5095 // Prototype of zoom callback is "void dragCallback(minDate, maxDate)"
5096 this.zoomCallback_
= attrs
.zoomCallback
|| null;
5098 // Create the containing DIV and other interactive elements
5099 this.createInterface_();
5101 // Create the PlotKit grapher
5102 this.layoutOptions_
= { 'errorBars': (this.errorBars_
|| this.customBars_
),
5103 'xOriginIsZero': false };
5104 MochiKit
.Base
.update(this.layoutOptions_
, attrs
);
5105 this.setColors_(attrs
);
5107 this.layout_
= new DateGraphLayout(this.layoutOptions_
);
5109 this.renderOptions_
= { colorScheme
: this.colors_
,
5111 strokeWidth
: this.strokeWidth_
,
5112 axisLabelFontSize
: 14,
5113 axisLineWidth
: DateGraph
.AXIS_LINE_WIDTH
};
5114 MochiKit
.Base
.update(this.renderOptions_
, attrs
);
5115 this.plotter_
= new DateGraphCanvasRenderer(this.hidden_
, this.layout_
,
5116 this.renderOptions_
);
5118 this.createStatusMessage_();
5119 this.createRollInterface_();
5120 this.createDragInterface_();
5122 connect(window
, 'onload', this, function(e
) { this.start_(); });
5126 * Returns the current rolling period, as set by the user or an option.
5127 * @return {Number} The number of days in the rolling window
5129 DateGraph
.prototype.rollPeriod
= function() {
5130 return this.rollPeriod_
;
5134 * Generates interface elements for the DateGraph: a containing div, a div to
5135 * display the current point, and a textbox to adjust the rolling average
5139 DateGraph
.prototype.createInterface_
= function() {
5140 // Create the all-enclosing graph div
5141 var enclosing
= this.maindiv_
;
5143 this.graphDiv
= MochiKit
.DOM
.DIV( { style
: { 'width': this.width_
+ "px",
5144 'height': this.height_
+ "px"
5146 appendChildNodes(enclosing
, this.graphDiv
);
5148 // Create the canvas to store
5149 var canvas
= MochiKit
.DOM
.CANVAS
;
5150 this.canvas_
= canvas( { style
: { 'position': 'absolute' },
5152 height
: this.height_
});
5153 appendChildNodes(this.graphDiv
, this.canvas_
);
5155 this.hidden_
= this.createPlotKitCanvas_(this.canvas_
);
5156 connect(this.hidden_
, 'onmousemove', this, function(e
) { this.mouseMove_(e
) });
5157 connect(this.hidden_
, 'onmouseout', this, function(e
) { this.mouseOut_(e
) });
5161 * Creates the canvas containing the PlotKit graph. Only plotkit ever draws on
5162 * this particular canvas. All DateGraph work is done on this.canvas_.
5163 * @param {Object} canvas The DateGraph canvas to over which to overlay the plot
5164 * @return {Object} The newly-created canvas
5167 DateGraph
.prototype.createPlotKitCanvas_
= function(canvas
) {
5168 var h
= document
.createElement("canvas");
5169 h
.style
.position
= "absolute";
5170 h
.style
.top
= canvas
.style
.top
;
5171 h
.style
.left
= canvas
.style
.left
;
5172 h
.width
= this.width_
;
5173 h
.height
= this.height_
;
5174 MochiKit
.DOM
.appendChildNodes(this.graphDiv
, h
);
5179 * Generate a set of distinct colors for the data series. This is done with a
5180 * color wheel. Saturation/Value are customizable, and the hue is
5181 * equally-spaced around the color wheel. If a custom set of colors is
5182 * specified, that is used instead.
5183 * @param {Object} attrs Various attributes, e.g. saturation and value
5186 DateGraph
.prototype.setColors_
= function(attrs
) {
5187 var num
= this.labels_
.length
;
5189 if (!attrs
.colors
) {
5190 var sat
= attrs
.colorSaturation
|| 1.0;
5191 var val
= attrs
.colorValue
|| 0.5;
5192 for (var i
= 1; i
<= num
; i
++) {
5193 var hue
= (1.0*i
/(1+num
));
5194 this.colors_
.push( MochiKit
.Color
.Color
.fromHSV(hue
, sat
, val
) );
5197 for (var i
= 0; i
< num
; i
++) {
5198 var colorStr
= attrs
.colors
[i
% attrs
.colors
.length
];
5199 this.colors_
.push( MochiKit
.Color
.Color
.fromString(colorStr
) );
5205 * Create the div that contains information on the selected point(s)
5206 * This goes in the top right of the canvas, unless an external div has already
5210 DateGraph
.prototype.createStatusMessage_
= function(){
5211 if (!this.labelsDiv_
) {
5213 var messagestyle
= { "style": {
5214 "position": "absolute",
5217 "width": divWidth
+ "px",
5219 "left": this.width_
- divWidth
+ "px",
5220 "background": "white",
5221 "textAlign": "left",
5222 "overflow": "hidden"}};
5223 this.labelsDiv_
= MochiKit
.DOM
.DIV(messagestyle
);
5224 MochiKit
.DOM
.appendChildNodes(this.graphDiv
, this.labelsDiv_
);
5229 * Create the text box to adjust the averaging period
5230 * @return {Object} The newly-created text box
5233 DateGraph
.prototype.createRollInterface_
= function() {
5234 var padding
= this.plotter_
.options
.padding
;
5235 var textAttr
= { "type": "text",
5237 "value": this.rollPeriod_
,
5238 "style": { "position": "absolute",
5240 "top": (this.height_
- 25 - padding
.bottom
) + "px",
5241 "left": (padding
.left
+1) + "px" }
5243 var roller
= MochiKit
.DOM
.INPUT(textAttr
);
5244 var pa
= this.graphDiv
;
5245 MochiKit
.DOM
.appendChildNodes(pa
, roller
);
5246 connect(roller
, 'onchange', this,
5247 function() { this.adjustRoll(roller
.value
); });
5252 * Set up all the mouse handlers needed to capture dragging behavior for zoom
5253 * events. Uses MochiKit.Signal to attach all the event handlers.
5256 DateGraph
.prototype.createDragInterface_
= function() {
5259 // Tracks whether the mouse is down right now
5260 var mouseDown
= false;
5261 var dragStartX
= null;
5262 var dragStartY
= null;
5263 var dragEndX
= null;
5264 var dragEndY
= null;
5265 var prevEndX
= null;
5267 // Utility function to convert page-wide coordinates to canvas coords
5268 var px
= PlotKit
.Base
.findPosX(this.canvas_
);
5269 var py
= PlotKit
.Base
.findPosY(this.canvas_
);
5270 var getX
= function(e
) { return e
.mouse().page
.x
- px
};
5271 var getY
= function(e
) { return e
.mouse().page
.y
- py
};
5273 // Draw zoom rectangles when the mouse is down and the user moves around
5274 connect(this.hidden_
, 'onmousemove', function(event
) {
5276 dragEndX
= getX(event
);
5277 dragEndY
= getY(event
);
5279 self
.drawZoomRect_(dragStartX
, dragEndX
, prevEndX
);
5280 prevEndX
= dragEndX
;
5284 // Track the beginning of drag events
5285 connect(this.hidden_
, 'onmousedown', function(event
) {
5287 dragStartX
= getX(event
);
5288 dragStartY
= getY(event
);
5291 // If the user releases the mouse button during a drag, but not over the
5292 // canvas, then it doesn't count as a zooming action.
5293 connect(document
, 'onmouseup', this, function(event
) {
5301 // Temporarily cancel the dragging event when the mouse leaves the graph
5302 connect(this.hidden_
, 'onmouseout', this, function(event
) {
5309 // If the mouse is released on the canvas during a drag event, then it's a
5310 // zoom. Only do the zoom if it's over a large enough area (>= 10 pixels)
5311 connect(this.hidden_
, 'onmouseup', this, function(event
) {
5314 dragEndX
= getX(event
);
5315 dragEndY
= getY(event
);
5316 var regionWidth
= Math
.abs(dragEndX
- dragStartX
);
5317 var regionHeight
= Math
.abs(dragEndY
- dragStartY
);
5319 if (regionWidth
< 2 && regionHeight
< 2 &&
5320 self
.clickCallback_
!= null &&
5321 self
.lastx_
!= undefined
) {
5322 self
.clickCallback_(event
, new Date(self
.lastx_
));
5325 if (regionWidth
>= 10) {
5326 self
.doZoom_(Math
.min(dragStartX
, dragEndX
),
5327 Math
.max(dragStartX
, dragEndX
));
5329 self
.canvas_
.getContext("2d").clearRect(0, 0,
5331 self
.canvas_
.height
);
5339 // Double-clicking zooms back out
5340 connect(this.hidden_
, 'ondblclick', this, function(event
) {
5341 self
.dateWindow_
= null;
5342 self
.drawGraph_(self
.rawData_
);
5343 var minDate
= self
.rawData_
[0][0];
5344 var maxDate
= self
.rawData_
[self
.rawData_
.length
- 1][0];
5345 self
.zoomCallback_(minDate
, maxDate
);
5350 * Draw a gray zoom rectangle over the desired area of the canvas. Also clears
5351 * up any previous zoom rectangles that were drawn. This could be optimized to
5352 * avoid extra redrawing, but it's tricky to avoid interactions with the status
5354 * @param {Number} startX The X position where the drag started, in canvas
5356 * @param {Number} endX The current X position of the drag, in canvas coords.
5357 * @param {Number} prevEndX The value of endX on the previous call to this
5358 * function. Used to avoid excess redrawing
5361 DateGraph
.prototype.drawZoomRect_
= function(startX
, endX
, prevEndX
) {
5362 var ctx
= this.canvas_
.getContext("2d");
5364 // Clean up from the previous rect if necessary
5366 ctx
.clearRect(Math
.min(startX
, prevEndX
), 0,
5367 Math
.abs(startX
- prevEndX
), this.height_
);
5370 // Draw a light-grey rectangle to show the new viewing area
5371 if (endX
&& startX
) {
5372 ctx
.fillStyle
= "rgba(128,128,128,0.33)";
5373 ctx
.fillRect(Math
.min(startX
, endX
), 0,
5374 Math
.abs(endX
- startX
), this.height_
);
5379 * Zoom to something containing [lowX, highX]. These are pixel coordinates
5380 * in the canvas. The exact zoom window may be slightly larger if there are no
5381 * data points near lowX or highX. This function redraws the graph.
5382 * @param {Number} lowX The leftmost pixel value that should be visible.
5383 * @param {Number} highX The rightmost pixel value that should be visible.
5386 DateGraph
.prototype.doZoom_
= function(lowX
, highX
) {
5387 // Find the earliest and latest dates contained in this canvasx range.
5388 var points
= this.layout_
.points
;
5391 // Find the nearest [minDate, maxDate] that contains [lowX, highX]
5392 for (var i
= 0; i
< points
.length
; i
++) {
5393 var cx
= points
[i
].canvasx
;
5394 var x
= points
[i
].xval
;
5395 if (cx
< lowX
&& (minDate
== null || x
> minDate
)) minDate
= x
;
5396 if (cx
> highX
&& (maxDate
== null || x
< maxDate
)) maxDate
= x
;
5398 // Use the extremes if either is missing
5399 if (minDate
== null) minDate
= points
[0].xval
;
5400 if (maxDate
== null) maxDate
= points
[points
.length
-1].xval
;
5402 this.dateWindow_
= [minDate
, maxDate
];
5403 this.drawGraph_(this.rawData_
);
5404 this.zoomCallback_(minDate
, maxDate
);
5408 * When the mouse moves in the canvas, display information about a nearby data
5409 * point and draw dots over those points in the data series. This function
5410 * takes care of cleanup of previously-drawn dots.
5411 * @param {Object} event The mousemove event from the browser.
5414 DateGraph
.prototype.mouseMove_
= function(event
) {
5415 var canvasx
= event
.mouse().page
.x
- PlotKit
.Base
.findPosX(this.hidden_
);
5416 var points
= this.layout_
.points
;
5421 // Loop through all the points and find the date nearest to our current
5423 var minDist
= 1e+100;
5425 for (var i
= 0; i
< points
.length
; i
++) {
5426 var dist
= Math
.abs(points
[i
].canvasx
- canvasx
);
5427 if (dist
> minDist
) break;
5431 if (idx
>= 0) lastx
= points
[idx
].xval
;
5432 // Check that you can really highlight the last day's data
5433 if (canvasx
> points
[points
.length
-1].canvasx
)
5434 lastx
= points
[points
.length
-1].xval
;
5436 // Extract the points we've selected
5438 for (var i
= 0; i
< points
.length
; i
++) {
5439 if (points
[i
].xval
== lastx
) {
5440 selPoints
.push(points
[i
]);
5444 // Clear the previously drawn vertical, if there is one
5446 var ctx
= this.canvas_
.getContext("2d");
5447 if (this.previousVerticalX_
>= 0) {
5448 var px
= this.previousVerticalX_
;
5449 ctx
.clearRect(px
- circleSize
- 1, 0, 2 * circleSize
+ 2, this.height_
);
5452 if (selPoints
.length
> 0) {
5453 var canvasx
= selPoints
[0].canvasx
;
5455 // Set the status message to indicate the selected point(s)
5456 var replace
= this.xValueFormatter_(lastx
) + ":";
5457 var clen
= this.colors_
.length
;
5458 for (var i
= 0; i
< selPoints
.length
; i
++) {
5459 if (this.labelsSeparateLines
) {
5462 var point
= selPoints
[i
];
5463 replace
+= " <b><font color='" + this.colors_
[i
%clen
].toHexString() + "'>"
5464 + point
.name
+ "</font></b>:"
5465 + this.round_(point
.yval
, 2);
5467 this.labelsDiv_
.innerHTML
= replace
;
5469 // Save last x position for callbacks.
5470 this.lastx_
= lastx
;
5472 // Draw colored circles over the center of each selected point
5474 for (var i
= 0; i
< selPoints
.length
; i
++) {
5476 ctx
.fillStyle
= this.colors_
[i
%clen
].toRGBString();
5477 ctx
.arc(canvasx
, selPoints
[i
%clen
].canvasy
, circleSize
, 0, 360, false);
5482 this.previousVerticalX_
= canvasx
;
5487 * The mouse has left the canvas. Clear out whatever artifacts remain
5488 * @param {Object} event the mouseout event from the browser.
5491 DateGraph
.prototype.mouseOut_
= function(event
) {
5492 // Get rid of the overlay data
5493 var ctx
= this.canvas_
.getContext("2d");
5494 ctx
.clearRect(0, 0, this.width_
, this.height_
);
5495 this.labelsDiv_
.innerHTML
= "";
5499 * Convert a JS date (millis since epoch) to YYYY/MM/DD
5500 * @param {Number} date The JavaScript date (ms since epoch)
5501 * @return {String} A date of the form "YYYY/MM/DD"
5504 DateGraph
.prototype.dateString_
= function(date
) {
5505 var d
= new Date(date
);
5508 var year
= "" + d
.getFullYear();
5509 // Get a 0 padded month string
5510 var month
= "" + (d
.getMonth() + 1); //months are 0-offset, sigh
5511 if (month
.length
< 2) month
= "0" + month
;
5512 // Get a 0 padded day string
5513 var day
= "" + d
.getDate();
5514 if (day
.length
< 2) day
= "0" + day
;
5516 return year
+ "/" + month + "/" + day
;
5520 * Round a number to the specified number of digits past the decimal point.
5521 * @param {Number} num The number to round
5522 * @param {Number} places The number of decimals to which to round
5523 * @return {Number} The rounded number
5526 DateGraph
.prototype.round_
= function(num
, places
) {
5527 var shift
= Math
.pow(10, places
);
5528 return Math
.round(num
* shift
)/shift
;
5532 * Fires when there's data available to be graphed.
5533 * @param {String} data Raw CSV data to be plotted
5536 DateGraph
.prototype.loadedEvent_
= function(data
) {
5537 this.rawData_
= this.parseCSV_(data
);
5538 this.drawGraph_(this.rawData_
);
5541 DateGraph
.prototype.months
= ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
5542 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
5543 DateGraph
.prototype.quarters
= ["Jan", "Apr", "Jul", "Oct"];
5546 * Add ticks on the x-axis representing years, months, quarters, weeks, or days
5549 DateGraph
.prototype.addXTicks_
= function() {
5550 // Determine the correct ticks scale on the x-axis: quarterly, monthly, ...
5551 var startDate
, endDate
;
5552 if (this.dateWindow_
) {
5553 startDate
= this.dateWindow_
[0];
5554 endDate
= this.dateWindow_
[1];
5556 startDate
= this.rawData_
[0][0];
5557 endDate
= this.rawData_
[this.rawData_
.length
- 1][0];
5560 var xTicks
= this.xTicker_(startDate
, endDate
);
5561 this.layout_
.updateOptions({xTicks
: xTicks
});
5565 * Add ticks to the x-axis based on a date range.
5566 * @param {Number} startDate Start of the date window (millis since epoch)
5567 * @param {Number} endDate End of the date window (millis since epoch)
5568 * @return {Array.<Object>} Array of {label, value} tuples.
5571 DateGraph
.prototype.dateTicker
= function(startDate
, endDate
) {
5572 var ONE_DAY
= 24*60*60*1000;
5573 startDate
= startDate
/ ONE_DAY
;
5574 endDate
= endDate
/ ONE_DAY
;
5575 var dateSpan
= endDate
- startDate
;
5578 var isMonthly
= false;
5580 if (dateSpan
> 30 * 366) { // decadal
5584 } else if (dateSpan
> 4*366) { // annual
5587 } else if (dateSpan
> 366) { // quarterly
5588 scale
= this.quarters
;
5590 } else if (dateSpan
> 40) { // monthly
5591 scale
= this.months
;
5593 } else if (dateSpan
> 10) { // weekly
5594 for (var week
= startDate
- 14; week
< endDate
+ 14; week
+= 7) {
5595 scale
.push(week
* ONE_DAY
);
5598 for (var day
= startDate
- 14; day
< endDate
+ 14; day
+= 1) {
5599 scale
.push(day
* ONE_DAY
);
5606 var startYear
= 1900 + (new Date(startDate
* ONE_DAY
)).getYear();
5607 var endYear
= 1900 + (new Date(endDate
* ONE_DAY
)).getYear();
5608 for (var i
= startYear
; i
<= endYear
; i
++) {
5609 if (i
% yearMod
!= 0) continue;
5610 for (var j
= 0; j
< scale
.length
; j
++ ) {
5611 var date
= Date
.parse(scale
[j
] + " 1, " + i
);
5612 xTicks
.push( {label
: scale
[j
] + "'" + ("" + i
).substr(2,2), v
: date
} );
5616 for (var i
= 0; i
< scale
.length
; i
++) {
5617 var date
= new Date(scale
[i
]);
5618 var year
= date
.getFullYear().toString();
5619 var label
= this.months
[date
.getMonth()] + date
.getDate();
5620 label
+= "'" + year
.substr(year
.length
- 2, 2);
5621 xTicks
.push( {label
: label
, v
: date
} );
5628 * Add ticks when the x axis has numbers on it (instead of dates)
5629 * @param {Number} startDate Start of the date window (millis since epoch)
5630 * @param {Number} endDate End of the date window (millis since epoch)
5631 * @return {Array.<Object>} Array of {label, value} tuples.
5634 DateGraph
.prototype.numericTicks
= function(minV
, maxV
) {
5639 scale
= Math
.pow( 10, Math
.floor(Math
.log(maxV
)/Math
.log(10.0)) );
5642 // Add a smallish number of ticks at human-friendly points
5643 var nTicks
= (maxV
- minV
) / scale
;
5644 while (2 * nTicks
< 20) {
5647 if ((maxV
- minV
) / nTicks
< this.minTickSize_
) {
5648 nTicks
= this.round_((maxV
- minV
) / this.minTickSize_
, 1);
5651 // Construct labels for the ticks
5653 for (var i
= 0; i
<= nTicks
; i
++) {
5654 var tickV
= minV
+ i
* (maxV
- minV
) / nTicks
;
5655 var label
= this.round_(tickV
, 2);
5656 if (this.labelsKMB_
) {
5658 if (tickV
>= k
*k
*k
) {
5659 label
= this.round_(tickV
/(k
*k
*k
), 1) + "B";
5660 } else if (tickV
>= k
*k
) {
5661 label
= this.round_(tickV
/(k
*k
), 1) + "M";
5662 } else if (tickV
>= k
) {
5663 label
= this.round_(tickV
/k
, 1) + "K";
5666 ticks
.push( {label
: label
, v
: tickV
} );
5672 * Adds appropriate ticks on the y-axis
5673 * @param {Number} minY The minimum Y value in the data set
5674 * @param {Number} maxY The maximum Y value in the data set
5677 DateGraph
.prototype.addYTicks_
= function(minY
, maxY
) {
5678 // Set the number of ticks so that the labels are human-friendly.
5679 var ticks
= this.numericTicks(minY
, maxY
);
5680 this.layout_
.updateOptions( { yAxis
: [minY
, maxY
],
5685 * Update the graph with new data. Data is in the format
5686 * [ [date1, val1, val2, ...], [date2, val1, val2, ...] if errorBars=false
5687 * or, if errorBars=true,
5688 * [ [date1, [val1,stddev1], [val2,stddev2], ...], [date2, ...], ...]
5689 * @param {Array.<Object>} data The data (see above)
5692 DateGraph
.prototype.drawGraph_
= function(data
) {
5694 this.layout_
.removeAllDatasets();
5695 // Loop over all fields in the dataset
5696 for (var i
= 1; i
< data
[0].length
; i
++) {
5698 for (var j
= 0; j
< data
.length
; j
++) {
5699 var date
= data
[j
][0];
5700 series
[j
] = [date
, data
[j
][i
]];
5702 series
= this.rollingAverage(series
, this.rollPeriod_
);
5704 // Prune down to the desired range, if necessary (for zooming)
5705 var bars
= this.errorBars_
|| this.customBars_
;
5706 if (this.dateWindow_
) {
5707 var low
= this.dateWindow_
[0];
5708 var high
= this.dateWindow_
[1];
5710 for (var k
= 0; k
< series
.length
; k
++) {
5711 if (series
[k
][0] >= low
&& series
[k
][0] <= high
) {
5712 pruned
.push(series
[k
]);
5713 var y
= bars
? series
[k
][1][0] : series
[k
][1];
5714 if (maxY
== null || y
> maxY
) maxY
= y
;
5719 for (var j
= 0; j
< series
.length
; j
++) {
5720 var y
= bars
? series
[j
][1][0] : series
[j
][1];
5721 if (maxY
== null || y
> maxY
) {
5722 maxY
= bars
? y
+ series
[j
][1][1] : y
;
5729 for (var j
=0; j
<series
.length
; j
++)
5730 vals
[j
] = [series
[j
][0],
5731 series
[j
][1][0], series
[j
][1][1], series
[j
][1][2]];
5732 this.layout_
.addDataset(this.labels_
[i
- 1], vals
);
5734 this.layout_
.addDataset(this.labels_
[i
- 1], series
);
5738 // Use some heuristics to come up with a good maxY value, unless it's been
5739 // set explicitly by the user.
5740 if (this.valueRange_
!= null) {
5741 this.addYTicks_(this.valueRange_
[0], this.valueRange_
[1]);
5743 // Add some padding and round up to an integer to be human-friendly.
5745 if (maxY
<= 0.0) maxY
= 1.0;
5747 var scale
= Math
.pow(10, Math
.floor(Math
.log(maxY
) / Math
.log(10.0)));
5748 maxY
= scale
* Math
.ceil(maxY
/ scale
);
5750 this.addYTicks_(0, maxY
);
5755 // Tell PlotKit to use this new data and render itself
5756 this.layout_
.evaluateWithError();
5757 this.plotter_
.clear();
5758 this.plotter_
.render();
5759 this.canvas_
.getContext('2d').clearRect(0, 0,
5760 this.canvas_
.width
, this.canvas_
.height
);
5764 * Calculates the rolling average of a data set.
5765 * If originalData is [label, val], rolls the average of those.
5766 * If originalData is [label, [, it's interpreted as [value, stddev]
5767 * and the roll is returned in the same form, with appropriately reduced
5768 * stddev for each value.
5769 * Note that this is where fractional input (i.e. '5/10') is converted into
5771 * @param {Array} originalData The data in the appropriate format (see above)
5772 * @param {Number} rollPeriod The number of days over which to average the data
5774 DateGraph
.prototype.rollingAverage
= function(originalData
, rollPeriod
) {
5775 if (originalData
.length
< 2)
5776 return originalData
;
5777 var rollPeriod
= Math
.min(rollPeriod
, originalData
.length
- 1);
5778 var rollingData
= [];
5779 var sigma
= this.sigma_
;
5781 if (this.fractions_
) {
5783 var den
= 0; // numerator/denominator
5785 for (var i
= 0; i
< originalData
.length
; i
++) {
5786 num
+= originalData
[i
][1][0];
5787 den
+= originalData
[i
][1][1];
5788 if (i
- rollPeriod
>= 0) {
5789 num
-= originalData
[i
- rollPeriod
][1][0];
5790 den
-= originalData
[i
- rollPeriod
][1][1];
5793 var date
= originalData
[i
][0];
5794 var value
= den
? num
/ den
: 0.0;
5795 if (this.errorBars_
) {
5796 if (this.wilsonInterval_
) {
5797 // For more details on this confidence interval, see:
5798 // http://en.wikipedia.org/wiki
/Binomial_confidence_interval
5800 var p
= value
< 0 ? 0 : value
, n
= den
;
5801 var pm
= sigma
* Math
.sqrt(p
*(1-p
)/n + sigma*sigma/(4*n
*n
));
5802 var denom
= 1 + sigma
* sigma
/ den
;
5803 var low
= (p
+ sigma
* sigma
/ (2 * den) - pm) / denom
;
5804 var high
= (p
+ sigma
* sigma
/ (2 * den) + pm) / denom
;
5805 rollingData
[i
] = [date
,
5806 [p
* mult
, (p
- low
) * mult
, (high
- p
) * mult
]];
5808 rollingData
[i
] = [date
, [0, 0, 0]];
5811 var stddev
= den
? sigma
* Math
.sqrt(value
* (1 - value
) / den
) : 1.0;
5812 rollingData
[i
] = [date
, [mult
* value
, mult
* stddev
, mult
* stddev
]];
5815 rollingData
[i
] = [date
, mult
* value
];
5818 } else if (this.customBars_
) {
5819 // just ignore the rolling for now.
5820 // TODO(danvk): do something reasonable.
5821 for (var i
= 0; i
< originalData
.length
; i
++) {
5822 var data
= originalData
[i
][1];
5824 rollingData
[i
] = [originalData
[i
][0], [y
, y
- data
[0], data
[2] - y
]];
5827 // Calculate the rolling average for the first rollPeriod - 1 points where
5828 // there is not enough data to roll over the full number of days
5829 var num_init_points
= Math
.min(rollPeriod
- 1, originalData
.length
- 2);
5830 if (!this.errorBars_
){
5831 for (var i
= 0; i
< num_init_points
; i
++) {
5833 for (var j
= 0; j
< i
+ 1; j
++)
5834 sum
+= originalData
[j
][1];
5835 rollingData
[i
] = [originalData
[i
][0], sum
/ (i
+ 1)];
5837 // Calculate the rolling average for the remaining points
5838 for (var i
= Math
.min(rollPeriod
- 1, originalData
.length
- 2);
5839 i
< originalData
.length
;
5842 for (var j
= i
- rollPeriod
+ 1; j
< i
+ 1; j
++)
5843 sum
+= originalData
[j
][1];
5844 rollingData
[i
] = [originalData
[i
][0], sum
/ rollPeriod
];
5847 for (var i
= 0; i
< num_init_points
; i
++) {
5850 for (var j
= 0; j
< i
+ 1; j
++) {
5851 sum
+= originalData
[j
][1][0];
5852 variance
+= Math
.pow(originalData
[j
][1][1], 2);
5854 var stddev
= Math
.sqrt(variance
)/(i
+1);
5855 rollingData
[i
] = [originalData
[i
][0],
5856 [sum
/(i
+1), sigma
* stddev
, sigma
* stddev
]];
5858 // Calculate the rolling average for the remaining points
5859 for (var i
= Math
.min(rollPeriod
- 1, originalData
.length
- 2);
5860 i
< originalData
.length
;
5864 for (var j
= i
- rollPeriod
+ 1; j
< i
+ 1; j
++) {
5865 sum
+= originalData
[j
][1][0];
5866 variance
+= Math
.pow(originalData
[j
][1][1], 2);
5868 var stddev
= Math
.sqrt(variance
) / rollPeriod
;
5869 rollingData
[i
] = [originalData
[i
][0],
5870 [sum
/ rollPeriod
, sigma
* stddev
, sigma
* stddev
]];
5879 * Parses a date, returning the number of milliseconds since epoch. This can be
5880 * passed in as an xValueParser in the DateGraph constructor.
5881 * @param {String} A date in YYYYMMDD format.
5882 * @return {Number} Milliseconds since epoch.
5885 DateGraph
.prototype.dateParser
= function(dateStr
) {
5887 if (dateStr
.search("-") != -1) {
5888 dateStrSlashed
= dateStr
.replace("-", "/", "g");
5889 } else if (dateStr
.search("/") != -1) {
5890 return Date
.parse(dateStr
);
5892 dateStrSlashed
= dateStr
.substr(0,4) + "/" + dateStr
.substr(4,2)
5893 + "/" + dateStr
.substr(6,2);
5895 return Date
.parse(dateStrSlashed
);
5899 * Parses a string in a special csv format. We expect a csv file where each
5900 * line is a date point, and the first field in each line is the date string.
5901 * We also expect that all remaining fields represent series.
5902 * if this.errorBars_ is set, then interpret the fields as:
5903 * date, series1, stddev1, series2, stddev2, ...
5904 * @param {Array.<Object>} data See above.
5907 DateGraph
.prototype.parseCSV_
= function(data
) {
5909 var lines
= data
.split("\n");
5910 var start
= this.labelsFromCSV_
? 1 : 0;
5911 if (this.labelsFromCSV_
) {
5912 var labels
= lines
[0].split(",");
5913 labels
.shift(); // a "date" parameter is assumed.
5914 this.labels_
= labels
;
5915 // regenerate automatic colors.
5916 this.setColors_(this.attrs_
);
5917 this.renderOptions_
.colorScheme
= this.colors_
;
5918 MochiKit
.Base
.update(this.plotter_
.options
, this.renderOptions_
);
5919 MochiKit
.Base
.update(this.layoutOptions_
, this.attrs_
);
5922 for (var i
= start
; i
< lines
.length
; i
++) {
5923 var line
= lines
[i
];
5924 if (line
.length
== 0) continue; // skip blank lines
5925 var inFields
= line
.split(',');
5926 if (inFields
.length
< 2)
5930 fields
[0] = this.xValueParser_(inFields
[0]);
5932 // If fractions are expected, parse the numbers as "A/B
"
5933 if (this.fractions_) {
5934 for (var j = 1; j < inFields.length; j++) {
5935 // TODO(danvk): figure out an appropriate way to flag parse errors.
5936 var vals = inFields[j].split("/");
5937 fields[j] = [parseFloat(vals[0]), parseFloat(vals[1])];
5939 } else if (this.errorBars_) {
5940 // If there are error bars, values are (value, stddev) pairs
5941 for (var j = 1; j < inFields.length; j += 2)
5942 fields[(j + 1) / 2] = [parseFloat(inFields[j]),
5943 parseFloat(inFields[j + 1])];
5944 } else if (this.customBars_) {
5945 // Bars are a low;center;high tuple
5946 for (var j = 1; j < inFields.length; j++) {
5947 var vals = inFields[j].split(";");
5948 fields[j] = [ parseFloat(vals[0]),
5949 parseFloat(vals[1]),
5950 parseFloat(vals[2]) ];
5953 // Values are just numbers
5954 for (var j = 1; j < inFields.length; j++)
5955 fields[j] = parseFloat(inFields[j]);
5963 * Get the CSV data. If it's in a function, call that function. If it's in a
5964 * file, do an XMLHttpRequest to get it.
5967 DateGraph.prototype.start_ = function() {
5968 if (typeof this.file_ == 'function') {
5969 // Stubbed out to allow this to run off a filesystem
5970 this.loadedEvent_(this.file_());
5972 var req = new XMLHttpRequest();
5974 req.onreadystatechange = function () {
5975 if (req.readyState == 4) {
5976 if (req.status == 200) {
5977 caller.loadedEvent_(req.responseText);
5982 req.open("GET
", this.file_, true);
5988 * Changes various properties of the graph. These can include:
5990 * <li>file: changes the source data for the graph</li>
5991 * <li>errorBars: changes whether the data contains stddev</li>
5993 * @param {Object} attrs The new properties and values
5995 DateGraph.prototype.updateOptions = function(attrs) {
5996 if (attrs.errorBars) {
5997 this.errorBars_ = attrs.errorBars;
5999 if (attrs.customBars) {
6000 this.customBars_ = attrs.customBars;
6002 if (attrs.strokeWidth) {
6003 this.strokeWidth_ = attrs.strokeWidth;
6005 if (attrs.rollPeriod) {
6006 this.rollPeriod_ = attrs.rollPeriod;
6008 if (attrs.dateWindow) {
6009 this.dateWindow_ = attrs.dateWindow;
6011 if (attrs.valueRange) {
6012 this.valueRange_ = attrs.valueRange;
6014 if (attrs.minTickSize) {
6015 this.minTickSize_ = attrs.minTickSize;
6017 if (typeof(attrs.labels) != 'undefined') {
6018 this.labels_ = attrs.labels;
6019 this.labelsFromCSV_ = (attrs.labels == null);
6021 this.layout_.updateOptions({ 'errorBars': this.errorBars_ });
6022 if (attrs['file'] && attrs['file'] != this.file_) {
6023 this.file_ = attrs['file'];
6026 this.drawGraph_(this.rawData_);
6031 * Adjusts the number of days in the rolling average. Updates the graph to
6032 * reflect the new averaging period.
6033 * @param {Number} length Number of days over which to average the data.
6035 DateGraph.prototype.adjustRoll = function(length) {
6036 this.rollPeriod_ = length;
6037 this.drawGraph_(this.rawData_);