ichart-1.0.js 187 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482
  1. /**
  2. * ichartjs Library v1.0 http://www.ichartjs.com/
  3. *
  4. * @author wanghe
  5. * @Copyright 2013 wanghetommy@gmail.com Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  8. */
  9. ;
  10. (function(window) {
  11. var ua = navigator.userAgent.toLowerCase(), mc = function(e) {
  12. return e.test(ua)
  13. }, ts = Object.prototype.toString, isOpera = mc(/opera/), isChrome = mc(/\bchrome\b/), isWebKit = mc(/webkit/), isSafari = !isChrome && mc(/safari/), isIE = !isOpera && mc(/msie/), supportCanvas = !!document.createElement('canvas').getContext, isGecko = !isWebKit
  14. && mc(/gecko/), isMobile = mc(/ipod|ipad|iphone|android/gi), arithmetic = {
  15. Linear : function(t, b, c, d) {
  16. return c * t / d + b;
  17. },
  18. Cubic : {
  19. easeIn : function(t, b, c, d) {
  20. return c * (t /= d) * t * t + b;
  21. },
  22. easeOut : function(t, b, c, d) {
  23. return c * ((t = t / d - 1) * t * t + 1) + b;
  24. },
  25. easeInOut : function(t, b, c, d) {
  26. if ((t /= d / 2) < 1)
  27. return c / 2 * t * t * t + b;
  28. return c / 2 * ((t -= 2) * t * t + 2) + b;
  29. }
  30. }
  31. };
  32. var iChart_ = (function(window) {
  33. /**
  34. * spirit from jquery
  35. */
  36. var isReady = false, readyBound = false, readyList = [], DOMContentLoaded = (function() {
  37. if (document.addEventListener) {
  38. return function() {
  39. document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false);
  40. ready();
  41. };
  42. } else if (document.attachEvent) {
  43. return function() {
  44. if (document.readyState === "complete") {
  45. document.detachEvent("onreadystatechange", DOMContentLoaded);
  46. ready();
  47. }
  48. };
  49. }
  50. })(), doScrollCheck = function() {
  51. if (isReady) {
  52. return;
  53. }
  54. try {
  55. document.documentElement.doScroll("left");
  56. } catch (e) {
  57. setTimeout(doScrollCheck, 1);
  58. return;
  59. }
  60. ready();
  61. }, ready = function() {
  62. if (!isReady) {
  63. isReady = true;
  64. for ( var i = 0; i < readyList.length; i++) {
  65. readyList[i].call(document);
  66. }
  67. readyList = [];
  68. }
  69. }, bindReady = function() {
  70. if (readyBound)
  71. return;
  72. readyBound = true;
  73. if (document.readyState === "complete") {
  74. return setTimeout(ready, 1);
  75. }
  76. if (document.addEventListener) {
  77. document.addEventListener("DOMContentLoaded", DOMContentLoaded, false);
  78. window.addEventListener("load", ready, false);
  79. } else if (document.attachEvent) {
  80. document.attachEvent("onreadystatechange", DOMContentLoaded);
  81. window.attachEvent("onload", ready);
  82. var toplevel = false;
  83. try {
  84. toplevel = window.frameElement == null;
  85. } catch (e) {
  86. }
  87. if (document.documentElement.doScroll && toplevel) {
  88. doScrollCheck();
  89. }
  90. }
  91. }, bind = function(fn) {
  92. bindReady();
  93. if (isReady)
  94. fn.call(document, _);
  95. else
  96. readyList.push(function() {
  97. return fn.call(this);
  98. });
  99. }, _ = function(selector) {
  100. if (!selector || selector.nodeType) {
  101. return selector;
  102. }
  103. if (typeof selector === "string") {
  104. if (selector.indexOf("#") != -1) {
  105. selector = selector.substring(1);
  106. }
  107. return document.getElementById(selector);
  108. }
  109. if (typeof selector === "function") {
  110. bind(selector);
  111. }
  112. };
  113. _.apply = function(d, e) {
  114. if (d && e && typeof e == "object") {
  115. for ( var a in e) {
  116. if (typeof e[a] != 'undefined')
  117. d[a] = e[a]
  118. }
  119. }
  120. if (!e && d) {
  121. var clone = {};
  122. for ( var a in d) {
  123. clone[a] = d[a]
  124. }
  125. return clone;
  126. }
  127. return d
  128. };
  129. _.apply(_, {
  130. version : "1.0",
  131. email : 'taylor@ichartjs.com',
  132. isEmpty : function(C, e) {
  133. return C === null || C === undefined || ((_.isArray(C) && !C.length)) || (!e ? C === "" : false)
  134. },
  135. isArray : function(e) {
  136. return ts.apply(e) === "[object Array]"
  137. },
  138. isDate : function(e) {
  139. return ts.apply(e) === "[object Date]"
  140. },
  141. isObject : function(e) {
  142. return !!e && ts.apply(e) === "[object Object]"
  143. },
  144. isFunction : function(e) {
  145. return ts.apply(e) === "[object Function]"
  146. },
  147. isNumber : function(e) {
  148. return typeof e === "number" && isFinite(e)
  149. },
  150. isString : function(e) {
  151. return typeof e === "string"
  152. },
  153. isBoolean : function(e) {
  154. return typeof e === "boolean"
  155. },
  156. isFalse : function(e) {
  157. return typeof e === "boolean" && !e;
  158. },
  159. isElement : function(e) {
  160. return e ? !!e.tagName : false
  161. },
  162. isDefined : function(e) {
  163. return typeof e !== "undefined"
  164. }
  165. });
  166. /**
  167. * only get the attr that target not exist
  168. */
  169. _.applyIf = function(d, e) {
  170. if (d && _.isObject(e)) {
  171. for ( var a in e) {
  172. if (_.isDefined(e[a]) && !_.isDefined(d[a]))
  173. d[a] = e[a]
  174. }
  175. }
  176. if (!e && d) {
  177. return _.apply(d);
  178. }
  179. return d
  180. };
  181. /**
  182. * there will apply a deep clone
  183. */
  184. _.merge = function(d, e, f) {
  185. if (d && _.isObject(e)) {
  186. for ( var a in e) {
  187. if (_.isDefined(e[a])) {
  188. if (_.isObject(e[a])) {
  189. if (_.isObject(d[a])) {
  190. _.merge(d[a], e[a]);
  191. } else {
  192. d[a] = _.clone(e[a], true);
  193. }
  194. } else {
  195. d[a] = e[a];
  196. }
  197. }
  198. }
  199. if (_.isObject(f)) {
  200. return _.merge(d, f);
  201. }
  202. }
  203. return d;
  204. };
  205. /**
  206. * clone attribute that given
  207. */
  208. _.clone = function(a, e, deep) {
  209. var d = {};
  210. if (_.isArray(a)&& _.isObject(e)) {
  211. for ( var i = 0; i < a.length; i++) {
  212. if (deep && _.isObject(e[a[i]]))
  213. d[a[i]] = _.clone(e[a[i]],deep);
  214. else
  215. d[a[i]] = e[a[i]];
  216. }
  217. } else if (_.isObject(a)) {
  218. for ( var b in a) {
  219. // avoid recursion reference
  220. if (e && _.isObject(a[b])&& !(a[b] instanceof _.Painter))
  221. d[b] = _.clone(a[b], e);
  222. else
  223. d[b] = a[b];
  224. }
  225. }
  226. return d;
  227. };
  228. _.override = function(e, D) {
  229. if (e&&D) {
  230. var C = e.prototype;
  231. _.apply(C, D);
  232. if (_.isIE && D.hasOwnProperty("toString")) {
  233. C.toString = D.toString
  234. }
  235. }
  236. };
  237. /**
  238. * spirit from ext2.0
  239. */
  240. _.extend = function() {
  241. var C = function(E) {
  242. for ( var D in E) {
  243. this[D] = E[D];
  244. }
  245. };
  246. var e = Object.prototype.constructor;
  247. return function(G, O) {
  248. var J = function() {
  249. G.apply(this, arguments);
  250. }
  251. var E = function() {
  252. }, H, D = G.prototype;
  253. E.prototype = D;
  254. H = J.prototype = new E();
  255. H.constructor = J;
  256. J.superclass = D;
  257. if (D.constructor == e) {
  258. D.constructor = G;
  259. }
  260. J.override = function(F) {
  261. _.override(J, F);
  262. };
  263. H.superclass = H.supr = (function() {
  264. return D;
  265. });
  266. H.override = C;
  267. _.override(J, O);
  268. J.extend = function(F) {
  269. return _.extend(J, F)
  270. };
  271. J.plugin_ = {};
  272. J.plugin = function(M,F) {
  273. if (_.isString(M) && _.isFunction(F))
  274. J.plugin_[M] = F;
  275. };
  276. return J;
  277. }
  278. }();
  279. // *******************Math************************
  280. var sin = Math.sin, cos = Math.cos, atan = Math.atan, tan = Math.tan, acos = Math.acos, sqrt = Math.sqrt, abs = Math.abs, pi = Math.PI, pi2 = 2 * pi, ceil = Math.ceil, round = Math.round, floor = Math.floor, max = Math.max, min = Math.min, pF = parseFloat,
  281. factor = function(v, w) {
  282. if (v == 0)
  283. return v;
  284. var M = abs(v),f = 0.1;
  285. if(M>1){
  286. while(M>1){
  287. M = M/10;
  288. f = f*10;
  289. }
  290. return floor(v/f+w)*f;
  291. }else{
  292. f = 1;
  293. while(M<1){
  294. M = M*10;
  295. f = f/10;
  296. }
  297. return round(v/f+w)*f;
  298. }
  299. }, colors = {
  300. navy : 'rgb(0,0,128)',
  301. olive : 'rgb(128,128,0)',
  302. orange : 'rgb(255,165,0)',
  303. silver : 'rgb(192,192,192)',
  304. white : 'rgb(255,255,255)',
  305. gold : 'rgb(255,215,0)',
  306. lime : 'rgb(0,255,0)',
  307. fuchsia : 'rgb(255,0,255)',
  308. aqua : 'rgb(0,255,255)',
  309. green : 'rgb(0,128,0)',
  310. gray : 'rgb(80,80,80)',
  311. red : 'rgb(255,0,0)',
  312. blue : 'rgb(0,0,255)',
  313. pink : 'rgb(255,192,203)',
  314. purple : 'rgb(128,0,128)',
  315. yellow : 'rgb(255,255,0)',
  316. maroon : 'rgb(128,0,0)',
  317. black : 'rgb(0,0,0)',
  318. azure : 'rgb(240,255,255)',
  319. beige : 'rgb(245,245,220)',
  320. brown : 'rgb(165,42,42)',
  321. cyan : 'rgb(0,255,255)',
  322. darkblue : 'rgb(0,0,139)',
  323. darkcyan : 'rgb(0,139,139)',
  324. darkgrey : 'rgb(169,169,169)',
  325. darkgreen : 'rgb(0,100,0)',
  326. darkkhaki : 'rgb(189,183,107)',
  327. darkmagenta : 'rgb(139,0,139)',
  328. darkolivegreen : 'rgb(85,107,47)',
  329. darkorange : 'rgb(255,140,0)',
  330. darkorchid : 'rgb(153,50,204)',
  331. darkred : 'rgb(139,0,0)',
  332. darksalmon : 'rgb(233,150,122)',
  333. darkviolet : 'rgb(148,0,211)',
  334. indigo : 'rgb(75,0,130)',
  335. khaki : 'rgb(240,230,140)',
  336. lightblue : 'rgb(173,216,230)',
  337. lightcyan : 'rgb(224,255,255)',
  338. lightgreen : 'rgb(144,238,144)',
  339. lightgrey : 'rgb(211,211,211)',
  340. lightpink : 'rgb(255,182,193)',
  341. lightyellow : 'rgb(255,255,224)',
  342. magenta : 'rgb(255,0,255)',
  343. violet : 'rgb(128,0,128)'
  344. }, hex2Rgb = function(hex) {
  345. hex = hex.replace(/#/g, "").replace(/^(\w)(\w)(\w)$/, "$1$1$2$2$3$3");
  346. return (hex.length==7?'rgba(':'rgb(') + parseInt(hex.substring(0, 2), 16) + ',' + parseInt(hex.substring(2, 4), 16) + ',' + parseInt(hex.substring(4, 6), 16) + (hex.length==7?',0.'+hex.substring(6,7)+')':')');
  347. }, i2hex = function(N) {
  348. return ('0' + parseInt(N).toString(16)).slice(-2);
  349. }, rgb2Hex = function(rgb) {
  350. var m = rgb.match(/rgb\((\d+),(\d+),(\d+)\)/);
  351. return m ? ('#' + i2hex(m[1]) + i2hex(m[2]) + i2hex(m[3])).toUpperCase() : null;
  352. }, c2a = function(rgb) {
  353. var result = /rgb\((\w*),(\w*),(\w*)\)/.exec(rgb);
  354. if (result) {
  355. return new Array(result[1], result[2], result[3]);
  356. }
  357. result = /rgba\((\w*),(\w*),(\w*),(.*)\)/.exec(rgb);
  358. if (result) {
  359. return new Array(result[1], result[2], result[3], result[4]);
  360. }
  361. throw new Error("invalid colors value '" + rgb + "'");
  362. }, toHsv = function(r, g, b) {
  363. if (_.isArray(r)) {
  364. g = r[1];
  365. b = r[2];
  366. r = r[0];
  367. }
  368. r = r / 255;
  369. g = g / 255;
  370. b = b / 255;
  371. var m = max(max(r, g), b), mi = min(min(r, g), b), dv = m - mi;
  372. if (dv == 0) {
  373. return new Array(0, 0, m);
  374. }
  375. var h;
  376. if (r == m) {
  377. h = (g - b) / dv;
  378. } else if (g == m) {
  379. h = (b - r) / dv + 2;
  380. } else if (b == m) {
  381. h = (r - g) / dv + 4;
  382. }
  383. h *= 60;
  384. if (h < 0)
  385. h += 360;
  386. return new Array(h, dv / m, m);
  387. }, toRgb = function(color) {
  388. if (!color)
  389. return color;
  390. color = color.replace(/\s/g, '').toLowerCase();
  391. // Look for rgb(255,255,255)
  392. if (/^rgb\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3}\)$/.exec(color)) {
  393. return color;
  394. }
  395. // Look for rgba(255,255,255,0.3)
  396. if (/^rgba\([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},(0(\.[0-9])?|1(\.0)?)\)$/.exec(color)) {
  397. return color;
  398. }
  399. // Look for #a0b1c2 or #fff
  400. if (/^#(([a-fA-F0-9]{6,7})|([a-fA-F0-9]{3}))$/.exec(color))
  401. return hex2Rgb(color);
  402. // Look a string for green
  403. if (colors[color])
  404. return colors[color];
  405. throw new Error("invalid colors value '" + color + "'");
  406. }, hsv2Rgb = function(h, s, v, a) {
  407. if (_.isArray(h)) {
  408. a = s;
  409. s = h[1];
  410. v = h[2];
  411. h = h[0];
  412. }
  413. var r, g, b,
  414. hi = floor(h / 60) % 6,
  415. f = h / 60 - hi,
  416. p = v * (1 - s),
  417. q = v * (1 - s * f),
  418. t = v * (1 - s * (1 - f));
  419. switch (hi) {
  420. case 0 :
  421. r = v;
  422. g = t;
  423. b = p;
  424. break;
  425. case 1 :
  426. r = q;
  427. g = v;
  428. b = p;
  429. break;
  430. case 2 :
  431. r = p;
  432. g = v;
  433. b = t;
  434. break;
  435. case 3 :
  436. r = p;
  437. g = q;
  438. b = v;
  439. break;
  440. case 4 :
  441. r = t;
  442. g = p;
  443. b = v;
  444. break;
  445. case 5 :
  446. r = v;
  447. g = p;
  448. b = q;
  449. break;
  450. }
  451. return 'rgb' + (a ? 'a' : '') + '(' + round(r * 255) + ',' + round(g * 255) + ',' + round(b * 255) + (a ? ',' + a + ')' : ')');
  452. },
  453. /**
  454. * the increment of s(v) of hsv model
  455. */
  456. s_inc = 0.05, v_inc = 0.14,
  457. inc = function(v, iv) {
  458. iv = iv || v_inc;
  459. if (v > 0.5) {
  460. return iv - (1 - v) / 10;
  461. } else if (v > 0.1) {
  462. return iv - 0.16 + v / 5;
  463. } else {
  464. return v > iv ? iv : v / 2;
  465. }
  466. },
  467. /**
  468. * @method anole,make color darker or lighter
  469. * @param {Boolean} d true:dark,false:light
  470. * @param {Object} rgb:color
  471. * @param {Number} iv (0-1)
  472. * @param {Number} is (0-1)
  473. */
  474. anole = function(d, rgb, iv, is) {
  475. if (!rgb)
  476. return rgb;
  477. rgb = c2a(toRgb(rgb));
  478. var hsv = toHsv(rgb);
  479. is = is!=0?(is || s_inc):is;
  480. hsv[1] -= is;
  481. if (d) {
  482. hsv[2] -= inc(hsv[2], iv);
  483. hsv[1] = _.upTo(hsv[1], 1);
  484. hsv[2] = _.lowTo(hsv[2], 0);
  485. } else {
  486. hsv[2] += inc((1 - hsv[2]), iv);
  487. hsv[1] = _.lowTo(hsv[1], 0);
  488. hsv[2] = _.upTo(hsv[2], 1);
  489. }
  490. return hsv2Rgb(hsv, rgb[3]);
  491. },
  492. topi = function(v){
  493. if(v==0)return 0;
  494. if(v%pi2==0)return pi2;
  495. return v%pi2;
  496. };
  497. _.apply(_, {
  498. getFont : function(w, s, f) {
  499. return w + " " + s + "px " + f;
  500. },
  501. /**
  502. * obtain the Dom Document*/
  503. getDoc : function() {
  504. var doc = window.contentWindow ? window.contentWindow.document : window.contentDocument ? window.contentDocument : window.document;
  505. return doc;
  506. },
  507. /**
  508. * define the interface,the subclass must implement it
  509. */
  510. DefineAbstract : function(M, H) {
  511. if (!H[M])
  512. throw new Error("Cannot instantiate the type '" + H.type + "'.you must implements it with method '" + M + "'.");
  513. },
  514. getAA : function(tf) {
  515. if (tf == 'linear')
  516. return arithmetic.Linear;
  517. if (tf == 'easeInOut' || tf == 'easeIn' || tf == 'easeOut')
  518. return arithmetic.Cubic[tf];
  519. return arithmetic.Linear;
  520. },
  521. /**
  522. * simple noConflict implements
  523. */
  524. noConflict : function() {
  525. return iChart_;
  526. },
  527. plugin : function(t, m, f) {
  528. if (_.isFunction(t))
  529. t.plugin(m, f);
  530. },
  531. parsePadding : function(s, d) {
  532. s = s || 0;
  533. if (_.isNumber(s))
  534. return new Array(s, s, s, s);
  535. if (_.isArray(s))
  536. return s;
  537. d = d || 0;
  538. s = s.replace(/^\s+|\s+$/g, "").replace(/\s{2,}/g, /\s/).replace(/\s/g, ',').split(",");
  539. if (s.length == 1) {
  540. s[0] = s[1] = s[2] = s[3] = pF(s[0]) || d;
  541. } else if (s.length == 2) {
  542. s[0] = s[2] = pF(s[0]) || d;
  543. s[1] = s[3] = pF(s[1]) || d;
  544. } else if (s.length == 3) {
  545. s[0] = pF(s[0]) || d;
  546. s[1] = s[3] = pF(s[1]) || d;
  547. s[2] = pF(s[2]) || d;
  548. } else {
  549. s[0] = pF(s[0]) || d;
  550. s[1] = pF(s[1]) || d;
  551. s[2] = pF(s[2]) || d;
  552. s[3] = pF(s[3]) || d;
  553. }
  554. return s;
  555. },
  556. /**
  557. * the distance of two point
  558. */
  559. distanceP2P : function(x1, y1, x2, y2) {
  560. return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
  561. },
  562. atan2Radian : function(ox, oy, x, y) {
  563. if (ox == x) {
  564. if (y > oy)
  565. return pi / 2;
  566. return pi * 3 / 2;
  567. }
  568. if (oy == y) {
  569. if (x > ox)
  570. return 0;
  571. return pi;
  572. }
  573. var q = _.quadrant(ox, oy, x, y),
  574. r = atan(abs((oy - y) / (ox - x)));
  575. return q?(q == 3?pi2:pi)+(q == 2?r:-r):r;
  576. },
  577. angle2Radian : function(a) {
  578. return a * pi / 180;
  579. },
  580. radian2Angle : function(r) {
  581. return r * 180 / pi;
  582. },
  583. /**
  584. * indicate angle in which quadrant,and it different from concept of Math.this will return 0 if it in first quadrant(other eg.0,1,2,3)
  585. */
  586. quadrant : function(ox, oy, x, y) {
  587. if (ox < x) {
  588. if (oy < y) {
  589. return 0;
  590. } else {
  591. return 3;
  592. }
  593. } else {
  594. if (oy < y) {
  595. return 1;
  596. } else {
  597. return 2;
  598. }
  599. }
  600. },
  601. toPI2 : function(a) {
  602. while(a<0)
  603. a+=pi2;
  604. return a%pi2;
  605. },
  606. visible:function(s, e, f){
  607. if(s>e)return [];
  608. var q1 = _.quadrantd(s),q2 = _.quadrantd(e);
  609. if((q1==2||q1==3)&&(q2==2||q2==3)&&((e-s)<pi))return[];
  610. s = _.toPI2(s);
  611. e = _.toPI2(e);
  612. if(e<s){e+=pi2;}
  613. if(s > pi){s = pi2;}
  614. else if(e>pi2){
  615. return [{s:s,e:pi,f:f},{s:pi2,e:e,f:f}]
  616. }else if(e>pi){
  617. e = pi;
  618. }
  619. return {s:s,e:e,f:f};
  620. },
  621. quadrantd : function(a) {
  622. if(a==0)return 0;
  623. if(a % pi2==0)return 3;
  624. while(a<0)
  625. a+=pi2;
  626. return ceil(2 * (a % pi2) / pi)-1;
  627. },
  628. upTo : function(u, v) {
  629. return v > u ? u : v;
  630. },
  631. lowTo : function(l, v) {
  632. return v < l ? l : v;
  633. },
  634. between : function(l, u, v) {
  635. return v > u ? u : v < l ? l : v;
  636. },
  637. inRange : function(l, u, v) {
  638. return u > v && l < v;
  639. },
  640. angleInRange : function(l, u, v) {
  641. v = (v -l);
  642. v = v<0?v+pi2:v;
  643. v = v %pi2;
  644. return (u -l) > v;
  645. },
  646. angleZInRange : function(l, u, v) {
  647. return u > l?u > v && l < v:(v > l || v < u);
  648. },
  649. inRangeClosed : function(l, u, v) {
  650. return u >= v && l <= v;
  651. },
  652. inEllipse : function(x, y, a, b) {
  653. return (x * x / a / a + y * y / b / b) <= 1;
  654. },
  655. p2Point : function(x, y, a, C) {
  656. return {
  657. x : x + cos(a) * C,
  658. y : y + sin(a) * C
  659. }
  660. },
  661. toRgb:toRgb,
  662. toRgba:function(c,o){
  663. var rgb = c2a(toRgb(c));
  664. return 'rgba(' + rgb[0]+',' + rgb[1]+',' + rgb[2]+',' + o +')';
  665. },
  666. /**
  667. * vector point
  668. */
  669. vectorP2P : function(x, y, radian) {
  670. if (!radian) {
  671. y = _.angle2Radian(y);
  672. x = _.angle2Radian(x);
  673. }
  674. y = sin(y);
  675. return {
  676. x : y * sin(x),
  677. y : y * cos(x)
  678. }
  679. },
  680. iGather : function(k) {
  681. return (k || 'ichartjs') + '-' + ceil(Math.random()*10000)+new Date().getTime().toString().substring(4);
  682. },
  683. toPercent : function(v, d) {
  684. return (v * 100).toFixed(d) + '%';
  685. },
  686. parsePercent:function(v,f){
  687. if(_.isString(v)){
  688. v = v.match(/(.*)%/);
  689. if(v){
  690. return f?floor(pF(v[1])*f/100):v[1]/100;
  691. }
  692. }
  693. return v;
  694. },
  695. parseFloat : function(v, d) {
  696. if (!_.isNumber(v)) {
  697. v = pF(v);
  698. if (!_.isNumber(v))
  699. throw new Error("[" + d +"]=" +v + "is not a valid number.");
  700. }
  701. return v;
  702. },
  703. ceil : function(max) {
  704. return factor(max,1);
  705. },
  706. floor : function(max, f) {
  707. return factor(max,-1);
  708. },
  709. _2D : '2d',
  710. _3D : '3d',
  711. light : function(rgb, iv, is) {
  712. return anole(false, rgb, iv, is);
  713. },
  714. dark : function(rgb, iv, is) {
  715. return anole(true, rgb, iv, is);
  716. },
  717. fixPixel : function(v) {
  718. return _.isNumber(v) ? v : pF(v.replace('px', "")) || 0;
  719. },
  720. toPixel : function(v) {
  721. return _.isNumber(v) ? v + 'px' : _.fixPixel(v) + 'px';
  722. },
  723. emptyFn : function() {
  724. return true;
  725. },
  726. supportCanvas : supportCanvas,
  727. isOpera : isOpera,
  728. isWebKit : isWebKit,
  729. isChrome : isChrome,
  730. isSafari : isSafari,
  731. isIE : isIE,
  732. isGecko : isGecko,
  733. isMobile : isMobile,
  734. touch: "ontouchend" in document,
  735. FRAME : isMobile ? 30 : 60
  736. });
  737. _.Assert = {
  738. gt : function(v, c, n) {
  739. if (!_.isNumber(v) && v >= c)
  740. throw new Error(n + " required Number gt " + c + ",given:" + v);
  741. },
  742. isNumber : function(v, n) {
  743. if (!_.isNumber(v))
  744. throw new Error(n + " required Number,given:" + v);
  745. },
  746. isArray : function(v, n) {
  747. if (!_.isArray(v))
  748. throw new Error(n + " required Array,given:" + v);
  749. },
  750. isTrue : function(v, cause) {
  751. if (v !== true)
  752. throw new Error(cause);
  753. }
  754. };
  755. /**
  756. * shim layer with setTimeout fallback
  757. */
  758. _.requestAnimFrame = (function() {
  759. var raf = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
  760. window.setTimeout(callback, 1000 / 60);
  761. };
  762. return function(f){raf(f)}
  763. })();
  764. /**
  765. * defined Event
  766. */
  767. _.Event = {
  768. addEvent : function(ele, type, fn, useCapture) {
  769. if (ele.addEventListener)
  770. ele.addEventListener(type, fn, useCapture);
  771. else if (ele.attachEvent)
  772. ele.attachEvent('on' + type, fn);
  773. else
  774. ele['on' + type] = fn;
  775. },
  776. fix : function(e) {
  777. /**
  778. * Fix event for mise
  779. */
  780. if (typeof (e) == 'undefined') {
  781. e = window.event;
  782. }
  783. var E = {
  784. target:e.target,
  785. pageX : e.pageX,
  786. pageY : e.pageY,
  787. offsetX : e.offsetX,
  788. offsetY : e.offsetY,
  789. stopPropagation:false,
  790. //time: new Date().getTime(),
  791. event:e
  792. };
  793. /**
  794. * This is mainly for FF which doesn't provide offsetX
  795. */
  796. if (typeof (e.offsetX) == 'undefined') {
  797. /**
  798. * Fix target property, if necessary
  799. */
  800. if (!e.target) {
  801. E.target = e.srcElement || document;
  802. }
  803. if(e.targetTouches){
  804. E.pageX = e.targetTouches[0].pageX;
  805. E.pageY = e.targetTouches[0].pageY;
  806. }
  807. /**
  808. * Calculate pageX/Y if missing and clientX/Y available
  809. */
  810. if (E.pageX == null && e.clientX != null) {
  811. var doc = document.documentElement, body = document.body;
  812. E.pageX = e.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
  813. E.pageY = e.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
  814. }
  815. /**
  816. * Browser not with offsetX and offsetY
  817. */
  818. var x = 0, y = 0, obj = e.target;
  819. while (obj != document.body && obj) {
  820. x += obj.offsetLeft;
  821. y += obj.offsetTop;
  822. obj = obj.offsetParent;
  823. }
  824. E.offsetX = E.pageX - x;
  825. E.offsetY = E.pageY - y;
  826. }
  827. E.x = E.offsetX;
  828. E.y = E.offsetY;
  829. /**
  830. * Any browser that doesn't implement stopPropagation() (MSIE)
  831. */
  832. if (!e.stopPropagation) {
  833. e.stopPropagation = function() {
  834. window.event.cancelBubble = true;
  835. }
  836. }
  837. return E;
  838. }
  839. };
  840. return _;
  841. })(window);
  842. /**
  843. * Add useful method
  844. */
  845. Array.prototype.each = function(f, s) {
  846. var j = this.length, r;
  847. for ( var i = 0; i < j; i++) {
  848. r = s ? f.call(s, this[i], i) : f(this[i], i);
  849. if (typeof r === "boolean" && !r) {
  850. break
  851. }
  852. };
  853. return this;
  854. };
  855. Array.prototype.eachAll = function(f, s) {
  856. this.each(function(d, i) {
  857. if (iChart_.isArray(d)) {
  858. return d.eachAll(f, s);
  859. } else {
  860. return s ? f.call(s, d, i) : f(d, i);
  861. }
  862. }, s);
  863. };
  864. Array.prototype.sor = function(f) {
  865. var _=this,L = _.length-1,T;
  866. for(var i = 0; i < L; i++){
  867. for (var j = L; j > i;j--) {
  868.   if (f?!f(_[j],_[j - 1]):(_[j] < _[j - 1])){
  869.   T = _[j];   
  870. _[j] = _[j - 1];   
  871. _[j - 1] = T;
  872. }
  873. }
  874. }
  875. };
  876. window.iChart = iChart_;
  877. if (!window.$) {
  878. window.$ = window.iChart;
  879. }
  880. })(window);
  881. ;(function($){
  882. /**
  883. * @overview This is base class of all element.All must extend this so that has ability for configuration and event
  884. * this class include some base attribute
  885. * @component#$.Element
  886. * @extend#Object
  887. */
  888. $.Element = function(config) {
  889. var _ = this._();
  890. /**
  891. * indicate the element's type
  892. */
  893. _.type = 'element';
  894. /**
  895. * define abstract method
  896. */
  897. $.DefineAbstract('configure', _);
  898. $.DefineAbstract('afterConfiguration', _);
  899. /**
  900. * All of the configuration will in this property
  901. */
  902. _.options = {};
  903. _.set({
  904. /**
  905. * @inner {String} The unique id of this element (defaults to an auto-assigned id).
  906. */
  907. id : '',
  908. /**
  909. * @cfg {Object} Specifies the border for this element.
  910. * Available property are:
  911. * @Option enable {boolean} If enable the border
  912. * @Option color {String} the border's color.(default to '#BCBCBC')
  913. * @Option style {String} the border's style.(default to 'solid')
  914. * @Option width {Number/String} the border's width.If given array,the option radius will be 0.(default to 1)
  915. * @Option radius {Number/String} the border's radius.(default to 0)
  916. */
  917. border : {
  918. enable : false,
  919. color : '#BCBCBC',
  920. style : 'solid',
  921. width : 1,
  922. radius : 0
  923. },
  924. /**
  925. * @cfg {Boolean} Specifies whether the element should be show a shadow.In general there will be get a high render speed when apply false.(default to false)
  926. */
  927. shadow : false,
  928. /**
  929. * @cfg {String} Specifies the color of your shadow is.(default to '#666666')
  930. */
  931. shadow_color : '#666666',
  932. /**
  933. * @cfg {Number} Specifies How blur you want your shadow to be.(default to 4)
  934. */
  935. shadow_blur : 4,
  936. /**
  937. * @cfg {Number} Specifies Horizontal distance (x-axis) between the shadow and the shape in pixel.(default to 0)
  938. */
  939. shadow_offsetx : 0,
  940. /**
  941. * @cfg {Number} Specifies Vertical distance (y-axis) between the shadow and the shape in pixel.(default to 0)
  942. */
  943. shadow_offsety : 0
  944. });
  945. /**
  946. * variable for short
  947. */
  948. _.W = 'width';
  949. _.H = 'height';
  950. _.O = 'top';
  951. _.B = 'bottom';
  952. _.L = 'left';
  953. _.R = 'right';
  954. _.C = 'center';
  955. _.X = 'originx';
  956. _.Y = 'originy';
  957. /**
  958. * the running variable cache
  959. */
  960. _.variable = {};
  961. /**
  962. * the container of all events
  963. */
  964. _.events = {
  965. 'mouseup':[],
  966. 'touchstart':[],
  967. 'touchmove':[],
  968. 'touchend':[],
  969. 'mousedown':[],
  970. 'dblclick':[]
  971. };
  972. this.registerEvent(
  973. /**
  974. * @event Fires after the element initializing is finished this is for test
  975. * @paramter $.Painter#this
  976. */
  977. 'initialize');
  978. _.initialization = false;
  979. /**
  980. * inititalize configure
  981. */
  982. _.configure.apply(_, Array.prototype.slice.call(arguments, 1));
  983. /**
  984. * clone the original config
  985. */
  986. _.default_ = $.clone(_.options,true);
  987. /**
  988. * megre customize config
  989. */
  990. _.set(config);
  991. _.afterConfiguration();
  992. }
  993. $.Element.prototype = {
  994. _:function(){return this},
  995. afterConfiguration : function() {
  996. /**
  997. * register customize event
  998. */
  999. if ($.isObject(this.get('listeners'))) {
  1000. for ( var e in this.get('listeners')) {
  1001. this.on(e, this.get('listeners')[e]);
  1002. }
  1003. }
  1004. this.initialize();
  1005. /**
  1006. * fire the initialize event,this probable use to unit test
  1007. */
  1008. this.fireEvent(this, 'initialize', [this]);
  1009. },
  1010. registerEvent : function() {
  1011. for ( var i = 0; i < arguments.length; i++) {
  1012. this.events[arguments[i]] = [];
  1013. }
  1014. },
  1015. fireString : function(socpe, name, args, s) {
  1016. var t = this.fireEvent(socpe, name, args);
  1017. return $.isString(t) ? t : (t!==true&&$.isDefined(t)?t.toString():s);
  1018. },
  1019. fireEvent : function(socpe, name, args) {
  1020. var L = this.events[name].length;
  1021. if (L == 1)
  1022. return this.events[name][0].apply(socpe, args);
  1023. var r = true;
  1024. for ( var i = 0; i < L; i++) {
  1025. if(!this.events[name][i].apply(socpe, args))
  1026. r = false;
  1027. }
  1028. return r;
  1029. },
  1030. on : function(n, fn) {
  1031. if($.isString(n)){
  1032. if (!this.events[n])
  1033. throw new Error('['+this.type+"] invalid event:'" + n + "'");
  1034. this.events[n].push(fn);
  1035. }else if($.isArray(n)){
  1036. n.each(function(c){this.on(c, fn)},this);
  1037. }
  1038. return this;
  1039. },
  1040. getPlugin:function(n){
  1041. return this.constructor.plugin_[n];
  1042. },
  1043. set : function(c) {
  1044. if ($.isObject(c))
  1045. $.merge(this.options, c);
  1046. },
  1047. pushIf : function(name, value) {
  1048. if (!$.isDefined(this.get(name))) {
  1049. return this.push(name, value);
  1050. }
  1051. return this.get(name);
  1052. },
  1053. /**
  1054. * average write speed about 0.013ms
  1055. */
  1056. push : function(name, value) {
  1057. var A = name.split("."),L=A.length - 1,V = this.options;
  1058. for (var i = 0; i < L; i++) {
  1059. if (!V[A[i]])
  1060. V[A[i]] = {};
  1061. V = V[A[i]];
  1062. }
  1063. V[A[L]] = value;
  1064. return value;
  1065. },
  1066. /**
  1067. * average read speed about 0.005ms
  1068. */
  1069. get : function(name) {
  1070. var A = name.split("."), V = this.options[A[0]];
  1071. for (var i = 1; i < A.length; i++) {
  1072. if (!V)
  1073. return null;
  1074. V = V[A[i]];
  1075. }
  1076. return V;
  1077. }
  1078. }
  1079. /**
  1080. * @end
  1081. */
  1082. /**
  1083. * @overview The interface this class defined d,so the sub class has must capability to draw and aware of event. this class is a abstract class,so you should not try to initialize it.
  1084. * @component#$.Painter
  1085. * @extend#$.Element
  1086. */
  1087. $.Painter = $.extend($.Element, {
  1088. configure : function() {
  1089. /**
  1090. * indicate the element's type
  1091. */
  1092. this.type = 'painter';
  1093. this.dimension = $._2D;
  1094. /**
  1095. * define abstract method
  1096. */
  1097. $.DefineAbstract('commonDraw', this);
  1098. $.DefineAbstract('initialize', this);
  1099. this.set({
  1100. /**
  1101. * @cfg {String} Specifies the default strokeStyle of the canvas's context in this element.(defaults to 'gray')
  1102. */
  1103. strokeStyle : 'gray',
  1104. /**
  1105. * @cfg {Number} Specifies the padding for this element in pixel,the same rule as css padding.(defaults to 10)
  1106. */
  1107. padding : 10,
  1108. /**
  1109. * @cfg {String} Specifies the font's color for this element.(defaults to 'black')
  1110. */
  1111. color : 'black',
  1112. /**
  1113. * @cfg {Number} Specifies Horizontal offset(x-axis) in pixel.(default to 0)
  1114. */
  1115. offsetx : 0,
  1116. /**
  1117. * @cfg {Number}Specifies Vertical distance (y-axis) in pixel.(default to 0)
  1118. */
  1119. offsety : 0,
  1120. /**
  1121. * @cfg {String} Specifies the backgroundColor for this element.(defaults to 'FDFDFD')
  1122. */
  1123. background_color : '#FEFEFE',
  1124. /**
  1125. * @cfg {float} Specifies the factor make color dark or light for this element,relative to background-color,the bigger the value you set,the larger the color changed.scope{0.01 - 0.5}.(defaults to '0.15')
  1126. */
  1127. color_factor : 0.15,
  1128. /**
  1129. * @inner {String} ('2d','3d')
  1130. */
  1131. style : '',
  1132. /**
  1133. * @cfg {Object} Here,specify as true by default
  1134. */
  1135. border : {
  1136. enable : true
  1137. },
  1138. /**
  1139. * @cfg {Boolean} True to apply the gradient.(default to false)
  1140. */
  1141. gradient : false,
  1142. /**
  1143. * @cfg {String} Specifies the gradient mode of background.(defaults to 'LinearGradientUpDown')
  1144. * @Option 'LinearGradientUpDown'
  1145. * @Option 'LinearGradientDownUp'
  1146. * @Option 'LinearGradientLeftRight'
  1147. * @Option 'LinearGradientRightLeft'
  1148. * @Option 'RadialGradientOutIn'
  1149. * @Option 'RadialGradientInOut'
  1150. */
  1151. gradient_mode:'LinearGradientUpDown',
  1152. /**
  1153. * @cfg {Number}Specifies the z-index.(default to 0)
  1154. */
  1155. z_index : 0,
  1156. /**
  1157. * @cfg {Object} A config object containing one or more event handlers.(default to null)
  1158. */
  1159. listeners : null,
  1160. /**
  1161. * @inner {Number} inner use
  1162. */
  1163. originx : 0,
  1164. /**
  1165. * @inner {Number} inner use
  1166. */
  1167. originy : 0
  1168. });
  1169. this.variable.event = {
  1170. mouseover : false
  1171. };
  1172. /**
  1173. * register the common event
  1174. */
  1175. this.registerEvent(
  1176. /**
  1177. * @event Fires when this element is clicked
  1178. * @paramter $.Painter#this
  1179. * @paramter EventObject#e The click event object
  1180. * @paramter Object#param The additional parameter
  1181. */
  1182. 'click',
  1183. /**
  1184. * @event Fires when the mouse move on the element
  1185. * @paramter $.Painter#this
  1186. * @paramter EventObject#e The mousemove event object
  1187. */
  1188. 'mousemove',
  1189. /**
  1190. * @event Fires when the mouse hovers over the element
  1191. * @paramter $.Painter#this
  1192. * @paramter EventObject#e The mouseover event object
  1193. */
  1194. 'mouseover',
  1195. /**
  1196. * @event Fires when the mouse exits the element
  1197. * @paramter $.Painter#this
  1198. * @paramter EventObject#e The mouseout event object
  1199. */
  1200. 'mouseout',
  1201. /**
  1202. * @event Fires before the element drawing.Return false from an event handler to stop the draw.
  1203. * @paramter $.Painter#this
  1204. */
  1205. 'beforedraw',
  1206. /**
  1207. * @event Fires after the element drawing when calling the draw method.
  1208. * @paramter $.Painter#this
  1209. */
  1210. 'draw');
  1211. },
  1212. is3D : function() {
  1213. return this.dimension == $._3D;
  1214. },
  1215. applyGradient:function(x,y,w,h){
  1216. var _ = this._();
  1217. if(_.get('gradient')){
  1218. _.push('f_color', _.T.gradient(x||_.x||0,y||_.y||0,w||_.get(_.W),h||_.get(_.H),[_.get('dark_color'), _.get('light_color')],_.get('gradient_mode')));
  1219. _.push('light_color', _.T.gradient(x||_.x||0,y||_.y||0,w||_.get(_.W),h||_.get(_.H),[_.get('background_color'), _.get('light_color')],_.get('gradient_mode')));
  1220. _.push('f_color_',_.get('f_color'));
  1221. }
  1222. },
  1223. /**
  1224. * @method The commnd fire to draw the chart use configuration,
  1225. * this is a abstract method.Currently known,both <link>$.Chart</link> and <link>$.Component</link> implement this method.
  1226. * @return void
  1227. */
  1228. draw : function(e) {
  1229. /**
  1230. * fire the beforedraw event
  1231. */
  1232. if (!this.fireEvent(this, 'beforedraw', [this,e])) {
  1233. return this;
  1234. }
  1235. /**
  1236. * execute the commonDraw() that the subClass implement
  1237. */
  1238. this.commonDraw(this,e);
  1239. /**
  1240. * fire the draw event
  1241. */
  1242. this.fireEvent(this, 'draw', [this,e]);
  1243. },
  1244. doConfig : function() {
  1245. var _ = this._(), p = $.parsePadding(_.get('padding')), b = _.get('border.enable'), b = b ? $.parsePadding(_.get('border.width')) : [0, 0, 0, 0], bg = $.toRgb(_.get('background_color')), f = _.get('color_factor'),g=_.get('gradient')?0:null;
  1246. _.set({
  1247. border_top:b[0],
  1248. border_right:b[1],
  1249. border_bottom:b[2],
  1250. border_left:b[3],
  1251. hborder:b[1] + b[3],
  1252. vborder:b[0] + b[2],
  1253. padding_top:p[0] + b[0],
  1254. padding_right:p[1] + b[1],
  1255. padding_bottom:p[2] + b[2],
  1256. padding_left:p[3] + b[3],
  1257. hpadding:p[1] + p[3] + b[1] + b[3],
  1258. vpadding:p[0] + p[2] + b[0] + b[2]
  1259. });
  1260. if (_.get('shadow')) {
  1261. _.push('shadow', {
  1262. color : _.get('shadow_color'),
  1263. blur : _.get('shadow_blur'),
  1264. offsetx : _.get('shadow_offsetx'),
  1265. offsety : _.get('shadow_offsety')
  1266. });
  1267. }
  1268. _.push('f_color', bg);
  1269. _.push('f_color_', bg);
  1270. _.push("light_color", $.light(bg, f,g));
  1271. _.push("dark_color", $.dark(bg, f*0.8,g));
  1272. _.push("light_color2", $.light(bg, f * 2,g));
  1273. _.id = _.get('id');
  1274. if(_.is3D()&&!_.get('xAngle_')){
  1275. var P = $.vectorP2P(_.get('xAngle'),_.get('yAngle'));
  1276. _.push('xAngle_',P.x);
  1277. _.push('yAngle_',P.y);
  1278. }
  1279. }
  1280. });
  1281. /**
  1282. * @end
  1283. */
  1284. /**
  1285. *
  1286. * @overview the base class use for Html componment
  1287. * @component#$.Html
  1288. * @extend#$.Element
  1289. */
  1290. $.Html = $.extend($.Element,{
  1291. configure : function(T) {
  1292. /**
  1293. * indicate the element's type
  1294. */
  1295. this.type = 'html';
  1296. this.T = T;
  1297. /**
  1298. * define abstract method
  1299. */
  1300. $.DefineAbstract('beforeshow',this);
  1301. this.set({
  1302. animation:true,
  1303. /**
  1304. * @inner Specifies the width of this element in pixels.
  1305. */
  1306. width:0,
  1307. /**
  1308. * @inner Specifies the height of this element in pixels.
  1309. */
  1310. height:0,
  1311. /**
  1312. * @cfg {String} Custom style specification to be applied to this element.(default to '')
  1313. * like this:'padding:10px;font-size:12px'
  1314. */
  1315. style:'',
  1316. /**
  1317. * @inner The z-index of this element.(default to 999)
  1318. */
  1319. index:999,
  1320. /**
  1321. * @inner The top of this element.(default to 0)
  1322. */
  1323. offset_top:0,
  1324. /**
  1325. * @inner The left of this element.(default to 0)
  1326. */
  1327. offset_left:0
  1328. });
  1329. this.transitions = "";
  1330. },
  1331. initialize:function(){
  1332. this.wrap = this.get('wrap');
  1333. this.dom = document.createElement("div");
  1334. if(this.get('shadow')){
  1335. this.css('boxShadow',this.get('shadow_offsetx')+'px '+this.get('shadow_offsety')+'px '+this.get('shadow_blur')+'px '+this.get('shadow_color'));
  1336. }
  1337. if(this.get('border.enable')){
  1338. this.css('border',this.get('border.width')+"px "+this.get('border.style')+" "+this.get('border.color'));
  1339. this.css('borderRadius',this.get('border.radius')+"px");
  1340. }
  1341. this.css('zIndex',this.get('index'));
  1342. this.applyStyle();
  1343. },
  1344. width:function(){
  1345. return this.dom.offsetWidth;
  1346. },
  1347. height:function(){
  1348. return this.dom.offsetHeight;
  1349. },
  1350. onTransitionEnd:function(fn,useCapture){
  1351. var type = 'transitionend';
  1352. if($.isWebKit){
  1353. type = 'webkitTransitionEnd';
  1354. }else if($.isOpera){
  1355. type = 'oTransitionEnd';
  1356. }
  1357. $.Event.addEvent(this.dom,type,fn,useCapture);
  1358. },
  1359. transition:function(v){
  1360. this.transitions = this.transitions==''?v:this.transitions+','+v;
  1361. if($.isWebKit){
  1362. this.css('WebkitTransition',this.transitions);
  1363. }else if($.isGecko){
  1364. this.css('MozTransition',this.transitions);
  1365. }else if($.isOpera){
  1366. this.css('OTransition',this.transitions);
  1367. }else{
  1368. this.css('transition',this.transitions);
  1369. }
  1370. },
  1371. show:function(e,m){
  1372. this.beforeshow(e,m);
  1373. this.css('visibility','visible');
  1374. if(this.get('animation')){
  1375. this.css('opacity',1);
  1376. }
  1377. },
  1378. hidden:function(e){
  1379. this.css('visibility','hidden');
  1380. },
  1381. getDom:function(){
  1382. return this.dom;
  1383. },
  1384. css:function(k,v){
  1385. if($.isString(k))if($.isDefined(v))this.dom.style[k]=v;else return this.dom.style[k];
  1386. },
  1387. applyStyle:function(){
  1388. var styles = this.get('style').split(";"),style;
  1389. for(var i = 0;i< styles.length;i++){
  1390. style = styles[i].split(":");
  1391. if(style.length>1)this.css(style[0],style[1]);
  1392. }
  1393. }
  1394. });
  1395. /**
  1396. * @end
  1397. */
  1398. /**
  1399. * @overview this a abstract component of all concrete chart
  1400. * @component#$.Component
  1401. * @extend#$.Painter
  1402. */
  1403. $.Component = $.extend($.Painter, {
  1404. configure : function(c) {
  1405. /**
  1406. * invoked the super class's configuration
  1407. */
  1408. $.Component.superclass.configure.apply(this, arguments);
  1409. /**
  1410. * indicate the element's type
  1411. */
  1412. this.type = 'component';
  1413. this.set({
  1414. /**
  1415. * @cfg {Number} Specifies the font size of this element in pixels.(default to 12)
  1416. */
  1417. fontsize : 12,
  1418. /**
  1419. * @cfg {String} Specifies the font of this element.(default to 'Verdana')
  1420. */
  1421. font : 'Verdana',
  1422. /**
  1423. * @cfg {String} Specifies the font weight of this element.(default to 'normal')
  1424. */
  1425. fontweight : 'normal',
  1426. /**
  1427. * @inner {Boolean} Specifies the config of Tip.For details see <link>$.Tip</link> Note:this has a extra property named 'enable',indicate whether tip available(default to false)
  1428. */
  1429. tip : {
  1430. enable : false,
  1431. border : {
  1432. width : 2
  1433. }
  1434. }
  1435. });
  1436. /**
  1437. * If this element can split or contain others.(default to false)
  1438. */
  1439. this.atomic = false;
  1440. /**
  1441. * If method draw be proxy.(default to false)
  1442. */
  1443. this.proxy = false;
  1444. this.inject(c);
  1445. },
  1446. initialize : function() {
  1447. $.DefineAbstract('isEventValid', this);
  1448. $.DefineAbstract('doDraw', this);
  1449. this.doConfig();
  1450. this.initialization = true;
  1451. },
  1452. /**
  1453. * @method return the component's dimension,return hold following property
  1454. * @property x:the left-top coordinate-x
  1455. * @property y:the left-top coordinate-y
  1456. * @property width:the width of component,note:available there applies box model
  1457. * @property height:the height of component,note:available there applies box model
  1458. * @return object
  1459. */
  1460. getDimension : function() {
  1461. return {
  1462. x : this.x,
  1463. y : this.y,
  1464. width : this.get("width"),
  1465. height : this.get("height")
  1466. }
  1467. },
  1468. doConfig : function() {
  1469. $.Component.superclass.doConfig.call(this);
  1470. var _ = this._();
  1471. _.x = _.push(_.X, _.get(_.X) + _.get('offsetx'));
  1472. _.y = _.push(_.Y, _.get(_.Y) + _.get('offsety'));
  1473. _.push('fontStyle', $.getFont(_.get('fontweight'), _.get('fontsize'), _.get('font')));
  1474. /**
  1475. * if have evaluate it
  1476. */
  1477. _.data = _.get('data');
  1478. if (_.get('tip.enable')) {
  1479. /**
  1480. * make tip's border in accord with sector
  1481. */
  1482. _.pushIf('tip.border.color', _.get('f_color'));
  1483. if (!$.isFunction(_.get('tip.invokeOffset')))
  1484. /**
  1485. * indicate the tip must calculate position
  1486. */
  1487. _.push('tip.invokeOffset', _.tipInvoke());
  1488. }
  1489. },
  1490. isMouseOver : function(e) {
  1491. return this.isEventValid(e,this);
  1492. },
  1493. redraw : function(e) {
  1494. this.container.draw(e);
  1495. },
  1496. commonDraw : function(_) {
  1497. /**
  1498. * execute the doDraw() that the subClass implement
  1499. */
  1500. if (!_.proxy)
  1501. _.doDraw.call(_,_);
  1502. },
  1503. inject : function(c) {
  1504. if (c) {
  1505. this.container = c;
  1506. this.target = this.T = c.T;
  1507. }
  1508. }
  1509. });
  1510. /**
  1511. * @end
  1512. */
  1513. /**
  1514. * @overview the tip component.
  1515. * @component#$.Tip
  1516. * @extend#$.Element
  1517. */
  1518. $.Tip = $.extend($.Html,{
  1519. configure:function(){
  1520. /**
  1521. * invoked the super class's configuration
  1522. */
  1523. $.Tip.superclass.configure.apply(this,arguments);
  1524. /**
  1525. * indicate the legend's type
  1526. */
  1527. this.type = 'tip';
  1528. this.set({
  1529. name:'',
  1530. value:'',
  1531. /**
  1532. * @cfg {String} Specifies the text want to disply.(default to '')
  1533. */
  1534. text:'',
  1535. /**
  1536. * @cfg {String} Specifies the tip's type.(default to 'follow') Available value are:
  1537. * @Option follow
  1538. * @Option fixed
  1539. */
  1540. showType:'follow',
  1541. /**
  1542. * @cfg {Function} Specifies Function to calculate the position.(default to null)
  1543. */
  1544. invokeOffset:null,
  1545. /**
  1546. * @cfg {Number} Specifies the duration when fadeIn/fadeOut in millisecond.(default to 300)
  1547. */
  1548. fade_duration:300,
  1549. /**
  1550. * @cfg {Number} Specifies the duration when move in millisecond.(default to 100)
  1551. */
  1552. move_duration:100,
  1553. /**
  1554. * ease
  1555. * linear
  1556. * ease-in
  1557. * ease-out
  1558. * ease-in-out
  1559. */
  1560. timing_function:'ease-out',
  1561. /**
  1562. * @cfg {Boolean} if calculate the position every time (default to false)
  1563. */
  1564. invokeOffsetDynamic:false,
  1565. /**
  1566. * @cfg {String} Specifies the css of this Dom.
  1567. */
  1568. style:'textAlign:left;padding:4px 5px;cursor:pointer;backgroundColor:rgba(239,239,239,.85);fontSize:12px;color:black;',
  1569. /**
  1570. * @cfg {Object} Override the default as enable = true,radius = 5
  1571. */
  1572. border:{
  1573. enable:true,
  1574. radius : 5
  1575. },
  1576. delay:200
  1577. });
  1578. this.registerEvent(
  1579. /**
  1580. * @event Fires when parse this tip's text.Return value will override existing.
  1581. * @paramter <link>$.Tip</link>#tip
  1582. * @paramter string#name the current tip's name
  1583. * @paramter string#value the current tip's value
  1584. * @paramter string#text the current tip's text
  1585. * @paramter int#index index of data,if there was a line
  1586. */
  1587. 'parseText');
  1588. },
  1589. position:function(t,l){
  1590. this.style.top = (t<0?0:t)+"px";
  1591. this.style.left = (l<0?0:l)+"px";
  1592. },
  1593. follow:function(e,m){
  1594. var _ = this._();
  1595. _.style.width = "";
  1596. if(_.get('invokeOffsetDynamic')){
  1597. if(m.hit){
  1598. if($.isString(m.text)||$.isNumber(m.text)){
  1599. _.text(m.name,m.value,m.text,m.i,_);
  1600. }
  1601. var o = _.get('invokeOffset')(_.width(),_.height(),m);
  1602. _.position(o.top,o.left);
  1603. }
  1604. }else{
  1605. if(_.get('showType')!='follow'&&$.isFunction(_.get('invokeOffset'))){
  1606. var o = _.get('invokeOffset')(_.width(),_.height(),m);
  1607. _.position(o.top,o.left);
  1608. }else{
  1609. _.position((e.y-_.height()*1.1-2),e.x+2);
  1610. }
  1611. }
  1612. },
  1613. text:function(n,v,t,i,_){
  1614. _.dom.innerHTML = _.fireString(_, 'parseText', [_,n,v,t,i],t);
  1615. },
  1616. beforeshow:function(e,m){
  1617. this.follow(e,m);
  1618. },
  1619. hidden:function(e){
  1620. if(this.get('animation')){
  1621. this.css('opacity',0);
  1622. }else{
  1623. this.css('visibility','hidden');
  1624. }
  1625. },
  1626. initialize:function(){
  1627. $.Tip.superclass.initialize.call(this);
  1628. var _ = this._();
  1629. _.css('position','absolute');
  1630. _.text(_.get('name'),_.get('value'),_.get('text'),0,_);
  1631. _.style = _.dom.style;
  1632. _.hidden();
  1633. if(_.get('animation')){
  1634. var m = _.get('move_duration')/1000+'s '+_.get('timing_function')+' 0s';
  1635. _.transition('opacity '+_.get('fade_duration')/1000+'s '+_.get('timing_function')+' 0s');
  1636. _.transition('top '+m);
  1637. _.transition('left '+m);
  1638. _.onTransitionEnd(function(e){
  1639. if(_.css('opacity')==0){
  1640. _.css('visibility','hidden');
  1641. }
  1642. },false);
  1643. }
  1644. _.wrap.appendChild(_.dom);
  1645. _.T.on('mouseover',function(c,e,m){
  1646. _.show(e,m);
  1647. }).on('mouseout',function(c,e,m){
  1648. _.hidden(e);
  1649. });
  1650. if(_.get('showType')=='follow'){
  1651. _.T.on('mousemove',function(c,e,m){
  1652. if(_.T.variable.event.mouseover){
  1653. setTimeout(function(){
  1654. if(_.T.variable.event.mouseover)
  1655. _.follow(e,m);
  1656. },_.get('delay'));
  1657. }
  1658. });
  1659. }
  1660. }
  1661. });
  1662. /**
  1663. * @end
  1664. */
  1665. /**
  1666. * @overview this element simulate the crosshair on the coordinate.actually this composed of some div of html.
  1667. * @component#$.CrossHair
  1668. * @extend#$.Html
  1669. */
  1670. $.CrossHair = $.extend($.Html,{
  1671. configure:function(){
  1672. /**
  1673. * invoked the super class's configuration
  1674. */
  1675. $.CrossHair.superclass.configure.apply(this,arguments);
  1676. /**
  1677. * indicate the component's type
  1678. */
  1679. this.type = 'crosshair';
  1680. this.set({
  1681. /**
  1682. * @inner {Number} Specifies the position top,normally this will given by chart.(default to 0)
  1683. */
  1684. top:0,
  1685. /**
  1686. * @inner {Number} Specifies the position left,normally this will given by chart.(default to 0)
  1687. */
  1688. left:0,
  1689. /**
  1690. * @inner {Boolean} private use
  1691. */
  1692. hcross:true,
  1693. /**
  1694. * @inner {Boolean} private use
  1695. */
  1696. vcross:true,
  1697. /**
  1698. * @inner {Function} private use
  1699. */
  1700. invokeOffset:null,
  1701. /**
  1702. * @cfg {Number} Specifies the linewidth of the crosshair.(default to 1)
  1703. */
  1704. line_width:1,
  1705. /**
  1706. * @cfg {Number} Specifies the linewidth of the crosshair.(default to 1)
  1707. */
  1708. line_color:'#1A1A1A',
  1709. delay:200
  1710. });
  1711. },
  1712. /**
  1713. * this function will implement at every target object,and this just default effect
  1714. */
  1715. follow:function(e,m){
  1716. if(this.get('invokeOffset')){
  1717. var o = this.get('invokeOffset')(e,m);
  1718. if(o&&o.hit){
  1719. this.position(o.top-this.top,o.left-this.left);
  1720. }
  1721. return false;
  1722. }else{
  1723. /**
  1724. * set the 1px offset will make the line at the top left all the time
  1725. */
  1726. this.position(e.y-this.top-1,e.x-this.left-1);
  1727. }
  1728. return true;
  1729. },
  1730. position:function(t,l){
  1731. this.horizontal.style.top = (t-this.size)+"px";
  1732. this.vertical.style.left = (l-this.size)+"px";
  1733. },
  1734. beforeshow:function(e,m){
  1735. if(!this.follow(e,m)){
  1736. this.position(-99,-99);
  1737. }
  1738. },
  1739. doCreate:function(_,w,h){
  1740. var d = document.createElement("div");
  1741. d.style.width= $.toPixel(w);
  1742. d.style.height= $.toPixel(h);
  1743. d.style.backgroundColor = _.get('line_color');
  1744. d.style.position="absolute";
  1745. _.dom.appendChild(d);
  1746. return d;
  1747. },
  1748. initialize:function(){
  1749. $.CrossHair.superclass.initialize.call(this);
  1750. var _ = this._(),L = $.toPixel(_.get('line_width'));
  1751. _.top = $.fixPixel(_.get(_.O));
  1752. _.left = $.fixPixel(_.get(_.L));
  1753. _.dom = document.createElement("div");
  1754. _.dom.style.zIndex=_.get('index');
  1755. _.dom.style.position="absolute";
  1756. /**
  1757. * set size zero make integration with vertical and horizontal
  1758. */
  1759. _.dom.style.width= $.toPixel(0);
  1760. _.dom.style.height=$.toPixel(0);
  1761. _.dom.style.top=$.toPixel(_.get(_.O));
  1762. _.dom.style.left=$.toPixel(_.get(_.L));
  1763. _.css('visibility','hidden');
  1764. _.horizontal = _.doCreate(_,_.get('hcross')?$.toPixel(_.get(_.W)):"0px",L);
  1765. _.vertical = _.doCreate(_,L,_.get('vcross')?$.toPixel(_.get(_.H)):"0px");
  1766. _.size = _.get('line_width')/2;
  1767. if(_.get('shadow')){
  1768. _.dom.style.boxShadow = _.get('shadowStyle');
  1769. }
  1770. _.wrap.appendChild(_.dom);
  1771. _.T.on('mouseover',function(c,e,m){
  1772. _.show(e,m);
  1773. }).on('mouseout',function(c,e,m){
  1774. _.hidden(e,m);
  1775. }).on('mousemove',function(c,e,m){
  1776. _.follow(e,m);
  1777. });
  1778. }
  1779. });
  1780. /**
  1781. * @end
  1782. */
  1783. /**
  1784. * @overview this component use for abc
  1785. * @component#$.Legend
  1786. * @extend#$.Component
  1787. */
  1788. $.Legend = $.extend($.Component, {
  1789. configure : function() {
  1790. /**
  1791. * invoked the super class's configuration
  1792. */
  1793. $.Legend.superclass.configure.apply(this, arguments);
  1794. /**
  1795. * indicate the legend's type
  1796. */
  1797. this.type = 'legend';
  1798. this.set({
  1799. /**
  1800. * @cfg {Array} Required,The datasource of Legend.Normally,this will given by chart.(default to undefined)
  1801. */
  1802. data : undefined,
  1803. /**
  1804. * @inner {Number} Specifies the width.Note if set to 'auto' will be fit the actual width.(default to 'auto')
  1805. */
  1806. width : 'auto',
  1807. /**
  1808. * @cfg {Number/String} Specifies the number of column.(default to 1) Note:If set to 'max',the list will be lie on the property row
  1809. */
  1810. column : 1,
  1811. /**
  1812. * @cfg {Number/String} Specifies the number of column.(default to 'max') Note:If set to 'max',the list will be lie on the property column
  1813. */
  1814. row : 'max',
  1815. /**
  1816. * @cfg {Number} Specifies the limited width.Normally,this will given by chart.(default to 0)
  1817. */
  1818. maxwidth : 0,
  1819. /**
  1820. * @cfg {Number} Specifies the lineheight when text display multiline.(default to 16)
  1821. */
  1822. line_height : 16,
  1823. /**
  1824. * @cfg {String} Specifies the shape of legend' sign (default to 'square') Available value are:
  1825. * @Option 'round'
  1826. * @Option 'square'
  1827. * @Option 'bar'
  1828. * @Option 'round-bar'
  1829. * @Option 'square-bar'
  1830. */
  1831. sign : 'square',
  1832. /**
  1833. * @cfg {Number} the size of legend' sign (default to 12)
  1834. */
  1835. sign_size : 12,
  1836. /**
  1837. * @cfg {Number} the distance of legend' sign and text (default to 5)
  1838. */
  1839. sign_space : 5,
  1840. /**
  1841. * @cfg {Number} Specifies the space between the sign and text.(default to 5)
  1842. */
  1843. legend_space : 5,
  1844. z_index : 1009,
  1845. /**
  1846. * @cfg {Boolean} If true the text's color will accord with sign's.(default to false)
  1847. */
  1848. text_with_sign_color : false,
  1849. /**
  1850. * @cfg {String} Specifies the horizontal position of the legend in chart.(defaults to 'right').Available value are:
  1851. * @Option 'left'
  1852. * @Option 'center' Only applies when valign = 'top|bottom'
  1853. * @Option 'right'
  1854. */
  1855. align : 'right',
  1856. /**
  1857. * @cfg {String} this property specifies the vertical position of the legend in an module (defaults to 'middle'). Available value are:
  1858. * @Option 'top'
  1859. * @Option 'middle' Only applies when align = 'left|right'
  1860. * @Option 'bottom'
  1861. */
  1862. valign : 'middle'
  1863. });
  1864. /**
  1865. * this element support boxMode
  1866. */
  1867. this.atomic = true;
  1868. this.registerEvent(
  1869. /**
  1870. * @event Fires when parse this element'data.Return text value will override existing.
  1871. * @paramter $.Chart#this
  1872. * @paramter string#text the text will display
  1873. * @paramter int#i the index of data
  1874. * @return string
  1875. */
  1876. 'parse');
  1877. },
  1878. isEventValid : function(e,_) {
  1879. var r = {
  1880. valid : false
  1881. };
  1882. if (e.x > this.x && e.x < (_.x + _.width) && e.y > _.y && e.y < (_.y + _.height)) {
  1883. _.data.each(function(d, i) {
  1884. if (e.x > d.x && e.x < (d.x + d.width_ + _.get('signwidth')) && e.y > d.y && e.y < (d.y + _.get('line_height'))) {
  1885. r = {
  1886. valid : true,
  1887. index : i,
  1888. target : d
  1889. }
  1890. return false;
  1891. }
  1892. }, _);
  1893. }
  1894. return r;
  1895. },
  1896. drawCell : function(x, y, text, color,n,_) {
  1897. var s = _.get('sign_size'),f = _.getPlugin('sign');
  1898. if(!f||!f.call(_,_.T,n,x + s / 2,y,s,color)){
  1899. if(n.indexOf("bar")!=-1){
  1900. _.T.box(x, y - s / 12, s, s / 6, 0, color);
  1901. }
  1902. if(n=='round'){
  1903. _.T.round(x + s / 2, y, s / 2, color);
  1904. }else if(n=='round-bar'){
  1905. _.T.round(x + s / 2, y, s / 4, color);
  1906. }else if (n == 'square-bar') {
  1907. _.T.box(x + s / 4, y - s / 4, s / 2, s / 2, 0, color);
  1908. }else if (n == 'square'){
  1909. _.T.box(x, y-s/2, s, s, 0, color);
  1910. }
  1911. }
  1912. _.T.fillText(text, x + _.get('signwidth'), y, 0, _.get('text_with_sign_color')?color:_.get('color'),'lr',_.get('line_height'));
  1913. },
  1914. doDraw : function(_) {
  1915. _.T.box(_.x, _.y, _.width, _.height, _.get('border'), _.get('f_color'), false, _.get('shadow'));
  1916. _.T.textStyle(_.L, 'middle', $.getFont(_.get('fontweight'), _.get('fontsize'), _.get('font')));
  1917. _.data.each(function(d) {
  1918. _.drawCell(d.x, d.y, d.text, d.color,d.sign,_);
  1919. });
  1920. },
  1921. doLayout:function(_,g){
  1922. var ss = _.get('sign_size'),
  1923. w = 0,
  1924. h=0,
  1925. temp = 0,
  1926. c = _.get('column'),
  1927. r = _.get('row'),
  1928. L = _.data.length;
  1929. _.T.textFont(_.get('fontStyle'));
  1930. if (_.get('line_height') < ss) {
  1931. _.push('line_height', ss + ss / 5);
  1932. }
  1933. _.push('signwidth', (ss + _.get('sign_space')));
  1934. /**
  1935. * calculate the width each item will used
  1936. */
  1937. _.data.each(function(d) {
  1938. d.width_ = _.T.measureText(d.text);
  1939. }, _);
  1940. /**
  1941. * calculate the each column's width it will used
  1942. */
  1943. for ( var i = 0; i < c; i++) {
  1944. temp = 0;
  1945. for ( var j = i; j < L; j+=c) {
  1946. temp = Math.max(temp, _.data[j].width_);
  1947. }
  1948. _.columnwidth[i] = temp;
  1949. w += temp;
  1950. }
  1951. /**
  1952. * calculate the each row's height it will used
  1953. */
  1954. for ( var i = 0; i < r; i++) {
  1955. temp =0;
  1956. for ( var j = i*c; j < L; j++) {
  1957. temp = Math.max(temp, _.data[j].text.split("\n").length);
  1958. }
  1959. _.columnheight[i] = temp;
  1960. h+=temp;
  1961. }
  1962. w = _.push(_.W, w + _.get('hpadding') + _.get('signwidth') * c + (c - 1) * _.get('legend_space'));
  1963. if (w > _.get('maxwidth')) {
  1964. var f = _.get('maxwidth')/w,l2=$.lowTo,o=Math.floor;
  1965. _.push('fontsize', l2(6,o(_.get('fontsize')*f)));
  1966. _.push('sign_size', l2(6,o(ss*f)));
  1967. _.push('sign_space', l2(4,o(_.get('sign_space')*f)));
  1968. _.push('legend_space', l2(4,o(_.get('legend_space')*f)));
  1969. _.push('fontStyle', $.getFont(_.get('fontweight'), _.get('fontsize'), _.get('font')));
  1970. _.doLayout(_,g);
  1971. return;
  1972. }
  1973. var d,x,y,y2;
  1974. _.width = w;
  1975. _.height = h = _.push(_.H, h * _.get('line_height') + _.get('vpadding'));
  1976. if (_.get('valign') == _.O) {
  1977. _.y = g.get('t_originy');
  1978. } else if (_.get('valign') == _.B) {
  1979. _.y = g.get('b_originy') - h;
  1980. } else {
  1981. _.y = g.get('centery') - h / 2;
  1982. }
  1983. if (_.get('align') == _.L) {
  1984. _.x = g.get('l_originx');
  1985. } else if (_.get('align') == _.C) {
  1986. _.x = g.get('centerx') - w / 2;
  1987. } else {
  1988. _.x = g.get('r_originx') - w;
  1989. }
  1990. _.x = _.push(_.X, _.x + _.get('offsetx'));
  1991. _.y = _.push(_.Y, _.y + _.get('offsety'));
  1992. y = _.y + _.get('padding_top');
  1993. ss = _.get('legend_space')+_.get('signwidth');
  1994. /**
  1995. * calculate the each cell's coordinate point
  1996. */
  1997. for ( var i = 0; i < r; i++) {
  1998. x = _.x + _.get('padding_left');
  1999. y2=(_.columnheight[i]/2)*_.get('line_height');
  2000. y+=y2;
  2001. for ( var j = 0; j < c&&i*c+j<L; j++) {
  2002. d = _.data[i*c+j];
  2003. d.y = y;
  2004. d.x = x;
  2005. x += _.columnwidth[j] + ss;
  2006. }
  2007. y+=y2;
  2008. }
  2009. },
  2010. doConfig : function() {
  2011. $.Legend.superclass.doConfig.call(this);
  2012. var _ = this._(),g = _.container,c = $.isNumber(_.get('column')),r = $.isNumber(_.get('row')), L = _.data.length;
  2013. /**
  2014. * if the position is incompatible,rectify it.
  2015. */
  2016. if (_.get('align') == _.C && _.get('valign') == 'middle') {
  2017. _.push('valign', _.O);
  2018. }
  2019. /**
  2020. * if this position incompatible with container,rectify it.
  2021. */
  2022. if (g.get('align') == _.L) {
  2023. if (_.get('valign') == 'middle') {
  2024. _.push('align', _.R);
  2025. }
  2026. }
  2027. /**
  2028. * calculate the width each item will used
  2029. */
  2030. _.data.each(function(d, i) {
  2031. $.merge(d, _.fireEvent(_, 'parse', [_, d.name, i]));
  2032. d.text = d.text || d.name;
  2033. d.sign = d.sign || _.get('sign')
  2034. }, _);
  2035. if (!c && !r)
  2036. c = _.push('column',1);
  2037. if (c && !r)
  2038. r = _.push('row', Math.ceil(L / _.get('column')));
  2039. if (!c && r)
  2040. c = _.push('column', Math.ceil(L / _.get('row')));
  2041. c = _.get('column');
  2042. r = _.get('row');
  2043. if (L > r * c) {
  2044. r += Math.ceil((L - r * c) / c);
  2045. r = _.push('row', r);
  2046. }
  2047. _.columnwidth = new Array(c);
  2048. _.columnheight = new Array(r);
  2049. _.doLayout(_,g);
  2050. }
  2051. });/** @end */
  2052. /**
  2053. * @overview this component use for abc
  2054. * @component#$.Label
  2055. * @extend#$.Component
  2056. */
  2057. $.Label = $.extend($.Component, {
  2058. configure : function() {
  2059. /**
  2060. * invoked the super class's configuration
  2061. */
  2062. $.Label.superclass.configure.apply(this, arguments);
  2063. /**
  2064. * indicate the legend's type
  2065. */
  2066. this.type = 'label';
  2067. this.set({
  2068. /**
  2069. * @cfg {String} Specifies the text of this label,Normally,this will given by chart.(default to '').
  2070. */
  2071. text : '',
  2072. /**
  2073. * @cfg {Number} Specifies the lineheight when text display multiline.(default to 12).
  2074. */
  2075. line_height : 12,
  2076. /**
  2077. * @cfg {Number} Specifies the thickness of line in pixel.(default to 1).
  2078. */
  2079. line_thickness : 1,
  2080. /**
  2081. * @cfg {String} Specifies the shape of legend' sign (default to 'square').Available value are:
  2082. * @Option 'round'
  2083. * @Option 'square'
  2084. */
  2085. sign : 'square',
  2086. /**
  2087. * @cfg {Number} Specifies the size of legend' sign in pixel.(default to 12)
  2088. */
  2089. sign_size : 12,
  2090. /**
  2091. * @cfg {Number} Override the default as 2 in pixel.
  2092. */
  2093. padding : '2 5',
  2094. /**
  2095. * @cfg {Number} Override the default as 2 in pixel.
  2096. */
  2097. offsety : 2,
  2098. /**
  2099. * @cfg {Number} Specifies the space between the sign and text.(default to 5)
  2100. */
  2101. sign_space : 5,
  2102. /**
  2103. * @cfg {Number} Override the default as '#efefef'.
  2104. */
  2105. background_color : '#efefef',
  2106. /**
  2107. * @cfg {Boolean} If true the text's color will accord with sign's.(default to false)
  2108. */
  2109. text_with_sign_color : false
  2110. });
  2111. /**
  2112. * this element support boxMode
  2113. */
  2114. this.atomic = true;
  2115. this.registerEvent();
  2116. },
  2117. isEventValid : function(e,_) {
  2118. return {
  2119. valid : $.inRange(_.labelx, _.labelx + _.get(_.W), e.x) && $.inRange(_.labely, _.labely + _.get(_.H), e.y)
  2120. };
  2121. },
  2122. text : function(text) {
  2123. if (text)
  2124. this.push('text', text);
  2125. this.push(this.W, this.T.measureText(this.get('text')) + this.get('hpadding') + this.get('sign_size') + this.get('sign_space'));
  2126. },
  2127. localizer : function(_) {
  2128. var Q = _.get('quadrantd'),p = _.get('line_points'),m=_.get('smooth'),Q=(Q >= 1 && Q <= 2),x=_.get('labelx'),y=_.get('labely');
  2129. _.labelx = x+(Q ? - _.get(_.W)-m : m);
  2130. _.labely = y-_.get(_.H)/2;
  2131. p[2] = {x:x,y:y};
  2132. p[3] = {x:p[2].x+(Q ? -m : m),y:p[2].y};
  2133. },
  2134. doLayout : function(x, y,n,_) {
  2135. _.push('labelx', _.get('labelx') + x/n);
  2136. _.push('labely', _.get('labely') + y/n);
  2137. _.get('line_points').each(function(p,i) {
  2138. p.x += x;
  2139. p.y += y;
  2140. return i==1;
  2141. }, _);
  2142. _.localizer(_);
  2143. },
  2144. doDraw : function(_){
  2145. var p = _.get('line_points'), ss = _.get('sign_size'), x = _.labelx + _.get('padding_left'), y = _.labely + _.get('padding_top');
  2146. _.T.label(p, _.get('line_thickness'), _.get('border.color'));
  2147. _.T.box(_.labelx, _.labely, _.get(_.W), _.get(_.H), _.get('border'), _.get('f_color'), false, _.get('shadow'));
  2148. _.T.textStyle(_.L, _.O, _.get('fontStyle'));
  2149. var textcolor = _.get('color');
  2150. if (_.get('text_with_sign_color')) {
  2151. textcolor = _.get('scolor');
  2152. }
  2153. if (_.get('sign') == 'square') {
  2154. _.T.box(x, y, ss, ss, 0, _.get('scolor'));
  2155. } else if(_.get('sign')){
  2156. _.T.round(x + ss / 2, y + ss / 2, ss / 2, _.get('scolor'));
  2157. }
  2158. _.T.fillText(_.get('text'), x + ss + _.get('sign_space'), y, _.get('textwidth'), textcolor);
  2159. },
  2160. doConfig : function() {
  2161. $.Label.superclass.doConfig.call(this);
  2162. var _ = this._();
  2163. _.T.textFont(_.get('fontStyle'));
  2164. if (_.get('fontsize') > _.get('line_height')) {
  2165. _.push('line_height', _.get('fontsize'));
  2166. }
  2167. if(!_.get('sign')){
  2168. _.push('sign_size',0);
  2169. _.push('sign_space',0);
  2170. }
  2171. _.push(_.H, _.get('line_height') + _.get('vpadding'));
  2172. _.text();
  2173. _.localizer(_);
  2174. }
  2175. });
  2176. /**
  2177. * @end
  2178. */
  2179. /**
  2180. * @overview this component use for abc
  2181. * @component#$.Text
  2182. * @extend#$.Component
  2183. */
  2184. $.Text = $.extend($.Component,{
  2185. configure:function(){
  2186. /**
  2187. * invoked the super class's configuration
  2188. */
  2189. $.Text.superclass.configure.apply(this,arguments);
  2190. /**
  2191. * indicate the component's type
  2192. */
  2193. this.type = 'text';
  2194. this.set({
  2195. /**
  2196. * @cfg {String} Specifies the text want to disply.(default to '')
  2197. */
  2198. text:'',
  2199. /**
  2200. * @cfg {String} there has two layers of meaning,when width is 0,Specifies the textAlign of html5.else this is the alignment of box.(default to 'center')
  2201. * when width is 0,Available value are:
  2202. * @Option start
  2203. * @Option end
  2204. * @Option left
  2205. * @Option right
  2206. * @Option center
  2207. * when width is not 0,Available value are:
  2208. * @Option left
  2209. * @Option right
  2210. * @Option center
  2211. */
  2212. textAlign:'center',
  2213. /**
  2214. * @cfg {String} Here,specify as false to make background transparent.(default to null)
  2215. */
  2216. background_color : 0,
  2217. /**
  2218. * @cfg {String} Specifies the textBaseline of html5.(default to 'top')
  2219. * Available value are:
  2220. * @Option top
  2221. * @Option hanging
  2222. * @Option middle
  2223. * @Option alphabetic
  2224. * @Option ideographic
  2225. * @Option bottom
  2226. */
  2227. textBaseline:'top',
  2228. /**
  2229. * @cfg {Object} Here,specify as false by default
  2230. * @see <link>$.Element#border</link>
  2231. */
  2232. border : {
  2233. enable : false
  2234. },
  2235. /**
  2236. * @cfg {Number} Specifies the maxwidth of text in pixels,if given 0 will not be limited.(default to 0)
  2237. */
  2238. width:0,
  2239. /**
  2240. * @cfg {Number} Specifies the maxheight of text in pixels,if given 0 will not be limited(default to 0)
  2241. */
  2242. height:0,
  2243. /**
  2244. * @cfg {Number} Here,specify as 0 by default
  2245. */
  2246. padding:0,
  2247. /**
  2248. * @cfg {String} Specifies the writing-mode of text.(default to 'lr') .
  2249. * Available value are:
  2250. * @Option 'lr'
  2251. */
  2252. writingmode : 'lr',
  2253. /**
  2254. * @cfg {Number} Specifies the lineheight when text display multiline.(default to 16).
  2255. */
  2256. line_height : 16,
  2257. /**
  2258. * @cfg {Number} Specifies the angle that text writed.0 to horizontal,clockwise.(default to 0).
  2259. */
  2260. rotate:0
  2261. });
  2262. this.registerEvent();
  2263. },
  2264. doDraw:function(_){
  2265. if(_.get('box_feature'))
  2266. _.T.box(_.x,_.y,_.get(_.W),_.get(_.H),_.get('border'),_.get('f_color'));
  2267. if(_.get('text')!='')
  2268. _.T.text(_.get('text'),_.get('textx'),_.get('texty'),_.get(_.W),_.get('color'),_.get('textAlign'),_.get('textBaseline'),_.get('fontStyle'),_.get('writingmode'),_.get('line_height'),_.get('shadow'),_.get('rotate'));
  2269. },
  2270. isEventValid:function(){
  2271. return {valid:false};
  2272. },
  2273. doLayout:function(x,y,n,_){
  2274. _.x = _.push(_.X,_.x+x);
  2275. _.y = _.push(_.Y,_.y+y);
  2276. _.push('textx',_.get('textx')+x);
  2277. _.push('texty',_.get('texty')+y);
  2278. },
  2279. doConfig:function(){
  2280. $.Text.superclass.doConfig.call(this);
  2281. var _ = this._(),x = _.x,y=_.y+_.get('padding_top'),w=_.get(_.W),h=_.get(_.H),a=_.get('textAlign');
  2282. x+=(a==_.C?w/2:(a==_.R?w-_.get('padding_right'):_.get('padding_left')));
  2283. if(h){
  2284. y+=h/2;
  2285. _.push('textBaseline','middle');
  2286. }
  2287. _.push('textx',x);
  2288. _.push('texty',y);
  2289. _.push('box_feature',w&&h);
  2290. _.applyGradient();
  2291. }
  2292. });
  2293. /**
  2294. * @end
  2295. */
  2296. ;
  2297. (function($) {
  2298. var PI = Math.PI, inc = PI / 90,inc2 = inc/2, ceil = Math.ceil, floor = Math.floor, PI2 = 2 * PI, max = Math.max, min = Math.min, sin = Math.sin, cos = Math.cos, fd = function(w, c) {
  2299. return w == 1 ? (floor(c) + 0.5) : Math.round(c);
  2300. }, getCurvePoint = function(seg, point, i, smo) {
  2301. var x = point.x, y = point.y, lp = seg[i - 1], np = seg[i + 1], lcx, lcy, rcx, rcy;
  2302. if (i < seg.length - 1) {
  2303. var lastY = lp.y, nextY = np.y, c;
  2304. lcx = (smo * x + lp.x) / (smo + 1);
  2305. lcy = (smo * y + lastY) / (smo + 1);
  2306. rcx = (smo * x + np.x) / (smo + 1);
  2307. rcy = (smo * y + nextY) / (smo + 1);
  2308. c = ((rcy - lcy) * (rcx - x)) / (rcx - lcx) + y - rcy;
  2309. lcy += c;
  2310. rcy += c;
  2311. if (lcy > lastY && lcy > y) {
  2312. lcy = max(lastY, y);
  2313. rcy = 2 * y - lcy;
  2314. } else if (lcy < lastY && lcy < y) {
  2315. lcy = min(lastY, y);
  2316. rcy = 2 * y - lcy;
  2317. }
  2318. if (rcy > nextY && rcy > y) {
  2319. rcy = max(nextY, y);
  2320. lcy = 2 * y - rcy;
  2321. } else if (rcy < nextY && rcy < y) {
  2322. rcy = min(nextY, y);
  2323. lcy = 2 * y - rcy;
  2324. }
  2325. point.rcx = rcx;
  2326. point.rcy = rcy;
  2327. }
  2328. return [lp.rcx || lp.x, lp.rcy || lp.y, lcx || x, lcy || y, x, y];
  2329. },
  2330. pF = function(n){
  2331. return $.isNumber(n)?n:$.parseFloat(n,n);
  2332. },
  2333. simple = function(c) {
  2334. var M,V=0,MI,ML=0,n='minValue',x='maxValue';
  2335. this.total = 0,init=false;
  2336. c.each(function(d,i){
  2337. V = d.value;
  2338. if($.isArray(V)){
  2339. var T = 0;
  2340. ML = V.length>ML?V.length:ML;
  2341. for(var j=0;j<V.length;j++){
  2342. V[j] = pF(V[j]);
  2343. T+=V[j];
  2344. if(!init){
  2345. M = MI = V[j];
  2346. init=true;
  2347. }
  2348. M = max(V[j],M);
  2349. MI = min(V[j],MI);
  2350. }
  2351. d.total = T;
  2352. }else{
  2353. V = pF(V);
  2354. d.value = V;
  2355. this.total+=V;
  2356. if(!init){
  2357. M = MI = V;
  2358. init=true;
  2359. }
  2360. M = max(V,M);
  2361. MI = min(V,MI);
  2362. }
  2363. },this);
  2364. if(this.get(n)){
  2365. MI = min(this.get(n),MI);
  2366. }
  2367. if(this.get(x)){
  2368. M = max(this.get(x),M);
  2369. }
  2370. if($.isArray(this.get('labels'))){
  2371. ML = this.get('labels').length>ML?this.get('labels').length:ML;
  2372. }
  2373. this.push('maxItemSize',ML);
  2374. this.push(n,MI);
  2375. this.push(x,M);
  2376. },
  2377. complex = function(c){
  2378. var _=this._(),M,MI,V,d,L,init=false;
  2379. _.labels = _.get('labels');
  2380. L =_.labels.length;
  2381. if(L==0){
  2382. L=c[0].value.length;for(var i=0;i<L;i++)_.labels.push("");
  2383. }
  2384. _.columns = [];_.total = 0;
  2385. for(var i=0;i<L;i++){
  2386. var item = [];
  2387. for(var j=0;j<c.length;j++){
  2388. d = c[j];
  2389. V = d.value[i];
  2390. if(!V)continue;
  2391. V = pF(V,V);
  2392. d.value[i] = V;
  2393. _.total+=V;
  2394. if(!init){
  2395. M = MI = V;
  2396. init=true;
  2397. }
  2398. M = max(V,M);
  2399. MI = min(V,MI);
  2400. item.push({
  2401. name:d.name,
  2402. value:d.value[i],
  2403. color:d.color
  2404. });
  2405. }
  2406. _.columns.push({
  2407. name:_.labels[i],
  2408. item:item
  2409. });
  2410. }
  2411. _.push('minValue',MI);
  2412. _.push('maxValue',M);
  2413. };
  2414. /**
  2415. * @private support an improved API for drawing in canvas
  2416. */
  2417. function Cans(c) {
  2418. if (typeof c === "string")
  2419. c = $(c);
  2420. if (!c || !c['tagName'] || c['tagName'].toLowerCase() != 'canvas')
  2421. throw new Error("there not a canvas element");
  2422. this.canvas = c;
  2423. this.c = this.canvas.getContext("2d");
  2424. this.width = this.canvas.width;
  2425. this.height = this.canvas.height;
  2426. }
  2427. Cans.prototype = {
  2428. getContext:function(){
  2429. return this.c;
  2430. },
  2431. css : function(a, s) {
  2432. if ($.isDefined(s))
  2433. this.canvas.style[a] = s;
  2434. else
  2435. return this.canvas.style[a];
  2436. },
  2437. /**
  2438. * draw ellipse API
  2439. */
  2440. ellipse : function(x, y, a, b, s, e, c, bo, bow, boc, sw, ccw, a2r, last) {
  2441. var angle = s,a2r = !!a2r;
  2442. this.save().gCo(last).strokeStyle(bo,bow, boc).shadowOn(sw).fillStyle(c).moveTo(x, y).beginPath();
  2443. if (a2r)
  2444. this.moveTo(x, y);
  2445. while (angle <= e) {
  2446. this.lineTo(x + a * cos(angle), y + (b * sin(angle)));
  2447. angle += inc;
  2448. }
  2449. return this.lineTo(x + a * cos(e), y + (b * sin(e))).closePath().stroke(bo).fill(c).restore();
  2450. },
  2451. /**
  2452. * arc
  2453. */
  2454. arc : function(x, y, r, dw, s, e, c, b, bw, bc, sw, ccw, a2r, last) {
  2455. if(!r)return this;
  2456. var ccw = !!ccw, a2r = !!a2r&&!dw;
  2457. this.save().gCo(last).strokeStyle(b,bw,bc).fillStyle(c).beginPath();
  2458. if(dw){
  2459. this.moveTo(x+cos(s)*(r-dw),y+sin(s)*(r-dw)).lineTo(x+cos(s)*r,y+sin(s)*r);
  2460. this.c.arc(x, y, r, s, e,ccw);
  2461. this.lineTo(x+cos(e)*(r-dw),y+sin(e)*(r-dw));
  2462. this.c.arc(x, y, r-dw, e, s,!ccw);
  2463. }else{
  2464. this.c.arc(x, y, r, s, e, ccw);
  2465. }
  2466. if (a2r)
  2467. this.lineTo(x, y);
  2468. this.closePath();
  2469. if(!b){
  2470. this.shadowOn(sw).fill(c);
  2471. }else{
  2472. this.shadowOn(sw).stroke(b).shadowOff().fill(c);
  2473. }
  2474. return this.restore();
  2475. },
  2476. /**
  2477. * draw sector
  2478. */
  2479. sector : function(x, y, r, dw,s, e, c, b, bw, bc, sw, ccw) {
  2480. if (sw)
  2481. this.arc(x, y, r, dw, s, e, c,0,0,0,sw,ccw, true, true);
  2482. return this.arc(x, y, r, dw, s, e, c, b, bw, bc, false, ccw, true);
  2483. },
  2484. sector3D : function() {
  2485. var x0, y0,sPaint = function(x, y, a, b, s, e, ccw, h, c) {
  2486. var Lo = function(A, h) {
  2487. this.lineTo(x + a * cos(A), y + (h || 0) + (b * sin(A)));
  2488. },
  2489. angle = s;
  2490. this.fillStyle($.dark(c)).moveTo(x + a * cos(s), y + (b * sin(s))).beginPath();
  2491. while (angle <= e) {
  2492. Lo.call(this, angle);
  2493. angle = angle + inc;
  2494. }
  2495. Lo.call(this, e);
  2496. this.lineTo(x + a * cos(e), (y + h) + (b * sin(e)));
  2497. angle = e;
  2498. while (angle >= s) {
  2499. Lo.call(this, angle, h);
  2500. angle = angle - inc;
  2501. }
  2502. Lo.call(this, s, h);
  2503. this.lineTo(x + a * cos(s), y + (b * sin(s))).closePath().fill(true);
  2504. }, layerDraw = function(x, y, a, b, ccw, h, A, c) {
  2505. var x0 = x + a * cos(A);
  2506. var y0 = y + h + (b * sin(A));
  2507. this.moveTo(x, y).beginPath().fillStyle(c).lineTo(x, y + h).lineTo(x0, y0).lineTo(x0, y0 - h).lineTo(x, y).closePath().fill(true);
  2508. }, layerPaint = function(x, y, a, b, s, e, ccw, h, c) {
  2509. var q1 = $.quadrantd(s),q2 = $.quadrantd(e);
  2510. c = $.dark(c);
  2511. if (q1==1||q1==2)
  2512. layerDraw.call(this, x, y, a, b, ccw, h, s, c);
  2513. if (q2==0||q2==3)
  2514. layerDraw.call(this, x, y, a, b, ccw, h, e, c);
  2515. };
  2516. var s3 = function(x, y, a, b, s, e, h, c, bo, bow, boc, sw, ccw, isw) {
  2517. /**
  2518. * paint bottom layer
  2519. */
  2520. this.ellipse(x, y + h, a, b, s, e, c, bo, bow, boc, sw, ccw, true);
  2521. /**
  2522. * paint inside layer
  2523. */
  2524. layerPaint.call(this, x, y, a, b, s, e, ccw, h, c);
  2525. /**
  2526. * paint top layer
  2527. */
  2528. this.ellipse(x, y, a, b, s, e, c, bo, bow, boc, false, ccw, true);
  2529. /**
  2530. * paint outside layer
  2531. */
  2532. sPaint.call(this, x, y, a, b, s, e, ccw, h, c);
  2533. return this;
  2534. }
  2535. s3.layerPaint = layerPaint;
  2536. s3.sPaint = sPaint;
  2537. s3.layerDraw = layerDraw;
  2538. return s3;
  2539. }(),
  2540. textStyle : function(a, l, f) {
  2541. return this.textAlign(a).textBaseline(l).textFont(f);
  2542. },
  2543. strokeStyle : function(b,w, c, j) {
  2544. if(b){
  2545. if (w)
  2546. this.c.lineWidth = w;
  2547. if (c)
  2548. this.c.strokeStyle = c;
  2549. if (j)
  2550. this.c.lineJoin = j;
  2551. }
  2552. return this;
  2553. },
  2554. globalAlpha : function(v) {
  2555. if (v)
  2556. this.c.globalAlpha = v;
  2557. return this;
  2558. },
  2559. fillStyle : function(c) {
  2560. if (c)
  2561. this.c.fillStyle = c;
  2562. return this;
  2563. },
  2564. arc2 : function(x, y, r, s, e, c) {
  2565. if(r)
  2566. this.c.arc(x, y, r, s, e, c);
  2567. return this;
  2568. },
  2569. textAlign : function(a) {
  2570. if (a)
  2571. this.c.textAlign = a;
  2572. return this;
  2573. },
  2574. textBaseline : function(l) {
  2575. if (l)
  2576. this.c.textBaseline = l;
  2577. return this;
  2578. },
  2579. textFont : function(font) {
  2580. if (font)
  2581. this.c.font = font;
  2582. return this;
  2583. },
  2584. shadowOn : function(s) {
  2585. if (s) {
  2586. this.c.shadowColor = s.color;
  2587. this.c.shadowBlur = s.blur;
  2588. this.c.shadowOffsetX = s.offsetx;
  2589. this.c.shadowOffsetY = s.offsety;
  2590. }
  2591. return this;
  2592. },
  2593. shadowOff : function() {
  2594. this.c.shadowColor = 'white';
  2595. this.c.shadowBlur = this.c.shadowOffsetX = this.c.shadowOffsetY = 0;
  2596. return this;
  2597. },
  2598. gradient : function(x, y, w, h, c,m) {
  2599. m = m.toLowerCase();
  2600. var x0=x,y0=y,f=!m.indexOf("linear");
  2601. m = m.substring(14);
  2602. if(f){
  2603. switch(m)
  2604.   {
  2605.    case 'updown':
  2606.    y0+=h;
  2607.    break;
  2608.    case 'downup':
  2609.    y+=h;
  2610.    break;
  2611. case 'leftright':
  2612.    x0+=w;
  2613.    break;
  2614.    case 'rightleft':
  2615. x+=w;
  2616.    break;
  2617.    default:
  2618.    return c[0];
  2619.    }
  2620. return this.avgLinearGradient(x,y,x0,y0,c);
  2621. }else{
  2622. x+=w/2;
  2623. y+=h/2;
  2624. if(m=='outin'){
  2625. c.reverse();
  2626. }
  2627. return this.avgRadialGradient(x,y,0,x,y,(w>h?h:w)*0.8,c);
  2628. }
  2629. },
  2630. avgLinearGradient : function(xs, ys, xe, ye, c) {
  2631. var g = this.createLinearGradient(xs, ys, xe, ye);
  2632. for ( var i = 0; i < c.length; i++)
  2633. g.addColorStop(i / (c.length - 1), c[i]);
  2634. return g;
  2635. },
  2636. createLinearGradient : function(xs, ys, xe, ye) {
  2637. return this.c.createLinearGradient(xs, ys, xe, ye);
  2638. },
  2639. avgRadialGradient : function(xs, ys, rs, xe, ye, re, c) {
  2640. var g = this.createRadialGradient(xs, ys, rs, xe, ye, re);
  2641. for ( var i = 0; i < c.length; i++)
  2642. g.addColorStop(i / (c.length - 1), c[i]);
  2643. return g;
  2644. },
  2645. createRadialGradient : function(xs, ys, rs, xe, ye, re) {
  2646. return this.c.createRadialGradient(xs, ys, rs, xe, ye, re);
  2647. },
  2648. text : function(t, x, y, max, color, align, line, font, mode, h,sw,ro) {
  2649. if(t=='')return this;
  2650. return this.save().textStyle(align, line, font).fillText(t, x, y, max, color, mode, h,sw,ro).restore();
  2651. },
  2652. fillText : function(t, x, y, max, color, mode, h,sw,ro) {
  2653. t = t.toString();
  2654. max = max || false;
  2655. mode = mode || 'lr';
  2656. h = h || 16;
  2657. var T = t.split(mode == 'tb' ? "" : "\n");
  2658. if(T.length>1){
  2659. if(this.c.textBaseline=='middle'){
  2660. y = y - (T.length-1)*h/2;
  2661. }else if(this.c.textBaseline=='bottom'){
  2662. y = y - (T.length-1)*h;
  2663. }
  2664. }
  2665. this.save().fillStyle(color).translate(x,y).rotate(inc2*ro).shadowOn(sw);
  2666. T.each(function(t,i) {
  2667. try {
  2668. if (max)
  2669. this.c.fillText(t, 0,i*h, max);
  2670. else
  2671. this.c.fillText(t, 0, i*h);
  2672. } catch (e) {
  2673. console.log(e.message + '[' + t + ',' + x + ',' + y + ']');
  2674. }
  2675. }, this);
  2676. return this.restore();
  2677. },
  2678. measureText : function(t){
  2679. t = t.split("\n");
  2680. var m=0;
  2681. t.each(function(o){
  2682. m = max(this.measureText(o).width,m);
  2683. },this.c);
  2684. return m;
  2685. },
  2686. moveTo : function(x, y) {
  2687. x = x || 0;
  2688. y = y || 0;
  2689. this.c.moveTo(x, y);
  2690. return this;
  2691. },
  2692. lineTo : function(x, y) {
  2693. x = x || 0;
  2694. y = y || 0;
  2695. this.c.lineTo(x, y);
  2696. return this;
  2697. },
  2698. save : function() {
  2699. this.c.save();
  2700. return this;
  2701. },
  2702. restore : function() {
  2703. this.c.restore();
  2704. return this;
  2705. },
  2706. beginPath : function() {
  2707. this.c.beginPath();
  2708. return this;
  2709. },
  2710. closePath : function() {
  2711. this.c.closePath();
  2712. return this;
  2713. },
  2714. stroke : function(s) {
  2715. if(s)
  2716. this.c.stroke();
  2717. return this;
  2718. },
  2719. fill : function(f) {
  2720. if(f)
  2721. this.c.fill();
  2722. return this;
  2723. },
  2724. /**
  2725. * can use cube3D instead of this?
  2726. */
  2727. cube : function(x, y, xv, yv, width, height, zdeep, bg, b, bw, bc, sw) {
  2728. x = fd(bw, x);
  2729. y = fd(bw, y);
  2730. zdeep = (zdeep && zdeep > 0) ? zdeep : width;
  2731. var x1 = x + zdeep * xv, y1 = y - zdeep * yv;
  2732. x1 = fd(bw, x1);
  2733. y1 = fd(bw, y1);
  2734. /**
  2735. * styles -> top-front-right
  2736. */
  2737. if (sw) {
  2738. this.polygon(bg, b, bw, bc, sw, false, [{x:x, y:y},{x: x1, y:y1},{x: x1 + width, y:y1},{x: x + width, y:y}]);
  2739. this.polygon(bg, b, bw, bc, sw, false, [{x:x, y:y},{x: x, y:y + height},{x: x + width,y: y + height},{x: x + width, y:y}]);
  2740. this.polygon(bg, b, bw, bc, sw, false, [{x:x + width, y:y},{x: x1 + width, y:y1},{x: x1 + width, y:y1 + height},{x: x + width, y:y + height}]);
  2741. }
  2742. /**
  2743. * clear the shadow on the body
  2744. */
  2745. this.polygon($.dark(bg), b, bw, bc, false, false, [{x:x, y:y}, {x:x1, y:y1}, {x:x1 + width, y:y1}, {x:x + width, y:y}]);
  2746. this.polygon(bg, b, bw, bc, false, false, [{x:x, y:y}, {x:x, y:y + height}, {x:x + width, y:y + height}, {x:x + width,y: y}]);
  2747. this.polygon($.dark(bg), b, bw, bc, false, false, [{x:x + width, y:y}, {x:x1 + width, y:y1}, {x:x1 + width, y:y1 + height}, {x:x + width, y:y + height}]);
  2748. return this;
  2749. },
  2750. cube3D : function(x, y, rotatex, rotatey, angle, w, h, zh, b, bw, bc, styles) {
  2751. /**
  2752. * styles -> lowerBottom-bottom-left-right-top-front
  2753. */
  2754. x = fd(bw, x);
  2755. y = fd(bw, y);
  2756. zh = (!zh || zh == 0) ? w : zh;
  2757. if (angle) {
  2758. var P = $.vectorP2P(rotatex, rotatey);
  2759. rotatex = x + zh * P.x, rotatey = y - zh * P.y;
  2760. } else {
  2761. rotatex = x + zh * rotatex, rotatey = y - zh * rotatey;
  2762. }
  2763. while (styles.length < 6)
  2764. styles.push(false);
  2765. rotatex = fd(bw, rotatex);
  2766. rotatey = fd(bw, rotatey);
  2767. var side = [];
  2768. if (rotatey < 0) {
  2769. if ($.isObject(styles[4]))
  2770. side.push($.applyIf({
  2771. points : [{x:x,y:y - h},{x:rotatex,y:rotatey - h},{x:rotatex + w, y:rotatey - h},{x: x + w, y:y - h}]
  2772. }, styles[4]));
  2773. } else {
  2774. if ($.isObject(styles[0]))
  2775. side.push($.applyIf({
  2776. points : [{x:x, y:y},{x: rotatex, y:rotatey},{x: rotatex + w, y:rotatey},{x: x + w,y:y}]
  2777. }, styles[0]));
  2778. }
  2779. if ($.isObject(styles[1]))
  2780. side.push($.applyIf({
  2781. points : [{x:rotatex, y:rotatey},{x: rotatex, y:rotatey - h}, {x:rotatex + w, y:rotatey - h},{x: rotatex + w,y:rotatey}]
  2782. }, styles[1]));
  2783. if ($.isObject(styles[2]))
  2784. side.push($.applyIf({
  2785. points : [{x:x, y:y}, {x:x, y:y - h},{x: rotatex, y:rotatey - h},{x: rotatex, y:rotatey}]
  2786. }, styles[2]));
  2787. if ($.isObject(styles[3]))
  2788. side.push($.applyIf({
  2789. points : [{x:x + w, y:y}, {x:x + w, y:y - h}, {x:rotatex + w, y:rotatey - h}, {x:rotatex + w, y:rotatey}]
  2790. }, styles[3]));
  2791. if (rotatey < 0) {
  2792. if ($.isObject(styles[0]))
  2793. side.push($.applyIf({
  2794. points : [{x:x,y: y}, {x:rotatex, y:rotatey}, {x:rotatex + w, y:rotatey}, {x:x + w, y:y}]
  2795. }, styles[0]));
  2796. } else {
  2797. if ($.isObject(styles[4]))
  2798. side.push($.applyIf({
  2799. points : [{x:x, y:y - h}, {x:rotatex, y:rotatey - h}, {x:rotatex + w, y:rotatey - h}, {x:x + w, y:y - h}]
  2800. }, styles[4]));
  2801. }
  2802. if ($.isObject(styles[5]))
  2803. side.push($.applyIf({
  2804. points : [{x:x, y:y}, {x:x, y:y - h}, {x:x + w, y:y - h}, {x:x + w, y:y}]
  2805. }, styles[5]));
  2806. side.each(function(s) {
  2807. this.polygon(s.color, b, bw, bc, s.shadow, s.alpha, s.points);
  2808. }, this);
  2809. return this;
  2810. },
  2811. polygon : function(bg, b, bw, bc, sw, alpham, p, smooth, smo,l) {
  2812. this.save().strokeStyle(b,bw, bc).beginPath().fillStyle(bg).globalAlpha(alpham).shadowOn(sw).moveTo(p[0].x,p[0].y);
  2813. if (smooth) {
  2814. this.moveTo(fd(bw,l[0].x),fd(bw,l[0].y)).lineTo(fd(bw, p[0].x), fd(bw, p[0].y));
  2815. for ( var i = 1; i < p.length; i++)
  2816. this.bezierCurveTo(getCurvePoint(p, p[i], i, smo));
  2817. this.lineTo(fd(bw,l[1].x),fd(bw,l[1].y));
  2818. } else {
  2819. for ( var i = 1; i < p.length; i++)
  2820. this.lineTo(fd(bw, p[i].x), fd(bw, p[i].y));
  2821. }
  2822. return this.closePath().stroke(b).fill(bg).restore();
  2823. },
  2824. lines : function(p, w, c, last) {
  2825. this.save().gCo(last).beginPath().strokeStyle(true,w, c).moveTo(fd(w, p[0]), fd(w, p[1]));
  2826. for ( var i = 2; i < p.length - 1; i += 2) {
  2827. this.lineTo(fd(w, p[i]), fd(w, p[i + 1]));
  2828. }
  2829. return this.stroke(true).restore();
  2830. },
  2831. bezierCurveTo : function(r) {
  2832. this.c.bezierCurveTo(r[0], r[1], r[2], r[3], r[4], r[5]);
  2833. return this;
  2834. },
  2835. label : function(p, w, c) {
  2836. return this.save()
  2837. .beginPath()
  2838. .strokeStyle(true,w, c)
  2839. .moveTo(fd(w, p[0].x), fd(w, p[0].y))
  2840. .bezierCurveTo([p[1].x,p[1].y,p[2].x,p[2].y,p[3].x,p[3].y])
  2841. .stroke(true)
  2842. .restore();
  2843. },
  2844. lineArray : function(p, w, c, smooth, smo) {
  2845. this.save().beginPath().strokeStyle(true,w, c).moveTo(fd(w, p[0].x), fd(w, p[0].y));
  2846. for ( var i = 1; i < p.length; i++){
  2847. if (smooth) {
  2848. this.bezierCurveTo(getCurvePoint(p, p[i], i, smo || 1.5));
  2849. } else {
  2850. this.lineTo(fd(w, p[i].x), fd(w, p[i].y));
  2851. }
  2852. }
  2853. return this.stroke(true).restore();
  2854. },
  2855. manyLine : function(p, w, c, smooth, smo) {
  2856. var T = [],Q = false;
  2857. smo = smo || 1.5;
  2858. p.each(function(p0){
  2859. if(p0.ignored&&Q){
  2860. this.lineArray(T, w, c, smooth, smo);
  2861. T = [];
  2862. Q = false;
  2863. }else if(!p0.ignored){
  2864. T.push(p0);
  2865. Q = true;
  2866. }
  2867. },this);
  2868. if(T.length){
  2869. this.lineArray(T, w, c, smooth, smo);
  2870. }
  2871. },
  2872. dotted : function(x1, y1, x2, y2, w, c,L,f,last) {
  2873. if (!w)
  2874. return this;
  2875. x1 = fd(w, x1);
  2876. y1 = fd(w, y1);
  2877. x2 = fd(w, x2);
  2878. y2 = fd(w, y2);
  2879. var d = $.distanceP2P(x1, y1, x2, y2),t;
  2880. if(L<=0||d<=L||(x1!=x2&&y1!=y2)){
  2881. return this.line(x1, y1, x2, y2, w, c, last);
  2882. }
  2883. if(x1>x2||y1>y2){
  2884. t = x1;
  2885. x1 = x2;
  2886. x2 = t;
  2887. t = y1;
  2888. y1 = y2;
  2889. y2 = t;
  2890. }
  2891. this.save().gCo(last).strokeStyle(true,w, c).beginPath().moveTo(x1,y1);
  2892. var S = L*(f || 1),g = floor(d/(L+S)),k = (d-g*(L+S))>L,h=(y1==y2);
  2893. g = k?g+1:g;
  2894. for(var i=1;i<=g;i++){
  2895. this.lineTo(h?x1+L*i+S*(i-1):x1,h?y1:y1+L*i+S*(i-1)).moveTo(h?x1+(L+S)*i:x1, h?y1:y1+(L+S)*i);
  2896. }
  2897. if(!k){
  2898. this.lineTo(x2,y2);
  2899. }
  2900. return this.stroke(true).restore();
  2901. },
  2902. line : function(x1, y1, x2, y2, w, c, last) {
  2903. if (!w)
  2904. return this;
  2905. this.save().gCo(last);
  2906. return this.beginPath().strokeStyle(true,w, c).moveTo(fd(w, x1), fd(w, y1)).lineTo(fd(w, x2), fd(w, y2)).stroke(true).restore();
  2907. },
  2908. round : function(x, y, r, c, bw, bc) {
  2909. return this.arc(x, y, r,0, 0, PI2, c, !!bc, bw, bc);
  2910. },
  2911. fillRect : function(x, y, w, h) {
  2912. this.c.fillRect(x, y, w, h);
  2913. return this;
  2914. },
  2915. translate : function(x, y) {
  2916. this.c.translate(x, y);
  2917. return this;
  2918. },
  2919. rotate : function(r) {
  2920. this.c.rotate(r);
  2921. return this;
  2922. },
  2923. clearRect : function(x, y, w, h) {
  2924. x = x || 0;
  2925. y = y || 0;
  2926. w = w || this.width;
  2927. h = h || this.height;
  2928. this.c.clearRect(x, y, w, h);
  2929. return this;
  2930. },
  2931. gCo : function(l) {
  2932. if(l)
  2933. return this.gCO(l);
  2934. return this;
  2935. },
  2936. gCO : function(l) {
  2937. this.c.globalCompositeOperation = l ? "destination-over" : "source-over";
  2938. return this;
  2939. },
  2940. box : function(x, y, w, h, b, bg, shadow, m,last) {
  2941. b = b || {
  2942. enable : 0
  2943. }
  2944. if (b.enable) {
  2945. var j = b.width, c = b.color, r = b.radius, f = $.isNumber(j);
  2946. j = $.parsePadding(j);
  2947. if(j[0]==j[1]&&j[1]==j[2]&&j[2]==j[3]){
  2948. f = true;
  2949. }
  2950. m = m?1:-1;
  2951. w += m*(j[1] + j[3]) / 2;
  2952. h += m*(j[0] + j[2]) / 2;
  2953. x -= m*(j[3] / 2);
  2954. y -= m*(j[0] / 2);
  2955. j = f ? j[0] : j;
  2956. r = (!f ||!r|| r == 0 || r == '0') ? 0 : $.parsePadding(r);
  2957. }
  2958. this.save().gCo(last).fillStyle(bg).strokeStyle(f,j, c);
  2959. /**
  2960. * draw a round corners border
  2961. */
  2962. if (r) {
  2963. this.beginPath().moveTo(fd(j,x+r[0]), fd(j, y))
  2964. .lineTo(fd(j,x+w - r[1]), fd(j, y))
  2965. .arc2(fd(j,x+w - r[1]), fd(j, y+r[1]), r[1], PI*3/2, PI2)
  2966. .lineTo(fd(j, x+w), fd(j,y+h - r[2]))
  2967. .arc2(fd(j,x+w - r[2]), fd(j, y+h-r[2]), r[2], 0, PI/2)
  2968. .lineTo(fd(j,x+r[3]), fd(j, y+h))
  2969. .arc2(fd(j,x+r[3]), fd(j, y+h-r[3]), r[3], PI/2, PI)
  2970. .lineTo(fd(j,x), fd(j,y+r[0]))
  2971. .arc2(fd(j,x+r[0]), fd(j, y+r[0]), r[0], PI, PI*3/2)
  2972. .closePath().shadowOn(shadow).stroke(j).shadowOff().fill(bg);
  2973. } else {
  2974. if (!b.enable || f) {
  2975. if (j&&b.enable){
  2976. this.shadowOn(shadow).c.strokeRect(x, y, w, h);
  2977. this.shadowOff();
  2978. }
  2979. if (bg)
  2980. this.fillRect(x, y, w, h);
  2981. } else {
  2982. if(j){
  2983. c = $.isArray(c) ? c : [c, c, c, c];
  2984. this.shadowOn(shadow).line(x+w, y+j[0] / 2, x+w, y+h - j[0] / 2, j[1], c[1], 0).line(x, y+j[0] / 2, x, y+h - j[0] / 2, j[3], c[3], 0).line(floor(x-j[3] / 2),y, x+w + j[1] / 2, y, j[0], c[0], 0).line(floor(x-j[3] / 2), y+h, x+w + j[1] / 2, y+h, j[2], c[2], 0).shadowOff();
  2985. }
  2986. if (bg) {
  2987. this.beginPath().moveTo(floor(x+j[3] / 2), floor(y+j[0] / 2)).lineTo(ceil(x+w - j[1] / 2), y+j[0] / 2).lineTo(ceil(x+w - j[1] / 2), ceil(y+h - j[2] / 2)).lineTo(floor(x+j[3] / 2), ceil(y+h - j[2] / 2)).lineTo(floor(x+j[3] / 2), floor(y+j[0] / 2)).closePath().fill(bg);
  2988. }
  2989. }
  2990. }
  2991. return this.restore();
  2992. },
  2993. toDataURL : function(g) {
  2994. return this.canvas.toDataURL(g || "image/png");
  2995. },
  2996. addEvent : function(type, fn, useCapture) {
  2997. $.Event.addEvent(this.canvas, type, fn, useCapture);
  2998. }
  2999. }
  3000. /**
  3001. * the public method,inner use
  3002. */
  3003. $.taylor = {
  3004. light:function(_,e){
  3005. e.highlight = false;
  3006. _.on('mouseover',function(){
  3007. e.highlight = true;
  3008. _.redraw('mouseover');
  3009. }).on('mouseout',function(){
  3010. e.highlight = false;
  3011. _.redraw('mouseout');
  3012. }).on('beforedraw',function(){
  3013. _.push('f_color',e.highlight?_.get('light_color'):_.get('f_color_'));
  3014. return true;
  3015. });
  3016. }
  3017. }
  3018. /**
  3019. * @overview this component use for abc
  3020. * @component#$.Chart
  3021. * @extend#$.Painter
  3022. */
  3023. $.Chart = $.extend($.Painter, {
  3024. /**
  3025. * @cfg {TypeName}
  3026. */
  3027. configure : function() {
  3028. /**
  3029. * invoked the super class's configuration
  3030. */
  3031. $.Chart.superclass.configure.apply(this, arguments);
  3032. /**
  3033. * indicate the element's type
  3034. */
  3035. this.type = 'chart';
  3036. /**
  3037. * indicate the data structure
  3038. */
  3039. this.dataType = 'simple';
  3040. this.set({
  3041. render : '',
  3042. /**
  3043. * @cfg {Array} Required,The datasource of Chart.must be not empty.
  3044. */
  3045. data : [],
  3046. /**
  3047. * @cfg {Number} Specifies the width of this canvas
  3048. */
  3049. width : undefined,
  3050. /**
  3051. * @cfg {Number} Specifies the height of this canvas
  3052. */
  3053. height : undefined,
  3054. /**
  3055. * @cfg {String} Specifies the default lineJoin of the canvas's context in this element.(defaults to 'round')
  3056. */
  3057. lineJoin : 'round',
  3058. /**
  3059. * @cfg {String} this property specifies the horizontal alignment of chart in an module (defaults to 'center') Available value are:
  3060. * @Option 'left'
  3061. * @Option 'center'
  3062. * @Option 'right'
  3063. */
  3064. align : 'center',
  3065. /**
  3066. * @cfg {Boolean} If true mouse change to a pointer when a mouseover fired.only available when use PC.(defaults to true)
  3067. */
  3068. default_mouseover_css : true,
  3069. /**
  3070. * @cfg {Boolean} If true ignore the event touchmove.only available when support touchEvent.(defaults to false)
  3071. */
  3072. turn_off_touchmove : false,
  3073. /**
  3074. * @cfg {Boolean} Specifies as true to display with percent.(default to false)
  3075. */
  3076. showpercent : false,
  3077. /**
  3078. * @cfg {Number} Specifies the number of decimal when use percent.(default to 1)
  3079. */
  3080. decimalsnum : 1,
  3081. /**
  3082. * @cfg {Object/String} Specifies the config of Title details see <link>$.Text</link>,If given a string,it will only apply the text.note:If the text is empty,then will not display
  3083. */
  3084. title : {
  3085. text : '',
  3086. fontweight : 'bold',
  3087. /**
  3088. * Specifies the font-size in pixels of title.(default to 20)
  3089. */
  3090. fontsize : 20,
  3091. /**
  3092. * Specifies the height of title will be take.(default to 30)
  3093. */
  3094. height : 30
  3095. },
  3096. /**
  3097. * @cfg {Object/String}Specifies the config of subtitle details see <link>$.Text</link>,If given a string,it will only apply the text.note:If the title or subtitle'text is empty,then will not display
  3098. */
  3099. subtitle : {
  3100. text : '',
  3101. fontweight : 'bold',
  3102. /**
  3103. * Specifies the font-size in pixels of title.(default to 16)
  3104. */
  3105. fontsize : 16,
  3106. /**
  3107. * Specifies the height of title will be take.(default to 20)
  3108. */
  3109. height : 20
  3110. },
  3111. /**
  3112. * @cfg {Object/String}Specifies the config of footnote details see <link>$.Text</link>,If given a string,it will only apply the text.note:If the text is empty,then will not display
  3113. */
  3114. footnote : {
  3115. text : '',
  3116. /**
  3117. * Specifies the font-color of footnote.(default to '#5d7f97')
  3118. */
  3119. color : '#5d7f97',
  3120. textAlign : 'right',
  3121. /**
  3122. * Specifies the height of title will be take.(default to 20)
  3123. */
  3124. height : 20
  3125. },
  3126. /**
  3127. * @inner {String} Specifies how align title horizontally Available value are:
  3128. * @Option 'left'
  3129. * @Option 'center'
  3130. * @Option 'right'
  3131. */
  3132. title_align : 'center',
  3133. /**
  3134. * @inner {String} Specifies how align title vertically Available value are:
  3135. * @Option 'top'
  3136. * @Option 'middle' Only applies when title_writingmode = 'tb'
  3137. * @Option 'bottom'
  3138. */
  3139. title_valign : 'top',
  3140. /**
  3141. * @cfg {Boolean} If true element will have a animation when show, false to skip the animation.(default to false)
  3142. */
  3143. animation : false,
  3144. /**
  3145. * @Function {Function} the custom funtion for animation.(default to null)
  3146. */
  3147. doAnimation : null,
  3148. /**
  3149. * @cfg {String} (default to 'ease-in-out') Available value are:
  3150. * @Option 'easeIn'
  3151. * @Option 'easeOut'
  3152. * @Option 'easeInOut'
  3153. * @Option 'linear'
  3154. */
  3155. animation_timing_function : 'easeInOut',
  3156. /**
  3157. * @cfg {Number} Specifies the duration when animation complete in millisecond.(default to 1000)
  3158. */
  3159. duration_animation_duration : 1000,
  3160. /**
  3161. * @cfg {Number} Specifies the chart's z_index.override the default as 999 to make it at top layer.(default to 999)
  3162. */
  3163. z_index:999,
  3164. /**
  3165. * @cfg {Object}Specifies the config of Legend.For details see <link>$.Legend</link> Note:this has a extra property named 'enable',indicate whether legend available(default to false)
  3166. */
  3167. legend : {
  3168. enable : false
  3169. },
  3170. /**
  3171. * @cfg {Object} Specifies the config of Tip.For details see <link>$.Tip</link> Note:this has a extra property named 'enable',indicate whether tip available(default to false)
  3172. */
  3173. tip : {
  3174. enable : false
  3175. }
  3176. });
  3177. /**
  3178. * register the common event
  3179. */
  3180. this.registerEvent(
  3181. /**
  3182. * @event Fires before this element Animation.Only valid when <link>animation</link> is true
  3183. * @paramter $.Chart#this
  3184. */
  3185. 'beforeAnimation',
  3186. /**
  3187. * @event Fires when this element Animation finished.Only valid when <link>animation</link> is true
  3188. * @paramter $.Chart#this
  3189. */
  3190. 'afterAnimation', 'animating');
  3191. this.T = null;
  3192. this.RENDERED = false;
  3193. this.animationed = false;
  3194. this.data = [];
  3195. this.plugins = [];
  3196. this.oneways = [];
  3197. this.total = 0;
  3198. },
  3199. toDataURL : function(g) {
  3200. return this.T.toDataURL(g);
  3201. },
  3202. segmentRect : function() {
  3203. this.T.clearRect(this.get('l_originx'), this.get('t_originy'), this.get('client_width'), this.get('client_height'));
  3204. },
  3205. resetCanvas : function() {
  3206. this.T.box(this.get('l_originx'), this.get('t_originy'), this.get('client_width'), this.get('client_height'),0,this.get('f_color'),0,0,true);
  3207. },
  3208. animation : function(_) {
  3209. /**
  3210. * clear the part of canvas
  3211. */
  3212. _.segmentRect();
  3213. /**
  3214. * doAnimation of implement
  3215. */
  3216. _.doAnimation(_.variable.animation.time, _.duration,_);
  3217. /**
  3218. * draw plugins
  3219. */
  3220. if(_.legend)
  3221. _.legend.draw();
  3222. /**
  3223. * draw plugins
  3224. */
  3225. _.plugins.each(function(p){
  3226. if(p.A_draw){
  3227. p.variable.animation.animating =true;
  3228. p.variable.animation.time =_.variable.animation.time;
  3229. p.variable.animation.duration =_.duration;
  3230. p.draw();
  3231. p.variable.animation.animating =false;
  3232. }
  3233. });
  3234. /**
  3235. * fill the background
  3236. */
  3237. _.resetCanvas();
  3238. if (_.variable.animation.time < _.duration) {
  3239. _.variable.animation.time++;
  3240. $.requestAnimFrame(function() {
  3241. _.animation(_);
  3242. });
  3243. } else {
  3244. $.requestAnimFrame(function() {
  3245. _.variable.animation.time = 0;
  3246. _.animationed = true;
  3247. _.draw();
  3248. _.processAnimation = false;
  3249. _.fireEvent(_, 'afterAnimation', [_]);
  3250. });
  3251. }
  3252. },
  3253. runAnimation : function() {
  3254. this.fireEvent(this, 'beforeAnimation', [this]);
  3255. this.animation(this);
  3256. },
  3257. doSort:function(){
  3258. this.components.sor(function(p, q){
  3259. return ($.isArray(p)?(p.zIndex||0):p.get('z_index'))>($.isArray(q)?(q.zIndex||0):q.get('z_index'))});
  3260. },
  3261. commonDraw : function(_,e) {
  3262. $.Assert.isTrue(_.RENDERED, _.type + ' has not rendered.');
  3263. $.Assert.isTrue(_.initialization, _.type + ' has initialize failed.');
  3264. $.Assert.gt(_.data.length,0,_.type + '\'s data is empty.');
  3265. if (!_.redraw) {
  3266. _.doSort();
  3267. _.oneways.eachAll(function(o) {o.draw()});
  3268. }
  3269. _.redraw = true;
  3270. if (!_.animationed && _.get('animation')) {
  3271. _.runAnimation();
  3272. return;
  3273. }
  3274. _.segmentRect();
  3275. _.components.eachAll(function(c) {
  3276. c.draw(e);
  3277. });
  3278. _.resetCanvas();
  3279. },
  3280. /**
  3281. * @method register the customize component
  3282. * @paramter <link>$.Custom</link>#component
  3283. * @return void
  3284. */
  3285. plugin : function(c) {
  3286. c.inject(this);
  3287. this.components.push(c);
  3288. this.plugins.push(c);
  3289. },
  3290. /**
  3291. * @method return the title,return undefined if unavailable
  3292. * @return <link>$.Text</link>#the title object
  3293. */
  3294. getTitle:function(){
  3295. return this.title;
  3296. },
  3297. /**
  3298. * @method return the subtitle,return undefined if unavailable
  3299. * @return <link>$.Text</link>#the subtitle object
  3300. */
  3301. getSubTitle:function(){
  3302. return this.subtitle;
  3303. },
  3304. /**
  3305. * @method return the footnote,return undefined if unavailable
  3306. * @return <link>$.Text</link>#the footnote object
  3307. */
  3308. getFootNote:function(){
  3309. return this.footnote;
  3310. },
  3311. /**
  3312. * @method return the main Drawing Area's dimension,return following property:
  3313. * x:the left-top coordinate-x
  3314. * y:the left-top coordinate-y
  3315. * width:the width of drawing area
  3316. * height:the height of drawing area
  3317. * @return Object#contains dimension info
  3318. */
  3319. getDrawingArea:function(){
  3320. return {
  3321. x:this.get("l_originx"),
  3322. x:this.get("t_originy"),
  3323. width:this.get("client_width"),
  3324. height:this.get("client_height")
  3325. }
  3326. },
  3327. /**
  3328. * @method set up the chart by latest configruation
  3329. * @return void
  3330. */
  3331. setUp:function(){
  3332. this.redraw = false;
  3333. this.T.clearRect();
  3334. this.initialization = false;
  3335. this.initialize();
  3336. },
  3337. create : function(_,shell) {
  3338. /**
  3339. * fit the window
  3340. */
  3341. if(_.get('fit')){
  3342. var w = window.innerWidth,
  3343. h = window.innerHeight,
  3344. style = $.getDoc().body.style;
  3345. style.padding = "0px";
  3346. style.margin = "0px";
  3347. style.overflow = "hidden";
  3348. _.push(_.W, w);
  3349. _.push(_.H, h);
  3350. }
  3351. /**
  3352. * did default should to calculate the size of warp?
  3353. */
  3354. _.width = _.pushIf(_.W, 400);
  3355. _.height = _.pushIf(_.H, 300);
  3356. _.canvasid = $.iGather(_.type);
  3357. _.shellid = "shell-"+_.canvasid;
  3358. var H = [];
  3359. H.push("<div id='");
  3360. H.push(_.shellid);
  3361. H.push("' style='width:");
  3362. H.push(_.width);
  3363. H.push("px;height:");
  3364. H.push(_.height);
  3365. H.push("px;padding:0px;margin:0px;overflow:hidden;position:relative;'>");
  3366. H.push("<canvas id= '");
  3367. H.push(_.canvasid);
  3368. H.push("' width='");
  3369. H.push(_.width);
  3370. H.push("' height='");
  3371. H.push(_.height);
  3372. H.push("'><p>Your browser does not support the canvas element</p></canvas></div>");
  3373. /**
  3374. * also use appendChild()
  3375. */
  3376. shell.innerHTML = H.join("");
  3377. _.shell = $(_.shellid);
  3378. /**
  3379. * the base canvas wrap for draw
  3380. */
  3381. _.T = _.target = new Cans(_.canvasid);
  3382. _.RENDERED = true;
  3383. },
  3384. initialize : function() {
  3385. var _ = this._(),d = _.get('data'),r = _.get('render');
  3386. /**
  3387. * create dom
  3388. */
  3389. if (!_.RENDERED) {
  3390. if (typeof r == "string" && $(r))
  3391. _.create(_,$(r));
  3392. else if (typeof r == 'object')
  3393. _.create(_,r);
  3394. }
  3395. /**
  3396. * set up
  3397. */
  3398. if (d.length > 0 && _.RENDERED && !_.initialization){
  3399. if(_.dataType=='simple'){
  3400. simple.call(_,d);
  3401. }else if(_.dataType=='complex'){
  3402. complex.call(_,d);
  3403. }
  3404. _.data = d;
  3405. _.doConfig();
  3406. _.initialization = true;
  3407. }
  3408. },
  3409. /**
  3410. * @method turn off the event listener
  3411. * @return void
  3412. */
  3413. eventOff:function(){this.stopEvent = true},
  3414. /**
  3415. * @method turn on the event listener
  3416. * @return void
  3417. */
  3418. eventOn:function(){this.stopEvent = false},
  3419. /**
  3420. * this method only invoked once
  3421. */
  3422. oneWay:function(_){
  3423. var E = _.variable.event,tot=!_.get('turn_off_touchmove'), mCSS = !$.touch&&_.get('default_mouseover_css'), O, AO,events = $.touch?['touchstart','touchmove']:['click','mousemove'];
  3424. _.stopEvent = false;
  3425. events.each(function(it) {
  3426. _.T.addEvent(it, function(e) {
  3427. if (_.processAnimation||_.stopEvent)
  3428. return;
  3429. if(e.targetTouches&&e.targetTouches.length!=1){
  3430. return;
  3431. }
  3432. _.fireEvent(_, it, [_, $.Event.fix(e)]);
  3433. }, false);
  3434. });
  3435. _.on(events[0], function(_, e) {
  3436. _.components.eachAll(function(C) {
  3437. var M = C.isMouseOver(e);
  3438. if (M.valid){
  3439. E.click = true;
  3440. C.fireEvent(C,'click', [C, e, M]);
  3441. return !e.stopPropagation;
  3442. }
  3443. });
  3444. if(E.click){
  3445. if(tot)
  3446. e.event.preventDefault();
  3447. E.click = false;
  3448. }
  3449. });
  3450. if(!$.touch||tot)
  3451. _.on(events[1], function(_, e) {
  3452. O = AO = false;
  3453. _.components.eachAll(function(cot) {
  3454. var cE = cot.variable.event, M = cot.isMouseOver(e);
  3455. if (M.valid) {
  3456. O = true;
  3457. AO = AO || cot.atomic;
  3458. if (!E.mouseover) {
  3459. E.mouseover = true;
  3460. _.fireEvent(_, 'mouseover', [cot,e, M]);
  3461. }
  3462. if (mCSS && AO) {
  3463. _.T.css("cursor", "pointer");
  3464. }
  3465. if (!cE.mouseover) {
  3466. cE.mouseover = true;
  3467. cot.fireEvent(cot, 'mouseover', [cot,e, M]);
  3468. }
  3469. cot.fireEvent(cot, 'mousemove', [cot,e, M]);
  3470. if(M.stop){
  3471. return false;
  3472. }
  3473. } else {
  3474. if (cE.mouseover) {
  3475. cE.mouseover = false;
  3476. cot.fireEvent(cot, 'mouseout', [cot,e, M]);
  3477. }
  3478. }
  3479. return !e.stopPropagation;
  3480. });
  3481. if(E.mouseover){
  3482. e.event.preventDefault();
  3483. if (mCSS && !AO) {
  3484. _.T.css("cursor", "default");
  3485. }
  3486. if (!O && E.mouseover) {
  3487. E.mouseover = false;
  3488. _.fireEvent(_, 'mouseout', [_,e]);
  3489. }
  3490. }
  3491. });
  3492. _.oneWay = $.emptyFn;
  3493. },
  3494. getPercent:function(v){
  3495. return this.get('showpercent') ? $.toPercent(v / this.total, this.get('decimalsnum')) : v;
  3496. },
  3497. doActing:function(_,d,o,i,t){
  3498. var f=!!_.get('communal_acting');
  3499. /**
  3500. * store or restore the option
  3501. */
  3502. _.push(f?'sub_option':'communal_acting',$.clone(_.get(f?'communal_acting':'sub_option'),true));
  3503. /**
  3504. * merge the option
  3505. */
  3506. $.merge(_.get('sub_option'),d);
  3507. /**
  3508. * merge specific option
  3509. */
  3510. $.merge(_.get('sub_option'),o);
  3511. /**
  3512. * prevent there no property background_color,use coloe instead
  3513. */
  3514. _.pushIf('sub_option.background_color', d.color);
  3515. if (_.get('sub_option.tip.enable')){
  3516. _.push('sub_option.tip.text',t || (d.name + ' ' +_.getPercent(d.value)));
  3517. _.push('sub_option.tip.name',d.name);
  3518. _.push('sub_option.tip.value',d.value);
  3519. _.push('sub_option.tip.total',_.total);
  3520. }
  3521. },
  3522. doConfig : function() {
  3523. $.Chart.superclass.doConfig.call(this);
  3524. var _ = this._();
  3525. $.Assert.isArray(_.data);
  3526. _.T.strokeStyle(true,0, _.get('strokeStyle'), _.get('lineJoin'));
  3527. _.processAnimation = _.get('animation');
  3528. /**
  3529. * for store the option of each item in chart
  3530. */
  3531. _.push('communal_acting',0);
  3532. _.duration = ceil(_.get('duration_animation_duration') * $.FRAME / 1000);
  3533. if($.isFunction(_.get('doAnimation'))){
  3534. _.doAnimation = _.get('doAnimation');
  3535. }
  3536. _.variable.animation = {
  3537. type : 0,
  3538. time : 0,
  3539. queue : []
  3540. };
  3541. _.components = [];
  3542. _.oneways = [];
  3543. /**
  3544. * push the background in it
  3545. */
  3546. _.oneways.push(new $.Custom({
  3547. drawFn:function(){
  3548. _.T.box(0, 0, _.width, _.height, _.get('border'), _.get('f_color'),0,0,true);
  3549. }
  3550. }));
  3551. /**
  3552. * make sure hold the customize plugin
  3553. */
  3554. _.plugins.each(function(o){
  3555. _.components.push(o);
  3556. });
  3557. _.applyGradient();
  3558. _.animationArithmetic = $.getAA(_.get('animation_timing_function'));
  3559. /**
  3560. _.on('afterAnimation', function() {
  3561. var N = _.variable.animation.queue.shift();
  3562. if (N) {
  3563. _[N.handler].apply(_, N.arguments);
  3564. }
  3565. });
  3566. */
  3567. _.oneWay(_);
  3568. _.push('r_originx', _.width - _.get('padding_right'));
  3569. _.push('b_originy', _.height - _.get('padding_bottom'));
  3570. var H = 0, l = _.push('l_originx', _.get('padding_left')), t = _.push('t_originy', _.get('padding_top')), w = _.push('client_width', (_.get(_.W) - _.get('hpadding'))), h;
  3571. if ($.isString(_.get('title'))) {
  3572. _.push('title', $.applyIf({
  3573. text : _.get('title')
  3574. }, _.default_.title));
  3575. }
  3576. if ($.isString(_.get('subtitle'))) {
  3577. _.push('subtitle', $.applyIf({
  3578. text : _.get('subtitle')
  3579. }, _.default_.subtitle));
  3580. }
  3581. if ($.isString(_.get('footnote'))) {
  3582. _.push('footnote', $.applyIf({
  3583. text : _.get('footnote')
  3584. }, _.default_.footnote));
  3585. }
  3586. if (_.get('title.text') != '') {
  3587. var st = _.get('subtitle.text') != '';
  3588. H = st ? _.get('title.height') + _.get('subtitle.height') : _.get('title.height');
  3589. t = _.push('t_originy', t + H);
  3590. _.push('title.originx', l);
  3591. _.push('title.originy', _.get('padding_top'));
  3592. _.push('title.width', w);
  3593. _.title = new $.Text(_.get('title'), _);
  3594. _.oneways.push(_.title);
  3595. if (st) {
  3596. _.push('subtitle.originx', l);
  3597. _.push('subtitle.originy', _.get('title.originy') + _.get('title.height'));
  3598. _.push('subtitle.width', w);
  3599. _.subtitle = new $.Text(_.get('subtitle'), _);
  3600. _.oneways.push(_.subtitle);
  3601. }
  3602. }
  3603. if (_.get('footnote.text') != '') {
  3604. var g = _.get('footnote.height');
  3605. H += g;
  3606. _.push('b_originy', _.get('b_originy') - g);
  3607. _.push('footnote.originx', l);
  3608. _.push('footnote.originy', _.get('b_originy'));
  3609. _.push('footnote.width', w);
  3610. _.footnote = new $.Text(_.get('footnote'), _);
  3611. _.oneways.push(_.footnote);
  3612. }
  3613. h = _.push('client_height', (_.get(_.H) - _.get('vpadding') - H));
  3614. _.push('minDistance', min(w, h));
  3615. _.push('maxDistance', max(w, h));
  3616. _.push('minstr', w < h ? _.W : _.H);
  3617. _.push('centerx', l + w / 2);
  3618. _.push('centery', t + h / 2);
  3619. /**
  3620. * clone config to sub_option
  3621. */
  3622. $.applyIf(_.get('sub_option'), $.clone(['shadow', 'shadow_color', 'shadow_blur', 'shadow_offsetx', 'shadow_offsety','tip'], _.options,true));
  3623. /**
  3624. * legend
  3625. */
  3626. if (_.get('legend.enable')) {
  3627. _.legend = new $.Legend($.apply({
  3628. maxwidth : w,
  3629. data : _.data
  3630. }, _.get('legend')), _);
  3631. _.components.push(_.legend);
  3632. }
  3633. _.push('sub_option.tip.wrap',_.push('tip.wrap', _.shell));
  3634. }
  3635. });
  3636. })($);
  3637. /**
  3638. * @end
  3639. */
  3640. /**
  3641. * @overview this component use for abc
  3642. * @component#$.Custom
  3643. * @extend#$.Component
  3644. */
  3645. $.Custom = $.extend($.Component,{
  3646. configure:function(){
  3647. /**
  3648. * invoked the super class's configuration
  3649. */
  3650. $.Custom.superclass.configure.apply(this,arguments);
  3651. /**
  3652. * indicate the component's type
  3653. */
  3654. this.type = 'custom';
  3655. this.set({
  3656. /**
  3657. * @cfg {Function} Specifies the customize function.(default to emptyFn)
  3658. */
  3659. drawFn:$.emptyFn,
  3660. /**
  3661. * @cfg {Function} Specifies the customize event valid function.(default to undefined)
  3662. */
  3663. eventValid:undefined,
  3664. /**
  3665. * @cfg {Boolean} If true when chart animating it also invoke darw.(default to true)
  3666. */
  3667. animating_draw:true
  3668. });
  3669. this.registerEvent();
  3670. },
  3671. doDraw:function(_){
  3672. _.get('drawFn').call(_,_);
  3673. },
  3674. isEventValid:function(e,_){
  3675. if($.isFunction(this.get('eventValid')))
  3676. return this.get('eventValid').call(this,e,_);
  3677. return {valid:false};
  3678. },
  3679. doConfig:function(){
  3680. $.Custom.superclass.doConfig.call(this);
  3681. this.A_draw = this.get('animating_draw');
  3682. this.variable.animation = {
  3683. animating:false,
  3684. time : 0,
  3685. duration:0
  3686. };
  3687. }
  3688. });
  3689. /**
  3690. * @end
  3691. */
  3692. /**
  3693. * @overview this is inner use for axis
  3694. * @component#$.Scale
  3695. * @extend#$.Component
  3696. */
  3697. $.Scale = $.extend($.Component, {
  3698. configure : function() {
  3699. /**
  3700. * invoked the super class's configuration
  3701. */
  3702. $.Scale.superclass.configure.apply(this, arguments);
  3703. /**
  3704. * indicate the component's type
  3705. */
  3706. this.type = 'scale';
  3707. this.set({
  3708. /**
  3709. * @cfg {String} Specifies alignment of this scale.(default to 'left')
  3710. */
  3711. position : 'left',
  3712. /**
  3713. * @cfg {String} the axis's type(default to 'h') Available value are:
  3714. * @Option 'h' :horizontal
  3715. * @Option 'v' :vertical
  3716. */
  3717. which : 'h',
  3718. /**
  3719. * @cfg {Number} Specifies value of Baseline Coordinate.(default to 0)
  3720. */
  3721. basic_value:0,
  3722. /**
  3723. * @cfg {Boolean} indicate whether the grid is accord with scale.(default to true)
  3724. */
  3725. scale2grid : true,
  3726. /**
  3727. * @inner {Number}
  3728. */
  3729. distance : undefined,
  3730. /**
  3731. * @cfg {Number} Specifies the start coordinate scale value.(default to 0)
  3732. */
  3733. start_scale : 0,
  3734. /**
  3735. * @cfg {Number} Specifies the end coordinate scale value.Note either this or property of max_scale must be has the given value.(default to undefined)
  3736. */
  3737. end_scale : undefined,
  3738. /**
  3739. * @cfg {Number} Specifies the chart's minimal value
  3740. */
  3741. min_scale : undefined,
  3742. /**
  3743. * @cfg {Number} Specifies the chart's maximal value
  3744. */
  3745. max_scale : undefined,
  3746. /**
  3747. * @cfg {Number} Specifies the space of two scale.Note either this or property of scale_share must be has the given value.(default to undefined)
  3748. */
  3749. scale_space : undefined,
  3750. /**
  3751. * @cfg {Number} Specifies the number of scale on axis.(default to 5)
  3752. */
  3753. scale_share : 5,
  3754. /**
  3755. * @cfg {Boolean} True to display the scale line.(default to true)
  3756. */
  3757. scale_enable : true,
  3758. /**
  3759. * @cfg {Number} Specifies the size of brush(context.linewidth).(default to 1)
  3760. */
  3761. scale_size : 1,
  3762. /**
  3763. * @cfg {Number} Specifies the width(length) of scale.(default to 4)
  3764. */
  3765. scale_width : 4,
  3766. /**
  3767. * @cfg {String} Specifies the color of scale.(default to 4)
  3768. */
  3769. scale_color : '#333333',
  3770. /**
  3771. * @cfg {String} Specifies the align against axis.(default to 'center') When the property of which set to 'h',Available value are:
  3772. * @Option 'left'
  3773. * @Option 'center'
  3774. * @Option 'right'
  3775. * When the property of which set to 'v', Available value are:
  3776. * @Option 'top'
  3777. * @Option 'center'
  3778. * @Option 'bottom'
  3779. */
  3780. scaleAlign : 'center',
  3781. /**
  3782. * @cfg {Array} the customize labels
  3783. */
  3784. labels : [],
  3785. /**
  3786. * @cfg {<link>$.Text</link>} Specifies label's option.
  3787. */
  3788. label : {},
  3789. /**
  3790. * @cfg {Number} Specifies the distance to scale.(default to 6)
  3791. */
  3792. text_space : 6,
  3793. /**
  3794. * @cfg {String} Specifies the align against axis.(default to 'left' or 'bottom' in v mode) When the property of which set to 'h',Available value are:
  3795. * @Option 'left'
  3796. * @Option 'right' When the property of which set to 'v', Available value are:
  3797. * @Option 'top'
  3798. * @Option 'bottom'
  3799. */
  3800. textAlign : 'left',
  3801. /**
  3802. * @cfg {Number} Specifies the number of decimal.this will change along with scale.(default to 0)
  3803. */
  3804. decimalsnum : 0,
  3805. /**
  3806. * @inner {String} the style of overlapping(default to 'none') Available value are:
  3807. * @Option 'square'
  3808. * @Option 'round'
  3809. * @Option 'none'
  3810. */
  3811. join_style : 'none',
  3812. /**
  3813. * @inner {Number}
  3814. */
  3815. join_size : 2
  3816. });
  3817. this.registerEvent(
  3818. /**
  3819. * @event Fires the event when parse text,you can return a object like this:{text:'',originx:100,originy:100} to override the given.
  3820. * @paramter string#text item's text
  3821. * @paramter int#originx coordinate-x of item's text
  3822. * @paramter int#originy coordinate-y of item's text
  3823. * @paramter int#index item's index
  3824. * @paramter boolean#last If last item
  3825. */
  3826. 'parseText');
  3827. },
  3828. isEventValid : function() {
  3829. return {
  3830. valid : false
  3831. };
  3832. },
  3833. /**
  3834. * from left to right,top to bottom
  3835. */
  3836. doDraw : function(_) {
  3837. if (_.get('scale_enable'))
  3838. _.items.each(function(item) {
  3839. _.T.line(item.x0, item.y0, item.x1, item.y1, _.get('scale_size'), _.get('scale_color'), false);
  3840. });
  3841. _.labels.each(function(l) {
  3842. l.draw();
  3843. });
  3844. },
  3845. doLayout:function(x,y,_){
  3846. if (_.get('scale_enable'))
  3847. _.items.each(function(item) {
  3848. item.x0+=x;
  3849. item.y0+=y;
  3850. item.x1+=x;
  3851. item.y1+=y;
  3852. });
  3853. _.labels.each(function(l) {
  3854. l.doLayout(x,y,0,l);
  3855. });
  3856. },
  3857. doConfig : function() {
  3858. $.Scale.superclass.doConfig.call(this);
  3859. $.Assert.isNumber(this.get('distance'), 'distance');
  3860. var _ = this._(),abs = Math.abs,customL = _.get('labels').length, min_s = _.get('min_scale'), max_s = _.get('max_scale'), s_space = _.get('scale_space'), e_scale = _.get('end_scale'), start_scale = _.get('start_scale');
  3861. _.items = [];
  3862. _.labels = [];
  3863. _.number = 0;
  3864. if (customL > 0) {
  3865. _.number = customL - 1;
  3866. } else {
  3867. $.Assert.isTrue($.isNumber(max_s) || $.isNumber(e_scale), 'max_scale&end_scale');
  3868. /**
  3869. * end_scale must greater than maxScale
  3870. */
  3871. if (!$.isNumber(e_scale) || e_scale < max_s) {
  3872. e_scale = _.push('end_scale', $.ceil(max_s));
  3873. }
  3874. /**
  3875. * startScale must less than minScale
  3876. */
  3877. if (start_scale > min_s) {
  3878. start_scale = _.push('start_scale', $.floor(min_s));
  3879. }
  3880. if (s_space && abs(s_space) < abs(e_scale - start_scale)) {
  3881. _.push('scale_share', (e_scale - start_scale) / s_space);
  3882. }
  3883. _.number = _.push('scale_share', abs(_.get('scale_share')));
  3884. /**
  3885. * value of each scale
  3886. */
  3887. if (!s_space || s_space >( e_scale - start_scale)) {
  3888. s_space = _.push('scale', (e_scale - start_scale) / _.get('scale_share'));
  3889. }
  3890. if (parseInt(s_space)!=s_space && _.get('decimalsnum') == 0) {
  3891. var dec = s_space+"";
  3892. dec = dec.substring(dec.indexOf('.')+1);
  3893. _.push('decimalsnum', dec.length);
  3894. }
  3895. }
  3896. /**
  3897. * the real distance of each scale
  3898. */
  3899. _.push('distanceOne', _.get('valid_distance') / _.number);
  3900. var text, x, y, x1 = 0, y1 = 0, x0 = 0, y0 = 0, tx = 0, ty = 0, w = _.get('scale_width'), w2 = w / 2, sa = _.get('scaleAlign'), ta = _.get('position'), ts = _.get('text_space'), tbl = '',aw = _.get('coo').get('axis.width');
  3901. _.push('which', _.get('which').toLowerCase());
  3902. _.isH = _.get('which') == 'h';
  3903. if (_.isH) {
  3904. if (sa == _.O) {
  3905. y0 = -w;
  3906. } else if (sa == _.C) {
  3907. y0 = -w2;
  3908. y1 = w2;
  3909. } else {
  3910. y1 = w;
  3911. }
  3912. if (ta == _.O) {
  3913. ty = -ts-aw[0];
  3914. tbl = _.B;
  3915. } else {
  3916. ty = ts+aw[2];
  3917. tbl = _.O;
  3918. }
  3919. ta = _.C;
  3920. } else {
  3921. if (sa == _.L) {
  3922. x0 = -w;
  3923. } else if (sa == _.C) {
  3924. x0 = -w2;
  3925. x1 = w2;
  3926. } else {
  3927. x1 = w;
  3928. }
  3929. tbl = 'middle';
  3930. if (ta == _.R) {
  3931. ta = _.L;
  3932. tx = ts+aw[1];
  3933. } else {
  3934. ta = _.R;
  3935. tx = -ts-aw[3];
  3936. }
  3937. }
  3938. /**
  3939. * valid width only applies when there is h,then valid_height only applies when there is v
  3940. */
  3941. for ( var i = 0; i <= _.number; i++) {
  3942. text = customL ? _.get('labels')[i] : (s_space * i + start_scale).toFixed(_.get('decimalsnum'));
  3943. x = _.isH ? _.get('valid_x') + i * _.get('distanceOne') : _.x;
  3944. y = _.isH ? _.y : _.get('valid_y') + _.get('distance') - i * _.get('distanceOne');
  3945. _.items.push({
  3946. x : x,
  3947. y : y,
  3948. x0 : x + x0,
  3949. y0 : y + y0,
  3950. x1 : x + x1,
  3951. y1 : y + y1
  3952. });
  3953. /**
  3954. * put the label into a Text?
  3955. */
  3956. _.labels.push(new $.Text($.applyIf($.apply(_.get('label'), $.merge({
  3957. text : text,
  3958. x : x,
  3959. y : y,
  3960. originx : x + tx,
  3961. originy : y + ty
  3962. }, _.fireEvent(_, 'parseText', [text, x + tx, y + ty, i, _.number == i]))), {
  3963. textAlign : ta,
  3964. textBaseline : tbl
  3965. }), _));
  3966. /**
  3967. * maxwidth = Math.max(maxwidth, _.T.measureText(text));
  3968. */
  3969. }
  3970. }
  3971. });
  3972. /**
  3973. * @end
  3974. */
  3975. $.Coordinate = {
  3976. coordinate_ : function() {
  3977. var _ = this._(),scale = _.get('coordinate.scale'),li=_.get('scaleAlign'),f=true;
  3978. if($.isObject(scale)){
  3979. scale = [scale];
  3980. }
  3981. if($.isArray(scale)){
  3982. scale.each(function(s){
  3983. if(s.position ==li){
  3984. f = false;
  3985. return false;
  3986. }
  3987. });
  3988. if(f){
  3989. if(li==_.L){
  3990. li = _.R;
  3991. }else if(li==_.R){
  3992. li = _.L;
  3993. }else if(li==_.O){
  3994. li = _.B;
  3995. }else{
  3996. li = _.O;
  3997. }
  3998. _.push('scaleAlign',li);
  3999. }
  4000. scale.each(function(s){
  4001. if(s.position ==li){
  4002. if(!s.start_scale)
  4003. s.min_scale = _.get('minValue');
  4004. if(!s.end_scale)
  4005. s.max_scale = _.get('maxValue');
  4006. return false;
  4007. }
  4008. });
  4009. }else{
  4010. _.push('coordinate.scale',{
  4011. position : li,
  4012. scaleAlign : li,
  4013. max_scale : _.get('maxValue'),
  4014. min_scale : _.get('minValue')
  4015. });
  4016. }
  4017. if (_.is3D()) {
  4018. _.push('coordinate.xAngle_', _.get('xAngle_'));
  4019. _.push('coordinate.yAngle_', _.get('yAngle_'));
  4020. /**
  4021. * the Coordinate' Z is same as long as the column's
  4022. */
  4023. _.push('coordinate.zHeight', _.get('zHeight') * _.get('bottom_scale'));
  4024. }
  4025. return new $[_.is3D()?'Coordinate3D':'Coordinate2D'](_.get('coordinate'), _);
  4026. },
  4027. coordinate : function() {
  4028. /**
  4029. * calculate chart's measurement
  4030. */
  4031. var _ = this._(), f = 0.8,
  4032. _w = _.get('client_width'),
  4033. _h = _.get('client_height'),
  4034. w = _.push('coordinate.width',$.parsePercent(_.get('coordinate.width'),_w)),
  4035. h = _.push('coordinate.height',$.parsePercent(_.get('coordinate.height'),_h)),
  4036. vw = _.get('coordinate.valid_width'),
  4037. vh = _.get('coordinate.valid_height');
  4038. if (!h || h > _h) {
  4039. h = _.push('coordinate.height', Math.floor(_h * f));
  4040. }
  4041. if (!w || w > _w) {
  4042. w = _.push('coordinate.width', Math.floor(_w * f));
  4043. }
  4044. vw = _.push('coordinate.valid_width',$.parsePercent(vw,w));
  4045. vh = _.push('coordinate.valid_height',$.parsePercent(vh,h));
  4046. if (_.is3D()) {
  4047. var a = _.get('coordinate.pedestal_height');
  4048. var b = _.get('coordinate.board_deep');
  4049. a = $.isNumber(a)?a:22;
  4050. b = $.isNumber(b)?b:20;
  4051. h = _.push('coordinate.height', h - a - b);
  4052. }
  4053. /**
  4054. * calculate chart's alignment
  4055. */
  4056. if (_.get('align') == _.L) {
  4057. _.push(_.X, _.get('l_originx'));
  4058. } else if (_.get('align') == _.R) {
  4059. _.push(_.X, _.get('r_originx') - w);
  4060. } else {
  4061. _.push(_.X, _.get('centerx') - w / 2);
  4062. }
  4063. _.x = _.push(_.X, _.get(_.X) + _.get('offsetx'));
  4064. _.y = _.push(_.Y, _.get('centery') - h / 2 + _.get('offsety'));
  4065. if (!vw || vw > w) {
  4066. _.push('coordinate.valid_width', w);
  4067. }
  4068. if (!vh || vh > h) {
  4069. _.push('coordinate.valid_height', h);
  4070. }
  4071. _.push('coordinate.originx', _.x);
  4072. _.push('coordinate.originy', _.y);
  4073. }
  4074. }
  4075. /**
  4076. * @overview this component use for abc
  4077. * @component#$.Coordinate2D
  4078. * @extend#$.Component
  4079. */
  4080. $.Coordinate2D = $.extend($.Component, {
  4081. configure : function() {
  4082. /**
  4083. * invoked the super class's configurationuration
  4084. */
  4085. $.Coordinate2D.superclass.configure.apply(this, arguments);
  4086. /**
  4087. * indicate the component's type
  4088. */
  4089. this.type = 'coordinate2d';
  4090. this.set({
  4091. /**
  4092. * @inner {Number}
  4093. */
  4094. sign_size : 12,
  4095. /**
  4096. * @inner {Number}
  4097. */
  4098. sign_space : 5,
  4099. /**
  4100. * @cfg {Array} the option for scale.For details see <link>$.Scale</link>
  4101. */
  4102. scale : [],
  4103. /**
  4104. * @cfg {String/Number} Here,specify as '80%' relative to client width.(default to '80%')
  4105. */
  4106. width:'80%',
  4107. /**
  4108. * @cfg {String/Number} Here,specify as '80%' relative to client height.(default to '80%')
  4109. */
  4110. height:'80%',
  4111. /**
  4112. * @cfg {String/Number} Specifies the valid width,less than the width of coordinate.you can applies a percent value relative to width.(default to '100%')
  4113. */
  4114. valid_width : '100%',
  4115. /**
  4116. * @cfg {String/Number} Specifies the valid height,less than the height of coordinate.you can applies a percent value relative to width.(default to '100%')
  4117. */
  4118. valid_height : '100%',
  4119. /**
  4120. * @cfg {Number} Specifies the linewidth of the grid.(default to 1)
  4121. */
  4122. grid_line_width : 1,
  4123. /**
  4124. * @cfg {String} Specifies the color of the grid.(default to '#dbe1e1')
  4125. */
  4126. grid_color : '#dbe1e1',
  4127. /**
  4128. * @cfg {Object} Specifies the stlye of horizontal grid.(default to empty object).Available property are:
  4129. * @Option solid {Boolean} True to draw a solid line.else draw a dotted line.(default to true)
  4130. * @Option size {Number} Specifies size of line segment when solid is false.(default to 10)
  4131. * @Option fator {Number} Specifies the times to size(default to 1)
  4132. * @Option width {Number} Specifies the width of grid line.(default to 1)
  4133. * @Option color {String} Specifies the color of grid line.(default to '#dbe1e1')
  4134. */
  4135. gridHStyle : {},
  4136. /**
  4137. * @cfg {Object} Specifies the stlye of horizontal grid.(default to empty object).Available property are:
  4138. * @Option solid {Boolean} True to draw a solid line.else draw a dotted line.(default to true)
  4139. * @Option size {Number} Specifies size of line segment when solid is false.(default to 10)
  4140. * @Option fator {Number} Specifies the times to size(default to 1)
  4141. * @Option width {Number} Specifies the width of grid line.(default to 1)
  4142. * @Option color {String} Specifies the color of grid line.(default to '#dbe1e1')
  4143. */
  4144. gridVStyle : {},
  4145. /**
  4146. * @cfg {Boolean} True to display grid line.(default to true)
  4147. */
  4148. gridlinesVisible : true,
  4149. /**
  4150. * @cfg {Boolean} indicate whether the grid is accord with scale,on the premise of grids is not specify. this just give a convenient way bulid grid for default.and actual value depend on scale's scale2grid
  4151. */
  4152. scale2grid : true,
  4153. /**
  4154. * @cfg {Object} this is grid config for custom.there has two valid property horizontal and vertical.the property's sub property is: way:the manner calculate grid-line (default to 'share_alike') Available property are:
  4155. * @Option share_alike
  4156. * @Option given_value value: when property way apply to 'share_alike' this property mean to the number of grid's line.
  4157. * when apply to 'given_value' this property mean to the distance each grid line(unit:pixel) .
  4158. * code will like:
  4159. * {
  4160. * horizontal: {way:'share_alike',value:10},
  4161. * vertical: { way:'given_value', value:40 }
  4162. * }
  4163. */
  4164. grids : undefined,
  4165. /**
  4166. * @cfg {Boolean} If True the grid line will be ignored when gird and axis overlap.(default to true)
  4167. */
  4168. ignoreOverlap : true,
  4169. /**
  4170. * @cfg {Boolean} If True the grid line will be ignored when gird and coordinate's edge overlap.(default to false)
  4171. */
  4172. ignoreEdge : false,
  4173. /**
  4174. * @inner {String} Specifies the label on x-axis
  4175. */
  4176. xlabel : '',
  4177. /**
  4178. * @inner {String} Specifies the label on y-axis
  4179. */
  4180. ylabel : '',
  4181. /**
  4182. * @cfg {String} Here,specify as false to make background transparent.(default to null)
  4183. */
  4184. background_color : 0,
  4185. /**
  4186. * @cfg {Boolean} True to stripe the axis.(default to true)
  4187. */
  4188. striped : true,
  4189. /**
  4190. * @cfg {String} Specifies the direction apply striped color.(default to 'v')Available value are:
  4191. * @Option 'h' horizontal
  4192. * @Option 'v' vertical
  4193. */
  4194. striped_direction : 'v',
  4195. /**
  4196. * @cfg {float(0.01 - 0.5)} Specifies the factor make color dark striped,relative to background-color,the bigger the value you set,the larger the color changed.(defaults to '0.01')
  4197. */
  4198. striped_factor : 0.01,
  4199. /**
  4200. * @cfg {Object} Specifies config crosshair.(default enable to false).For details see <link>$.CrossHair</link> Note:this has a extra property named 'enable',indicate whether crosshair available(default to false)
  4201. */
  4202. crosshair : {
  4203. enable : false
  4204. },
  4205. /**
  4206. * @cfg {Number} Required,Specifies the width of this coordinate.(default to undefined)
  4207. */
  4208. width : undefined,
  4209. /**
  4210. * @cfg {Number} Required,Specifies the height of this coordinate.(default to undefined)
  4211. */
  4212. height : undefined,
  4213. /**
  4214. * @cfg {Number}Override the default as -1 to make sure it at the bottom.(default to -1)
  4215. */
  4216. z_index : -1,
  4217. /**
  4218. * @cfg {Object} Specifies style for axis of this coordinate. Available property are:
  4219. * @Option enable {Boolean} True to display the axis.(default to true)
  4220. * @Option color {String} Specifies the color of each axis.(default to '#666666')
  4221. * @Option width {Number/Array} Specifies the width of each axis, If given the a array,there must be have have 4 element, like this:[1,0,0,1](top-right-bottom-left).(default to 1)
  4222. */
  4223. axis : {
  4224. enable : true,
  4225. color : '#666666',
  4226. width : 1
  4227. }
  4228. });
  4229. this.scale = [];
  4230. this.gridlines = [];
  4231. },
  4232. getScale : function(p) {
  4233. for ( var i = 0; i < this.scale.length; i++) {
  4234. var k = this.scale[i];
  4235. if (k.get('position') == p) {
  4236. var u = [k.get('basic_value'),k.get('start_scale'),k.get('end_scale'),k.get('end_scale') - k.get('start_scale'),0];
  4237. u[4] = $.inRange(u[1],u[2]+1,u[0])||$.inRange(u[2]-1,u[1],u[0]);
  4238. return {
  4239. range:u[4],
  4240. basic:u[4]?(u[0]-u[1]) / u[3]:0,
  4241. start : u[4]?u[0]:u[1],
  4242. end : u[2],
  4243. distance : u[3]
  4244. };
  4245. }
  4246. }
  4247. return {
  4248. start : 0,
  4249. end : 0,
  4250. distance : 0
  4251. };
  4252. },
  4253. isEventValid : function(e,_) {
  4254. return {
  4255. valid : e.x > _.x && e.x < (_.x + _.get(_.W)) && e.y < _.y + _.get(_.H) && e.y > _.y
  4256. };
  4257. },
  4258. doDraw : function(_) {
  4259. _.T.box(_.x, _.y, _.get(_.W), _.get(_.H), 0, _.get('f_color'));
  4260. if (_.get('striped')) {
  4261. var x, y, f = false, axis = _.get('axis.width'), c = $.dark(_.get('background_color'), _.get('striped_factor'),0);
  4262. }
  4263. var v = (_.get('striped_direction') == 'v');
  4264. _.gridlines.each(function(g,i) {
  4265. if (_.get('striped')) {
  4266. if (f) {
  4267. if (v)
  4268. _.T.box(g.x1, g.y1 + g.width, g.x2 - g.x1, y - g.y1 - g.width, 0, c);
  4269. else
  4270. _.T.box(x + g.width, g.y2, g.x1 - x, g.y1 - g.y2, 0, c);
  4271. }
  4272. x = g.x1;
  4273. y = g.y1;
  4274. f = !f;
  4275. }
  4276. }).each(function(g) {
  4277. if(!g.overlap){
  4278. if(g.solid){
  4279. _.T.line(g.x1, g.y1, g.x2, g.y2, g.width, g.color);
  4280. }else{
  4281. _.T.dotted(g.x1, g.y1, g.x2, g.y2, g.width, g.color,g.size,g.fator);
  4282. }
  4283. }
  4284. });
  4285. _.T.box(_.x, _.y, _.get(_.W), _.get(_.H), _.get('axis'), false, _.get('shadow'),true);
  4286. _.scale.each(function(s) {
  4287. s.draw()
  4288. });
  4289. },
  4290. doConfig : function() {
  4291. $.Coordinate2D.superclass.doConfig.call(this);
  4292. var _ = this._();
  4293. $.Assert.isNumber(_.get(_.W), _.W);
  4294. $.Assert.isNumber(_.get(_.H), _.H);
  4295. /**
  4296. * this element not atomic because it is a container,so this is a particular case.
  4297. */
  4298. _.atomic = false;
  4299. /**
  4300. * apply the gradient color to f_color
  4301. */
  4302. if (_.get('gradient') && $.isString(_.get('f_color'))) {
  4303. _.push('f_color', _.T.avgLinearGradient(_.x, _.y, _.x, _.y + _.get(_.H), [_.get('dark_color'), _.get('light_color')]));
  4304. }
  4305. if (_.get('axis.enable')) {
  4306. var aw = _.get('axis.width');
  4307. if (!$.isArray(aw))
  4308. _.push('axis.width', [aw, aw, aw, aw]);
  4309. }else{
  4310. _.push('axis.width', [0, 0, 0, 0]);
  4311. }
  4312. if (_.get('crosshair.enable')) {
  4313. _.push('crosshair.wrap', _.container.shell);
  4314. _.push('crosshair.height', _.get(_.H));
  4315. _.push('crosshair.width', _.get(_.W));
  4316. _.push('crosshair.top', _.y);
  4317. _.push('crosshair.left', _.x);
  4318. _.crosshair = new $.CrossHair(_.get('crosshair'), _);
  4319. }
  4320. var jp, cg = !!(_.get('gridlinesVisible') && _.get('grids')), hg = cg && !!_.get('grids.horizontal'), vg = cg && !!_.get('grids.vertical'), h = _.get(_.H), w = _.get(_.W), vw = _.get('valid_width'), vh = _.get('valid_height'), k2g = _.get('gridlinesVisible')
  4321. && _.get('scale2grid') && !(hg && vg), sw = (w - vw) / 2, sh = (h - vh) / 2, axis = _.get('axis.width');
  4322. _.push('x_start', _.x+(w - vw) / 2);
  4323. _.push('x_end', _.x + (w + vw) / 2);
  4324. _.push('y_start', _.y+(h - vh) / 2);
  4325. _.push('y_end', _.y + (h + vh) / 2);
  4326. if (!$.isArray(_.get('scale'))) {
  4327. if ($.isObject(_.get('scale')))
  4328. _.push('scale', [_.get('scale')]);
  4329. else
  4330. _.push('scale', []);
  4331. }
  4332. _.get('scale').each(function(kd, i) {
  4333. jp = kd['position'];
  4334. jp = jp || _.L;
  4335. jp = jp.toLowerCase();
  4336. kd[_.X] = _.x;
  4337. kd['coo'] = _;
  4338. kd[_.Y] = _.y;
  4339. kd['valid_x'] = _.x + sw;
  4340. kd['valid_y'] = _.y + sh;
  4341. kd['position'] = jp;
  4342. /**
  4343. * calculate coordinate,direction,distance
  4344. */
  4345. if (jp == _.O) {
  4346. kd['which'] = 'h';
  4347. kd['distance'] = w;
  4348. kd['valid_distance'] = vw;
  4349. } else if (jp == _.R) {
  4350. kd['which'] = 'v';
  4351. kd['distance'] = h;
  4352. kd['valid_distance'] = vh;
  4353. kd[_.X] += w;
  4354. kd['valid_x'] += vw;
  4355. } else if (jp == _.B) {
  4356. kd['which'] = 'h';
  4357. kd['distance'] = w;
  4358. kd['valid_distance'] = vw;
  4359. kd[_.Y] += h;
  4360. kd['valid_y'] += vh;
  4361. } else {
  4362. kd['which'] = 'v';
  4363. kd['distance'] = h;
  4364. kd['valid_distance'] = vh;
  4365. }
  4366. _.scale.push(new $.Scale(kd, _.container));
  4367. }, _);
  4368. var iol = _.push('ignoreOverlap', _.get('ignoreOverlap') && _.get('axis.enable') || _.get('ignoreEdge'));
  4369. if (iol) {
  4370. if (_.get('ignoreEdge')) {
  4371. var ignoreOverlap = function(w, x, y) {
  4372. return w == 'v' ? (y == _.y) || (y == _.y + h) : (x == _.x) || (x == _.x + w);
  4373. }
  4374. } else {
  4375. var ignoreOverlap = function(wh, x, y) {
  4376. return wh == 'v' ? (y == _.y && axis[0] > 0) || (y == (_.y + h) && axis[2] > 0) : (x == _.x && axis[3] > 0) || (x == (_.x + w) && axis[1] > 0);
  4377. }
  4378. }
  4379. }
  4380. var g = {
  4381. solid : true,
  4382. size : 10,
  4383. fator : 1,
  4384. width : _.get('grid_line_width'),
  4385. color : _.get('grid_color')
  4386. },
  4387. ghs = $.applyIf(_.get('gridHStyle'),g),
  4388. gvs = $.applyIf(_.get('gridVStyle'),g);
  4389. if (k2g) {
  4390. var scale, x, y, p;
  4391. _.scale.each(function(scale) {
  4392. p = scale.get('position');
  4393. /**
  4394. * disable,given specfiy grid will ignore scale2grid
  4395. */
  4396. if ($.isFalse(scale.get('scale2grid')) || hg && scale.get('which') == 'v' || vg && scale.get('which') == 'h') {
  4397. return;
  4398. }
  4399. x = y = 0;
  4400. if (p == _.O) {
  4401. y = h;
  4402. } else if (p == _.R) {
  4403. x = -w;
  4404. } else if (p == _.B) {
  4405. y = -h;
  4406. } else {
  4407. x = w;
  4408. }
  4409. scale.items.each(function(item) {
  4410. if (iol)
  4411. _.gridlines.push($.applyIf({
  4412. overlap:ignoreOverlap.call(_, scale.get('which'), item.x, item.y),
  4413. x1 : item.x,
  4414. y1 : item.y,
  4415. x2 : item.x + x,
  4416. y2 : item.y + y
  4417. },scale.isH?gvs:ghs));
  4418. });
  4419. });
  4420. }
  4421. if (vg) {
  4422. var gv = _.get('grids.vertical');
  4423. $.Assert.gt(gv['value'],0, 'value');
  4424. var d = w / gv['value'], n = gv['value'];
  4425. if (gv['way'] == 'given_value') {
  4426. n = d;
  4427. d = gv['value'];
  4428. d = d > w ? w : d;
  4429. }
  4430. for ( var i = 0; i <= n; i++) {
  4431. if (iol)
  4432. _.gridlines.push($.applyIf({
  4433. overlap:ignoreOverlap.call(_, 'h', _.x + i * d, _.y),
  4434. x1 : _.x + i * d,
  4435. y1 : _.y,
  4436. x2 : _.x + i * d,
  4437. y2 : _.y + h,
  4438. H : false,
  4439. width : gvs.width,
  4440. color : gvs.color
  4441. },gvs));
  4442. }
  4443. }
  4444. if (hg) {
  4445. var gh = _.get('grids.horizontal');
  4446. $.Assert.gt(gh['value'],0,'value');
  4447. var d = h / gh['value'], n = gh['value'];
  4448. if (gh['way'] == 'given_value') {
  4449. n = d;
  4450. d = gh['value'];
  4451. d = d > h ? h : d;
  4452. }
  4453. for ( var i = 0; i <= n; i++) {
  4454. if (iol)
  4455. _.gridlines.push($.applyIf({
  4456. overlap:ignoreOverlap.call(_, 'v', _.x, _.y + i * d),
  4457. x1 : _.x,
  4458. y1 : _.y + i * d,
  4459. x2 : _.x + w,
  4460. y2 : _.y + i * d,
  4461. H : true,
  4462. width : ghs.width,
  4463. color : ghs.color
  4464. },ghs));
  4465. }
  4466. }
  4467. }
  4468. });
  4469. /**
  4470. * @end
  4471. */
  4472. /**
  4473. * @overview this component use for abc
  4474. * @component#$.Coordinate3D
  4475. * @extend#$.Coordinate2D
  4476. */
  4477. $.Coordinate3D = $.extend($.Coordinate2D, {
  4478. configure : function() {
  4479. /**
  4480. * invoked the super class's configurationuration
  4481. */
  4482. $.Coordinate3D.superclass.configure.apply(this, arguments);
  4483. /**
  4484. * indicate the component's type
  4485. */
  4486. this.type = 'coordinate3d';
  4487. this.dimension = $._3D;
  4488. this.set({
  4489. /**
  4490. * @cfg {Number} Three-dimensional rotation X in degree(angle).socpe{0-90},Normally, this will accord with the chart.(default to 60)
  4491. */
  4492. xAngle : 60,
  4493. /**
  4494. * @cfg {Number} Three-dimensional rotation Y in degree(angle).socpe{0-90},Normally, this will accord with the chart.(default to 20)
  4495. */
  4496. yAngle : 20,
  4497. xAngle_ : undefined,
  4498. yAngle_ : undefined,
  4499. /**
  4500. * @cfg {Number} Required,Specifies the z-axis deep of this coordinate,Normally, this will given by chart.(default to 0)
  4501. */
  4502. zHeight : 0,
  4503. /**
  4504. * @cfg {Number} Specifies pedestal height of this coordinate.(default to 22)
  4505. */
  4506. pedestal_height : 22,
  4507. /**
  4508. * @cfg {Number} Specifies board deep of this coordinate.(default to 20)
  4509. */
  4510. board_deep : 20,
  4511. /**
  4512. * @cfg {Boolean} If true display the left board.(default to true)
  4513. */
  4514. left_board:true,
  4515. /**
  4516. * @cfg {Boolean} Override the default as true
  4517. */
  4518. gradient : true,
  4519. /**
  4520. * @cfg {float} Override the default as 0.18.
  4521. */
  4522. color_factor : 0.18,
  4523. /**
  4524. * @cfg {Boolean} Override the default as true.
  4525. */
  4526. ignoreEdge : true,
  4527. /**
  4528. * @cfg {Boolean} Override the default as false.
  4529. */
  4530. striped : false,
  4531. /**
  4532. * @cfg {String} Override the default as '#a4ad96'.
  4533. */
  4534. grid_color : '#a4ad96',
  4535. /**
  4536. * @cfg {String} Override the default as '#d6dbd2'.
  4537. */
  4538. background_color : '#d6dbd2',
  4539. /**
  4540. * @cfg {Number} Override the default as 4.
  4541. */
  4542. shadow_offsetx : 4,
  4543. /**
  4544. * @cfg {Number} Override the default as 2.
  4545. */
  4546. shadow_offsety : 2,
  4547. /**
  4548. * @cfg {Array} Specifies the style of board(wall) of this coordinate.
  4549. * the length of array will be 6,if less than 6,it will instead of <link>background_color</link>.and each object option has two property. Available property are:
  4550. * @Option color the color of wall
  4551. * @Option alpha the opacity of wall
  4552. */
  4553. wall_style : [],
  4554. /**
  4555. * @cfg {Boolean} Override the default as axis.enable = false.
  4556. */
  4557. axis : {
  4558. enable : false
  4559. }
  4560. });
  4561. },
  4562. doDraw : function(_) {
  4563. var w = _.get(_.W), h = _.get(_.H), xa = _.get('xAngle_'), ya = _.get('yAngle_'), zh = _.get('zHeight'), offx = _.get('z_offx'), offy = _.get('z_offy');
  4564. /**
  4565. * bottom
  4566. */
  4567. if(_.get('pedestal_height'))
  4568. _.T.cube3D(_.x, _.y + h + _.get('pedestal_height'), xa, ya, false, w, _.get('pedestal_height'), zh * 3 / 2, _.get('axis.enable'), _.get('axis.width'), _.get('axis.color'), _.get('bottom_style'));
  4569. /**
  4570. * board_style
  4571. */
  4572. if(_.get('board_deep'))
  4573. _.T.cube3D(_.x +offx, _.y+h - offy, xa, ya, false, w, h, _.get('board_deep'), _.get('axis.enable'), _.get('axis.width'), _.get('axis.color'), _.get('board_style'));
  4574. _.T.cube3D(_.x, _.y + h, xa, ya, false, w, h, zh, _.get('axis.enable'), _.get('axis.width'), _.get('axis.color'), _.get('wall_style'));
  4575. _.gridlines.each(function(g) {
  4576. if(g.solid){
  4577. if(_.get('left_board'))
  4578. _.T.line(g.x1, g.y1, g.x1 + offx, g.y1 - offy,g.width, g.color);
  4579. _.T.line(g.x1 + offx, g.y1 - offy, g.x2 + offx, g.y2 - offy, g.width, g.color);
  4580. }else{
  4581. if(_.get('left_board'))
  4582. _.T.dotted(g.x1, g.y1, g.x1 + offx, g.y1 - offy,g.width, g.color,g.size,g.fator);
  4583. _.T.dotted(g.x1 + offx, g.y1 - offy, g.x2 + offx, g.y2 - offy, g.width, g.color,g.size,g.fator);
  4584. }
  4585. });
  4586. _.scale.each(function(s) {
  4587. s.draw();
  4588. });
  4589. },
  4590. doConfig : function() {
  4591. $.Coordinate3D.superclass.doConfig.call(this);
  4592. var _ = this._(),
  4593. ws = _.get('wall_style'),
  4594. bg = _.get('background_color'),
  4595. h = _.get(_.H),
  4596. w = _.get(_.W),
  4597. f = _.get('color_factor'),
  4598. offx = _.push('z_offx',_.get('xAngle_') * _.get('zHeight')),
  4599. offy = _.push('z_offy',_.get('yAngle_') * _.get('zHeight'));
  4600. /**
  4601. * bottom-lower bottom-left
  4602. */
  4603. while(ws.length < 6){
  4604. ws.push({color : bg});
  4605. }
  4606. if(!_.get('left_board')){
  4607. ws[2] = false;
  4608. _.scale.each(function(s){
  4609. s.doLayout(offx,-offy,s);
  4610. });
  4611. }
  4612. /**
  4613. * right-front
  4614. */
  4615. _.push('bottom_style', [{
  4616. color : _.get('shadow_color'),
  4617. shadow : _.get('shadow')
  4618. }, false, false, {
  4619. color : ws[3].color
  4620. },false, {
  4621. color : ws[3].color
  4622. }]);
  4623. /**
  4624. * right-top
  4625. */
  4626. _.push('board_style', [false, false, false,{
  4627. color : ws[4].color
  4628. },{
  4629. color : ws[5].color
  4630. }, false]);
  4631. /**
  4632. * lowerBottom-bottom-left-right-top-front
  4633. */
  4634. if (_.get('gradient')) {
  4635. if ($.isString(ws[0].color)) {
  4636. ws[0].color = _.T.avgLinearGradient(_.x, _.y + h, _.x + w, _.y + h, [$.dark(ws[0].color,f/2+0.06),$.dark(ws[0].color,f/2+0.06)]);
  4637. }
  4638. if ($.isString(ws[1].color)) {
  4639. ws[1].color = _.T.avgLinearGradient(_.x + offx, _.y - offy, _.x + offx, _.y + h - offy, [$.dark(ws[1].color,f),$.light(ws[1].color,f)]);
  4640. }
  4641. if ($.isString(ws[2].color)) {
  4642. ws[2].color = _.T.avgLinearGradient(_.x, _.y, _.x, _.y + h, [$.light(ws[2].color,f/3),$.dark(ws[2].color,f)]);
  4643. }
  4644. _.get('bottom_style')[5].color = _.T.avgLinearGradient(_.x, _.y + h, _.x, _.y + h + _.get('pedestal_height'), [$.light(ws[3].color,f/2+0.06),$.dark(ws[3].color,f/2,0)]);
  4645. }
  4646. _.push('wall_style', [ws[0],ws[1],ws[2]]);
  4647. }
  4648. });
  4649. /*
  4650. * @end
  4651. */
  4652. /**
  4653. * @overview this component use for abc
  4654. * @component#$.Rectangle
  4655. * @extend#$.Component
  4656. */
  4657. $.Rectangle = $.extend($.Component,{
  4658. configure:function(){
  4659. /**
  4660. * invoked the super class's configuration
  4661. */
  4662. $.Rectangle.superclass.configure.apply(this,arguments);
  4663. /**
  4664. * indicate the component's type
  4665. */
  4666. this.type = 'rectangle';
  4667. this.set({
  4668. /**
  4669. * @cfg {Number} Specifies the width of this element in pixels,Normally,this will given by chart.(default to 0)
  4670. */
  4671. width:0,
  4672. /**
  4673. * @cfg {Number} Specifies the height of this element in pixels,Normally,this will given by chart.(default to 0)
  4674. */
  4675. height:0,
  4676. /**
  4677. * @cfg {Number} the distance of column's edge and value in pixels.(default to 4)
  4678. */
  4679. value_space:4,
  4680. /**
  4681. * @cfg {String} Specifies the text of this element,Normally,this will given by chart.(default to '')
  4682. */
  4683. value:'',
  4684. /**
  4685. * @cfg {<link>$.Text</link>} Specifies the config of label,set false to make label disabled.
  4686. */
  4687. label : {},
  4688. /**
  4689. * @cfg {String} Specifies the name of this element,Normally,this will given by chart.(default to '')
  4690. */
  4691. name:'',
  4692. /**
  4693. * @cfg {String} Specifies the tip alignment of chart(defaults to 'top').Available value are:
  4694. * @Option 'left'
  4695. * @Option 'right'
  4696. * @Option 'top'
  4697. * @Option 'bottom'
  4698. */
  4699. tipAlign:'top',
  4700. /**
  4701. * @cfg {String} Specifies the value's text alignment of chart(defaults to 'top') Available value are:
  4702. * @Option 'left'
  4703. * @Option 'right'
  4704. * @Option 'top'
  4705. * @Option 'bottom'
  4706. */
  4707. valueAlign:'top',
  4708. /**
  4709. * @cfg {Number} Override the default as 3
  4710. */
  4711. shadow_blur:3,
  4712. /**
  4713. * @cfg {Number} Override the default as -1
  4714. */
  4715. shadow_offsety:-1
  4716. });
  4717. /**
  4718. * this element support boxMode
  4719. */
  4720. this.atomic = true;
  4721. this.registerEvent(
  4722. /**
  4723. * @event Fires when parse this label's data.Return value will override existing.
  4724. * @paramter <link>$.Rectangle</link>#rect
  4725. * @paramter string#text the current label's text
  4726. */
  4727. 'parseText');
  4728. this.label = null;
  4729. },
  4730. doDraw:function(_){
  4731. _.drawRectangle();
  4732. if(_.label)
  4733. _.label.draw();
  4734. },
  4735. doConfig:function(){
  4736. $.Rectangle.superclass.doConfig.call(this);
  4737. var _ = this._(),v = _.variable.event,vA=_.get('valueAlign');
  4738. $.Assert.gt(_.get(_.W),0,_.W);
  4739. /**
  4740. * mouseover light
  4741. */
  4742. $.taylor.light(_,v);
  4743. _.width = _.get(_.W);
  4744. _.height = _.get(_.H);
  4745. var x = _.push('centerx',_.x + _.width/2),
  4746. y = _.push('centery',_.y + _.height/2),
  4747. a = _.C,
  4748. b = 'middle',
  4749. s=_.get('value_space');
  4750. _.push('value',_.fireString(_, 'parseText', [_, _.get('value')], _.get('value')));
  4751. if(vA==_.L){
  4752. a = _.R;
  4753. x = _.x - s;
  4754. }else if(vA==_.R){
  4755. a = _.L;
  4756. x =_.x + _.width + s;
  4757. }else if(vA==_.B){
  4758. y = _.y + _.height + s;
  4759. b = _.O;
  4760. }else{
  4761. y = _.y - s;
  4762. b = _.B;
  4763. }
  4764. if(_.get('label')){
  4765. _.push('label.originx', x);
  4766. _.push('label.originy', y);
  4767. _.push('label.text',_.get('value'));
  4768. $.applyIf(_.get('label'),{
  4769. textAlign : a,
  4770. textBaseline : b,
  4771. color:_.get('color')
  4772. });
  4773. _.label = new $.Text(_.get('label'), _);
  4774. }
  4775. if(_.get('tip.enable')){
  4776. if(_.get('tip.showType')!='follow'){
  4777. _.push('tip.invokeOffsetDynamic',false);
  4778. }
  4779. _.tip = new $.Tip(_.get('tip'),_);
  4780. }
  4781. }
  4782. });
  4783. /**
  4784. *@end
  4785. */
  4786. /**
  4787. * @overview this component use for abc
  4788. * @component#$.Rectangle2D
  4789. * @extend#$.Rectangle
  4790. */
  4791. $.Rectangle2D = $.extend($.Rectangle,{
  4792. configure:function(){
  4793. /**
  4794. * invoked the super class's configuration
  4795. */
  4796. $.Rectangle2D.superclass.configure.apply(this,arguments);
  4797. /**
  4798. * indicate the component's type
  4799. */
  4800. this.type = 'rectangle2d';
  4801. this.set({
  4802. /**
  4803. * @cfg {Number} Override the default as -2
  4804. */
  4805. shadow_offsety:-2
  4806. });
  4807. },
  4808. drawRectangle:function(){
  4809. var _ = this._();
  4810. _.T.box(
  4811. _.get(_.X),
  4812. _.get(_.Y),
  4813. _.get(_.W),
  4814. _.get(_.H),
  4815. _.get('border'),
  4816. _.get('f_color'),
  4817. _.get('shadow'));
  4818. },
  4819. isEventValid:function(e,_){
  4820. return {valid:e.x>_.x&&e.x<(_.x+_.width)&&e.y<(_.y+_.height)&&e.y>(_.y)};
  4821. },
  4822. tipInvoke:function(){
  4823. var _ = this._();
  4824. /**
  4825. * base on event?
  4826. */
  4827. return function(w,h){
  4828. return {
  4829. left:_.tipX(w,h),
  4830. top:_.tipY(w,h)
  4831. }
  4832. }
  4833. },
  4834. doConfig:function(){
  4835. $.Rectangle2D.superclass.doConfig.call(this);
  4836. var _ = this._(),tipAlign = _.get('tipAlign');
  4837. if(tipAlign==_.L||tipAlign==_.R){
  4838. _.tipY = function(w,h){return _.get('centery') - h/2;};
  4839. }else{
  4840. _.tipX = function(w,h){return _.get('centerx') -w/2;};
  4841. }
  4842. if(tipAlign==_.L){
  4843. _.tipX = function(w,h){return _.x - _.get('value_space') -w;};
  4844. }else if(tipAlign==_.R){
  4845. _.tipX = function(w,h){return _.x + _.width + _.get('value_space');};
  4846. }else if(tipAlign==_.B){
  4847. _.tipY = function(w,h){return _.y +_.height+3;};
  4848. }else{
  4849. _.tipY = function(w,h){return _.y - h -3;};
  4850. }
  4851. _.applyGradient();
  4852. }
  4853. });
  4854. /**
  4855. *@end
  4856. */
  4857. /**
  4858. * @overview this component use for abc
  4859. * @component#$.Rectangle3D
  4860. * @extend#$.Rectangle
  4861. */
  4862. $.Rectangle3D = $.extend($.Rectangle,{
  4863. configure:function(){
  4864. /**
  4865. * invoked the super class's configuration
  4866. */
  4867. $.Rectangle3D.superclass.configure.apply(this,arguments);
  4868. /**
  4869. * indicate the component's type
  4870. */
  4871. this.type = 'rectangle3d';
  4872. this.dimension = $._3D;
  4873. this.set({
  4874. /**
  4875. * @cfg {Number} Specifies Three-dimensional z-axis deep in pixels.Normally,this will given by chart.(default to undefined)
  4876. */
  4877. zHeight:undefined,
  4878. /**
  4879. * @cfg {Number} Three-dimensional rotation X in degree(angle).socpe{0-90}.Normally,this will given by chart.(default to 60)
  4880. */
  4881. xAngle:60,
  4882. /**
  4883. * @cfg {Number} Three-dimensional rotation Y in degree(angle).socpe{0-90}.Normally,this will given by chart.(default to 20)
  4884. */
  4885. yAngle:20,
  4886. xAngle_:undefined,
  4887. yAngle_:undefined,
  4888. /**
  4889. * @cfg {Number} Override the default as 2
  4890. */
  4891. shadow_offsetx:2
  4892. });
  4893. },
  4894. drawRectangle:function(){
  4895. var _ = this._();
  4896. _.T.cube(
  4897. _.get(_.X),
  4898. _.get(_.Y),
  4899. _.get('xAngle_'),
  4900. _.get('yAngle_'),
  4901. _.get(_.W),
  4902. _.get(_.H),
  4903. _.get('zHeight'),
  4904. _.get('f_color'),
  4905. _.get('border.enable'),
  4906. _.get('border.width'),
  4907. _.get('light_color'),
  4908. _.get('shadow')
  4909. );
  4910. },
  4911. isEventValid:function(e,_){
  4912. return {valid:e.x>_.x&&e.x<(_.x+_.get(_.W))&&e.y<_.y+_.get(_.H)&&e.y>_.y};
  4913. },
  4914. tipInvoke:function(){
  4915. var _ = this._();
  4916. return function(w,h){
  4917. return {
  4918. left:_.topCenterX - w/2,
  4919. top:_.topCenterY - h
  4920. }
  4921. }
  4922. },
  4923. doConfig:function(){
  4924. $.Rectangle3D.superclass.doConfig.call(this);
  4925. var _ = this._();
  4926. _.pushIf("zHeight",_.get(_.W));
  4927. _.topCenterX=_.x+(_.get(_.W)+_.get(_.W)*_.get('xAngle_'))/2;
  4928. _.topCenterY=_.y-_.get(_.W)*_.get('yAngle_')/2;
  4929. if(_.get('valueAlign')==_.O&&_.label){
  4930. _.label.push('textx',_.topCenterX);
  4931. _.label.push('texty',_.topCenterY);
  4932. }
  4933. }
  4934. });
  4935. /**
  4936. *@end
  4937. */
  4938. /**
  4939. * @overview this component use for config sector,this is a abstract class.
  4940. * @component#$.Sector
  4941. * @extend#$.Component
  4942. */
  4943. $.Sector = $.extend($.Component, {
  4944. configure : function() {
  4945. /**
  4946. * invoked the super class's configuration
  4947. */
  4948. $.Sector.superclass.configure.apply(this, arguments);
  4949. /**
  4950. * indicate the component's type
  4951. */
  4952. this.type = 'sector';
  4953. this.set({
  4954. /**
  4955. * @cfg {String} Specifies the value of this element,Normally,this will given by chart.(default to '')
  4956. */
  4957. value : '',
  4958. /**
  4959. * @cfg {String} Specifies the name of this element,Normally,this will given by chart.(default to '')
  4960. */
  4961. name : '',
  4962. /**
  4963. * @cfg {Boolean} True will not darw.(default to false)
  4964. */
  4965. ignored : false,
  4966. /**
  4967. * @inner {Boolean} True to make sector counterclockwise.(default to false)
  4968. */
  4969. counterclockwise : false,
  4970. /**
  4971. * @cfg {Number} Specifies the start angle of this sector.Normally,this will given by chart.(default to 0)
  4972. */
  4973. startAngle : 0,
  4974. /**
  4975. * @cfg {Number} middleAngle = (endAngle - startAngle)/2.Normally,this will given by chart.(default to 0)
  4976. */
  4977. middleAngle : 0,
  4978. /**
  4979. * @cfg {Number} Specifies the end angle of this sector.Normally,this will given by chart.(default to 0)
  4980. */
  4981. endAngle : 0,
  4982. /**
  4983. * @cfg {Number} Specifies total angle of this sector,totalAngle = (endAngle - startAngle).Normally,this will given by chart.(default to 0)
  4984. */
  4985. totalAngle : 0,
  4986. /**
  4987. * @inner {String} the event's name trigger pie bound(default to 'click').
  4988. */
  4989. bound_event : 'click',
  4990. /**
  4991. * @cfg {Boolean} True to bound this sector.(default to false)
  4992. */
  4993. expand : false,
  4994. /**
  4995. * @cfg {Number} Specifies the width when show a donut.only applies when it not 0.(default to 0)
  4996. */
  4997. donutwidth : 0,
  4998. /**
  4999. * @inner {Boolean} If true means just one piece could bound at same time.(default to false)
  5000. */
  5001. mutex : false,
  5002. /**
  5003. * @inner {Number} Specifies the offset when bounded.Normally,this will given by chart.(default to undefined)
  5004. */
  5005. increment : undefined,
  5006. /**
  5007. * @cfg {String} Specifies the gradient mode of background.(defaults to 'RadialGradientOutIn')
  5008. * @Option 'RadialGradientOutIn'
  5009. * @Option 'RadialGradientInOut'
  5010. */
  5011. gradient_mode : 'RadialGradientOutIn',
  5012. /**
  5013. * @cfg {Number} Specifies the threshold value in angle that applies mini_label.(default to 15)
  5014. */
  5015. mini_label_threshold_angle : 15,
  5016. /**
  5017. * @cfg {<link>$.Text</link>} Specifies the config of label.when mini_label is a object,there will as a <link>$.Text</link>.(default to false) note:set false to make minilabel disabled.
  5018. */
  5019. mini_label : false,
  5020. /**
  5021. * @cfg {<link>$.Label</link>} Specifies the config of label.when mini_label is unavailable,there will as a <link>$.Label</link>. note:set false to make label disabled.
  5022. */
  5023. label : {}
  5024. });
  5025. /**
  5026. * this element support boxMode
  5027. */
  5028. this.atomic = true;
  5029. this.registerEvent('changed',
  5030. /**
  5031. * @event Fires when parse this label's data.Return value will override existing. Only valid when label is available
  5032. * @paramter <link>$.Sector</link>#sector the sector object
  5033. * @paramter string#text the current label's text
  5034. */
  5035. 'parseText');
  5036. this.label = null;
  5037. this.tip = null;
  5038. },
  5039. bound : function() {
  5040. if (!this.expanded)
  5041. this.toggle();
  5042. },
  5043. rebound : function() {
  5044. if (this.expanded)
  5045. this.toggle();
  5046. },
  5047. toggle : function() {
  5048. this.fireEvent(this, this.get('bound_event'), [this]);
  5049. },
  5050. /**
  5051. * @method get the sector's dimension,return hold following property
  5052. * @property x:the x-coordinate of the center of the sector
  5053. * @property y:the y-coordinate of the center of the sector
  5054. * @property startAngle:The starting angle, in radians (0 is at the 3 o'clock position of the arc's circle)
  5055. * @property endAngle:the ending angle, in radians
  5056. * @property middleAngle:the middle angle, in radians
  5057. * @return object
  5058. */
  5059. getDimension : function() {
  5060. var _ = this._();
  5061. return {
  5062. x : _.x,
  5063. x : _.y,
  5064. startAngle : _.get("startAngle"),
  5065. middleAngle : _.get("middleAngle"),
  5066. endAngle : _.get("endAngle")
  5067. }
  5068. },
  5069. doDraw : function(_) {
  5070. if (!_.get('ignored')) {
  5071. if (_.label&&!_.get('mini_label')){
  5072. _.label.draw();
  5073. }
  5074. _.drawSector();
  5075. if (_.label&&_.get('mini_label')){
  5076. _.label.draw();
  5077. }
  5078. }
  5079. },
  5080. doText : function(_, x, y) {
  5081. _.push('label.originx', x);
  5082. _.push('label.originy', y);
  5083. _.push('label.textBaseline', 'middle');
  5084. _.label = new $.Text(_.get('label'), _);
  5085. },
  5086. doLabel : function(_, x, y, Q, p, x0, y0,L) {
  5087. _.push('label.originx', x);
  5088. _.push('label.originy', y);
  5089. _.push('label.quadrantd', Q);
  5090. _.push('label.line_points', p);
  5091. _.push('label.labelx', x0);
  5092. _.push('label.labely', y0);
  5093. _.push('label.smooth', L);
  5094. _.push('label.angle', _.get('middleAngle')%(Math.PI*2));
  5095. _.label = new $.Label(_.get('label'), _);
  5096. },
  5097. isLabel : function() {
  5098. return this.get('label') && !this.get('mini_label');
  5099. },
  5100. doConfig : function() {
  5101. $.Sector.superclass.doConfig.call(this);
  5102. var _ = this._(), v = _.variable.event, f = _.get('label'),event=_.get('bound_event'),g;
  5103. /**
  5104. * mouseover light
  5105. */
  5106. $.taylor.light(_,v);
  5107. _.push('totalAngle', _.get('endAngle') - _.get('startAngle'));
  5108. if (f) {
  5109. if (_.get('mini_label')) {
  5110. if ((_.get('mini_label_threshold_angle') * Math.PI / 180) > _.get('totalAngle')) {
  5111. _.push('mini_label', false);
  5112. } else {
  5113. $.apply(_.get('label'),_.get('mini_label'));
  5114. }
  5115. }
  5116. _.push('label.text', _.fireString(_, 'parseText', [_,_.get('label.text')], _.get('label.text')));
  5117. _.pushIf('label.border.color', _.get('border.color'));
  5118. /**
  5119. * make the label's color in accord with sector
  5120. */
  5121. _.push('label.scolor', _.get('background_color'));
  5122. }
  5123. _.variable.event.status = _.expanded = _.get('expand');
  5124. if (_.get('tip.enable')) {
  5125. if (_.get('tip.showType') != 'follow') {
  5126. _.push('tip.invokeOffsetDynamic', false);
  5127. }
  5128. _.tip = new $.Tip(_.get('tip'), _);
  5129. }
  5130. v.poped = false;
  5131. /**
  5132. *need test profile/time
  5133. */
  5134. _.on(event, function() {
  5135. v.poped = true;
  5136. _.expanded = !_.expanded;
  5137. _.redraw(event);
  5138. v.poped = false;
  5139. });
  5140. _.on('beforedraw', function(a,b) {
  5141. if(b==event){
  5142. g = false;
  5143. _.x = _.get(_.X);
  5144. _.y = _.get(_.Y);
  5145. if (_.expanded) {
  5146. if (_.get('mutex') && !v.poped) {
  5147. _.expanded = false;
  5148. g = true;
  5149. } else {
  5150. _.x += _.get('inc_x');
  5151. _.y -= _.get('inc_y');
  5152. }
  5153. }
  5154. if (v.status != _.expanded) {
  5155. _.fireEvent(_, 'changed', [_, _.expanded]);
  5156. g = true;
  5157. v.status = _.expanded;
  5158. }
  5159. if (f&&g)
  5160. _.label.doLayout(_.get('inc_x') * (_.expanded ? 1 : -1), -_.get('inc_y') * (_.expanded ? 1 : -1),2,_.label);
  5161. }
  5162. return true;
  5163. });
  5164. }
  5165. });
  5166. /**
  5167. * @end
  5168. */
  5169. /**
  5170. * @overview this component use for abc
  5171. * @component#$.Sector2D
  5172. * @extend#$.Sector
  5173. */
  5174. $.Sector2D = $.extend($.Sector,{
  5175. configure:function(){
  5176. /**
  5177. * invoked the super class's configuration
  5178. */
  5179. $.Sector2D.superclass.configure.apply(this,arguments);
  5180. /**
  5181. * indicate the component's type
  5182. */
  5183. this.type = 'sector2d';
  5184. this.set({
  5185. /**
  5186. * @cfg {Float (0~)} Specifies the sector's radius.Normally,this will given by chart.(default to 0)
  5187. */
  5188. radius:0
  5189. });
  5190. },
  5191. drawSector:function(){
  5192. this.T.sector(
  5193. this.x,
  5194. this.y,
  5195. this.r,
  5196. this.get('donutwidth'),
  5197. this.get('startAngle'),
  5198. this.get('endAngle'),
  5199. this.get('f_color'),
  5200. this.get('border.enable'),
  5201. this.get('border.width'),
  5202. this.get('border.color'),
  5203. this.get('shadow'),
  5204. this.get('counterclockwise'));
  5205. },
  5206. isEventValid:function(e,_){
  5207. if(!_.get('ignored')){
  5208. if(_.isLabel()&&_.label.isEventValid(e,_.label).valid){
  5209. return {valid:true};
  5210. }
  5211. var r = $.distanceP2P(_.x,_.y,e.x,e.y),b=_.get('donutwidth');
  5212. if(_.r<r||(b&&(_.r-b)>r)){
  5213. return {valid:false};
  5214. }
  5215. if($.angleInRange(_.get('startAngle'),_.get('endAngle'),$.atan2Radian(_.x,_.y,e.x,e.y))){
  5216. return {valid:true};
  5217. }
  5218. }
  5219. return {valid:false};
  5220. },
  5221. tipInvoke:function(){
  5222. var _ = this;
  5223. return function(w,h){
  5224. var P = $.p2Point(this.x,this.y,this.get('middleAngle'),this.r*0.8),Q = $.quadrantd(this.get('middleAngle'));
  5225. return {
  5226. left:(Q>=2&&Q<=3)?(P.x - w):P.x,
  5227. top:Q>=3?(P.y - h):P.y
  5228. }
  5229. }
  5230. },
  5231. doConfig:function(){
  5232. $.Sector2D.superclass.doConfig.call(this);
  5233. var _ = this._();
  5234. _.r = _.get('radius');
  5235. $.Assert.gt(_.r,0);
  5236. if(_.get('donutwidth')>_.r){
  5237. _.push('donutwidth',0);
  5238. }
  5239. _.applyGradient(_.x-_.r,_.y-_.r,2*_.r,2*_.r);
  5240. var A = _.get('middleAngle'),L = _.pushIf('increment',$.lowTo(5,_.r/10)),p2;
  5241. _.push('inc_x',L * Math.cos(2 * Math.PI -A));
  5242. _.push('inc_y',L * Math.sin(2 * Math.PI - A));
  5243. L *=2;
  5244. if(_.get('label')){
  5245. if(_.get('mini_label')){
  5246. P2 = $.p2Point(_.x,_.y,A,_.get('donutwidth')?_.r - _.get('donutwidth')/2:_.r/2);
  5247. _.doText(_,P2.x,P2.y);
  5248. }else{
  5249. var Q = $.quadrantd(A),
  5250. P = $.p2Point(_.x,_.y,A,_.r + L),
  5251. C1 = $.p2Point(_.x,_.y,A,_.r + L*0.6);
  5252. P2 = $.p2Point(_.x,_.y,A,_.r);
  5253. _.doLabel(_,P2.x,P2.y,Q,[{x:P2.x,y:P2.y},{x:C1.x,y:C1.y},{x:P.x,y:P.y}],P.x,P.y,L*0.4);
  5254. }
  5255. }
  5256. }
  5257. });
  5258. /**
  5259. * @end
  5260. */
  5261. /**
  5262. * @overview this component use for abc
  5263. * @component#$.Sector3D
  5264. * @extend#$.Sector
  5265. */
  5266. $.Sector3D = $.extend($.Sector,{
  5267. configure:function(){
  5268. /**
  5269. * invoked the super class's configuration
  5270. */
  5271. $.Sector3D.superclass.configure.apply(this,arguments);
  5272. /**
  5273. * indicate the component's type
  5274. */
  5275. this.type = 'sector3d';
  5276. this.dimension = $._3D;
  5277. this.set({
  5278. /**
  5279. * @cfg {Number} Specifies major semiaxis of ellipse.Normally,this will given by chart.(default to 0)
  5280. */
  5281. semi_major_axis:0,
  5282. /**
  5283. * @cfg {Number} Specifies minor semiaxis of ellipse.Normally,this will given by chart.(default to 0)
  5284. */
  5285. semi_minor_axis:0,
  5286. /**
  5287. * @cfg {Float (0~)} Specifies the sector's height(thickness).Normally,this will given by chart.(default to 0)
  5288. */
  5289. cylinder_height:0
  5290. });
  5291. },
  5292. drawSector:function(){
  5293. this.T.sector3D(
  5294. this.x,
  5295. this.y,
  5296. this.a,
  5297. this.b,
  5298. this.get('startAngle'),
  5299. this.get('endAngle'),
  5300. this.h,
  5301. this.get('f_color'),
  5302. this.get('border.enable'),
  5303. this.get('border.width'),
  5304. this.get('border.color'),
  5305. this.get('shadow'),
  5306. this.get('shadow_color'),
  5307. this.get('shadow_blur'),
  5308. this.get('shadow_offsetx'),
  5309. this.get('shadow_offsety'),
  5310. this.get('counterclockwise'));
  5311. },
  5312. isEventValid:function(e,_){
  5313. if(!_.get('ignored')){
  5314. if(_.isLabel()&&_.label.isEventValid(e,_.label).valid){
  5315. return {valid:true};
  5316. }
  5317. if(!$.inEllipse(e.x - _.x,e.y-_.y,_.a,_.b)){
  5318. return {valid:false};
  5319. }
  5320. if($.angleZInRange(_.sA,_.eA,$.atan2Radian(_.x,_.y,e.x,e.y))){
  5321. return {valid:true};
  5322. }
  5323. }
  5324. return {valid:false};
  5325. },
  5326. p2p:function(x,y,a,z){
  5327. return {
  5328. x:x+this.a*Math.cos(a)*z,
  5329. y:y+this.b*Math.sin(a)*z
  5330. };
  5331. },
  5332. tipInvoke:function(){
  5333. var _ = this,A = _.get('middleAngle'),Q = $.quadrantd(A);
  5334. return function(w,h){
  5335. var P = _.p2p(_.x,_.y,A,0.6);
  5336. return {
  5337. left:(Q>=2&&Q<=3)?(P.x - w):P.x,
  5338. top:Q>=3?(P.y - h):P.y
  5339. }
  5340. }
  5341. },
  5342. doConfig:function(){
  5343. $.Sector3D.superclass.doConfig.call(this);
  5344. var _ = this._(),ccw = _.get('counterclockwise'),mA = _.get('middleAngle');
  5345. _.a = _.get('semi_major_axis');
  5346. _.b = _.get('semi_minor_axis');
  5347. _.h = _.get('cylinder_height');
  5348. $.Assert.gt(_.a,0);
  5349. $.Assert.gt(_.b,0);
  5350. var pi2 = 2 * Math.PI,toAngle = function(A){
  5351. while(A<0)A+=pi2;
  5352. return Math.abs($.atan2Radian(0,0,_.a*Math.cos(A),ccw?(-_.b*Math.sin(A)):(_.b*Math.sin(A))));
  5353. },
  5354. L = _.pushIf('increment',$.lowTo(5,_.a/10));
  5355. _.sA = toAngle.call(_,_.get('startAngle'));
  5356. _.eA = toAngle.call(_,_.get('endAngle'));
  5357. _.mA = toAngle.call(_,mA);
  5358. _.push('inc_x',L * Math.cos(pi2 -_.mA));
  5359. _.push('inc_y',L * Math.sin(pi2 - _.mA));
  5360. L *=2;
  5361. if(_.get('label')){
  5362. if(_.get('mini_label')){
  5363. var P3 = _.p2p(_.x,_.y,mA,0.5);
  5364. _.doText(_,P3.x,P3.y);
  5365. }else{
  5366. var Q = $.quadrantd(mA),
  5367. P = _.p2p(_.x,_.y,mA,L/_.a+1),
  5368. C1 = _.p2p(_.x,_.y,mA,L*0.6/_.a+1),
  5369. P2 = _.p2p(_.x,_.y,mA,1);
  5370. _.doLabel(_,P2.x,P2.y,Q,[{x:P2.x,y:P2.y},{x:C1.x,y:C1.y},{x:P.x,y:P.y}],P.x,P.y,L*0.4);
  5371. }
  5372. }
  5373. }
  5374. });
  5375. /**
  5376. *@end
  5377. */
  5378. /**
  5379. * @overview this component use for abc
  5380. * @component#$.Pie
  5381. * @extend#$.Chart
  5382. */
  5383. $.Pie = $.extend($.Chart, {
  5384. /**
  5385. * initialize the context for the pie
  5386. */
  5387. configure : function() {
  5388. /**
  5389. * invoked the super class's configuration
  5390. */
  5391. $.Pie.superclass.configure.call(this);
  5392. this.type = 'pie';
  5393. this.set({
  5394. /**
  5395. * @cfg {Float/String} Specifies the pie's radius.If given a percentage,it will relative to minDistance.(default to '100%')
  5396. */
  5397. radius : '100%',
  5398. /**
  5399. * @cfg {Number} initial angle for first sector.(default to 0)
  5400. */
  5401. offset_angle : 0,
  5402. /**
  5403. * @cfg {Number(0~90)} separate angle of all sector.(default to 0)
  5404. */
  5405. separate_angle:0,
  5406. /**
  5407. * @cfg {String} the event's name trigger pie pop(default to 'click')
  5408. */
  5409. bound_event : 'click',
  5410. /**
  5411. * @inner {Boolean} True to make sector counterclockwise.(default to false)
  5412. */
  5413. counterclockwise : false,
  5414. /**
  5415. * @cfg {Boolean} when label's position in conflict.auto layout.(default to true).
  5416. */
  5417. intellectLayout : true,
  5418. /**
  5419. * @cfg {Number} Specifies the distance in pixels when two label is incompatible with each other.(default 4),
  5420. */
  5421. layout_distance : 4,
  5422. /**
  5423. * @inner {Boolean} if it has animate when a piece popd (default to false)
  5424. */
  5425. pop_animate : false,
  5426. /**
  5427. * @cfg {Boolean} Specifies as true it means just one piece could pop (default to false)
  5428. */
  5429. mutex : false,
  5430. /**
  5431. * @cfg {Number} Specifies the length when sector bounded.(default to 1/8 radius,and minimum is 5),
  5432. */
  5433. increment : undefined,
  5434. /**
  5435. * @cfg {<link>$.Sector</link>} option of sector.Note,Pie2d depend on Sector2d and pie3d depend on Sector3d.For details see <link>$.Sector</link>
  5436. */
  5437. sub_option : {
  5438. label : {}
  5439. }
  5440. });
  5441. this.registerEvent(
  5442. /**
  5443. * @event Fires when this element' sector bounded
  5444. * @paramter <link>$.Sector2d</link>#sector
  5445. * @paramter string#name
  5446. * @paramter int#index
  5447. */
  5448. 'bound',
  5449. /**
  5450. * @event Fires when this element' sector rebounded
  5451. * @paramter <link>$.Sector2d</link>#sector
  5452. * @paramter string#name
  5453. * @paramter int#index
  5454. */
  5455. 'rebound');
  5456. },
  5457. /**
  5458. * @method Toggle sector bound or rebound by a specific index.
  5459. * @paramter int#i the index of sector
  5460. * @return void
  5461. */
  5462. toggle : function(i) {
  5463. this.sectors[i || 0].toggle();
  5464. },
  5465. /**
  5466. * @method bound sector by a specific index.
  5467. * @paramter int#i the index of sector
  5468. * @return void
  5469. */
  5470. bound : function(i) {
  5471. this.sectors[i || 0].bound();
  5472. },
  5473. /**
  5474. * @method rebound sector by a specific index.
  5475. * @paramter int#i the index of sector
  5476. * @return void
  5477. */
  5478. rebound : function(i) {
  5479. this.sectors[i || 0].rebound();
  5480. },
  5481. /**
  5482. * @method Returns an array containing all sectors of this pie
  5483. * @return Array#the collection of sectors
  5484. */
  5485. getSectors : function() {
  5486. return this.sectors;
  5487. },
  5488. doAnimation : function(t, d,_) {
  5489. var si = 0, cs = _.oA;
  5490. _.sectors.each(function(s, i) {
  5491. si = _.animationArithmetic(t, 0, s.get('totalAngle'), d);
  5492. s.push('startAngle', cs);
  5493. s.push('endAngle', cs + si);
  5494. cs += si;
  5495. if (!_.is3D())
  5496. s.drawSector();
  5497. });
  5498. if (_.is3D()) {
  5499. _.proxy.drawSector();
  5500. }
  5501. },
  5502. parse : function(_) {
  5503. _.data.each(function(d,i){
  5504. _.doParse(_,d,i);
  5505. },_);
  5506. /**
  5507. * layout the label
  5508. */
  5509. _.localizer(_);
  5510. },
  5511. doParse : function(_,d, i) {
  5512. var t = d.name + ' ' +_.getPercent(d.value);
  5513. _.doActing(_,d,i,t);
  5514. _.push('sub_option.id', i);
  5515. if(_.get('sub_option.label'))
  5516. _.push('sub_option.label.text', t);
  5517. _.push('sub_option.listeners.changed', function(se, st, i) {
  5518. _.fireEvent(_, st ? 'bound' : 'rebound', [_, se.get('name')]);
  5519. });
  5520. _.sectors.push(_.doSector(_,d));
  5521. },
  5522. dolayout : function(_,x,y,l,d,Q) {
  5523. if(_.is3D()?$.inEllipse(_.get(_.X) - x,_.topY-y,_.a,_.b):$.distanceP2P(_.get(_.X),_.topY,x,y)<_.r){
  5524. y=_.topY-y;
  5525. l.push('labelx',_.get(_.X)+(Math.sqrt(_.r*_.r-y*y)*2+d)*(Q==0||Q==3?1:-1));
  5526. l.localizer(l);
  5527. }
  5528. },
  5529. localizer:function(_){
  5530. if (_.get('intellectLayout')) {
  5531. var unlayout = [],layouted = [],d = _.get('layout_distance'),Q,x,y;
  5532. _.sectors.each(function(f, i) {
  5533. if(f.isLabel())
  5534. unlayout.push(f.label);
  5535. });
  5536. unlayout.sor(function(p, q) {
  5537. return Math.abs(Math.sin(p.get('angle'))) - Math.abs(Math.sin(q.get('angle')))>0;
  5538. });
  5539. unlayout.each(function(la) {
  5540. layouted.each(function(l) {
  5541. x = l.labelx, y = l.labely;
  5542. if ((la.labely <= y && (y - la.labely-1) < la.get(_.H)) || (la.labely > y && (la.labely - y-1) < l.get(_.H))) {
  5543. if ((la.labelx < x && (x - la.labelx) < la.get(_.W)) || (la.labelx > x && (la.labelx - x) < l.get(_.W))) {
  5544. Q = la.get('quadrantd');
  5545. la.push('labely', (la.get('labely')+ y - la.labely) + (la.get(_.H) + d)*(Q>1?-1:1));
  5546. la.localizer(la);
  5547. _.dolayout(_,la.get('labelx'),la.get('labely')+la.get(_.H)/2*(Q<2?-1:1),la,d,Q);
  5548. }
  5549. }
  5550. }, _);
  5551. layouted.push(la);
  5552. });
  5553. }
  5554. },
  5555. doConfig : function() {
  5556. $.Pie.superclass.doConfig.call(this);
  5557. $.Assert.gt(this.total,0,'this.total');
  5558. var _ = this._(),r = _.get('radius'), f = _.get('sub_option.label') ? 0.35 : 0.44,pi2=Math.PI*2;
  5559. _.sub = _.is3D()?'Sector3D':'Sector2D';
  5560. _.sectors = [];
  5561. _.sectors.zIndex = _.get('z_index');
  5562. _.components.push(_.sectors);
  5563. _.oA = $.angle2Radian(_.get('offset_angle'))%pi2;
  5564. //If 3D,let it bigger
  5565. if (_.is3D())
  5566. f += 0.06;
  5567. f = Math.floor(_.get('minDistance') * f);
  5568. var L = _.data.length,sepa = $.angle2Radian($.between(0,90,_.get('separate_angle'))),PI = pi2-sepa,sepa=sepa/L,eA = _.oA+sepa, sA = eA;
  5569. _.data.each(function(d, i) {
  5570. eA += (d.value / _.total) * PI;
  5571. if (i == (L - 1)) {
  5572. eA = pi2 + _.oA;
  5573. }
  5574. d.startAngle = sA;
  5575. d.endAngle = eA;
  5576. d.totalAngle = eA - sA;
  5577. d.middleAngle = (sA + eA) / 2;
  5578. sA = eA+sepa;
  5579. }, _);
  5580. r = $.parsePercent(r,f);
  5581. /**
  5582. * calculate pie chart's radius
  5583. */
  5584. if (r <= 0 || r > f) {
  5585. r = _.push('radius',f);
  5586. }
  5587. _.r = r;
  5588. /**
  5589. * calculate pie chart's alignment
  5590. */
  5591. if (_.get('align') == _.L) {
  5592. _.push(_.X, r + _.get('l_originx') + _.get('offsetx'));
  5593. } else if (_.get('align') == _.R) {
  5594. _.push(_.X, _.get('r_originx') - r + _.get('offsetx'));
  5595. } else {
  5596. _.push(_.X, _.get('centerx') + _.get('offsetx'));
  5597. }
  5598. _.topY = _.push(_.Y, _.get('centery') + _.get('offsety'));
  5599. $.apply(_.get('sub_option'),$.clone([_.X, _.Y, 'bound_event','mutex','increment'], _.options));
  5600. }
  5601. });
  5602. /** @end */
  5603. /**
  5604. * @overview this component use for abc
  5605. * @component#@chart#$.Pie2D
  5606. * @extend#$.Pie
  5607. */
  5608. $.Pie2D = $.extend($.Pie, {
  5609. /**
  5610. * initialize the context for the pie2d
  5611. */
  5612. configure : function() {
  5613. /**
  5614. * invoked the super class's configuration
  5615. */
  5616. $.Pie2D.superclass.configure.call(this);
  5617. this.type = 'pie2d';
  5618. },
  5619. doSector:function(_){
  5620. return new $[_.sub](_.get('sub_option'), _);
  5621. },
  5622. doConfig : function() {
  5623. $.Pie2D.superclass.doConfig.call(this);
  5624. var _ = this._();
  5625. /**
  5626. * quick config to all rectangle
  5627. */
  5628. _.push('sub_option.radius',_.r)
  5629. _.parse(_);
  5630. }
  5631. });
  5632. /**
  5633. * @end
  5634. */
  5635. /**
  5636. * @overview this component use for abc
  5637. * @component#@chart#$.Pie3D
  5638. * @extend#$.Pie
  5639. */
  5640. $.Pie3D = $.extend($.Pie, {
  5641. configure : function() {
  5642. /**
  5643. * invoked the super class's configuration
  5644. */
  5645. $.Pie3D.superclass.configure.apply(this, arguments);
  5646. this.type = 'pie3d';
  5647. this.dimension = $._3D;
  5648. this.set({
  5649. /**
  5650. * @cfg {Number} Three-dimensional rotation Z in degree(angle).socpe{0-90}.(default to 45)
  5651. */
  5652. zRotate : 45,
  5653. /**
  5654. * @cfg {Number} Specifies the pie's thickness in pixels.(default to 30)
  5655. */
  5656. yHeight : 30
  5657. });
  5658. },
  5659. doSector : function(_,d) {
  5660. _.push('sub_option.cylinder_height', (d.cylinder_height ? d.cylinder_height * Math.cos($.angle2Radian(_.get('zRotate'))) : _.get('cylinder_height')));
  5661. var s = new $[_.sub](_.get('sub_option'), _);
  5662. s.proxy = true;
  5663. return s;
  5664. },
  5665. doConfig : function() {
  5666. $.Pie3D.superclass.doConfig.call(this);
  5667. var _ = this._(), z = _.get('zRotate');
  5668. _.push('zRotate', $.between(0, 90, 90 - z));
  5669. _.push('cylinder_height', _.get('yHeight') * Math.cos($.angle2Radian(z)));
  5670. _.a = _.push('sub_option.semi_major_axis', _.r);
  5671. _.b = _.push('sub_option.semi_minor_axis', _.r * z / 90);
  5672. _.topY = _.push('sub_option.originy', _.get(_.Y) - _.get('yHeight') / 2);
  5673. _.parse(_);
  5674. var layer,spaint,L = [],c = _.get('counterclockwise'), abs = function(n,M) {
  5675. /**
  5676. * If M,close to pi/2,else pi*3/2
  5677. */
  5678. return 1 + Math.sin(M?(n+Math.PI):n);
  5679. }, t = 'startAngle', d = 'endAngle',Q,s,e
  5680. /**
  5681. * If the inside layer visibile
  5682. */
  5683. lay =function(C,g,z,f){
  5684. Q = $.quadrantd(g);
  5685. if (C &&(Q ==0 || Q ==3) || (!C && (Q ==2 || Q ==1))) {
  5686. layer.push({
  5687. g : g,
  5688. z : g==z,
  5689. x : f.x,
  5690. y : f.y,
  5691. a : f.a,
  5692. b : f.b,
  5693. color : $.dark(f.get('background_color')),
  5694. h : f.h,
  5695. F : f
  5696. });
  5697. }
  5698. };
  5699. _.proxy = new $.Custom({
  5700. z_index : _.get('z_index') + 1,
  5701. drawFn : function() {
  5702. this.drawSector();
  5703. L = [];
  5704. _.sectors.each(function(s) {
  5705. if (s.get('label')) {
  5706. if (s.expanded)
  5707. L.push(s.label);
  5708. else
  5709. s.label.draw();
  5710. }
  5711. });
  5712. L.each(function(l) {
  5713. l.draw()
  5714. });
  5715. }
  5716. });
  5717. _.proxy.drawSector = function() {
  5718. /**
  5719. * paint bottom layer
  5720. */
  5721. _.sectors.each(function(s, i) {
  5722. _.T.ellipse(s.x, s.y + s.h, s.a, s.b, s.get(t), s.get(d), 0, s.get('border.enable'), s.get('border.width'), s.get('border.color'), s.get('shadow'), c, true);
  5723. }, _);
  5724. layer = [];
  5725. spaint = [];
  5726. /**
  5727. * sort layer
  5728. */
  5729. _.sectors.each(function(f) {
  5730. lay(c,f.get(t),f.get(d),f);
  5731. lay(!c,f.get(d),f.get(t),f);
  5732. spaint = spaint.concat($.visible(f.get(t),f.get(d),f));
  5733. }, _);
  5734. /**
  5735. * realtime sort
  5736. */
  5737. layer.sor(function(p, q) {
  5738. var r = abs(p.g) - abs(q.g);
  5739. return r==0?p.z:r > 0;
  5740. });
  5741. /**
  5742. * paint inside layer
  5743. */
  5744. layer.each(function(f, i) {
  5745. _.T.sector3D.layerDraw.call(_.T, f.x, f.y, f.a + 0.5, f.b + 0.5, c, f.h, f.g, f.color);
  5746. }, _);
  5747. if(!_.processAnimation){
  5748. /**
  5749. * realtime sort
  5750. */
  5751. spaint.sor(function(p, q) {
  5752. return abs((p.s+p.e)/2,1) - abs((q.s+q.e)/2,1)<0;
  5753. });
  5754. }
  5755. /**
  5756. * paint outside layer
  5757. */
  5758. spaint.each(function(s, i) {
  5759. _.T.sector3D.sPaint.call(_.T, s.f.x, s.f.y, s.f.a, s.f.b, s.s, s.e, c, s.f.h, s.f.get('f_color'));
  5760. }, _);
  5761. /**
  5762. * paint top layer
  5763. */
  5764. _.sectors.each(function(s, i) {
  5765. _.T.ellipse(s.x, s.y, s.a, s.b, s.get(t), s.get(d), s.get('f_color'), s.get('border.enable'), s.get('border.width'), s.get('border.color'), false, false, true);
  5766. }, _);
  5767. }
  5768. _.components.push(_.proxy);
  5769. }
  5770. });
  5771. /**
  5772. * @end
  5773. */
  5774. /**
  5775. * @overview this component use for show a donut chart
  5776. * @component#@chart#$.Donut2D
  5777. * @extend#$.Pie
  5778. */
  5779. $.Donut2D = $.extend($.Pie, {
  5780. /**
  5781. * initialize the context for the pie2d
  5782. */
  5783. configure : function() {
  5784. /**
  5785. * invoked the super class's configuration
  5786. */
  5787. $.Donut2D.superclass.configure.call(this);
  5788. this.type = 'donut2d';
  5789. this.set({
  5790. /**
  5791. * @cfg {Number} Specifies the width when show a donut.If the value lt 1,It will be as a percentage,value will be radius*donutwidth.only applies when it not 0.(default to 0.3)
  5792. */
  5793. donutwidth : 0.3,
  5794. /**
  5795. * @cfg {Object/String} Specifies the config of Center Text details see <link>$.Text</link>,If given a string,it will only apply the text.note:If the text is empty,then will not display
  5796. */
  5797. center : {
  5798. text:'',
  5799. line_height:24,
  5800. fontweight : 'bold',
  5801. /**
  5802. * Specifies the font-size in pixels of center text.(default to 24)
  5803. */
  5804. fontsize : 24
  5805. }
  5806. });
  5807. },
  5808. doSector:function(){
  5809. return new $.Sector2D(this.get('sub_option'), this);
  5810. },
  5811. doConfig : function() {
  5812. $.Donut2D.superclass.doConfig.call(this);
  5813. var _ = this._(),d='donutwidth',r = _.r;
  5814. /**
  5815. * quick config to all rectangle
  5816. */
  5817. _.push('sub_option.radius',r)
  5818. if(_.get(d)>0){
  5819. if(_.get(d)<1){
  5820. _.push(d,Math.floor(r*_.get(d)));
  5821. }else if(_.get(d)>=r){
  5822. _.push(d,0);
  5823. }
  5824. _.push('sub_option.donutwidth',_.get(d));
  5825. }
  5826. if ($.isString(_.get('center'))) {
  5827. _.push('center', $.applyIf({
  5828. text : _.get('center')
  5829. }, _.default_.center));
  5830. }
  5831. if (_.get('center.text') != '') {
  5832. _.push('center.originx',_.get(_.X));
  5833. _.push('center.originy',_.get(_.Y));
  5834. _.push('center.textBaseline','middle');
  5835. _.components.push(new $.Text(_.get('center'), _));
  5836. }
  5837. _.parse(_);
  5838. }
  5839. });
  5840. /**
  5841. * @end
  5842. */
  5843. /**
  5844. * @overview this class is abstract,use for config column
  5845. * @component#$.Column
  5846. * @extend#$.Chart
  5847. */
  5848. $.Column = $.extend($.Chart, {
  5849. /**
  5850. * initialize the context for the Column
  5851. */
  5852. configure : function(config) {
  5853. /**
  5854. * invoked the super class's configuration
  5855. */
  5856. $.Column.superclass.configure.call(this);
  5857. this.type = 'column';
  5858. this.set({
  5859. /**
  5860. * @cfg {<link>$.Coordinate2D</link>} the option for coordinate.
  5861. */
  5862. coordinate : {},
  5863. /**
  5864. * @cfg {Number} the width of each column(default to calculate according to coordinate's width)
  5865. */
  5866. colwidth : undefined,
  5867. /**
  5868. * @cfg {Number} the distance of column's bottom and text(default to 6)
  5869. */
  5870. text_space : 6,
  5871. /**
  5872. * @cfg {String} the align of scale(default to 'left') Available value are:
  5873. * @Option 'left'
  5874. * @Option 'right'
  5875. */
  5876. scaleAlign : 'left',
  5877. /**
  5878. * @cfg {<link>$.Rectangle</link>} Specifies option of rectangle.
  5879. */
  5880. sub_option : {},
  5881. /**
  5882. * @cfg {<link>$.Text</link>} Specifies option of label at bottom.
  5883. */
  5884. label:{}
  5885. });
  5886. this.registerEvent();
  5887. },
  5888. doAnimation : function(t, d,_) {
  5889. var h;
  5890. _.coo.draw();
  5891. _.labels.each(function(l){
  5892. l.draw();
  5893. });
  5894. _.rectangles.each(function(r){
  5895. h = Math.ceil(_.animationArithmetic(t, 0, r.height, d));
  5896. r.push(_.Y, r.y + (r.height - h));
  5897. r.push(_.H, h);
  5898. r.drawRectangle();
  5899. });
  5900. },
  5901. /**
  5902. * @method Returns the coordinate of this element.
  5903. * @return $.Coordinate2D
  5904. */
  5905. getCoordinate:function(){
  5906. return this.coo;
  5907. },
  5908. doLabel:function(_,id,text,x, y){
  5909. _.labels.push(new $.Text($.apply(_.get('label'),{
  5910. id : id,
  5911. text : text,
  5912. originx : x,
  5913. originy : y
  5914. }), _));
  5915. },
  5916. doParse : function(_,d, i, o) {
  5917. _.doActing(_,d,o,i);
  5918. },
  5919. doConfig : function() {
  5920. $.Column.superclass.doConfig.call(this);
  5921. var _ = this._(),c = 'colwidth',z = 'z_index';
  5922. _.sub = _.is3D()?'Rectangle3D':'Rectangle2D';
  5923. _.rectangles = [];
  5924. _.labels = [];
  5925. _.components.push(_.labels);
  5926. _.components.push(_.rectangles);
  5927. /**
  5928. * apply the coordinate feature
  5929. */
  5930. $.Coordinate.coordinate.call(_);
  5931. _.rectangles.zIndex = _.get(z);
  5932. _.labels.zIndex = _.get(z) + 1;
  5933. var L = _.data.length, W = _.get('coordinate.valid_width'),w_,hw,KL;
  5934. if (_.dataType == 'simple') {
  5935. w_= Math.floor(W*2 / (L * 3 + 1));
  5936. hw = _.pushIf(c, w_);
  5937. KL = L+1;
  5938. }else{
  5939. KL = _.get('labels').length;
  5940. L = KL * L + (_.is3D()?(L-1)*KL*_.get('group_fator'):0);
  5941. w_= Math.floor(W / (KL + 1 + L));
  5942. hw = _.pushIf(c,w_);
  5943. KL +=1;
  5944. }
  5945. if (hw * L > W) {
  5946. hw = _.push(c, w_);
  5947. }
  5948. /**
  5949. * the space of two column
  5950. */
  5951. _.push('hispace', (W - hw * L) / KL);
  5952. if (_.is3D()) {
  5953. _.push('zHeight', _.get(c) * _.get('zScale'));
  5954. _.push('sub_option.zHeight', _.get('zHeight'));
  5955. _.push('sub_option.xAngle_', _.get('xAngle_'));
  5956. _.push('sub_option.yAngle_', _.get('yAngle_'));
  5957. }
  5958. /**
  5959. * use option create a coordinate
  5960. */
  5961. _.coo = $.Coordinate.coordinate_.call(_);
  5962. _.components.push(_.coo);
  5963. _.push('sub_option.width', _.get(c));
  5964. }
  5965. });
  5966. /**
  5967. * @end
  5968. */
  5969. /**
  5970. * @overview the column2d componment
  5971. * @component#@chart#$.Column2D
  5972. * @extend#$.Column
  5973. */
  5974. $.Column2D = $.extend($.Column, {
  5975. /**
  5976. * initialize the context for the Column2D
  5977. */
  5978. configure : function() {
  5979. /**
  5980. * invoked the super class's configuration
  5981. */
  5982. $.Column2D.superclass.configure.call(this);
  5983. this.type = 'column2d';
  5984. },
  5985. doConfig : function() {
  5986. $.Column2D.superclass.doConfig.call(this);
  5987. /**
  5988. * get the max/min scale of this coordinate for calculated the height
  5989. */
  5990. var _ = this._(),
  5991. c = _.get('colwidth'),
  5992. s = _.get('hispace'),
  5993. S = _.coo.getScale(_.get('scaleAlign')),
  5994. H = _.coo.get(_.H),
  5995. h2 = c / 2,
  5996. gw = c + s,
  5997. h,
  5998. y0 = _.coo.get(_.Y) + H,
  5999. y = y0 - S.basic*H - (_.is3D()?(_.get('zHeight') * (_.get('bottom_scale') - 1) / 2 * _.get('yAngle_')):0),
  6000. x = s+_.coo.get('x_start');
  6001. y0 = y0 + _.get('text_space') + _.coo.get('axis.width')[2];
  6002. _.data.each(function(d, i) {
  6003. h = (d.value - S.start) * H / S.distance;
  6004. _.doParse(_,d, i, {
  6005. id : i,
  6006. originx :x + i * gw,
  6007. originy : y - (h>0? h :0),
  6008. height : Math.abs(h)
  6009. });
  6010. _.rectangles.push(new $[_.sub](_.get('sub_option'), _));
  6011. _.doLabel(_,i, d.name, x + gw * i + h2, y0);
  6012. }, _);
  6013. }
  6014. });
  6015. /**
  6016. *@end
  6017. */
  6018. /**
  6019. * @overview this component use for abc
  6020. * @component#@chart#$.Column3D
  6021. * @extend#$.Column2D
  6022. */
  6023. $.Column3D = $.extend($.Column2D, {
  6024. /**
  6025. * initialize the context for the Column3D
  6026. */
  6027. configure : function() {
  6028. /**
  6029. * invoked the super class's configuration
  6030. */
  6031. $.Column3D.superclass.configure.call(this);
  6032. this.type = 'column3d';
  6033. this.dimension = $._3D;
  6034. this.set({
  6035. /**
  6036. * @cfg {<link>$.Coordinate3D</link>} the option for coordinate.
  6037. */
  6038. coordinate : {},
  6039. /**
  6040. * @cfg {Number(0~90)} Three-dimensional rotation X in degree(angle).(default to 60)
  6041. */
  6042. xAngle : 60,
  6043. /**
  6044. * @cfg {Number(0~90)} Three-dimensional rotation Y in degree(angle).(default to 20)
  6045. */
  6046. yAngle : 20,
  6047. /**
  6048. * @cfg {Number} Three-dimensional z-axis deep factor.frame of reference is width.(default to 1)
  6049. */
  6050. zScale : 1,
  6051. /**
  6052. * @cfg {Number(1~)} Three-dimensional z-axis deep factor of pedestal.frame of reference is width.(default to 1.4)
  6053. */
  6054. bottom_scale : 1.4
  6055. });
  6056. },
  6057. doConfig : function() {
  6058. $.Column3D.superclass.doConfig.call(this);
  6059. }
  6060. });
  6061. /**
  6062. *@end
  6063. */
  6064. /**
  6065. * @overview this component will draw a cluster column2d chart.
  6066. * @component#@chart#$.ColumnMulti2D
  6067. * @extend#$.Column
  6068. */
  6069. $.ColumnMulti2D = $.extend($.Column, {
  6070. /**
  6071. * initialize the context for the ColumnMulti2D
  6072. */
  6073. configure : function() {
  6074. /**
  6075. * invoked the super class's configuration
  6076. */
  6077. $.ColumnMulti2D.superclass.configure.call(this);
  6078. this.type = 'columnmulti2d';
  6079. this.dataType = 'complex';
  6080. this.set({
  6081. /**
  6082. * @cfg {Array} the array of labels close to the axis
  6083. */
  6084. labels : []
  6085. });
  6086. },
  6087. doConfig : function() {
  6088. $.ColumnMulti2D.superclass.doConfig.call(this);
  6089. /**
  6090. * get the max/min scale of this coordinate for calculated the height
  6091. */
  6092. var _ = this._(),
  6093. s = _.get('hispace'),
  6094. bw = _.get('colwidth'),
  6095. H = _.coo.get(_.H),
  6096. S = _.coo.getScale(_.get('scaleAlign')),
  6097. q = bw * (_.get('group_fator') || 0),
  6098. gw = _.data.length * bw + s + (_.is3D() ? (_.data.length - 1) * q : 0),
  6099. h,
  6100. x = _.coo.get('x_start') + s,
  6101. y = _.coo.get(_.Y) - S.basic * H + H,
  6102. y0=_.coo.get(_.Y) + H + _.get('text_space')+ _.coo.get('axis.width')[2];
  6103. _.columns.each(function(column, i) {
  6104. column.item.each(function(d, j) {
  6105. h = (d.value - S.start) * H / S.distance;
  6106. _.doParse(_, d, j, {
  6107. id : i + '-' + j,
  6108. originx : x + j * (bw + q) + i * gw,
  6109. originy : y - (h > 0 ? h : 0),
  6110. height : Math.abs(h)
  6111. });
  6112. _.rectangles.push(new $[_.sub](_.get('sub_option'), this));
  6113. }, _);
  6114. _.doLabel(_, i, column.name, x - s * 0.5 + (i + 0.5) * gw, y0);
  6115. }, _);
  6116. }
  6117. });
  6118. /**
  6119. * @end
  6120. */
  6121. /**
  6122. * @overview this component will draw a cluster column3d chart.
  6123. * @component#@chart#$.ColumnMulti3D
  6124. * @extend#$.ColumnMulti2D
  6125. */
  6126. $.ColumnMulti3D = $.extend($.ColumnMulti2D, {
  6127. /**
  6128. * initialize the context for the ColumnMulti3D
  6129. */
  6130. configure : function() {
  6131. /**
  6132. * invoked the super class's configuration
  6133. */
  6134. $.ColumnMulti3D.superclass.configure.call(this);
  6135. this.type = 'columnmulti3d';
  6136. this.dataType = 'complex';
  6137. this.dimension = $._3D;
  6138. this.set({
  6139. /**
  6140. * @cfg {Number(0~90)} Three-dimensional rotation X in degree(angle).(default to 60)
  6141. */
  6142. xAngle : 60,
  6143. /**
  6144. * @cfg {Number(0~90)} Three-dimensional rotation Y in degree(angle).(default to 20)
  6145. */
  6146. yAngle : 20,
  6147. /**
  6148. * @cfg {Number} Three-dimensional z-axis deep factor.frame of reference is width.(default to 1)
  6149. */
  6150. zScale : 1,
  6151. group_fator : 0.3,
  6152. /**
  6153. * @cfg {Number(1~)} Three-dimensional z-axis deep factor of pedestal.frame of reference is width.(default to 1.4)
  6154. */
  6155. bottom_scale : 1.4
  6156. });
  6157. },
  6158. doConfig : function() {
  6159. $.ColumnMulti3D.superclass.doConfig.call(this);
  6160. }
  6161. });
  6162. /**
  6163. * @end
  6164. */
  6165. /**
  6166. * @overview this class is abstract,use for config bar
  6167. * @component#$.Bar
  6168. * @extend#$.Chart
  6169. */
  6170. $.Bar = $.extend($.Chart, {
  6171. /**
  6172. * initialize the context for the bar
  6173. */
  6174. configure : function() {
  6175. /**
  6176. * invoked the super class's configuration
  6177. */
  6178. $.Bar.superclass.configure.call(this);
  6179. this.type = 'bar';
  6180. this.set({
  6181. /**
  6182. * @cfg {<link>$.Coordinate2D</link>} the option for coordinate.
  6183. */
  6184. coordinate : {
  6185. striped_direction : 'h'
  6186. },
  6187. /**
  6188. * @cfg {Number} Specifies the width of each bar(default to calculate according to coordinate's height)
  6189. */
  6190. barheight : undefined,
  6191. /**
  6192. * @cfg {Number} Specifies the distance of bar's bottom and text(default to 6)
  6193. */
  6194. text_space : 6,
  6195. /**
  6196. * @cfg {String} Specifies the align of scale(default to 'bottom') Available value are:
  6197. * @Option 'bottom'
  6198. */
  6199. scaleAlign : 'bottom',
  6200. /**
  6201. * @cfg {<link>$.Rectangle</link>} Specifies option of rectangle.
  6202. */
  6203. sub_option : {},
  6204. /**
  6205. * @cfg {<link>$.Text</link>} Specifies option of label at left.
  6206. */
  6207. label : {}
  6208. });
  6209. },
  6210. /**
  6211. * @method Returns the coordinate of this element.
  6212. * @return $.Coordinate2D
  6213. */
  6214. getCoordinate : function() {
  6215. return this.coo;
  6216. },
  6217. doLabel : function(id, text, x, y) {
  6218. this.labels.push(new $.Text($.apply(this.get('label'), {
  6219. id : id,
  6220. text : text,
  6221. textAlign : 'right',
  6222. textBaseline : 'middle',
  6223. originx : x,
  6224. originy : y
  6225. }), this));
  6226. },
  6227. doParse : function(_, d, i, o) {
  6228. _.doActing(_, d, o,i);
  6229. },
  6230. doAnimation : function(t, d,_) {
  6231. _.coo.draw();
  6232. _.labels.each(function(l) {
  6233. l.draw();
  6234. });
  6235. _.rectangles.each(function(r) {
  6236. r.push(_.W, Math.ceil(_.animationArithmetic(t, 0, r.width, d)));
  6237. r.drawRectangle();
  6238. });
  6239. },
  6240. doConfig : function() {
  6241. $.Bar.superclass.doConfig.call(this);
  6242. var _ = this._(), b = 'barheight', z = 'z_index';
  6243. /**
  6244. * Apply the coordinate feature
  6245. */
  6246. $.Coordinate.coordinate.call(_);
  6247. _.rectangles = [];
  6248. _.labels = [];
  6249. _.rectangles.zIndex = _.get(z);
  6250. _.labels.zIndex = _.get(z) + 1;
  6251. _.components.push(_.labels);
  6252. _.components.push(_.rectangles);
  6253. var L = _.data.length, H = _.get('coordinate.valid_height'),h_,bh,KL;
  6254. if (_.dataType == 'simple') {
  6255. h_= Math.floor(H*2 / (L * 3 + 1));
  6256. bh = _.pushIf(b, h_);
  6257. KL = L+1;
  6258. }else{
  6259. KL = _.get('labels').length;
  6260. L = KL * L + (_.is3D()?(L-1)*KL*_.get('group_fator'):0);
  6261. h_= Math.floor(H / (KL + 1 + L));
  6262. bh = _.pushIf(b,h_);
  6263. KL +=1;
  6264. }
  6265. if (bh * L > H) {
  6266. bh = _.push(b, h_);
  6267. }
  6268. /**
  6269. * the space of two bar
  6270. */
  6271. _.push('barspace', (H - bh * L) / KL);
  6272. /**
  6273. * use option create a coordinate
  6274. */
  6275. _.coo = $.Coordinate.coordinate_.call(_);
  6276. _.components.push(_.coo);
  6277. /**
  6278. * quick config to all rectangle
  6279. */
  6280. _.push('sub_option.height', bh);
  6281. _.push('sub_option.valueAlign', _.R);
  6282. _.push('sub_option.tipAlign', _.R);
  6283. }
  6284. });
  6285. /**
  6286. * @end
  6287. */
  6288. /**
  6289. * @overview this component will draw a bar2d chart.
  6290. * @component#@chart#$.Bar2D
  6291. * @extend#$.Bar
  6292. */
  6293. $.Bar2D = $.extend($.Bar, {
  6294. /**
  6295. * initialize the context for the pie
  6296. */
  6297. configure : function() {
  6298. /**
  6299. * invoked the super class's configuration
  6300. */
  6301. $.Bar2D.superclass.configure.call(this);
  6302. this.type = 'bar2d';
  6303. },
  6304. doConfig : function() {
  6305. $.Bar2D.superclass.doConfig.call(this);
  6306. /**
  6307. * get the max/min scale of this coordinate for calculated the height
  6308. */
  6309. var _ = this._(),
  6310. h = _.get('barheight'),
  6311. b = _.get('barspace'),
  6312. S = _.coo.getScale(_.get('scaleAlign')),
  6313. W = _.coo.get(_.W),
  6314. h2 = h / 2,
  6315. gw = h + b,
  6316. w,
  6317. I = _.coo.get(_.X) + S.basic * W,
  6318. x0 = _.coo.get(_.X) - _.get('text_space')-_.coo.get('axis.width')[3],
  6319. y0 = _.coo.get('y_start')+ b;
  6320. _.data.each(function(d, i) {
  6321. w = (d.value - S.start) * W / S.distance;
  6322. _.doParse(_, d, i, {
  6323. id : i,
  6324. originy : y0 + i * gw,
  6325. width : Math.abs(w),
  6326. originx : I + (w > 0 ? 0 : -Math.abs(w))
  6327. });
  6328. _.rectangles.push(new $.Rectangle2D(_.get('sub_option'), _));
  6329. _.doLabel(i, d.name, x0, y0 + i * gw + h2);
  6330. }, _);
  6331. }
  6332. });
  6333. /**
  6334. * @end
  6335. */
  6336. /**
  6337. * @overview this component will draw a cluster bar2d chart.
  6338. * @component#@chart#$.BarMulti2D
  6339. * @extend#$.Bar
  6340. */
  6341. $.BarMulti2D = $.extend($.Bar, {
  6342. /**
  6343. * initialize the context for the BarMulti2D
  6344. */
  6345. configure : function() {
  6346. /**
  6347. * invoked the super class's configuration
  6348. */
  6349. $.BarMulti2D.superclass.configure.call(this);
  6350. this.type = 'barmulti2d';
  6351. this.dataType = 'complex';
  6352. this.set({
  6353. /**
  6354. * @cfg {Array} the array of labels close to the axis
  6355. */
  6356. labels : []
  6357. });
  6358. },
  6359. doConfig : function() {
  6360. $.BarMulti2D.superclass.doConfig.call(this);
  6361. /**
  6362. * get the max/min scale of this coordinate for calculated the height
  6363. */
  6364. var _ = this._(), L = _.data.length,W = _.coo.get(_.W), b = 'barheight', s = 'barspace',bh=_.get(b),
  6365. S = _.coo.getScale(_.get('scaleAlign')), gw = L * bh + _.get(s), h2 = _.get(b) / 2,w,
  6366. I = _.coo.get(_.X) + S.basic*W,x = _.coo.get(_.X)-_.get('text_space')-_.coo.get('axis.width')[3],
  6367. y = _.coo.get('y_start')+ _.get(s);
  6368. _.columns.each(function(column, i) {
  6369. column.item.each(function(d, j) {
  6370. w = (d.value - S.start) * W / S.distance;
  6371. _.doParse(_, d, j, {
  6372. id : i + '-' + j,
  6373. originy : y + j * bh + i * gw,
  6374. width : Math.abs(w),
  6375. originx: I+(w>0?0:-Math.abs(w))
  6376. });
  6377. _.rectangles.push(new $.Rectangle2D(_.get('sub_option'), _));
  6378. }, _);
  6379. _.doLabel(i, column.name, x, y - _.get(s) * 0.5 + (i + 0.5) * gw);
  6380. }, _);
  6381. }
  6382. });
  6383. /**
  6384. * @end
  6385. */
  6386. /**
  6387. * Line ability for real-time show
  6388. *
  6389. * @overview this component use for abc
  6390. * @component#$.LineSegment
  6391. * @extend#$.Component
  6392. */
  6393. $.LineSegment = $.extend($.Component, {
  6394. configure : function() {
  6395. /**
  6396. * invoked the super class's configuration
  6397. */
  6398. $.LineSegment.superclass.configure.apply(this, arguments);
  6399. /**
  6400. * indicate the component's type
  6401. */
  6402. this.type = 'linesegment';
  6403. this.set({
  6404. /**
  6405. * @cfg {Number} Specifies the default linewidth of the canvas's context in this element.(defaults to 1)
  6406. */
  6407. brushsize : 1,
  6408. /**
  6409. * @cfg {Boolean} If true there show a point when Line-line intersection(default to true)
  6410. */
  6411. intersection : true,
  6412. /**
  6413. * @cfg {<link>$.Text</link>} Specifies the config of label,set false to make label disabled.
  6414. */
  6415. label : {},
  6416. /**
  6417. * @cfg {String} Specifies the shape of two line segment' point(default to 'round').Only applies when intersection is true Available value are:
  6418. * @Option 'round'
  6419. */
  6420. sign : 'round',
  6421. /**
  6422. * @cfg {Boolean} If true the centre of point will be hollow.(default to true)
  6423. */
  6424. hollow : true,
  6425. /**
  6426. * @cfg {Boolean} If true the color of the centre of point will be hollow_color.else will be background_color.(default to true)
  6427. */
  6428. hollow_inside:true,
  6429. /**
  6430. * @cfg {String} Specifies the bgcolor when hollow applies true.(default to '#FEFEFE')
  6431. */
  6432. hollow_color : '#FEFEFE',
  6433. /**
  6434. * @cfg {Boolean} If true Line will smooth.(default to false)
  6435. */
  6436. smooth : false,
  6437. /**
  6438. * @cfg {Number} Specifies smoothness of line will be.(default to 1.5)
  6439. * 1 means control points midway between points, 2 means 1/3 from the point,formula is 1/(smoothing + 1) from the point
  6440. */
  6441. smoothing : 1.5,
  6442. /**
  6443. * @cfg {Number} Specifies the size of point.(default size 6).Only applies when intersection is true
  6444. */
  6445. point_size : 6,
  6446. /**
  6447. * @inner {Array} the set of points to compose line segment
  6448. */
  6449. points : [],
  6450. /**
  6451. * @inner {Boolean} If true the event accord width coordinate.(default to false)
  6452. */
  6453. keep_with_coordinate : false,
  6454. /**
  6455. * @cfg {Number} Override the default as 1
  6456. */
  6457. shadow_blur : 1,
  6458. /**
  6459. * @cfg {Number} Override the default as 1
  6460. */
  6461. shadow_offsety : 1,
  6462. /**
  6463. * @inner {Number} Specifies the space between two point
  6464. */
  6465. point_space : 0,
  6466. /**
  6467. * @inner {Object} reference of coordinate
  6468. */
  6469. coordinate : null,
  6470. /**
  6471. * @cfg {Number} Specifies the valid range of x-direction.(default to 0)
  6472. */
  6473. event_range_x : 0,
  6474. /**
  6475. * @cfg {Boolean} If true tip show when the mouse must enter the valid distance of axis y.(default to false)
  6476. */
  6477. limit_y : false,
  6478. /**
  6479. * @cfg {Number} Specifies the space between the tip and point.(default to 2)
  6480. */
  6481. tip_offset : 2,
  6482. /**
  6483. * @cfg {Number} Specifies the valid range of y-direction.(default to 0)
  6484. */
  6485. event_range_y : 0
  6486. });
  6487. this.registerEvent(
  6488. /**
  6489. * @event Fires when parse this label's data.Return value will override existing.
  6490. * @paramter <link>$.LineSegment</link>#seg
  6491. * @paramter string#text the current label's text
  6492. */
  6493. 'parseText');
  6494. this.tip = null;
  6495. this.ignored_ = false;
  6496. },
  6497. drawSegment : function() {
  6498. var _ = this._(),p = _.get('points'),b=_.get('f_color'),h=_.get('brushsize');
  6499. if (_.get('area')) {
  6500. _.T.polygon(_.get('light_color2'), false, 1, '', false,_.get('area_opacity'), _.get('smooth')?p:[{x:_.x,y:_.y}].concat(p.concat([{x:_.x + _.get(_.W),y:_.y}])), _.get('smooth'), _.get('smoothing'),[{x:_.x,y:_.y},{x:_.x + _.get(_.W),y:_.y}]);
  6501. }
  6502. _.T.shadowOn(_.get('shadow'));
  6503. _.T[_.ignored_?"manyLine":"lineArray"](p,h, b, _.get('smooth'), _.get('smoothing'));
  6504. if (_.get('intersection')) {
  6505. var f = _.getPlugin('sign'),s=_.get('point_size'),j = _.get('hollow_color');
  6506. if(_.get('hollow_inside')){
  6507. j=b;
  6508. b = _.get('hollow_color');
  6509. }
  6510. p.each(function(q,i){
  6511. if(!q.ignored){
  6512. if(!f||!f.call(_,_.T,_.get('sign'),q.x, q.y,s,b,j)){
  6513. if (_.get('hollow')) {
  6514. _.T.round(q.x, q.y, s/2-h,b,h+1,j);
  6515. } else {
  6516. _.T.round(q.x, q.y, s/2,b);
  6517. }
  6518. }
  6519. }
  6520. },_);
  6521. }
  6522. if (_.get('shadow')) {
  6523. _.T.shadowOff();
  6524. }
  6525. },
  6526. doDraw : function(_) {
  6527. _.drawSegment();
  6528. if (_.get('label')) {
  6529. _.labels.each(function(l){
  6530. l.draw();
  6531. });
  6532. }
  6533. },
  6534. isEventValid : function() {
  6535. return {
  6536. valid : false
  6537. };
  6538. },
  6539. tipInvoke : function() {
  6540. var x = this.x, y = this.y, o = this.get('tip_offset'), s = this.get('point_size') + o, _ = this;
  6541. return function(w, h, m) {
  6542. var l = m.left, t = m.top;
  6543. l = ((_.tipPosition < 3 && (l - w - x - o > 0)) || (_.tipPosition > 2 && (l - w - x - o < 0))) ? l - (w + o) : l + o;
  6544. t = _.tipPosition % 2 == 0 ? t + s : t - h - s;
  6545. return {
  6546. left : l,
  6547. top : t
  6548. }
  6549. }
  6550. },
  6551. doConfig : function() {
  6552. $.LineSegment.superclass.doConfig.call(this);
  6553. $.Assert.gt(this.get('point_space'),0,'point_space');
  6554. var _ = this._(),L = !!_.get('label'),ps = _.get('point_size') * 3 / 2,sp = _.get('point_space'), ry = _.get('event_range_y'), rx = _.get('event_range_x'), heap = _.get('tipInvokeHeap'), p = _.get('points'),N=_.get('name');
  6555. _.labels = [];
  6556. p.each(function(q){
  6557. q.x_ = q.x;
  6558. q.y_ = q.y;
  6559. if(q.ignored)_.ignored_ = true;
  6560. if(!q.ignored&&L){
  6561. _.push('label.originx', q.x);
  6562. _.push('label.originy', q.y-ps);
  6563. _.push('label.text',_.fireString(_, 'parseText', [_, q.value],q.value));
  6564. $.applyIf(_.get('label'),{
  6565. textBaseline : 'bottom',
  6566. color:_.get('f_color')
  6567. });
  6568. _.labels.push(new $.Text(_.get('label'), _))
  6569. }
  6570. });
  6571. if (rx <= 0||rx > sp / 2) {
  6572. rx = _.push('event_range_x', sp / 2);
  6573. }
  6574. if (ry == 0) {
  6575. ry = _.push('event_range_y', ps/2);
  6576. }
  6577. if (_.get('tip.enable')) {
  6578. /**
  6579. * _ use for tip coincidence
  6580. */
  6581. _.on('mouseover', function(c,e, m) {
  6582. heap.push(_);
  6583. _.tipPosition = heap.length;
  6584. }).on('mouseout', function(c,e, m) {
  6585. heap.pop();
  6586. });
  6587. _.push('tip.invokeOffsetDynamic', true);
  6588. _.tip = new $.Tip(_.get('tip'), _);
  6589. }
  6590. var c = _.get('coordinate'), ly = _.get('limit_y'), k = _.get('keep_with_coordinate'), valid = function(p0, x, y) {
  6591. if (!p0.ignored&&Math.abs(x - (p0.x)) < rx && (!ly || (ly && Math.abs(y - (p0.y)) < ry))) {
  6592. return true;
  6593. }
  6594. return false;
  6595. }, to = function(i) {
  6596. return {
  6597. valid : true,
  6598. name : N,
  6599. value : p[i].value,
  6600. text : p[i].text,
  6601. top : p[i].y,
  6602. left : p[i].x,
  6603. i:i,
  6604. hit : true
  6605. };
  6606. };
  6607. /**
  6608. * override the default method
  6609. */
  6610. _.isEventValid = function(e) {
  6611. if (c && !c.isEventValid(e,c).valid) {
  6612. return {
  6613. valid : false
  6614. };
  6615. }
  6616. var ii = Math.floor((e.x - _.x) / sp);
  6617. if (ii < 0 || ii >= (p.length - 1)) {
  6618. ii = $.between(0, p.length - 1, ii);
  6619. if (valid(p[ii], e.x, e.y))
  6620. return to(ii);
  6621. else
  6622. return {
  6623. valid : k
  6624. };
  6625. }
  6626. /**
  6627. * calculate the pointer's position will between which two point?this function can improve location speed
  6628. */
  6629. for ( var i = ii; i <= ii + 1; i++) {
  6630. if (valid(p[i], e.x, e.y))
  6631. return to(i);
  6632. }
  6633. return {
  6634. valid : k
  6635. };
  6636. }
  6637. }
  6638. });
  6639. /**
  6640. *@end
  6641. */
  6642. /**
  6643. * @overview this class is abstract,use for config line
  6644. * @component#$.Line
  6645. * @extend#$.Chart
  6646. */
  6647. $.Line = $.extend($.Chart, {
  6648. /**
  6649. * initialize the context for the line
  6650. */
  6651. configure : function() {
  6652. /**
  6653. * invoked the super class's configuration
  6654. */
  6655. $.Line.superclass.configure.call(this);
  6656. this.type = 'line';
  6657. this.set({
  6658. /**
  6659. * @cfg {Number} Specifies the default linewidth of the canvas's context in this element.(defaults to 1)
  6660. */
  6661. brushsize : 1,
  6662. /**
  6663. * @cfg {Object} the option for coordinate
  6664. */
  6665. coordinate : {
  6666. axis : {
  6667. width : [0, 0, 2, 2]
  6668. }
  6669. },
  6670. /**
  6671. * @cfg {Object} Specifies config crosshair.(default enable to false).For details see <link>$.CrossHair</link> Note:this has a extra property named 'enable',indicate whether crosshair available(default to false)
  6672. */
  6673. crosshair : {
  6674. enable : false
  6675. },
  6676. /**
  6677. * @cfg {Function} when there has more than one linesegment,you can use tipMocker make them as a tip.(default to null)
  6678. * @paramter Array tips the array of linesegment's tip
  6679. * @paramter int the index of data
  6680. * @return String
  6681. */
  6682. tipMocker:null,
  6683. /**
  6684. * @cfg {Number(0.0~1.0)} If null,the position there will follow the points.If given a number,there has a fixed postion,0 is top,and 1 to bottom.(default to null)
  6685. */
  6686. tipMockerOffset:null,
  6687. /**
  6688. * @cfg {String} the align of scale.(default to 'left') Available value are:
  6689. * @Option 'left'
  6690. * @Option 'right'
  6691. */
  6692. scaleAlign : 'left',
  6693. /**
  6694. * @cfg {String} the align of label.(default to 'bottom') Available value are:
  6695. * @Option 'top,'bottom'
  6696. */
  6697. labelAlign : 'bottom',
  6698. /**
  6699. * @cfg {Array} the array of labels close to the axis
  6700. */
  6701. labels : [],
  6702. /**
  6703. * @inner {Number} the distance of column's bottom and text.(default to 6)
  6704. */
  6705. label_space : 6,
  6706. /**
  6707. * @inner {Boolean} if the point are proportional space.(default to true)
  6708. */
  6709. proportional_spacing : true,
  6710. /**
  6711. * @inner {Number} the space of each label
  6712. */
  6713. label_spacing : 0,
  6714. /**
  6715. * @cfg {<link>$.LineSegment</link>} the option for linesegment.
  6716. */
  6717. sub_option : {},
  6718. /**
  6719. * {Object} the option for legend.
  6720. */
  6721. legend : {
  6722. sign : 'bar'
  6723. },
  6724. /**
  6725. * @cfg {<link>$.Text</link>} Specifies option of label at bottom.
  6726. */
  6727. label:{}
  6728. });
  6729. this.registerEvent(
  6730. /**
  6731. * @event Fires when parse this element'data.Return value will override existing.
  6732. * @paramter object#data the data of one linesegment
  6733. * @paramter object#v the point's value
  6734. * @paramter int#x coordinate-x of point
  6735. * @paramter int#y coordinate-y of point
  6736. * @paramter int#index the index of point
  6737. * @return Object object Detail:
  6738. * @property text the text of point
  6739. * @property x coordinate-x of point
  6740. * @property y coordinate-y of point
  6741. */
  6742. 'parsePoint');
  6743. },
  6744. /**
  6745. * @method Returns the coordinate of this element.
  6746. * @return $.Coordinate2D
  6747. */
  6748. getCoordinate : function() {
  6749. return this.coo;
  6750. },
  6751. doConfig : function() {
  6752. $.Line.superclass.doConfig.call(this);
  6753. var _ = this._(), s = _.data.length == 1;
  6754. /**
  6755. * apply the coordinate feature
  6756. */
  6757. $.Coordinate.coordinate.call(_);
  6758. var vw = _.get('coordinate.valid_width'),vh = _.get('coordinate.valid_height');
  6759. _.lines = [];
  6760. _.lines.zIndex = _.get('z_index');
  6761. _.components.push(_.lines);
  6762. if (_.get('proportional_spacing'))
  6763. _.push('label_spacing', vw / (_.get('maxItemSize') - 1));
  6764. _.push('sub_option.width', vw);
  6765. _.push('sub_option.height', vh);
  6766. _.pushIf('sub_option.keep_with_coordinate',s);
  6767. if (_.get('crosshair.enable')) {
  6768. _.push('coordinate.crosshair', _.get('crosshair'));
  6769. _.push('coordinate.crosshair.hcross', s);
  6770. _.push('coordinate.crosshair.invokeOffset', function(e, m) {
  6771. /**
  6772. * TODO how fire muti line?now fire by first line
  6773. */
  6774. var r = _.lines[0].isEventValid(e);
  6775. return r.valid ? r : false;
  6776. });
  6777. }
  6778. _.pushIf('coordinate.scale',[{
  6779. position : _.get('scaleAlign'),
  6780. max_scale : _.get('maxValue')
  6781. }, {
  6782. position : _.get('labelAlign'),
  6783. start_scale : 1,
  6784. scale : 1,
  6785. end_scale : _.get('maxItemSize'),
  6786. labels : _.get('labels'),
  6787. label:_.get('label')
  6788. }]);
  6789. /**
  6790. * use option create a coordinate
  6791. */
  6792. _.coo = $.Coordinate.coordinate_.call(_);
  6793. _.push('sub_option.originx', _.coo.get('x_start'));
  6794. _.push('sub_option.originy', _.coo.get(_.Y) + _.coo.get(_.H));
  6795. _.components.push(_.coo);
  6796. if (_.get('tip.enable')){
  6797. if($.isFunction(_.get('tipMocker'))){
  6798. _.push('sub_option.tip.enable', false);
  6799. _.push('tip.invokeOffsetDynamic', true);
  6800. var U,x=_.coo.get(_.X),y=_.coo.get(_.Y),H=_.coo.get(_.H),f = _.get('tipMockerOffset'),r0,r,r1;
  6801. f = $.isNumber(f)?(f<0?0:(f>1?1:f)):null;
  6802. _.push('tip.invokeOffset',function(w,h,m){
  6803. if(f!=null){
  6804. m.top = y+(H-h)*f;
  6805. }else{
  6806. m.top = m.maxTop-(m.maxTop-m.minTop)/3-h;
  6807. if(h>H||y>m.top){
  6808. m.top = y;
  6809. }
  6810. }
  6811. return {
  6812. left:(m.left - w - x > 5)?m.left-w-5:m.left+5,
  6813. top:m.top
  6814. }
  6815. });
  6816. /**
  6817. * proxy the event parseText
  6818. */
  6819. var p = _.get('tip.listeners.parseText');
  6820. if(p)
  6821. delete _.get('tip.listeners').parseText;
  6822. var mocker = new $.Custom({
  6823. eventValid:function(e){
  6824. r = _.lines[0].isEventValid(e);
  6825. r.hit = r0 != r.i;
  6826. if(r.valid){
  6827. r0 = r.i;
  6828. U = [];
  6829. _.lines.each(function(l,i){
  6830. r1 = l.isEventValid(e);
  6831. if(i==0){
  6832. r.minTop = r.maxTop = r1.top;
  6833. }else{
  6834. r.minTop = Math.min(r.minTop,r1.top);
  6835. r.maxTop = Math.max(r.maxTop,r1.top);
  6836. }
  6837. U.push(p?p(null,r1.name,r1.value,r1.text,r1.i):(r1.name+' '+r1.value));
  6838. });
  6839. r.text = _.get('tipMocker').call(_,U,r.i)||'tipMocker not return';
  6840. }
  6841. return r.valid ? r : false;
  6842. }
  6843. });
  6844. new $.Tip(_.get('tip'),mocker);
  6845. _.components.push(mocker);
  6846. }
  6847. }
  6848. /**
  6849. * quick config to all linesegment
  6850. */
  6851. $.applyIf(_.get('sub_option'), $.clone(['area_opacity'], _.options));
  6852. }
  6853. });
  6854. /**
  6855. * @end
  6856. */
  6857. /**
  6858. * @overview this component will draw a line2d chart.
  6859. * @component#@chart#$.LineBasic2D
  6860. * @extend#$.Line
  6861. */
  6862. $.LineBasic2D = $.extend($.Line, {
  6863. /**
  6864. * initialize the context for the LineBasic2D
  6865. */
  6866. configure : function() {
  6867. /**
  6868. * invoked the super class's configuration
  6869. */
  6870. $.LineBasic2D.superclass.configure.call(this);
  6871. this.type = 'basicline2d';
  6872. this.tipInvokeHeap = [];
  6873. },
  6874. doAnimation : function(t, d,_) {
  6875. _.coo.draw();
  6876. _.lines.each(function(l){
  6877. l.get('points').each(function(p){
  6878. p.y = l.y - Math.ceil(_.animationArithmetic(t, 0, l.y - p.y_, d));
  6879. });
  6880. l.drawSegment();
  6881. });
  6882. },
  6883. doConfig : function() {
  6884. $.LineBasic2D.superclass.doConfig.call(this);
  6885. var _ = this._();
  6886. /**
  6887. * get the max/min scale of this coordinate for calculated the height
  6888. */
  6889. var S = _.coo.getScale(_.get('scaleAlign')), H = _.get('coordinate.valid_height'), sp = _.get('label_spacing'), points, x, y,
  6890. ox = _.get('sub_option.originx'), oy = _.get('sub_option.originy')- S.basic*H, p;
  6891. _.push('sub_option.tip.showType', 'follow');
  6892. _.push('sub_option.coordinate', _.coo);
  6893. _.push('sub_option.tipInvokeHeap', _.tipInvokeHeap);
  6894. _.push('sub_option.point_space', sp);
  6895. _.data.each(function(d, i) {
  6896. points = [];
  6897. d.value.each(function(v, j) {
  6898. x = sp * j;
  6899. y = (v - S.start) * H / S.distance;
  6900. p = {
  6901. x : ox + x,
  6902. y : oy - y,
  6903. value : v,
  6904. text : d.name+' '+v
  6905. };
  6906. $.merge(p, _.fireEvent(_, 'parsePoint', [d, v, x, y, j]));
  6907. points.push(p);
  6908. }, _);
  6909. _.push('sub_option.name', d.name);
  6910. _.push('sub_option.points', points);
  6911. _.push('sub_option.brushsize', d.linewidth || d.line_width || 1);
  6912. _.push('sub_option.background_color', d.background_color || d.color);
  6913. _.lines.push(new $.LineSegment(_.get('sub_option'), _));
  6914. }, this);
  6915. }
  6916. });
  6917. /**
  6918. * @end
  6919. */
  6920. /**
  6921. * @overview this component use for abc
  6922. * @component#@chart#$.Area2D
  6923. * @extend#$.LineBasic2D
  6924. */
  6925. $.Area2D = $.extend($.LineBasic2D, {
  6926. /**
  6927. * initialize the context for the area2d
  6928. */
  6929. configure : function() {
  6930. /**
  6931. * invoked the super class's configuration
  6932. */
  6933. $.Area2D.superclass.configure.call(this);
  6934. this.type = 'area2d';
  6935. this.set({
  6936. /**
  6937. * @cfg {Float} Specifies the opacity of this area.(default to 0.3)
  6938. */
  6939. area_opacity : 0.3
  6940. });
  6941. },
  6942. doConfig : function() {
  6943. /**
  6944. * must apply the area's config before
  6945. */
  6946. this.push('sub_option.area', true);
  6947. $.Area2D.superclass.doConfig.call(this);
  6948. }
  6949. });
  6950. /**
  6951. * @end
  6952. */
  6953. })(iChart);